00001 #ifndef __RealSMatrix_H__ 00002 #define __RealSMatrix_H__ 00003 00004 00005 00040 #include <stdio.h> 00041 #include "RealVector.hpp" 00042 #include "H.hpp" // householder reflective matrix 00043 00044 class I; 00045 class RTriDiagonalMatrix; 00046 00047 class RealSMatrix 00048 { 00049 private: 00050 00051 int width; 00052 double** data; 00053 00054 public: 00055 00056 RealSMatrix(int n, double value=0.0); 00057 RealSMatrix(I& ident); 00058 RealSMatrix(H& h); 00059 RealSMatrix(const RealSMatrix& m); 00060 RealSMatrix operator=(const RealSMatrix& m); 00061 00062 ~RealSMatrix(); 00063 00064 RealSMatrix* copy(); 00065 RealSMatrix* identity(); 00066 00067 RealSMatrix* AtA(RealSMatrix* dest=0); 00068 00069 RealSMatrix t(); 00070 00071 int size(){ return width*width; } 00072 00073 int getWidth()const { return width; } 00074 int getHeight()const { return width; } 00075 00076 // base 0 00077 void set0(int i, int j, double value){ data[i][j]= value; } 00078 double get0(int i, int j)const { return data[i][j]; } 00079 00080 // base 1 00081 void set(int i, int j, double value){ data[i-1][j-1]= value; } 00082 double get(int i, int j)const { return data[i-1][j-1]; } 00083 00084 // computations 00085 void setAll(double value=0.0); 00086 void set(RealSMatrix* from); 00087 void setIdentity(); 00088 00089 // optimized transform (reduced cons) 00090 RealSMatrix* multA_X(RealSMatrix* dest); // X <-- A*X 00091 00092 void addA_kX(RealSMatrix& dest, double k=1.0); // A <-- A+k*X 00093 void addA_k_vvT(RealVector& v, double k=1.0); // A <-- A+k*(v*vT) 00094 double vTAv(RealVector& v); // quadratic form: vT*A*v 00095 double rayleighQuotient(RealVector& v){return vTAv(v)/v.vT_v();} // r= vT*A*v/(vT*v) approximates an eigenvalue 00096 00097 double det(); 00098 double trace(); 00099 double cond(); 00100 00101 // norm 00102 double normeMin(); 00103 double normeInfinite(); 00104 double norme2(); // spectral norme= sqrt( max eigenvalue ) 00105 double normeF(); // frobenius norme 00106 00107 double sum(); 00108 00109 double minimum(); 00110 double maximum(); 00111 double mean(){ return sum()/size(); } 00112 double sigma(); 00113 00114 // matrix generation 00115 RealSMatrix* jacobiEV(RealVector* dEigenValue, RealSMatrix* vEigenVector); // Numerical Recipes p365-6 00116 00117 // math vectorial op 00118 RealSMatrix sqrt(); 00119 RealSMatrix pow(double pow); 00120 RealSMatrix sqr(); 00121 RealSMatrix exp(); 00122 RealSMatrix log(); 00123 RealSMatrix log(double base); 00124 00125 RealSMatrix sin(); 00126 RealSMatrix cos(); 00127 RealSMatrix tan(); 00128 00129 // matrix operations 00130 // ================= 00131 00132 void HA_inplace(H& h); // A= H * A low cost memory 00133 void HA_inplace(H& h, int nI); // A= H * A low cost memory 00134 00135 void AH_inplace(H& h); // A= A * H low cost memory 00136 void AH_inplace(H& h, int nI); // A= A * H low cost memory 00137 void AH_inplace(H& h, int nI, int ny); // A= A * H low cost memory 00138 00139 RealSMatrix* qrHouseholderR(RealSMatrix* r=0); // QR upper Triangulation 00140 00141 void qrHouseholder(RealSMatrix* q, RealSMatrix* r); 00142 void qrGivens(RealSMatrix* q, RealSMatrix* r); 00143 void qrCGS(RealSMatrix* q, RealSMatrix* r); 00144 void qrMGS(RealSMatrix* q, RealSMatrix* r); 00145 RealSMatrix* upperHessenberg(RealSMatrix* uH=0); 00146 00147 // Penrose pseudoinverse via QR methods 00148 RealSMatrix* pseudoInverse(RealSMatrix* x=0); 00149 RealSMatrix* varianceCovariance(RealSMatrix* aT_aInverse=0); // X= (At*A)^(-1) 00150 00151 // Neuronic and eigenvectors of a matrix 00152 RealVector* oja(int nmax=100, double beta=0.1, RealVector* oldFirstPCA=0); // Find First principal component or ev. 00153 RealSMatrix* mOja(double nmax=100, double beta=0.1, RealSMatrix* oldPCA=0); // Find all principal component/eigenvectors 00154 RealSMatrix* apex(double nmax=100, double beta=0.1, RealSMatrix* oldPCA=0); // Find all principal component/eigenvectors 00155 00156 // Neuronic and eigenvalues of a matrix: lambdai= E( (wi*x)^2 )= var( wi*x ) 00157 double ojaEigenvalue(int nmax=100, int ns=10, double beta=0.1, RealVector* oldFirstPCA=0); // Evaluates first eigenvalue. 00158 RealVector* apexEigenvalues(int nmax=100, int ns=10, double beta=0.1, RealSMatrix* oldPCA=0); // Evaluates all eigenvalues. 00159 00160 // Simple PCA: SPCA1 and SPCA2 (M. Partridge, University of Sydney Australia, 1997) 00161 RealVector* firstPcSPCA(int type=2, bool batch=false, int nmax=100, RealVector* oldFirstPCA=0); // Find First principal component or ev. 00162 double firstEigenvalueSPCA(int type=2, bool batch=false, int nmax=100, RealVector* oldFirstPCA=0); // Find First principal component or ev. 00163 00164 RealVector* kiemePcSPCA(int type=2, int k=0, bool batch=false, int nmax=100, RealVector* oldFirstPCA=0); // Find kieme principal component or ev. 00165 double kiemeEigenvalueSPCA(int type=2, int k=0, bool batch=false, int nmax=100, RealVector* oldFirstPCA=0); // Find kieme principal component or ev. 00166 00167 RealSMatrix* fullSPCA(int type=2, bool batch=false, double nmax=100, RealSMatrix* oldPCA=0); // Find all principal component/eigenvectors 00168 RealVector* eigenvaluesSPCA(int type=2, bool batch=false, double nmax=100, RealSMatrix* oldPCA=0); // Find all principal component/eigenvectors 00169 00170 // eigenvectors 00171 RealVector* inverseIteration(double eigenvalue, int nmax=3, RealVector* ev=0); 00172 00173 // eigenvalues 00174 RealSMatrix* bidiagonalisation(RealSMatrix* biDiag=0); 00175 RealSMatrix* svdGolubKahan(RealSMatrix* biDiag=0); 00176 00177 RealSMatrix* qrIteration(int iterMax=3, RealSMatrix* Ak=0); // simple QR iteration for eigenvalues O(N^4) 00178 RealSMatrix* qrHessenbergIteration(int iterMax=3, RealSMatrix* r=0); // Hessenberg QR converge faster and is O(N^3) 00179 RealSMatrix* qrShift(int iterMax=3, RealSMatrix* r=0); 00180 RealSMatrix* qrDoubleShift(int iterMax=3, RealSMatrix* r=0); // Can support complexes via double iterations 00181 //RealSMatrix* qrImplicit(int iterMax=3, RealSMatrix* r=0); 00182 00183 RealSMatrix* qrSymmetric(int iterMax=3, RealSMatrix* r=0); // A symmetric=>Hu is tridiagonal & eigenvalues are all real 00184 RTriDiagonalMatrix* lanczosSymmetric(RTriDiagonalMatrix* t=0); // Generates cheap large tridiagonals 00185 RTriDiagonalMatrix* lanczosMGS(RTriDiagonalMatrix* t=0); // Tridiagonalise easier with modified Gram-Schmidt Lanczos 00186 00187 // Factorisation 00188 void luDoolittle(RealSMatrix* l1, RealSMatrix* u); // A -> L1, U 00189 void luCrout(RealSMatrix* l, RealSMatrix* u1){} // A -> L, U1 00190 00191 // incomplete factorisation 00192 RealSMatrix* ilu0(); 00193 RealSMatrix* iluth(double threshold=0.001); 00194 //RealSMatrix* iluk(); 00195 00196 // linear solvers A*x=b 00197 RealVector* backwardSubstitution(RealVector& b, RealVector* x=0); // U*x=b 00198 RealVector* backwardSubstitutionU1(RealVector& b, RealVector* x=0); // U1*x=b 00199 RealVector* forwardElimination(RealVector& b, RealVector* x=0); // L*x=b 00200 RealVector* forwardEliminationL1(RealVector& b, RealVector* x=0); // L1*x=b 00201 00202 RealVector* linearSolverU(RealVector& b, RealVector* x=0); 00203 RealVector* linearSolverU1(RealVector& b, RealVector* x=0); 00204 RealVector* linearSolverL(RealVector& b, RealVector* x=0); 00205 RealVector* linearSolverL1(RealVector& b, RealVector* x=0); 00206 00207 // U, L 00208 RealSMatrix* inverseOfU(RealSMatrix* uinv=0); // Uinv = U^-1 00209 RealSMatrix* inverseOfU1(RealSMatrix* uinv=0); // U1inv = U1^-1 00210 00211 // scalar single operations 00212 void operator+=(double value); 00213 void operator-=(double value); 00214 void operator*=(double value); 00215 void operator/=(double value); 00216 00217 // matrix single operations 00218 void operator+=(const RealSMatrix& m); 00219 void operator-=(const RealSMatrix& m); 00220 void operator*=(const RealSMatrix& m); 00221 00222 // friends 00223 friend RealVectorT operator*(const RealVectorT& vt, const RealSMatrix& m); 00224 friend RealVector operator*(const RealSMatrix& m, const RealVector& v); 00225 00226 void output(); 00227 void output(FILE* file); 00228 }; 00229 00230 #endif 00231 00232 00233