#ifndef _LA_NONCLASS_H_ #define _LA_NONCLASS_H_ #include "vec.h" #include "smat.h" #include "mat.h" #include "la_traits.h" //MISC export template const NRMat diagonalmatrix(const NRVec &x) { int n=x.size(); NRMat result((T)0,n,n); T *p = result[0]; for(int j=0; j inline const NRMat commutator ( const NRMat &x, const NRMat &y, const bool trx=0, const bool tryy=0) { NRMat r(trx?x.ncols():x.nrows(), tryy?y.nrows():y.ncols()); r.gemm((T)0,x,trx?'t':'n',y,tryy?'t':'n',(T)1); r.gemm((T)1,y,tryy?'t':'n',x,trx?'t':'n',(T)-1); return r; } //more efficient commutator for a special case of full matrices template inline const NRMat anticommutator ( const NRMat &x, const NRMat &y, const bool trx=0, const bool tryy=0) { NRMat r(trx?x.ncols():x.nrows(), tryy?y.nrows():y.ncols()); r.gemm((T)0,x,trx?'t':'n',y,tryy?'t':'n',(T)1); r.gemm((T)1,y,tryy?'t':'n',x,trx?'t':'n',(T)1); return r; } ////////////////////// // LAPACK interface // ////////////////////// #define declare_la(T) \ extern const NRVec diagofproduct(const NRMat &a, const NRMat &b,\ bool trb=0, bool conjb=0); \ extern T trace2(const NRMat &a, const NRMat &b, bool trb=0); \ extern T trace2(const NRSMat &a, const NRSMat &b, const bool diagscaled=0);\ extern void linear_solve(NRMat &a, NRMat *b, double *det=0,int n=0); \ extern void linear_solve(NRSMat &a, NRMat *b, double *det=0, int n=0); \ extern void linear_solve(NRMat &a, NRVec &b, double *det=0, int n=0); \ extern void linear_solve(NRSMat &a, NRVec &b, double *det=0, int n=0); \ extern void diagonalize(NRMat &a, NRVec &w, const bool eivec=1, const bool corder=1, int n=0, NRMat *b=NULL, const int itype=1); \ extern void diagonalize(NRSMat &a, NRVec &w, NRMat *v, const bool corder=1, int n=0, NRSMat *b=NULL, const int itype=1);\ extern void singular_decomposition(NRMat &a, NRMat *u, NRVec &s,\ NRMat *v, const bool corder=1, int m=0, int n=0); declare_la(double) declare_la(complex) // Separate declarations //general nonsymmetric matrix and generalized diagonalization extern void gdiagonalize(NRMat &a, NRVec &wr, NRVec &wi, NRMat *vl, NRMat *vr, const bool corder=1, int n=0, NRMat *b=NULL, NRVec *beta=NULL); extern void gdiagonalize(NRMat &a, NRVec< complex > &w, NRMat< complex >*vl, NRMat< complex > *vr, const bool corder=1, int n=0, NRMat *b=NULL, NRVec *beta=NULL); extern NRMat matrixfunction(NRSMat a, double (*f) (double)); extern NRMat matrixfunction(NRMat a, complex (*f)(const complex &),const bool adjust=0); ////////////////////////////// //other than lapack functions/ ////////////////////////////// //functions on matrices inline NRMat sqrt(const NRSMat &a) { return matrixfunction(a,&sqrt); } inline NRMat log(const NRSMat &a) { return matrixfunction(a,&log); } extern NRMat log(const NRMat &a); extern const NRMat realpart(const NRMat< complex >&); extern const NRMat imagpart(const NRMat< complex >&); extern const NRMat< complex > realmatrix (const NRMat&); extern const NRMat< complex > imagmatrix (const NRMat&); //inverse by means of linear solve, preserving rhs intact template const NRMat inverse(NRMat a, T *det=0) { #ifdef DEBUG if(a.nrows()!=a.ncols()) laerror("inverse() for non-square matrix"); #endif NRMat result(a.nrows(),a.nrows()); result = (T)1.; linear_solve(a, &result, det); return result; } //general determinant template const typename LA_traits::elementtype determinant(MAT a)//again passed by value { typename LA_traits::elementtype det; if(a.nrows()!=a.ncols()) laerror("determinant of non-square matrix"); linear_solve(a,NULL,&det); return det; } //auxiliary routine to adjust eigenvectors to guarantee real logarithm extern void adjustphases(NRMat &v); #endif