28#include "gsl/gsl_linalg.h"
29#include "gsl/gsl_eigen.h"
65 if(_matrix !=
nullptr) gsl_matrix_free( (gsl_matrix*)_matrix );
72 if(_matrix !=
nullptr) gsl_matrix_complex_free( (gsl_matrix_complex*)_matrix );
80 if (&mm ==
this)
return *
this;
82 if(!mm.
_matrix) { _matrix =
nullptr;
return *
this; }
84 gsl_matrix_memcpy((gsl_matrix*)_matrix, (
const gsl_matrix*)mm.
_matrix);
91 if (&mm ==
this)
return *
this;
93 if(!mm.
_matrix) { _matrix =
nullptr;
return *
this; }
95 gsl_matrix_complex_memcpy((gsl_matrix_complex*)_matrix, (
const gsl_matrix_complex*)mm.
_matrix);
105 gsl_matrix_memcpy( (gsl_matrix*)
_matrix, (gsl_matrix*)mm.
_matrix );
115 gsl_matrix_complex_memcpy( (gsl_matrix_complex*)
_matrix, (gsl_matrix_complex*)mm.
_matrix );
119template <
class Tmplt>
125template <
class Tmplt>
129 for(
size_t a=1;
a<=i;
a++)
130 for(
size_t b=1; b<=j; b++)
131 operator()(
a,b) = value;
134template <
class Tmplt>
140template <
class Tmplt>
144 for(
size_t a=1;
a<=i;
a++)
146 for(
size_t b=1; b<
a; b++) mm(
a, b) = off_diag_value;
147 for(
size_t b=
a+1; b<=i; b++) mm(
a, b) = off_diag_value;
148 mm(
a,
a) = diag_value;
154template <
class Tmplt>
165 _matrix = gsl_matrix_alloc(i, j);
171 _matrix = gsl_matrix_complex_alloc(i, j);
177 _matrix = gsl_matrix_alloc(i, j);
178 for(
size_t a=0;
a<i;
a++)
179 for(
size_t b=0; b<j; b++)
180 operator()(
a+1,b+1) = data[b*i +
a];
186 _matrix = gsl_matrix_complex_alloc(i, j);
187 for(
size_t a=0;
a<i;
a++)
188 for(
size_t b=0; b<j; b++)
189 operator()(
a+1,b+1) = data[b*i +
a];
200 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix::determinant()",
"Attempt to get determinant of non-square matrix"));
201 gsl_permutation * p = gsl_permutation_alloc (num_row());
203 gsl_linalg_complex_LU_decomp ((gsl_matrix_complex*)copy.
_matrix, p, &signum);
204 gsl_permutation_free(p);
205 return gsl_linalg_complex_LU_det((gsl_matrix_complex*)copy.
_matrix, signum);
212 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix::determinant()",
"Attempt to get determinant of non-square matrix"));
213 gsl_permutation * p = gsl_permutation_alloc (num_row());
215 gsl_linalg_LU_decomp ((gsl_matrix*)copy.
_matrix, p, &signum);
216 double d = gsl_linalg_LU_det((gsl_matrix*)copy.
_matrix, signum);
217 gsl_permutation_free(p);
221template <
class Tmplt>
233 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix::invert()",
"Attempt to get inverse of non-square matrix"));
234 gsl_permutation* perm = gsl_permutation_alloc(num_row());
237 gsl_linalg_complex_LU_decomp ( (gsl_matrix_complex*)lu.
_matrix, perm, &s);
238 gsl_linalg_complex_LU_invert ( (gsl_matrix_complex*)lu.
_matrix, perm, (gsl_matrix_complex*)_matrix);
239 gsl_permutation_free( perm );
240 for(
size_t i=1; i<=num_row(); i++)
241 for(
size_t j=1; j<=num_row(); j++)
242 if(
operator()(i,j) !=
operator()(i,j))
throw(
GeneralClassicException(
"MMatrix::invert()",
"Failed to invert matrix - singular?"));
248 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix::invert()",
"Attempt to get inverse of non-square matrix"));
249 gsl_permutation* perm = gsl_permutation_alloc(num_row());
252 gsl_linalg_LU_decomp ( (gsl_matrix*)lu.
_matrix, perm, &s);
253 gsl_linalg_LU_invert ( (gsl_matrix*)lu.
_matrix, perm, (gsl_matrix*)_matrix);
254 gsl_permutation_free( perm );
255 for(
size_t i=1; i<=num_row(); i++)
256 for(
size_t j=1; j<=num_row(); j++)
257 if(
operator()(i,j) !=
operator()(i,j))
throw(
GeneralClassicException(
"MMatrix::invert()",
"Failed to invert matrix - singular?"));
264 gsl_matrix_transpose_memcpy ((gsl_matrix*)in.
_matrix, (gsl_matrix*)_matrix);
272 gsl_matrix_complex_transpose_memcpy ((gsl_matrix_complex*)in.
_matrix, (gsl_matrix_complex*)_matrix);
276template <
class Tmplt>
280 for(
size_t i=min_row; i<=max_row; i++)
281 for(
size_t j=min_col; j<=max_col; j++)
282 sub_matrix(i-min_row+1, j-min_col+1) = operator()(i,j);
289template <
class Tmplt>
292 Tmplt t = operator()(1,1);
293 for(
size_t i=2; i<=num_row() && i<=num_col(); i++) t+=
operator()(i,i);
300template <
class Tmplt>
303 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix<double>::eigenvalues",
"Attempt to get eigenvectors of non-square matrix") );
306 gsl_eigen_nonsymm_workspace * w = gsl_eigen_nonsymm_alloc(num_row());
307 gsl_eigen_nonsymm_params(0, 1, w);
308 int ierr = gsl_eigen_nonsymm(get_matrix(temp), evals.
get_vector(evals), w);
309 gsl_eigen_nonsymm_free(w);
315template <
class Tmplt>
318 if(num_row() != num_col())
throw(
GeneralClassicException(
"MMatrix<double>::eigenvectors",
"Attempt to get eigenvectors of non-square matrix") );
322 gsl_eigen_nonsymmv_workspace * w = gsl_eigen_nonsymmv_alloc(num_row());
323 int ierr = gsl_eigen_nonsymmv(get_matrix(temp), evals.
get_vector(evals), get_matrix(evecs), w);
324 gsl_eigen_nonsymmv_free(w);
325 if(ierr != 0)
throw(
GeneralClassicException(
"MMatrix<Tmplt>::eigenvectors",
"Failed to calculate eigenvalue"));
335 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1., (gsl_matrix*)m1.
_matrix, (gsl_matrix*)m2.
_matrix, 0., (gsl_matrix*)out.
_matrix);
352 for(
size_t i=1; i<=mat.
num_row(); i++)
355 for(
size_t j=1; j<mat.
num_col(); j++)
356 out << mat(i,j) <<
" ";
357 out << mat(i,mat.
num_col()) <<
"\n";
369 for(
size_t i=1; i<=
nr; i++)
370 for(
size_t j=1; j<=nc; j++)
381 for(
size_t i=1; i<=mc.
num_row(); i++)
382 for(
size_t j=1; j<=mc.
num_col(); j++)
383 md(i,j) =
re(mc(i,j));
390 for(
size_t i=1; i<=mc.
num_row(); i++)
391 for(
size_t j=1; j<=mc.
num_col(); j++)
392 md(i,j) =
im(mc(i,j));
399 for(
size_t i=1; i<=mc.
num_row(); i++)
400 for(
size_t j=1; j<=mc.
num_col(); j++)
408 throw(
GeneralClassicException(
"MMatrix<m_complex>::complex",
"Attempt to build complex matrix when real and imaginary matrix don't have the same size"));
410 for(
size_t i=1; i<=mc.
num_row(); i++)
411 for(
size_t j=1; j<=mc.
num_col(); j++)
416template <
class Tmplt>
420 for(
size_t i=1; i<=num_row(); i++) temp(i) = operator()(i,column);
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
m_complex m_complex_build(double r, double i)
template std::ostream & operator<<(std::ostream &out, MMatrix< m_complex > mat)
template std::istream & operator>>(std::istream &in, MMatrix< double > &mat)
MMatrix< double > re(MMatrix< m_complex > mc)
MMatrix< m_complex > & operator*=(MMatrix< m_complex > &m1, MMatrix< m_complex > m2)
MMatrix< m_complex > complex(MMatrix< double > real, MMatrix< double > imaginary)
std::istream & operator>>(std::istream &in, MMatrix< Tmplt > &mat)
MMatrix< double > im(MMatrix< m_complex > mc)
BOOST_UBLAS_INLINE V trace(ublas::matrix< V > &e)
Computes the trace of a square matrix.
void invert()
turns this matrix into its inverse
size_t num_col() const
returns number of columns in the matrix
void build_matrix(size_t i, size_t j)
size_t num_row() const
returns number of rows in the matrix
MMatrix< Tmplt > inverse() const
returns matrix inverse leaving this matrix unchanged
static MMatrix< Tmplt > Diagonal(size_t i, Tmplt diag_value, Tmplt off_diag_value)
Construct a square matrix filling on and off diagonal values.
MMatrix()
default constructor makes an empty MMatrix of size (0,0)
static gsl_vector * get_vector(const MVector< double > &m)