/* Copyright 2002 Ben Blum, Christian Shelton * * This file is part of GameTracer. * * GameTracer is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GameTracer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GameTracer; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _CMATRIX_H_ #define _CMATRIX_H_ #include #ifdef SOLARIS #include #endif #include #include #include #include #include #include #include using namespace std; class cmatrix; class cmatrixrow { public: double operator[](int) const { return 0.0; } }; class cvector { friend class cmatrix; public: static int num_vec_cons; inline cvector() { cvector::num_vec_cons++; m = 1; x = new double[1]; } inline cvector(int m) { cvector::num_vec_cons++; this->m = m; x = new double[m]; } ~cvector(); inline cvector(const cvector &v) { cvector::num_vec_cons++; m = v.m; x = new double[m]; //for(int i=0;im = m; x = new double[m]; for(int i=0;im = m; if (keep) x = v; else { x = new double[m]; //for(int i=0;ima) ma = t; return ma; } inline double min() const { double t,mi = x[0]; for(int i=1;i0?x[0]:-x[0]; for(int i=1;i0?x[i]:-x[i]))>ma) ma = t; return ma; } inline double absmin() const { double t,mi = x[0]>0?x[0]:-x[0]; for(int i=1;i0?x[i]:-x[i]))m) return false; #if !defined(HAVE_BCMP) for(int i=0;ix[i]!=x[i]) return false; return true; #else return bcmp(x,v->x,m*sizeof(double))==0; #endif // HAVE_BCMP } inline bool operator==(const double &a) const { for(int i=0;i>(istream &s, cvector &v); inline double *values() { return x; } inline int getm() const { return m; } inline ostream &niceprint(ostream &s) { for(int i=0;i f2) ? f1 : f2); } inline cvector operator+(const cvector &a, const cvector &b) { return cvector(a)+=b; } inline cvector operator-(const cvector &a, const cvector &b) { return cvector(a)-=b; } inline cvector operator+(const cvector &a, const double &b) { return cvector(a)+=b; } inline cvector operator-(const cvector &a, const double &b) { return cvector(a)-=b; } inline cvector operator+(const double &a, const cvector &b) { return cvector(b)+=a; } inline cvector operator-(const double &a, const cvector &b) { return cvector(b.getm(),a)-=b; } inline cvector operator*(const cvector &a, const double &b) { return cvector(a)*=b; } inline cvector operator*(const double &a, const cvector &b) { return cvector(b)*=a; } inline cvector operator/(const cvector &a, const double &b) { return cvector(a)/=b; } inline ostream &operator<<(ostream &s, const cvector& v) { // s << v.m << ' '; for(int i=0;i>(istream &s, cvector& v) { int tm; s >> tm; if (tm!=v.m) { delete []v.x; v.m = tm; v.x = new double[tm]; } for(int i=0;i> v.x[i]; return s; } class cmatrix { public: inline cmatrix(int m=1, int n=1) { this->m = m; this->n = n; s = m*n; x = new double[s]; } ~cmatrix(); inline cmatrix(const cmatrix &ma, bool transpose=false) { s = ma.m*ma.n; x = new double[s]; if (transpose) { int i,j,c; n = ma.m; m = ma.n; c = 0; for(i=0;im = m; this->n = n; s = m*n; x = new double[s]; if (diaonly) { int i; //for(i=0;i=m) for(i=0;im = m; this->n = n; s = m*n; x = new double[s]; //for(int i=0;im = m; this->n = n; s = m*n; //int i; x = new double[s]; //for(i=0;ima) ma=t; return ma; } inline double min() const { double t,mi = x[0]; for(int i=1;i0?x[0]:-x[0]; for(int i=1;i0?x[i]:-x[i]))0?x[0]:-x[0]; for(int i=1;i0?x[i]:-x[i]))>ma) ma=t; return ma; } inline bool operator==(const cmatrix &ma) const { if (ma.n!=n||ma.m!=m) return false; #if !defined(HAVE_BCMP) for(int i=0;i>(istream& s, cmatrix& ma); // LU decomposition -- ix is the row permutations int LUdecomp(cmatrix &LU, int *ix) const; // LU back substitution -- // ix from above fn call (this should be an LU combination) void LUbacksub(int *ix, double *col) const; // solves equation Ax=b (A is this, x is the returned value) bool solve(cvector &b, cvector &dest); double *solve(const double *b, bool &worked) const; inline double *solve(const double *b) const { bool w; return solve(b,w); } inline void negate() { for(int i = 0; i < s; i++) x[i] = -x[i]; } cmatrix inv(bool &worked) const; inline cmatrix inv() const { bool w; return inv(w); } double adjoint(); inline double trace(); double testAdjoint(); inline void multiply(const cvector &source, cvector &dest) { assert(n == source.m && m == dest.m); int i,j,c=0; for(i = 0; i < m; i++) { dest[i] = 0; for(j = 0; j < n; j++,c++) dest[i] += x[c] * source[j]; } } inline double *values() { return x; } // w needs to points to an array of n fp numbers void svd(cmatrix &u, cmatrix &v, double *w); // makes the matrix tri-diagonal (if symmetric) // The matrix is replaced by Q, and the vectors d and e hold // the diagonal and off-diagonal elements respectively void tridiag(cvector &d, cvector &e); // converts the Q matrix from tridiag into the eigenvectors // d and e are the diagonal and off-diagonal elements from // tridiag and the eigenvalues are left in d void tridiagev(cvector &d, cvector &e); // returns the inverse of a real, symmetric matrix // via eigenvalue decomposition. If any of the e.v. are // very close to zero, it uses the psuedo inverse // (ie 1/ev = 0) cmatrix syminv(double tol=1e-10) const; // uses the above two to compute eigen decomp of symmetric // matrix (destroys matrix and replaces with eigenvectors) cvector eigensym() { cvector d,e; tridiag(d,e); tridiagev(d,e); return d; } inline ostream &niceprint(ostream& s) { s << m << ' ' << n << endl; for(int i=0;i>(istream& s, cmatrix& ma) { int tn,tm; s >> tm >> tn; if (tm!=ma.m || tn!=ma.n) { delete []ma.x; ma.s = tm*tn; ma.x = new double[ma.s]; ma.m = tm; ma.n = tn; } for(int i=0;i> ma.x[i]; } return s; } #endif