Boost logo

Ublas :

From: Antonio Martino (antonio.martino_at_[hidden])
Date: 2005-02-06 06:36:55


Here is an example of the unexpected behaviour of project():

CODE (uncomment to get the working versions!):

#include "boost/numeric/ublas/matrix.hpp"

namespace UBLAS = boost::numeric::ublas;

//after run m is filled with the cholesky factorization
template <typename M>
inline
std::size_t choleskyT (M &U)
{
    
   //counter
   std::size_t i = 0;
            
        bool Positive = true;
        std::size_t size = U.size2();
        for (i = 0; i < size; ++ i)
        {
                typename M::value_type t(U (i, i));
        
          /*
      //working version:
      (U.row (i)) (UBLAS::range (i + 1, size)) -= UBLAS::prod (
         (UBLAS::column (U, i)) (UBLAS::range (0, i)),
         UBLAS::conj (U (UBLAS::range (0, i), UBLAS::range (i + 1, size)))
         );
          */
                 
      //compiler error:
      UBLAS::project(U.row (i))(UBLAS::range (i + 1, size)) -= UBLAS::prod (
         UBLAS::project (UBLAS::column (U, i), UBLAS::range (0, i)),
         UBLAS::conj (UBLAS::project (U, UBLAS::range (0, i), UBLAS::range
(i + 1, size)))
         );

                //although it is using UBLAS::project it works properly
(worth noting
                // that there is no assignment to projection!):
                t -= UBLAS::inner_prod (
               UBLAS::conj (UBLAS::project (UBLAS::column (U, i),
UBLAS::range (0, i))),
               UBLAS::project (UBLAS::column (U, i), UBLAS::range (0, i))
            );
                
                if ( t <= 0 ){
                        Positive = false;
                        break;
                }
                
                t = sqrt (t);
                U (i, i) = t;
                
      //working version:
      //(U.row (i)) (UBLAS::range (i + 1, size)) /= t;
      //compiler error:
          UBLAS::project(U.row (i), UBLAS::range (i + 1, size)) /= t;
   }
        
        return i;
}

int main(int argc, char *argv[])
{
    boost::numeric::ublas::matrix<double> A(3,3);
    
    A(0,0) = 3; A(0, 1) = 1; A(0, 2) = 0;
    A(1,0) = 1; A(1, 1) = 3; A(1, 2) = 1;
    A(2,0) = 0; A(2, 1) = 1; A(2, 2) = 3;
    
    choleskyT(A);
}

COMPILATION LOG for VC71 (sorry but my compiler is in italian!)

------ Inizio generazione: Progetto: Chol, Configurazione: Debug Win32
------

Compilazione in corso...
main.cpp
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::matrix_indirect<M,boost::numeric::ublas::indirect_ar
ray<A>> boost::numeric::ublas::project(M &,const
boost::numeric::ublas::indirect_array<A> &,const
boost::numeric::ublas::indirect_array<A> &)": argomenti previsti: 3,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(5394):
vedere la dichiarazione di "boost::numeric::ublas::project"
        f:\antonio\chol\main.cpp(67): vedere il riferimento all'istanza
"size_t choleskyT<boost::numeric::ublas::matrix<T>>(M &)" del template di
funzione in corso di compilazione
        with
        [
            T=double,
            M=boost::numeric::ublas::matrix<double>
        ]
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::matrix_slice<M> boost::numeric::ublas::project(const
boost::numeric::ublas::matrix_slice<M> &,const matrix_slice<M>::slice_type
&,const matrix_slice<M>::slice_type &)": argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(4442):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::matrix_slice<M>
boost::numeric::ublas::project(boost::numeric::ublas::matrix_slice<M>
&,const matrix_slice<M>::slice_type &,const matrix_slice<M>::slice_type &)":
argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(4437):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::matrix_slice<const M>
boost::numeric::ublas::project(const M &,const matrix_slice<M>::slice_type
&,const matrix_slice<M>::slice_type &)": argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(4419):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::matrix_slice<M> boost::numeric::ublas::project(M
&,const matrix_slice<M>::slice_type &,const matrix_slice<M>::slice_type &)":
argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(4407):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::matrix_range<M> boost::numeric::ublas::project(const
boost::numeric::ublas::matrix_range<M> &,const matrix_range<M>::range_type
&,const matrix_range<M>::range_type &)": argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(3484):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::matrix_range<M>
boost::numeric::ublas::project(boost::numeric::ublas::matrix_range<M>
&,const matrix_range<M>::range_type &,const matrix_range<M>::range_type &)":
argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(3479):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::matrix_range<const M>
boost::numeric::ublas::project(const M &,const matrix_range<M>::range_type
&,const matrix_range<M>::range_type &)": argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(3473):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::matrix_range<M> boost::numeric::ublas::project(M
&,const matrix_range<M>::range_type &,const matrix_range<M>::range_type &)":
argomenti previsti: 3, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\matrix_proxy.hpp(3461):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_indirect<V,boost::numeric::ublas::indirect_arr
ay<A>> boost::numeric::ublas::project(const
boost::numeric::ublas::vector_indirect<V,boost::numeric::ublas::indirect_arr
ay<A>> &,const boost::numeric::ublas::indirect_array<A> &)": argomenti
previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1711):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_indirect<V,boost::numeric::ublas::indirect_ar
ray<A>>
boost::numeric::ublas::project(boost::numeric::ublas::vector_indirect<V,boos
t::numeric::ublas::indirect_array<A>> &,const
boost::numeric::ublas::indirect_array<A> &)": argomenti previsti: 2,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1706):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_indirect<V,IA>
boost::numeric::ublas::project(const
boost::numeric::ublas::vector_indirect<V,IA> &,const
vector_indirect<V,IA>::slice_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1701):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_indirect<V,IA>
boost::numeric::ublas::project(boost::numeric::ublas::vector_indirect<V,IA>
&,const vector_indirect<V,IA>::slice_type &)": argomenti previsti: 2,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1696):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_indirect<V,IA>
boost::numeric::ublas::project(const
boost::numeric::ublas::vector_indirect<V,IA> &,const
vector_indirect<V,IA>::range_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1691):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_indirect<V,IA>
boost::numeric::ublas::project(boost::numeric::ublas::vector_indirect<V,IA>
&,const vector_indirect<V,IA>::range_type &)": argomenti previsti: 2,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1686):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_indirect<const
V,boost::numeric::ublas::indirect_array<A>>
boost::numeric::ublas::project(const V &,const
boost::numeric::ublas::indirect_array<A> &)": argomenti previsti: 2,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1680):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_indirect<V,boost::numeric::ublas::indirect_ar
ray<A>> boost::numeric::ublas::project(V &,const
boost::numeric::ublas::indirect_array<A> &)": argomenti previsti: 2,
forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1668):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_slice<V> boost::numeric::ublas::project(const
boost::numeric::ublas::vector_slice<V> &,const vector_slice<V>::slice_type
&)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1102):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_slice<V>
boost::numeric::ublas::project(boost::numeric::ublas::vector_slice<V>
&,const vector_slice<V>::slice_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1097):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_slice<const V>
boost::numeric::ublas::project(const V &,const vector_slice<V>::slice_type
&)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1091):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_slice<V> boost::numeric::ublas::project(V
&,const vector_slice<V>::slice_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(1079):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_range<V> boost::numeric::ublas::project(const
boost::numeric::ublas::vector_range<V> &,const vector_range<V>::range_type
&)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(560):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_range<V>
boost::numeric::ublas::project(boost::numeric::ublas::vector_range<V>
&,const vector_range<V>::range_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(555):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780: "const
boost::numeric::ublas::vector_range<const V>
boost::numeric::ublas::project(const V &,const vector_range<V>::range_type
&)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(549):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(29) : error C2780:
"boost::numeric::ublas::vector_range<V> boost::numeric::ublas::project(V
&,const vector_range<V>::range_type &)": argomenti previsti: 2, forniti: 1
        f:\antonio\boost_1_32_0\boost\numeric\ublas\vector_proxy.hpp(537):
vedere la dichiarazione di "boost::numeric::ublas::project"
f:\antonio\chol\main.cpp(52) : error C2678: "/=" binario: non è stato
trovato alcun operatore che accetti un operando sinistro di tipo "const
boost::numeric::ublas::vector_range<V>". È anche possibile che non vi siano
conversioni accettabili
        with
        [
            V=const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double>>
        ]

Il log di generazione è stato salvato in
"file://f:\antonio\chol\Vc\Chol\Debug\BuildLog.htm"
Chol - 26 errore/i, 0 avviso/i

COMPILATION LOG FOR GCC 3.4.2

Compilatore: dev-cpp-3.4.2
Building Makefile: "F:\antonio\chol\Makefile.win"
Esecuzione di make...
mingw32-make.exe -f "F:\antonio\chol\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"C:/Dev-Cpp/include/c++/3.4.2"
-I"C:/Dev-Cpp/include/c++/3.4.2/mingw32"
-I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include"
-I..\boost_1_32_0

main.cpp: In function `size_t choleskyT(M&) [with M =
boost::numeric::ublas::matrix<double, boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >]':
main.cpp:67: instantiated from here
main.cpp:29: error: no matching function for call to
`project(boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<dou
ble, boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >
>)'

main.cpp:67: instantiated from here
main.cpp:52: error: passing `const boost::numeric::ublas::vector_range<const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >
>' as `this' argument of `boost::numeric::ublas::vector_range<E>&
boost::numeric::ublas::vector_range<E>::operator/=(const AT&) [with AT =
double, V = const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >
>]' discards qualifiers

../boost_1_32_0/boost/numeric/ublas/functional.hpp: In static member
function `static void boost::numeric::ublas::scalar_divides_assign<T1,
T2>::apply(typename boost::numeric::ublas::scalar_binary_assign_functor<T1,
T2>::argument1_type, typename
boost::numeric::ublas::scalar_binary_assign_functor<T1, T2>::argument2_type)
[with T1 = const double&, T2 = double]':
../boost_1_32_0/boost/numeric/ublas/vector_assign.hpp:126: instantiated
from `void boost::numeric::ublas::indexing_vector_assign_scalar(F, V&, const
T&) [with F = boost::numeric::ublas::scalar_divides_assign<const double&,
double>, V = boost::numeric::ublas::vector_range<const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >
>, T = double]'
../boost_1_32_0/boost/numeric/ublas/vector_assign.hpp:140: instantiated
from `void boost::numeric::ublas::vector_assign_scalar(F, V&, const T&,
boost::numeric::ublas::dense_proxy_tag) [with F =
boost::numeric::ublas::scalar_divides_assign<const double&, double>, V =
boost::numeric::ublas::vector_range<const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >
>, T = double]'
../boost_1_32_0/boost/numeric/ublas/vector_assign.hpp:182: instantiated
from `void boost::numeric::ublas::vector_assign_scalar(F, V&, const T&)
[with F = boost::numeric::ublas::scalar_divides_assign<const double&,
double>, V = boost::numeric::ublas::vector_range<const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > > >
>, T = double]'

../boost_1_32_0/boost/numeric/ublas/vector_proxy.hpp:203: instantiated
from `boost::numeric::ublas::vector_range<E>&
boost::numeric::ublas::vector_range<E>::operator/=(const AT&) [with AT =
double, V = const
boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double,
boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >
>]'
main.cpp:52: instantiated from `size_t choleskyT(M&) [with M =
boost::numeric::ublas::matrix<double, boost::numeric::ublas::row_major,
boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >]'
main.cpp:67: instantiated from here
../boost_1_32_0/boost/numeric/ublas/functional.hpp:272: error: assignment of
read-only reference `t1'

mingw32-make.exe: *** [main.o] Error 1

Esecuzione terminata

The problem is reported twice as you may see. Note that there is no test of
matrix projection in assignment!

I have used ublas boost 1.32 distribution for both tests

Bye
Antonio