Armadillo 可以在 Mat<float> 上做 eig_gen 吗?
Can Armadillo do eig_gen on Mat<float>?
我正在使用犰狳。我有这些变量:
arma::Mat<float> m_matrix;
arma::cx_vec m_eigenvalues;
arma::cx_mat m_eigenvectors;
我想这样做:
void calculate_eigens ()
{
arma :: eig_gen (m_eigenvalues, m_eigenvectors, m_matrix);
}
但是eig_gen
的函数原型不允许这些参数类型,它希望第三个参数是双精度矩阵。
这是 gcc 错误:
error: no matching function for call to ‘eig_gen(arma::cx_vec&, arma::cx_mat&, arma::Mat&)’
note: candidate: template typename arma::enable_if2<arma::is_supported_blas_type::value, arma::Col<std::complex > >::result arma::eig_gen(const arma::Base<typename T1::elem_type, T1>&)
armadillo_bits/fn_eig_gen.hpp:25:1: note: template argument deduction/substitution failed:
note: candidate expects 1 argument, 3 provided
这修复了它。
void calculate_eigens ()
{
auto tmp = arma::conv_to<arma::Mat<double>>::from(m_matrix);
arma :: eig_gen (m_eigenvalues, m_eigenvectors, tmp);
}
我不想进行此转换。我查看了犰狳的来源,似乎 eig_gen
将其主要工作推迟到此功能:
template<typename eT>
inline
void
geev(char* jobvl, char* jobvr, blas_int* N, eT* a, blas_int* lda, eT* wr, eT* wi, eT* vl, blas_int* ldvl, eT* vr, blas_int* ldvr, eT* work, blas_int* lwork, blas_int* info)
{
arma_type_check(( is_supported_blas_type<eT>::value == false ));
if(is_float<eT>::value)
{
typedef float T;
arma_fortran(arma_sgeev)(jobvl, jobvr, N, (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
}
else
if(is_double<eT>::value)
{
typedef double T;
arma_fortran(arma_dgeev)(jobvl, jobvr, N, (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
}
}
eT*a
参数是在 m_matrix
从 Mat<T>::get_ref
传入的,所以在我看来,库作者希望 eig_gen
在 [=] 上愉快地工作22=] 以及 Mat<double>
但它在实践中不起作用。
如何在不首先转换为 Mat<double>
的情况下计算 Mat<float>
上的 eigenvalues/eigenvectors?
您需要确保所有矩阵和向量具有相同的精度,而不仅仅是输入矩阵。单精度的正确用法是:
arma::fmat X;
arma::cx_fvec eigvals;
arma::cx_fmat eigvecs;
// ... fill X with values ...
arma::eig_gen(eigvals, eigvecs, X);
我正在使用犰狳。我有这些变量:
arma::Mat<float> m_matrix;
arma::cx_vec m_eigenvalues;
arma::cx_mat m_eigenvectors;
我想这样做:
void calculate_eigens ()
{
arma :: eig_gen (m_eigenvalues, m_eigenvectors, m_matrix);
}
但是eig_gen
的函数原型不允许这些参数类型,它希望第三个参数是双精度矩阵。
这是 gcc 错误:
error: no matching function for call to ‘eig_gen(arma::cx_vec&, arma::cx_mat&, arma::Mat&)’
note: candidate: template typename arma::enable_if2<arma::is_supported_blas_type::value, arma::Col<std::complex > >::result arma::eig_gen(const arma::Base<typename T1::elem_type, T1>&)
armadillo_bits/fn_eig_gen.hpp:25:1: note: template argument deduction/substitution failed:
note: candidate expects 1 argument, 3 provided
这修复了它。
void calculate_eigens ()
{
auto tmp = arma::conv_to<arma::Mat<double>>::from(m_matrix);
arma :: eig_gen (m_eigenvalues, m_eigenvectors, tmp);
}
我不想进行此转换。我查看了犰狳的来源,似乎 eig_gen
将其主要工作推迟到此功能:
template<typename eT>
inline
void
geev(char* jobvl, char* jobvr, blas_int* N, eT* a, blas_int* lda, eT* wr, eT* wi, eT* vl, blas_int* ldvl, eT* vr, blas_int* ldvr, eT* work, blas_int* lwork, blas_int* info)
{
arma_type_check(( is_supported_blas_type<eT>::value == false ));
if(is_float<eT>::value)
{
typedef float T;
arma_fortran(arma_sgeev)(jobvl, jobvr, N, (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
}
else
if(is_double<eT>::value)
{
typedef double T;
arma_fortran(arma_dgeev)(jobvl, jobvr, N, (T*)a, lda, (T*)wr, (T*)wi, (T*)vl, ldvl, (T*)vr, ldvr, (T*)work, lwork, info);
}
}
eT*a
参数是在 m_matrix
从 Mat<T>::get_ref
传入的,所以在我看来,库作者希望 eig_gen
在 [=] 上愉快地工作22=] 以及 Mat<double>
但它在实践中不起作用。
如何在不首先转换为 Mat<double>
的情况下计算 Mat<float>
上的 eigenvalues/eigenvectors?
您需要确保所有矩阵和向量具有相同的精度,而不仅仅是输入矩阵。单精度的正确用法是:
arma::fmat X;
arma::cx_fvec eigvals;
arma::cx_fmat eigvecs;
// ... fill X with values ...
arma::eig_gen(eigvals, eigvecs, X);