Броненосец: решить с помощью sp_mat

Я пишу базовую программу FEM, используя Armadillo. Я использую sp_mat и vec как матричный и векторный тип. Проблема в том, что когда я делаю solve(X, b), я получаю сообщение об ошибке. Может быть, solve не поддерживает sp_mat. Любые альтернативы, кроме использования плотных матриц? Ниже приведен код, в котором sp_mat не компилируется. Если вместо этого я использую закомментированную строку mat A, она работает нормально.

    int N = 3;
double h = 1./N;

//mat A = zeros<mat>(N+1,N+1);
sp_mat A(N+1,N+1); 
for(int i=0;i<=N;i++) {
    if(i>0) {A(i,i-1)=-1.;}
    A(i,i)=2.;
    if(i<N) {A(i,i+1)=-1.;}
}
A(N,N)=1;

vec b = zeros(N+1);
for(int i=0;i<=N;i++) {
    b(i)=h; 
}

vec zeta = solve(A,b);
cout << zeta;

Ошибка:

make all 
Building file: ../src/FEM.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/FEM.d" -MT"src/FEM.d" -o "src/FEM.o" "../src/FEM.cpp"
../src/FEM.cpp: In function ‘int main()’:
../src/FEM.cpp:37:22: error: no matching function for call to ‘solve(arma::sp_mat&, arma::vec&)’
  vec zeta = solve(A,b);
                      ^
../src/FEM.cpp:37:22: note: candidates are:
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:25:1: note: template<class T1, class T2> const arma::Glue<T1, T2, arma::glue_solve> arma::solve(const arma::Base<typename T1::elem_type, T1>&, const arma::Base<typename T1::elem_type, T2>&, bool, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:25:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘const arma::Base<typename T1::elem_type, T1>’
  vec zeta = solve(A,b);
                      ^
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:44:1: note: template<class T1, class T2> const arma::Glue<T1, T2, arma::glue_solve> arma::solve(const arma::Base<typename T1::elem_type, T1>&, const arma::Base<typename T1::elem_type, T2>&, const char*, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:44:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘const arma::Base<typename T1::elem_type, T1>’
  vec zeta = solve(A,b);
                      ^
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:67:1: note: template<class T1, class T2> const arma::Glue<T1, T2, arma::glue_solve_tr> arma::solve(const arma::Op<T1, arma::op_trimat>&, const arma::Base<typename T1::elem_type, T2>&, bool, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:67:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘const arma::Op<T1, arma::op_trimat>’
  vec zeta = solve(A,b);
                      ^
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:87:1: note: template<class T1, class T2> const arma::Glue<T1, T2, arma::glue_solve_tr> arma::solve(const arma::Op<T1, arma::op_trimat>&, const arma::Base<typename T1::elem_type, T2>&, const char*, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:87:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘const arma::Op<T1, arma::op_trimat>’
  vec zeta = solve(A,b);
                      ^
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:110:1: note: template<class T1, class T2> bool arma::solve(arma::Mat<typename T1::elem_type>&, const arma::Base<typename T1::elem_type, T1>&, const arma::Base<typename T1::elem_type, T2>&, bool, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:110:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘arma::Mat<typename T1::elem_type>’
  vec zeta = solve(A,b);
                      ^
In file included from /usr/include/armadillo:397:0,
                 from ../src/FEM.cpp:10:
/usr/include/armadillo_bits/fn_solve.hpp:139:1: note: template<class T1, class T2> bool arma::solve(arma::Mat<typename T1::elem_type>&, const arma::Base<typename T1::elem_type, T1>&, const arma::Base<typename T1::elem_type, T2>&, const char*, const typename arma::arma_blas_type_only<typename T1::elem_type>::result*)
 solve
 ^
/usr/include/armadillo_bits/fn_solve.hpp:139:1: note:   template argument deduction/substitution failed:
../src/FEM.cpp:37:22: note:   ‘arma::sp_mat {aka arma::SpMat<double>}’ is not derived from ‘arma::Mat<typename T1::elem_type>’
  vec zeta = solve(A,b);
                      ^
make: *** [src/FEM.o] Error 1

person dani    schedule 07.03.2014    source источник


Ответы (2)


Поддержка разреженных матриц в Armadillo еще не завершена.

Вы можете использовать ARPACK для (собственного) разложения разреженной матрицы. Решатели разреженных матриц, вероятно, появятся в следующем выпуске, который может использовать библиотеку CXSparse из проекта SuiteSparse.

person Dirk Eddelbuettel    schedule 07.03.2014

Начиная с версии 5.0, в Armadillo есть функция spsolve() для решения разреженных систем.

person hbrerkere    schedule 17.04.2015