c++ - Armadillo 可以在 Mat<float> 上执行 eig_gen 吗?

标签 c++ linear-algebra lapack armadillo blas

我正在使用 Armadillo 。我有这些变量:

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 的函数原型(prototype)不允许这些参数类型,它希望第三个参数是 double 矩阵。

以下是 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);
}

我不想进行此转换。我查看了 Armadillo 的来源,似乎 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参数是从 Mat<T>::get_ref 传入的上m_matrix ,所以在我看来,库作者的意图是 eig_gen愉快地工作Mat<float>以及 Mat<double>但实际上行不通。

如何计算 Mat<float> 上的特征值/特征向量无需先转换为 Mat<double>

最佳答案

您需要确保所有矩阵和 vector 具有相同的精度,而不仅仅是输入矩阵。单精度的正确用法是:

arma::fmat     X;
arma::cx_fvec  eigvals;
arma::cx_fmat  eigvecs;

// ... fill X with values ...

arma::eig_gen(eigvals, eigvecs, X);

关于c++ - Armadillo 可以在 Mat<float> 上执行 eig_gen 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46912636/

相关文章:

c++ - 无法解释不明确的模板特化

c++ - Eigen 3/C++ : MatrixXd multiply one row with another

java - 在 Java 中计算协方差矩阵

r - 带 R 的 Gram Schmidt

c++ - Lapack 链接错误,使用 -fPIC 重新编译

c - C中链接库中函数的并行计算

c++ - 对使用带有 istream 参数的构造函数感到困惑

c++ - 具有不可移动/可复制类型的 std::tuple

c++ qt未定义对`_imp的引用

python - Cython调用lapack,报错: `Cannot take address of Python variable'