00001 /********************************************************************** 00002 ** This program is part of 'MOOSE', the 00003 ** Messaging Object Oriented Simulation Environment. 00004 ** Copyright (C) 2003-2011 Upinder S. Bhalla. and NCBS 00005 ** It is made available under the terms of the 00006 ** GNU Lesser General Public License version 2.1 00007 ** See the file COPYING.LIB for the full notice. 00008 **********************************************************************/ 00009 00010 #ifndef _MATRIXOPS_H 00011 #define _MATRIXOPS_H 00013 //Few functions for performing simple matrix operations. 00014 //Note that all matrices here are square, which is the type encountered in 00015 //solving the differential equations associated with first-order kinetics of 00016 //the Markov channel model. 00017 // 00018 //Author : Vishaka Datta S, 2011, NCBS 00020 using std::vector; 00021 00022 typedef vector< vector< double > > Matrix; 00023 typedef vector< double > Vector; 00024 00025 //Idea taken from the implementation of the DGETRF method in LAPACK. When 00026 //the pivot is zero, we divide by a small number instead of simply throwing up 00027 //an error and not returning a result. 00028 #define EPSILON 1e-15 00029 00030 #define FIRST 1 00031 #define SECOND 2 00032 00033 #define DUMMY 0 00034 00035 //Just a debug function to print the matrix. 00036 void matPrint( Matrix* ); 00037 00038 void vecPrint( Vector* ); 00039 00040 //Computes product of two square matrices. 00041 //Version 1 : Returns the result in a new matrix. 00042 Matrix* matMatMul( Matrix*, Matrix* ); 00043 00044 //Version 2 : Returns the result in either of the matrices passed in. 00045 //The third parameter determines which matrix to destroy in order to return 00046 //the result in it. 00047 void matMatMul( Matrix*, Matrix*, unsigned int ); 00048 00049 //Special version to multiply upper and lower triangular matrices (in that 00050 //order). Used specially by the matInv method. The result is stored in the 00051 //first matrix. 00052 //Thanks to the structure of this multiplication, the multiplication can be 00053 //carried out in place. 00054 void triMatMul( Matrix*, Matrix* ); 00055 00056 //Special matrix multiplication when the second matrix is a permutation matrix 00057 //i.e. the columns are to be permuted. 00058 //This helps in avoiding a matrix multiplication. 00059 void matPermMul( Matrix*, vector< unsigned int >* ); 00060 00061 //Computes sum of two square matrices. 00062 Matrix* matMatAdd( const Matrix*, const Matrix*, double, double ); 00063 00064 //Version 2 : Returns the result in either of the matrices that are passed as 00065 //arguments. 00066 void matMatAdd( Matrix*, Matrix*, double, double, unsigned int ); 00067 00068 //Adds k*I to given matrix. Original is intact. 00069 Matrix* matEyeAdd( const Matrix*, double ); 00070 00071 //Version 2 : Returns the matrix in first argument i.e. original is destroyed. 00072 void matEyeAdd( Matrix*, double, unsigned int ); 00073 00074 //Computes the result of multiplying all terms of a matrix by a scalar and then 00075 //adding another scalar i.e. B = a*A + b. 00076 //First argument is scale i.e. 'a' and second argument is shift i.e. 'b'. 00077 Matrix* matScalShift( const Matrix*, double, double ); 00078 00079 void matScalShift( Matrix*, double, double, unsigned int ); 00080 00081 //Computes the result of multiplying a row vector with a matrix (in that order). 00082 Vector* vecMatMul( const Vector*, Matrix* ); 00083 00084 //Computes the result of scaling and shifting a vector. 00085 Vector* vecScalShift( const Vector*, double, double ); 00086 00087 void vecScalShift( Vector*, double, double, unsigned int ); 00088 00089 //Computes the result of multiplying a matrix with a column vector (in that order). 00090 Vector* matVecMul( Matrix*, Vector* ); 00091 00092 //Computes the sum of two vectors. 00093 Vector* vecVecScalAdd( const Vector*, const Vector*, double, double ); 00094 00095 //Version 2 : Returns the result in the first vector. 00096 void vecVecScalAdd( Vector*, Vector*, double, double, unsigned int ); 00097 00098 //Trace of matrix. 00099 double matTrace( Matrix* ); 00100 00101 //Calculate column norm of matrix. 00102 double matColNorm( Matrix* ); 00103 00104 //Plain old matrix transpose i.e. done out-of-place. 00105 Matrix* matTrans( Matrix* ); 00106 00107 //Matrix inverse implemented using LU-decomposition (Doolittle algorithm) 00108 //Returns NULL if matrix is singular. 00109 void matInv( Matrix*, vector< unsigned int >*, Matrix* ); 00110 00111 //Carry out partial pivoting. 00112 double doPartialPivot( Matrix*, unsigned int, unsigned int, vector< unsigned int >*); 00113 00115 //Memory allocation routines. 00117 Matrix* matAlloc( unsigned int ); 00118 00119 Vector* vecAlloc( unsigned int ); 00120 00121 #endif