/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralMatrix.h,v 1.3 2004/11/24 20:41:59 kamenik Exp $ */ /* Tag $Name: $ */ #ifndef GENERAL_MATRIX_H #define GENERAL_MATRIX_H #include "Vector.h" #include class GeneralMatrix; class ConstGeneralMatrix { friend class GeneralMatrix; protected: ConstVector data; int rows; int cols; int ld; public: ConstGeneralMatrix(const double* d, int m, int n) : data(d, m*n), rows(m), cols(n), ld(m) {} ConstGeneralMatrix(const GeneralMatrix& m); ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols); virtual ~ConstGeneralMatrix() {} const double& get(int i, int j) const {return data[j*ld+i];} int numRows() const {return rows;} int numCols() const {return cols;} int getLD() const {return ld;} const double* base() const {return data.base();} const ConstVector& getData() const {return data;} double getNormInf() const; double getNorm1() const; /* x = scalar(a)*x + scalar(b)*this*d */ void multVec(double a, Vector& x, double b, const ConstVector& d) const; /* x = scalar(a)*x + scalar(b)*this'*d */ void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const; /* x = x + this*d */ void multaVec(Vector& x, const ConstVector& d) const {multVec(1.0, x, 1.0, d);} /* x = x + this'*d */ void multaVecTrans(Vector& x, const ConstVector& d) const {multVecTrans(1.0, x, 1.0, d);} /* x = x - this*d */ void multsVec(Vector& x, const ConstVector& d) const {multVec(1.0, x, -1.0, d);} /* x = x - this'*d */ void multsVecTrans(Vector& x, const ConstVector& d) const {multVecTrans(1.0, x, -1.0, d);} /* m = inv(this)*m */ void multInvLeft(GeneralMatrix& m) const; /* m = inv(this')*m */ void multInvLeftTrans(GeneralMatrix& m) const; /* d = inv(this)*d */ void multInvLeft(Vector& d) const; /* d = inv(this')*d */ void multInvLeftTrans(Vector& d) const; bool isFinite() const; /** Returns true of the matrix is exactly zero. */ bool isZero() const; virtual void print() const; protected: void multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const; }; class GeneralMatrix { friend class ConstGeneralMatrix; protected: Vector data; int rows; int cols; int ld; public: GeneralMatrix(int m, int n) : data(m*n), rows(m), cols(n), ld(m) {} GeneralMatrix(const double* d, int m, int n) : data(d, m*n), rows(m), cols(n), ld(m) {} GeneralMatrix(double* d, int m, int n) : data(d, m*n), rows(m), cols(n), ld(m) {} GeneralMatrix(const GeneralMatrix& m); GeneralMatrix(const ConstGeneralMatrix& m); GeneralMatrix(const GeneralMatrix&m, const char* dummy); // transpose GeneralMatrix(const ConstGeneralMatrix&m, const char* dummy); // transpose GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols); GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols); /* this = a*b */ GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b); /* this = a*b' */ GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum); /* this = a'*b */ GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b); /* this = a'*b */ GeneralMatrix(const GeneralMatrix& a, const char* dum1, const GeneralMatrix& b, const char* dum2); virtual ~GeneralMatrix(); const GeneralMatrix& operator=(const GeneralMatrix& m) {data=m.data; rows=m.rows; cols=m.cols; ld=m.ld; return *this;} const double& get(int i, int j) const {return data[j*ld+i];} double& get(int i, int j) {return data[j*ld+i];} int numRows() const {return rows;} int numCols() const {return cols;} int getLD() const {return ld;} double* base() {return data.base();} const double* base() const {return data.base();} Vector& getData() {return data;} const Vector& getData() const {return data;} double getNormInf() const {return ConstGeneralMatrix(*this).getNormInf();} double getNorm1() const {return ConstGeneralMatrix(*this).getNorm1();} /* place matrix m to the position (i,j) */ void place(const ConstGeneralMatrix& m, int i, int j); void place(const GeneralMatrix& m, int i, int j) {place(ConstGeneralMatrix(m), i, j);} /* this = a*b */ void mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b); void mult(const GeneralMatrix& a, const GeneralMatrix& b) {mult(ConstGeneralMatrix(a), ConstGeneralMatrix(b));} /* this = this + scalar*a*b */ void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, double mult=1.0); void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, double mult=1.0) {multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), mult);} /* this = this + scalar*a*b' */ void multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b, const char* dum, double mult=1.0); void multAndAdd(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum, double mult=1.0) {multAndAdd(ConstGeneralMatrix(a), ConstGeneralMatrix(b), dum, mult);} /* this = this + scalar*a'*b */ void multAndAdd(const ConstGeneralMatrix& a, const char* dum, const ConstGeneralMatrix& b, double mult=1.0); void multAndAdd(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b, double mult=1.0) {multAndAdd(ConstGeneralMatrix(a), dum, ConstGeneralMatrix(b), mult);} /* this = this + scalar*a'*b' */ void multAndAdd(const ConstGeneralMatrix& a, const char* dum1, const ConstGeneralMatrix& b, const char* dum2, double mult=1.0); void multAndAdd(const GeneralMatrix& a, const char* dum1, const GeneralMatrix& b, const char* dum2, double mult=1.0) {multAndAdd(ConstGeneralMatrix(a), dum1, ConstGeneralMatrix(b),dum2, mult);} /* this = this + scalar*a*a' */ void addOuter(const ConstVector& a, double mult=1.0); void addOuter(const Vector& a, double mult=1.0) {addOuter(ConstVector(a), mult);} /* this = this * m */ void multRight(const ConstGeneralMatrix& m); void multRight(const GeneralMatrix& m) {multRight(ConstGeneralMatrix(m));} /* this = m * this */ void multLeft(const ConstGeneralMatrix& m); void multLeft(const GeneralMatrix& m) {multLeft(ConstGeneralMatrix(m));} /* this = this * m' */ void multRightTrans(const ConstGeneralMatrix& m); void multRightTrans(const GeneralMatrix& m) {multRightTrans(ConstGeneralMatrix(m));} /* this = m' * this */ void multLeftTrans(const ConstGeneralMatrix& m); void multLeftTrans(const GeneralMatrix& m) {multLeftTrans(ConstGeneralMatrix(m));} /* x = scalar(a)*x + scalar(b)*this*d */ void multVec(double a, Vector& x, double b, const ConstVector& d) const {ConstGeneralMatrix(*this).multVec(a, x, b, d);} /* x = scalar(a)*x + scalar(b)*this'*d */ void multVecTrans(double a, Vector& x, double b, const ConstVector& d) const {ConstGeneralMatrix(*this).multVecTrans(a, x, b, d);} /* x = x + this*d */ void multaVec(Vector& x, const ConstVector& d) const {ConstGeneralMatrix(*this).multaVec(x, d);} /* x = x + this'*d */ void multaVecTrans(Vector& x, const ConstVector& d) const {ConstGeneralMatrix(*this).multaVecTrans(x, d);} /* x = x - this*d */ void multsVec(Vector& x, const ConstVector& d) const {ConstGeneralMatrix(*this).multsVec(x, d);} /* x = x - this'*d */ void multsVecTrans(Vector& x, const ConstVector& d) const {ConstGeneralMatrix(*this).multsVecTrans(x, d);} /* this = zero */ void zeros(); /** this = unit (on main diagonal) */ void unit(); /* this = NaN */ void nans(); /* this = Inf */ void infs(); /* this = scalar*this */ void mult(double a); /* this = this + scalar*m */ void add(double a, const ConstGeneralMatrix& m); void add(double a, const GeneralMatrix& m) {add(a, ConstGeneralMatrix(m));} /* this = this + scalar*m' */ void add(double a, const ConstGeneralMatrix& m, const char* dum); void add(double a, const GeneralMatrix& m, const char* dum) {add(a, ConstGeneralMatrix(m), dum);} bool isFinite() const {return (ConstGeneralMatrix(*this)).isFinite();} bool isZero() const {return (ConstGeneralMatrix(*this)).isZero();} virtual void print() const {ConstGeneralMatrix(*this).print();} private: void copy(const ConstGeneralMatrix& m, int ioff = 0, int joff = 0); void copy(const GeneralMatrix& m, int ioff = 0, int joff = 0) {copy(ConstGeneralMatrix(m), ioff, joff);} void gemm(const char* transa, const ConstGeneralMatrix& a, const char* transb, const ConstGeneralMatrix& b, double alpha, double beta); void gemm(const char* transa, const GeneralMatrix& a, const char* transb, const GeneralMatrix& b, double alpha, double beta) {gemm(transa, ConstGeneralMatrix(a), transb, ConstGeneralMatrix(b), alpha, beta);} /* this = this * op(m) (without whole copy of this) */ void gemm_partial_right(const char* trans, const ConstGeneralMatrix& m, double alpha, double beta); void gemm_partial_right(const char* trans, const GeneralMatrix& m, double alpha, double beta) {gemm_partial_right(trans, ConstGeneralMatrix(m), alpha, beta);} /* this = op(m) *this (without whole copy of this) */ void gemm_partial_left(const char* trans, const ConstGeneralMatrix& m, double alpha, double beta); void gemm_partial_left(const char* trans, const GeneralMatrix& m, double alpha, double beta) {gemm_partial_left(trans, ConstGeneralMatrix(m), alpha, beta);} /* number of rows/columns for copy used in gemm_partial_* */ static int md_length; }; class SVDDecomp { protected: /** Minimum of number of rows and columns of the decomposed * matrix. */ const int minmn; /** Singular values. */ Vector sigma; /** Orthogonal matrix U. */ GeneralMatrix U; /** Orthogonal matrix V^T. */ GeneralMatrix VT; /** Convered flag. */ bool conv; public: SVDDecomp(const GeneralMatrix& A) : minmn(std::min(A.numRows(), A.numCols())), sigma(minmn), U(A.numRows(), A.numRows()), VT(A.numCols(), A.numCols()), conv(false) {construct(A);} const GeneralMatrix& getU() const {return U;} const GeneralMatrix& getVT() const {return VT;} void solve(const GeneralMatrix& B, GeneralMatrix& X) const; void solve(const Vector& b, Vector& x) const { GeneralMatrix xmat(x.base(), x.length(), 1); solve(GeneralMatrix(b.base(), b.length(), 1), xmat); } private: void construct(const GeneralMatrix& A); }; #endif /* GENERAL_MATRIX_H */ // Local Variables: // mode:C++ // End: