/*! \file GMatrix.h * \brief this file defines the \ref Math::GMatrix class that is part of the Math namespace */ #ifndef GMATRIX_H #define GMATRIX_H #include #include #include #include #include #include #include #include #include #include "Coordinate.h" #include "Matrix.h" #include "Precision.h" using namespace std; namespace Math { /*! \class Math::GMatrix \brief General n x m matrix General matrix class that eventually should replace \ref Math::Matrix class. will have to adjust error checks for this class and adjust inverse and make most calls inline to increase speed. */ class GMatrix { private: int row,col; Double_t *matrix; protected: ///useful comparison functions which can be used with qsort int compare_Double(const void* a,const void* b) { Double_t arg1 = *((Double_t*) a); Double_t arg2 = *((Double_t*) b); if( arg1 < arg2 ) return -1; else if( arg1==arg2 ) return 0; else return 1; } public: /// \name Constructors & Destructors //@{ /// Constructor (where data can be is initilized) otherwise set to zero GMatrix(int r, int c, Double_t *data=NULL) { if (r*c>0){ row=r;col=c; matrix=new Double_t[row*col]; if (data!=NULL){ for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) matrix[i*col+j] = data[i*col+j]; } else{ for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) matrix[i*col+j] = 0.; } } else { row=0;col=0;matrix=NULL; printf("Error, net size 0 with row,col=%d,%d\n",row,col); } } /// Constructor based on Coordinate. GMatrix(const Coordinate &c) { row=3;col=1; matrix=new Double_t[row*col]; for (int i = 0; i < row; i++) matrix[i] = c[i]; } /// Constructor Matrix GMatrix(const Matrix &m) { row=3;col=3; matrix=new Double_t[row*col]; for (int i=0; i0&&col>0) delete[] matrix; } //@} /// \name Get & Set functions //@{ ///get row dimensions int Row()const {return row;} ///get col dimensions int Col()const {return col;} ///get rank int Rank()const {return min(row,col);} //@} /// \name Overloaded Operators //@{ /// How to access a matrix element: M(i, j) Double_t& operator () (int i, int j) { //if (j1e-32&&ipivot)){ k++; if (k==row)k=0; ipivot=(P(k,k)==1); } P(j,j)=0;P(k,k)=0; P(j,k)=1;P(k,j)=1; for (int l=0;l1e-32&&ipivot)){ k++; if (k==row)k=0; ipivot=(P(k,k)==1); } P(j,j)=0;P(k,k)=0; P(j,k)=1;P(k,j)=1; for (int l=0;l1e-8) return 0; return 1; } /// Check if matrix is zero matrix int isZero() const { Double_t sm=0; for (int i=0;ij : & l_{i1}*u_{1j}+l_{i2}*u_{2j}+...+l_{ij}*u_{ij}&=a_{ij} \end{array} \f] with condition that \f$ l_{ii}=1 \f$. \n If matrix singular and no decomposition, print error and return zero matrix. Here matrix is singular if diagonal element is zero. \n Must alter this to pivot method so that subroutine reorder matrix if necessary and diagonals can be zero. */ GMatrix LUDecomp() const { if (row!=col) { printf("only implemented for square, returning zeros\n"); return GMatrix(row,col); } else { Double_t A[row*col]; Int_t i, j, k, p, p_k, p_row, p_col; for (j=0;j=0; p_i -= row, i-- ) { for (j = row - 1; j > i; j--) { U[p_i + j] = -U[p_i + j]; for (k = i + 1, p_k = p_i + row; k < j; p_k += row, k++ ) U[p_i + j] -= U[p_i + k] * U[p_k + j]; } } return GMatrix(row,row,U); } /// \brief Adjugate (classical adjoint) of matrix /// This is simply the transpose of the cofactor of the matrix GMatrix Adjugate() const { GMatrix cofactorT(row,col); for (int i=0;i 4 && (sqrt(eigen[ip]*eigen[ip])+temp1)==(sqrt(eigen[ip]*eigen[ip])+tol) && (sqrt(eigen[iq]*eigen[iq])+temp1)==(sqrt(eigen[iq]*eigen[iq])+tol)) m(ip,iq)=0.0; else if (thres 4 && (sqrt(eigen[ip]*eigen[ip])+temp1)==(sqrt(eigen[ip]*eigen[ip])+tol) && (sqrt(eigen[iq]*eigen[iq])+temp1)==(sqrt(eigen[iq]*eigen[iq])+tol)) m(ip,iq)=0.0; else if (thres=10) { printf("Too many iterations in routine jacobi, giving zeros\n"); for (int i=0;ie1>e2..>eN //qsort(eigen.matrix,row,sizeof(Double_t),compare_Double); return eigen; } } // Computes the eigenvectors of the matrix, given the eigenvalues. Sadly, this function will only work // properly on symmetric matrices -- i.e., all real eigenvalues. //GMatrix Eigenvectors(const Coordinate& e) const; /// Calculate eigenvalues \e and eigenvector of matrix of rank N. Stored as a GMatrix, e1, e2 ...eN. void Eigenvalvec(GMatrix &eigenval, GMatrix &eigenvector, Double_t tol=1e-2) const { if (isSymmetric()==0||isZero()==1) { printf("only implemented for nonzero symmetric matrices, returning null matrix\n"); for (int i=0;i