// This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // // Copyright (C) 2008 Gael Guennebaud // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GSL_HELPER #define EIGEN_GSL_HELPER #include #include #include #include #include #include #include namespace Eigen { template::IsComplex> struct GslTraits { typedef gsl_matrix* Matrix; typedef gsl_vector* Vector; static Matrix createMatrix(int rows, int cols) { return gsl_matrix_alloc(rows,cols); } static Vector createVector(int size) { return gsl_vector_alloc(size); } static void free(Matrix& m) { gsl_matrix_free(m); m=0; } static void free(Vector& m) { gsl_vector_free(m); m=0; } static void prod(const Matrix& m, const Vector& v, Vector& x) { gsl_blas_dgemv(CblasNoTrans,1,m,v,0,x); } static void cholesky(Matrix& m) { gsl_linalg_cholesky_decomp(m); } static void cholesky_solve(const Matrix& m, const Vector& b, Vector& x) { gsl_linalg_cholesky_solve(m,b,x); } static void eigen_symm(const Matrix& m, Vector& eval, Matrix& evec) { gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc(m->size1); Matrix a = createMatrix(m->size1, m->size2); gsl_matrix_memcpy(a, m); gsl_eigen_symmv(a,eval,evec,w); gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC); gsl_eigen_symmv_free(w); free(a); } static void eigen_symm_gen(const Matrix& m, const Matrix& _b, Vector& eval, Matrix& evec) { gsl_eigen_gensymmv_workspace * w = gsl_eigen_gensymmv_alloc(m->size1); Matrix a = createMatrix(m->size1, m->size2); Matrix b = createMatrix(_b->size1, _b->size2); gsl_matrix_memcpy(a, m); gsl_matrix_memcpy(b, _b); gsl_eigen_gensymmv(a,b,eval,evec,w); gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC); gsl_eigen_gensymmv_free(w); free(a); } }; template struct GslTraits { typedef gsl_matrix_complex* Matrix; typedef gsl_vector_complex* Vector; static Matrix createMatrix(int rows, int cols) { return gsl_matrix_complex_alloc(rows,cols); } static Vector createVector(int size) { return gsl_vector_complex_alloc(size); } static void free(Matrix& m) { gsl_matrix_complex_free(m); m=0; } static void free(Vector& m) { gsl_vector_complex_free(m); m=0; } static void cholesky(Matrix& m) { gsl_linalg_complex_cholesky_decomp(m); } static void cholesky_solve(const Matrix& m, const Vector& b, Vector& x) { gsl_linalg_complex_cholesky_solve(m,b,x); } static void prod(const Matrix& m, const Vector& v, Vector& x) { gsl_blas_zgemv(CblasNoTrans,gsl_complex_rect(1,0),m,v,gsl_complex_rect(0,0),x); } static void eigen_symm(const Matrix& m, gsl_vector* &eval, Matrix& evec) { gsl_eigen_hermv_workspace * w = gsl_eigen_hermv_alloc(m->size1); Matrix a = createMatrix(m->size1, m->size2); gsl_matrix_complex_memcpy(a, m); gsl_eigen_hermv(a,eval,evec,w); gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC); gsl_eigen_hermv_free(w); free(a); } static void eigen_symm_gen(const Matrix& m, const Matrix& _b, gsl_vector* &eval, Matrix& evec) { gsl_eigen_genhermv_workspace * w = gsl_eigen_genhermv_alloc(m->size1); Matrix a = createMatrix(m->size1, m->size2); Matrix b = createMatrix(_b->size1, _b->size2); gsl_matrix_complex_memcpy(a, m); gsl_matrix_complex_memcpy(b, _b); gsl_eigen_genhermv(a,b,eval,evec,w); gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC); gsl_eigen_genhermv_free(w); free(a); } }; template void convert(const MatrixType& m, gsl_matrix* &res) { // if (res) // gsl_matrix_free(res); res = gsl_matrix_alloc(m.rows(), m.cols()); for (int i=0 ; i void convert(const gsl_matrix* m, MatrixType& res) { res.resize(int(m->size1), int(m->size2)); for (int i=0 ; i void convert(const VectorType& m, gsl_vector* &res) { if (res) gsl_vector_free(res); res = gsl_vector_alloc(m.size()); for (int i=0 ; i void convert(const gsl_vector* m, VectorType& res) { res.resize (m->size); for (int i=0 ; i void convert(const MatrixType& m, gsl_matrix_complex* &res) { res = gsl_matrix_complex_alloc(m.rows(), m.cols()); for (int i=0 ; i void convert(const gsl_matrix_complex* m, MatrixType& res) { res.resize(int(m->size1), int(m->size2)); for (int i=0 ; i void convert(const VectorType& m, gsl_vector_complex* &res) { res = gsl_vector_complex_alloc(m.size()); for (int i=0 ; i void convert(const gsl_vector_complex* m, VectorType& res) { res.resize(m->size); for (int i=0 ; i