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 #ifndef _MARKOVSOLVERBASE_H 00010 #define _MARKOVSOLVERBASE_H 00011 00013 //Class : MarkovSolverBase 00014 //Author : Vishaka Datta S, 2011, NCBS 00015 //Description : Base class for all current Markov solver(s) (and future ones, 00016 //hopefully). 00017 // 00018 //After the setup of the MarkovRateTable class, where the user has entered 00019 //the lookup tables for the various transition rates, we have enough 00020 //information to compute all the exponential matrices that correspond to the 00021 //solution of the kinetic equation at each time step. 00022 // 00023 //Before the channel simulation is run, the setup of the MarkovSolver requires 00024 //that a table of matrix exponentials be computed and stored. In general, 00025 //this would require a 2D lookup table where each exponential is index by 00026 //([L],V) where [L] = ligand concentration and V = membrane voltage. 00027 //In the case all rates are either ligand or voltage dependent, not both, a 1D 00028 //lookup table of exponentials suffices. 00029 // 00030 //The above computations are achieved by going through the lookup tables 00031 //of the MarkovRateTable class. In a general case, the number of divisions 00032 //i.e. step sizes in each lookup table will be different. We choose the smallest 00033 //such step size, and assume that rates with bigger step sizes stay constant 00034 //over this time interval. By iterating over the whole range, we setup the 00035 //exponential table. 00036 // 00037 //The MarkovSolverBase class handles all the bookkeeping for the table of matrix 00038 //exponentials. It also handles all the above-mentioned interactions with the 00039 //remaining MOOSE classes. 00040 // 00041 //Any MarkovSolver class that derives from this one only need implement 00042 //a ComputeMatrixExponential() function, which handles the actual computation 00043 //of a the matrix exponential given the Q_ matrix. 00044 // 00046 00048 //SrcFinfos 00050 00051 class MarkovSolverBase { 00052 public : 00053 MarkovSolverBase(); 00054 00055 virtual ~MarkovSolverBase(); 00056 00058 //Set-get stuff. 00060 Matrix getQ() const ; 00061 Vector getState() const; 00062 Vector getInitialState() const; 00063 void setInitialState( Vector ); 00064 00065 //Lookup table related stuff. Have stuck to the same naming 00066 //used in the Interpol2D class for simplicity. 00067 void setXmin( double ); 00068 double getXmin() const; 00069 void setXmax( double ); 00070 double getXmax() const; 00071 void setXdivs( unsigned int ); 00072 unsigned int getXdivs() const; 00073 double getInvDx() const; 00074 00075 void setYmin( double ); 00076 double getYmin() const; 00077 void setYmax( double ); 00078 double getYmax() const; 00079 void setYdivs( unsigned int ); 00080 unsigned int getYdivs() const; 00081 double getInvDy() const; 00082 00084 //Lookup table related stuff. 00086 00087 //Fills up lookup table of matrix exponentials. 00088 void innerFillupTable( vector< unsigned int >, string, 00089 unsigned int, unsigned int ); 00090 void fillupTable(); 00091 00092 //This returns the pointer to the exponential of the Q matrix. 00093 virtual Matrix* computeMatrixExponential(); 00094 00095 //State space interpolation routines. 00096 Vector* bilinearInterpolate() const; 00097 Vector* linearInterpolate() const; 00098 00099 //Computes the updated state of the system. Is called from the process 00100 //function. 00101 void computeState(); 00102 00104 //MsgDest functions. 00106 void reinit( const Eref&, ProcPtr ); 00107 void process( const Eref&, ProcPtr ); 00108 00109 //Handles information about Vm from the compartment. 00110 void handleVm( double ); 00111 00112 //Handles concentration information. 00113 void handleLigandConc( double ); 00114 00115 //Takes the Id of a MarkovRateTable object to initialize the table of matrix 00116 //exponentials. 00117 void init( Id, double ); 00118 00119 static const Cinfo* initCinfo(); 00120 00122 //Unit test 00124 #ifdef DO_UNIT_TESTS 00125 friend void testMarkovSolverBase(); 00126 #endif 00127 00128 protected : 00129 //The instantaneous rate matrix. 00130 Matrix *Q_; 00131 00132 #ifdef DO_UNIT_TESTS 00133 //Allows us to set Vm_ and ligandConc_ for the state space interpolation 00134 //unit test in the MarkovSolver class. 00135 void setVm( double ); 00136 void setLigandConc( double ); 00137 #endif 00138 00139 private : 00141 //Helper functions. 00143 00144 //Sets the values of xMin, xMax, xDivs, yMin, yMax, yDivs. 00145 void setLookupParams(); 00146 00148 //Lookup table related stuff. 00150 /* 00151 * Exponentials of all rate matrices that are generated over the 00152 * duration of the simulation. The idea is that when copies of the channel 00153 * are made, they will all refer this table to get the appropriate 00154 * exponential matrix. 00155 * 00156 * The exponential matrices are computed over a range of voltage levels 00157 * and/or ligand concentrations and stored in the appropriate lookup table. 00158 * 00159 * Depending on whether 00160 * 1) All rates are constant, 00161 * 2) Rates vary with only 1 parameter i.e. ligand/votage, 00162 * 3) Some rates are 2D i.e. vary with two parameters, 00163 * we store the table of exponentials in the appropriate pointers below. 00164 * 00165 * If a system contains both 2D and 1D rates, then, only the 2D pointer 00166 * is used. 00167 */ 00168 //Used for storing exponentials when at least one of the rates are 1D and 00169 //none are 2D. 00170 vector< Matrix* > expMats1d_; 00171 00172 Matrix* expMat_; 00173 00174 //Used for storing exponentials when at least one of the rates are 2D. 00175 vector< vector< Matrix* > > expMats2d_; 00176 00177 double xMin_; 00178 double xMax_; 00179 double invDx_; 00180 unsigned int xDivs_; 00181 double yMin_; 00182 double yMax_; 00183 double invDy_; 00184 unsigned int yDivs_; 00185 00187 //Miscallenous stuff 00189 00190 //Pointer to the MarkovRateTable object. Necessary to glean information 00191 //about the properties of all the transition rates. 00192 MarkovRateTable* rateTable_; 00193 00194 //Instantaneous state of the system. 00195 Vector state_; 00196 00197 //Initial state of the system. 00198 Vector initialState_; 00199 00200 //Stands for a lot of things. The dimension of the Q matrix, the number of 00201 //states in the rate table, etc which all happen to be the same. 00202 unsigned int size_; 00203 00204 //Membrane voltage. 00205 double Vm_; 00206 //Ligand concentration. 00207 double ligandConc_; 00208 00209 //Time step in simulation. The state at t = (t0 + dt) is given by 00210 //exp( A * dt ) * [state at t = t0 ]. 00211 double dt_; 00212 }; 00213 //End of class definition. 00214 #endif