Armadillo eigs_sym(A,k) para matriz esparsa complexa A

Aug 20 2020

Para encontrar os 10 menores autovalores de uma matriz esparsa 'A', o código mínimo abaixo funciona bem:

g++ -std=c++17  -o test_sparse.o -c test_sparse.cpp
g++ -std=c++17  -o myapp test_sparse.o -larmadillo -larpack
#include <armadillo>
#include <iostream>
int main(){
    arma::SpMat<double> A = arma::sprandu(100,100,0.1) ;
    A = A.t()*A ;
    arma::dvec e = arma::eigs_sym(A,10,"sm") ;
    std::cout << e ; 
    return 0 ;
}

Mas quando eu mudo A para uma matriz esparsa complexa, como:

#include <armadillo>
#include <iostream>
#include <complex>
int main(){
    arma::SpMat<arma::cx_double> A = arma::sprandu<arma::SpMat<arma::cx_double>>(100,100,0.1) ;
    A = A.t()*A ;
    arma::dvec e = arma::eigs_sym(A,1,"sm") ;
    std::cout << e ; 
    return 0 ;
}

com os mesmos sinalizadores de compilação, recebo o seguinte erro de função sem correspondência:

g++ -std=c++17  -o test_sparse.o -c test_sparse.cpp
test_sparse.cpp:8:43: error: no matching function for call to ‘eigs_sym(arma::SpMat<std::complex<double> >&, int, const char [3])’
    8 |     arma::dvec e = arma::eigs_sym(A,1,"sm") ;                    ^
make: *** [Makefile:47: test_sparse.o] Error 1

eu sei dehttp://arma.sourceforge.net/docs.html#config_hppeste

ARMA_USE_ARPACK Habilita o uso de ARPACK ou uma substituição de alta velocidade para ARPACK. Armadillo requer ARPACK para a autodecomposição de matrizes esparsas complexas, ou seja. eigs_gen(), eigs_sym() e svds()

então eu mudo o arquivo config.hpp e aqui está a linha correspondente no meu config.hpparquivo:

#if !defined(ARMA_USE_NEWARP)
#define ARMA_USE_NEWARP
#endif
#if !defined(ARMA_USE_ARPACK)
#define ARMA_USE_ARPACK
#endif
#if !defined(ARMA_USE_SUPERLU)
#define ARMA_USE_SUPERLU
#endif

mais informações: posso executar o arpack do gfortran sem nenhum problema.

Alguma ideia de como fazer o truque? Obrigado por sua ajuda com antecedência.

Respostas

francesco Aug 20 2020 at 17:43

É uma limitação inerente da biblioteca. De acordo com a documentação (grifo meu):

eigs_sym número limitado de autovalores e autovetores de matriz real simétrica esparsa

eigs_gen número limitado de autovalores e autovetores de matriz quadrada geral esparsa

Você deve usar eigs_geno que permite matrizes complexas. Ou você deve converter a matriz em uma densa e usar eig_sym.