Boost logo

Ublas :

Subject: Re: [ublas] [bindings] [lapack] geev and the type of the input matrix
From: Marco Guazzone (marco.guazzone_at_[hidden])
Date: 2010-07-06 05:09:43


On Tue, Jul 6, 2010 at 8:32 AM, Marco Guazzone <marco.guazzone_at_[hidden]> wrote:
[cut]

>
> Thomas and Paul,
>
> Thank you very much for the hints!
>

Just another question (sorry for abusing of your patience)

I'd like to create an "eigen" function (as a wrapper of lapack::geev)
which accepts as input matrix both:
* a const& matrix (since it is not modified anymore), and
* a matrix_expression (in order to allow the user to call say
eigen(trans(A),...) )

Obviously this translates in:

--- [code] ---
template <
  typename MatrixExprT,
  typename OutRealVectorT,
  typename OutImagVectorT,
  typename OutLeftMatrixT,
  typename OutRightMatrixT
>
void eigen( ublas::matrix_expression<MatrixExprT> const& A,
                 OutRealVectorT& rv,
                 OutImagVectorT& iv,
                 OutLeftMatrixT& LV,
                 OutRightMatrixT& RV);
--- [/code] ---

However, this code does not compile
$ g++ -Wall -ansi -pedantic -I ~/path/to/boost-numeric_bindings -lm
-llapack -o lapack_geev lapack_geev.cpp

--- [error] ---
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:461:
  instantiated from ‘typename
boost::disable_if<boost::numeric::bindings::lapack::detail::is_workspace<MatrixVR>,
long int>::type boost::numeric::bindings::lapack::geev(char, char,
const MatrixA&, VectorWR&, VectorWI&, MatrixVL&, MatrixVR&) [with
MatrixA = boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >, VectorWR =
boost::numeric::ublas::vector<double,
boost::numeric::ublas::unbounded_array<double, std::allocator<double>
> >, VectorWI = boost::numeric::ublas::vector<double,
boost::numeric::ublas::unbounded_array<double, std::allocator<double>
> >, MatrixVL = boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >, MatrixVR =
boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >]’
lapack_geev_2.cpp:25: instantiated from ‘void
detail::eigen_impl(const MatrixExprT&, OutRealVectorT&,
OutImagVectorT&, OutLeftMatrixT&, OutRightMatrixT&,
boost::numeric::ublas::column_major_tag) [with MatrixExprT =
boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >, OutRealVectorT =
boost::numeric::ublas::vector<double,
boost::numeric::ublas::unbounded_array<double, std::allocator<double>
> >, OutImagVectorT = boost::numeric::ublas::vector<double,
boost::numeric::ublas::unbounded_array<double, std::allocator<double>
> >, OutLeftMatrixT = boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >, OutRightMatrixT =
boost::numeric::ublas::matrix<double,
boost::numeric::ublas::basic_column_major<long unsigned int, long
int>, boost::numeric::ublas::unbounded_array<double,
std::allocator<double> > >]’
lapack_geev_2.cpp:42: instantiated from ‘void eigen(const
MatrixExprT&, OutRealVectorT&, OutImagVectorT&, OutLeftMatrixT&,
OutRightMatrixT&) [with MatrixExprT = main()::in_matrix_type,
OutRealVectorT = main()::out_vector_type, OutImagVectorT =
main()::out_vector_type, OutLeftMatrixT = main()::out_matrix_type,
OutRightMatrixT = main()::out_matrix_type]’
lapack_geev_2.cpp:77: instantiated from here
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:227:
error: no matching function for call to ‘geev(const char&, const
char&, ptrdiff_t, const double*, ptrdiff_t, double*, double*, double*,
ptrdiff_t, double*, ptrdiff_t, double*, int)’
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:57:
note: candidates are: ptrdiff_t
boost::numeric::bindings::lapack::detail::geev(char, char,
fortran_int_t, float*, fortran_int_t, float*, float*, float*,
fortran_int_t, float*, fortran_int_t, float*, fortran_int_t)
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:72:
note: ptrdiff_t
boost::numeric::bindings::lapack::detail::geev(char, char,
fortran_int_t, double*, fortran_int_t, double*, double*, double*,
fortran_int_t, double*, fortran_int_t, double*, fortran_int_t) <near
match>
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:87:
note: ptrdiff_t
boost::numeric::bindings::lapack::detail::geev(char, char,
fortran_int_t, std::complex<float>*, fortran_int_t,
std::complex<float>*, std::complex<float>*, fortran_int_t,
std::complex<float>*, fortran_int_t, std::complex<float>*,
fortran_int_t, float*)
/path/to/boost-numeric_bindings/boost/numeric/bindings/lapack/driver/geev.hpp:104:
note: ptrdiff_t
boost::numeric::bindings::lapack::detail::geev(char, char,
fortran_int_t, std::complex<double>*, fortran_int_t,
std::complex<double>*, std::complex<double>*, fortran_int_t,
std::complex<double>*, fortran_int_t, std::complex<double>*,
fortran_int_t, double*)

... many other errors ...
--- [/error] ---

I've also tried different combinations, that is:

void eigen(ublas::matrix_expression<MatrixExprT>& A, ...)
void eigen(MatrixExprT const& A, ...)
void eigen(MatrixExprT A, ...)

The only that works is the last one.

So what's wrong with my code?

PS: I've attached a sample code. To make it fail during compilation
uncomment (for each function declaration) one of the lines between
the "[NOT COMPILE]" region.

Thank you very much!!

Cheers,

-- Marco