// // Matrix.h // // This file contains declarations for the Matrix class. // This code is part of the Bioinformatics Template Library (BTL). // /// Copyright (C) 1997 Birkbeck College, Malet Street, London WC1E 7HX, U.K. // (classlib@mail.cryst.bbk.ac.uk) // // This library is free software; you can // redistribute it and/or modify it under the terms of // the GNU Library General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your // option) any later version. This library 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 Library General Public License for more details. // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free Software // Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /////////////////////////////////////////////////////////////////////////// #if !defined (MATRIX_H) #define MATRIX_H #include "Typedefn.h" #include "MathVector.h" #if !defined(SGI_CC) using namespace std; #endif /**#: [Description =" This class represents a mathematical Matrix of any dimension. Matrices where one of the two dimensions is unity are more efficiently modelled using the Vector class.

There are two types associated with this class:

value_type : this type is the same as the Vector::value_type and defines the type of the elements of the Matrix.

size_type : this type is the same as the Vector::size_type and defines the type of the Matrix indexes. It should always be an unsigned integer type."] [Authors = "D.S.Moss, W.R.Pitt, I.Tickle."] [Files = "Matrix.h, Matrix.cpp"] [Friends="Friend equivalents to some functions are available and are documented with these functions. Also available is: friend ostream& operator<<(ostream &os, const Matrix &m); "] [Dependencies="Vector, NumericLimits, NumericUtilities"] */ class Matrix { public: typedef Vector::value_type value_type; // The type of elements stored // in the Matrix. typedef Vector::size_type size_type; // The type used for the Matrix // indexes and size. typedef value_type* iterator; // The iterator type typedef const value_type* const_iterator; // The const iterator type private: value_type *mat; // Pointer to start of array holding // the matrix. size_type nrows, ncols; // The number of rows and columns. // Subroutine to compute eigenvalues & eigenvectors of a real // symmetric matrix, from IBM SSP manual (see p165). Ian Tickle // April 1992, (modified by David Moss February 1993). /**#: [Hidden] */ void Eigen(int mv, int n, long double* a, long double* r) const; // Sort eigenvectors according to descending order of // eigenvalues (called by Eigens) /**#: [Hidden] */ void Esort(int mv, int n, long double* a, long double* r) const; // Constructs the square symmetric matrix needed for least // squares fitting. public: //............................................................................. // CONSTRUCTORS/DESTRUCTOR. /**#: [Description="Constructor for default 3x3 matrix and initialise elements to zero."] */ Matrix(); /**#: [Description="Constructs a unit matrix of size s*s."] */ Matrix(const size_type& s); /**#: [Description="Constructs a Matrix with p rows and q columns. Initialises each element to zero"] */ Matrix(const size_type& p, const size_type& q); /**#: [Description="Constructs a Matrix with p rows and q columns. Elements are initialised to those in array."] */ Matrix(const value_type * const array, const size_type& p, const size_type& q); /**#: [Description="Constructor for a 3x3 Matrix with initialisation"] */ Matrix(const value_type& e1, const value_type& e2, const value_type& e3, const value_type& e4, const value_type& e5, const value_type& e6, const value_type& e7, const value_type& e8,const value_type& e9); /**#: [Description="Constructor for 3x3 rotation matrix for a rotation about a given axis by a given number of degrees."] */ Matrix(const Vector& axis, const value_type& angle); /**#: [Description="Copy constructor"] */ Matrix(const Matrix &m); /**#: [Description="Destructor"] */ ~Matrix() { delete[] mat;} //............................................................................. // OVERLOADED OPERATORS. /**#: [Description="Matrix assignment"] */ Matrix& operator=(const Matrix &m); /**#: [Description="Read only access a matrix element given its indices e.g. x(i,j) i = row, j = column. N.B. (i,j >= 1)"] */ value_type operator()(const size_type& i, const size_type& j) const; /**#: [Description="Read/write access a matrix element given its indices e.g. x(i,j) i = row, j = column. N.B. (i,j >= 1)"] */ value_type& operator()(const size_type& i, const size_type& j); /**#: [Description="Returns an iterator that points the first element of a given row. N.B. ( 0 <= i < nrows )"] */ iterator operator[](const size_type& i); /**#: [Description="Returns a const iterator that points the first elment of a given row. N.B. ( 0 <= i < nrows )"] */ const_iterator operator[](const size_type& i) const; /**#: [Description="Matrix multiplication e.g. Matrix m1,m2,m3; .... m3 = m1 * m2;"]*/ Matrix operator*(const Matrix& m) const; /**#: [Description="Postmultiplication of a Matrix by a Vector. e.g. Matrix m; Vector v1,v2; ... v2 = m * v1; "] [Restrictions="The size of v must equal the number of columns in this Matrix."] [Friend="There exists a friend function: friend Vector operator*(const Vector &v, const Matrix& m); that performs premultiplication of Matrix by a Vector. This method is slightly less efficient than postmultiplication and requires that the size of Vector v must equal the number of rows in Matrix m."]*/ Vector operator*(const Vector &v) const; //............................................................................. // Premultiplication of a Matrix by a Vector. friend Vector operator*(const Vector &v, const Matrix& m); /**#: [Description="Multiple each element by a number"] */ Matrix& operator*=(const value_type& r); /**#: [Description="Multiple each element by a number"] [Friend="The friend function: friend Matrix operator*(const value_type& r, const Matrix& m); is also available."] */ Matrix operator*(const value_type& r) const; //............................................................................. // Multiplication of a value_type by a Matrix. friend Matrix operator*(const value_type& r, const Matrix& m); /**#: [Description="Divide each element by a number"] */ Matrix& operator/=(const value_type& r); /**#: [Description="Divide each element by a number"] */ Matrix operator/(const value_type& r) const; /**#: [Description="Subtraction of a number from each element."] */ Matrix& operator-=(const value_type &v); /**#: [Description="Subtraction of a number from each element."] */ Matrix operator-(const value_type &v) const; /**#: [Description="Addition of a number to each element."] */ Matrix& operator+=(const value_type &v); /**#: [Description="Addition of a number to each element."] */ Matrix operator+(const value_type &v) const; /**#: [Description="Subtraction of a vector from the rows of a matrix"] [Restrictions="The the size of Vector v must equal the number of columns in this Matrix."] */ Matrix& operator-=(const Vector &v); /**#: [Description="Subtraction of a vector from the rows of a matrix"] [Restrictions="The the size of Vector v must equal the number of columns in this Matrix."] */ Matrix operator-(const Vector &v) const; /**#: [Description="Addition of a vector to the rows of a matrix"] [Restrictions="The the size of Vector v must equal the number of columns in this Matrix."] */ Matrix& operator+=(const Vector &v); /**#: [Description="Addition of a vector to the rows of a matrix"] [Restrictions="The the size of Vector v must equal the number of columns in this Matrix."] */ Matrix operator+(const Vector &v) const; /**#: [Description="Matrix subtraction"] [Restrictions="The the size of Matrix m must equal the size of this Matrix."] */ Matrix& operator-=(const Matrix &m); /**#: [Description="Matrix subtraction"] [Restrictions="The the size of Matrix m must equal the size of this Matrix."] */ Matrix operator-(const Matrix &m) const; /**#: [Description="Matrix addition"] [Restrictions="The the size of Matrix m must equal the size of this Matrix."] */ Matrix& operator+=(const Matrix &m); /**#: [Description="Matrix addition"] [Restrictions="The the size of Matrix m must equal the size of this Matrix."] */ Matrix operator+(const Matrix &m) const; /**#: [Description="Matrix multiplication Transpose(m1) * m2 N.B. this is less efficient than (but not equivalent to) operator%"] [Restrictions="Both *this and the input Matrix must have the same number of rows"] */ Matrix operator&(const Matrix& m) const; /**#: [Description="Matrix multiplication m1 * Transpose(m2) N.B. this is more efficient than (but not equivalent to) operator&"] [Restrictions="Both *this and the input Matrix must have the same number of columns"] */ Matrix operator%(const Matrix& m) const; /**#: [Description="Equality operator"]*/ bool operator==(const Matrix& m) const; // ostream operator friend ostream& operator<<(ostream &os, const Matrix &m); //............................................................................. // OTHER FUNCTIONS. /**#: [Description="Returns an iterator that points to the first element in the Matrix"] */ iterator begin() { return mat; } /**#: [Description="Returns a const_iterator that points to the first element in the Matrix"] */ const_iterator begin() const { return mat; } /**#: [Description="Returns an iterator that can be used in a comparison for ending a traversal through this Matrix"] */ iterator end() { return mat + size(); } /**#: [Description="Returns a const_iterator that can be used in a comparison for ending a traversal through this Matrix"] */ const_iterator end() const { return mat + size(); } /**#: [Description="Size of Matrix (the number of rows times the number of columns)"] */ size_type size() const { return ncols * nrows; } /**#: [Description="Matrix adjoint"] [Restrictions="Square matrices only"].*/ Matrix Adjoint() const; /**#: [Description="Returns zero if the cooresponding Matrix elements are all identical within the floating point precision used. If they are not identical then the function finds the largest difference between cooresponding elements and outputs the number of significant digits in this difference. The range this number can take depends on the floating point precision used. The maximum is typically equal to 6 for single precision (FLT_DIG) and 15 for double precision (DBL_DIG)."]*/ unsigned int IsNotEqualTo(const Matrix& m) const; /**#: [Description="Inverts a positive definite square matrix.

