Armadillo eigs_sym(A,k) para matriz dispersa compleja A
Para encontrar los 10 valores propios más pequeños de una matriz dispersa 'A', el código mínimo a continuación funciona bien:
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 ;
}
Pero cuando cambio A a una matriz dispersa compleja, 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 ;
}
con las mismas banderas de compilación, obtengo el siguiente error de función no coincidente:
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
lo sé porhttp://arma.sourceforge.net/docs.html#config_hppque
ARMA_USE_ARPACK Habilite el uso de ARPACK o un reemplazo de alta velocidad para ARPACK. Armadillo requiere ARPACK para la descomposición propia de matrices dispersas complejas, es decir. eigs_gen(), eigs_sym() y svds()
así que cambio el archivo config.hpp y aquí está la línea correspondiente en mi config.hpp
archivo:
#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
más información: puedo ejecutar arpack desde gfortran sin problema.
¿Alguna idea de cómo hacer el truco? De forma anticipada, muchas gracias por su ayuda.
Respuestas
Es una limitación inherente de la biblioteca. Según la documentación (énfasis mío):
eigs_sym número limitado de valores propios y vectores propios de matriz real simétrica escasa
eigs_gen número limitado de valores propios y vectores propios de matriz cuadrada general escasa
Debería usar eigs_genlo que permite matrices complejas. O debe convertir la matriz en una densa y usar eig_sym.