【问题标题】:Can Armadillo do eig_gen on Mat<float>?犰狳可以在 Mat<float> 上做 eig_gen 吗?
【发布时间】:2017-10-24 14:05:42
【问题描述】:

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

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 错误:

错误:没有匹配函数调用“eig_gen(arma::cx_vec&, arma::cx_mat&, arma::Mat&)”

注意:候选:模板类型名 arma::enable_if2<:is_supported_blas_type::value arma::col>>::result arma::eig_gen(const arma::Base&)

armadillo_bits/fn_eig_gen.hpp:25:1:注意:模板参数推导/替换失败:

注意:候选人期望 1 个参数,提供 3 个

这解决了它。

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&lt;T&gt;::get_ref 传入的,所以在我看来,库作者打算让 eig_genMat&lt;float&gt;Mat&lt;double&gt; 上愉快地工作,但它没有在实践中行不通。

如何在不首先转换为 Mat&lt;double&gt; 的情况下计算 Mat&lt;float&gt; 上的特征值/特征向量?

【问题讨论】:

    标签: c++ linear-algebra lapack armadillo blas


    【解决方案1】:

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

    arma::fmat     X;
    arma::cx_fvec  eigvals;
    arma::cx_fmat  eigvecs;
    
    // ... fill X with values ...
    
    arma::eig_gen(eigvals, eigvecs, X);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 2017-09-28
      • 1970-01-01
      • 2015-07-15
      • 2012-04-27
      • 1970-01-01
      • 2017-11-16
      相关资源
      最近更新 更多