D S Moss May 1991

Employs Cholesky decomposition in step (1). (1)M=LL(tr) (2)compute L(-1) (3)M(-1)=L(-1)(tr)L(-1)"] [Restrictions="Symmetric positive definite matrices only."] */ void CholeskyInverse(); /**#: [Description="Calculate the mean of each column of this Matrix and store the answer in a Vector"] */ Vector ColumnMean() const; /**#: [Description="Matrix determinant"] [Restrictions="Square matrices only."] */ value_type Determinant() const; /**#: [Description="Eigenvalues and eigenvectors of a symmetric matrix"] [Restrictions="*this matrix must be square and symmetric."] [Parameters="(1) A returned vector with the same dimension as *this Matrix (n) containing eigenvalues in decreasing magnitude; (2) A returned Matrix of size n^2 containing eigenvectors stored columnwise in the same order as the eigenvalues magnitude"] */ void Eigens(Vector &eval, Matrix &evec) const; /**#: [Description="Matrix inverse. Answer overwrites this Matrix."] */ void Inverse(); /**#: [Description="Find the largest difference between elements of matrices of the same dimensions."] */ value_type MaxDifference(const Matrix& m) const; /**#: [Description="Find the minor of a square matrix."] [Restrictions="This matrix must be square."] */ Matrix Minor(size_type i, size_type j) const; /**#: [Description="Read number of rows."] */ size_type ReadNRows() const {return nrows;} /**#: [Description="Read number of columns."] */ size_type ReadNCols() const {return ncols;} /**#: [Description="Copy a row of this Matrix into a Vector"] */ Vector ReadRow(const size_type& rowIndx) const; /**#: [Description="Calculate inverse of a small square matrix (inverse = adjoint/determinant)."] */ Matrix SquareInverse() const; /**#: [Description="Single value decomposition.

A = U * diag(L) * V.transpose() where A is this Matrix.

On completion, this matrix is overwritten with matrix U, the diagonal of matrix diag(L) is written over the input Vector L and Matrix V replaces the input Matrix."] [Restrictions=On input, the size of Vector L must equal the number of columns in this Matrix and Matrix V must be a square Matrix with dimensions equal to the number of columns in the input Matrix." */ void SVD(Vector& L, Matrix& V); /**#: [Description="Matrix transpose"] */ Matrix Transpose() const; /**#: [Description="Copy data from a Vector into a row of this Matrix."] [Restrictions="The size of the input Vector must equal the number of columns in this Matrix."] */ void WriteRow(const Vector& rowVector, const size_type& rowIndx); /**#: [Description="Copy data from an array into a row of this Matrix. This routine assumes that the size of the input array is equal the number of columns in this Matrix."] */ void WriteRow(const value_type* rowArr, const size_type& rowIndx); }; // class Matrix #endif // Matrix.h