|
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 02:32:43
On Tue, Jul 6, 2010 at 4:01 AM, Paul Leopardi
<paul.leopardi_at_[hidden]> wrote:
> Hi,
> On Tuesday 06 July 2010 06:45:31 Thomas Klimpel wrote:
>> Marco Guazzone wrote:
>> > However, there are situations where the input matrix has only real
>> > numbers and the output eigen{vectors,values} are complex.
>>
>> Yes, and they will occur in complex conjugate pairs then.
>>
>> > So, since (in addition to a complex matrix) a non-complex matrix may
>> > also give complex eigen{vectors,values}, why is the check on the
>> > value type not done on the output types (i.e., VectorW, MatrixVL,
>> > MatrixVL)?
>>
>> Because this is an automatically generated straightforward binding against
>> the corresponding lapack routine, without any further modifications for
>> greater convenience.
>>
>> > IMHO, this would avoid the user (e.g., me ;) ) to copy its working
>> > (possibly non-complex) matrix variable into a temp complex matrix
>> > before using lapack::geev.
>>
>> You shouldn't do this. Just use the non-complex version of geev with your
>> non-complex matrix, and decode the complex conjugate pairs in the output
>> correctly. In case you just need the eigenvalues, all you need to do is
>> create one vector of complex numbers from two vectors of real numbers
>> without any special case handling. The decoding of the eigenvectors is
>> less nice, and will also double the memory consumption.
>
> In GluCat ( http://glucat.sf.net ) there is a very similar situation, but with
> gees instead of geev. The file glucat/matrix_imp.h has (simplified):
>
> /// Eigenvalues of a matrix
> template< typename Matrix_T >
> ublas::vector< std::complex<double> >
> eigenvalues(const Matrix_T& val)
> {
> typedef std::complex<double> complex_t;
> typedef typename ublas::vector<complex_t> complex_vector_t;
> typedef typename Matrix_T::size_type matrix_index_t;
>
> const matrix_index_t dim = val.size1();
> complex_vector_t lambda = complex_vector_t(dim);
> lambda.clear();
>
> namespace lapack = boost::numeric::bindings::lapack;
> typedef typename ublas::matrix<double, ublas::column_major>
> lapack_matrix_t;
>
> lapack_matrix_t T = to_lapack(val);
> lapack_matrix_t V = T;
> typedef typename ublas::vector<double> vector_t;
> vector_t real_lambda = vector_t(dim);
> vector_t imag_lambda = vector_t(dim);
> fortran_int_t sdim = 0;
>
> lapack::gees ('N','N',(logical_t*)0,T,sdim,real_lambda,imag_lambda,V);
>
> lambda.clear();
> for (vector_t::size_type k=0; k!= dim; ++k)
> lambda[k] = complex_t(real_lambda[k], imag_lambda[k]);
> return lambda;
> }
Thomas and Paul,
Thank you very much for the hints!
Cheers,
-- Marco