MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MarkovSolverBase.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2011 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include <float.h> //Needed for DBL_MAX and DBL_MIN
11 #include "header.h"
12 #include "MatrixOps.h"
13 
14 #include "VectorTable.h"
15 #include "../builtins/Interpol2D.h"
16 #include "MarkovRateTable.h"
17 
18 #include "MarkovSolverBase.h"
19 
21 {
22  static SrcFinfo1< Vector > stateOut("stateOut",
23  "Sends updated state to the MarkovChannel class."
24  );
25  return &stateOut;
26 }
27 
29 {
31  //SharedFinfos
33  static DestFinfo handleVm("handleVm",
34  "Handles incoming message containing voltage information.",
36  );
37 
38  static Finfo* channelShared[] =
39  {
40  &handleVm
41  };
42 
43  static SharedFinfo channel("channel",
44  "This message couples the MarkovSolverBase to the Compartment. The "
45  "compartment needs Vm in order to look up the correct matrix "
46  "exponential for computing the state.",
47  channelShared, sizeof( channelShared ) / sizeof( Finfo* )
48  );
49 
51  //DestFinfos
53 
54  static DestFinfo process( "process",
55  "Handles process call",
57 
58  static DestFinfo reinit( "reinit",
59  "Handles reinit call",
61 
62  static Finfo* processShared[] =
63  {
64  &process, &reinit
65  };
66 
67  static SharedFinfo proc( "proc",
68  "This is a shared message to receive Process message from the"
69  "scheduler. The first entry is a MsgDest for the Process "
70  "operation. It has a single argument, ProcInfo, which "
71  "holds lots of information about current time, thread, dt and"
72  "so on. The second entry is a MsgDest for the Reinit "
73  "operation. It also uses ProcInfo.",
74  processShared, sizeof( processShared ) / sizeof( Finfo* )
75  );
76 
77  static DestFinfo ligandConc("ligandConc",
78  "Handles incoming message containing ligand concentration.",
80  );
81 
82  static DestFinfo init("init",
83  "Setups the table of matrix exponentials associated with the"
84  " solver object.",
86  );
87 
89  //*ValueFinfos
91 
93  "Instantaneous rate matrix.",
95  );
96 
98  "Current state of the channel.",
100  );
101 
102  static ValueFinfo< MarkovSolverBase, Vector > initialstate("initialState",
103  "Initial state of the channel.",
106  );
107 
108  static ValueFinfo< MarkovSolverBase, double > xmin( "xmin",
109  "Minimum value for x axis of lookup table",
112  );
113  static ValueFinfo< MarkovSolverBase, double > xmax( "xmax",
114  "Maximum value for x axis of lookup table",
117  );
118  static ValueFinfo< MarkovSolverBase, unsigned int > xdivs( "xdivs",
119  "# of divisions on x axis of lookup table",
122  );
124  "Reciprocal of increment on x axis of lookup table",
126  );
127  static ValueFinfo< MarkovSolverBase, double > ymin( "ymin",
128  "Minimum value for y axis of lookup table",
131  );
132  static ValueFinfo< MarkovSolverBase, double > ymax( "ymax",
133  "Maximum value for y axis of lookup table",
136  );
137  static ValueFinfo< MarkovSolverBase, unsigned int > ydivs( "ydivs",
138  "# of divisions on y axis of lookup table",
141  );
143  "Reciprocal of increment on y axis of lookup table",
145  );
146 
147  static Finfo* markovSolverFinfos[] =
148  {
149  &channel, //SharedFinfo
150  &proc, //SharedFinfo
151  stateOut(), //SrcFinfo
152  &ligandConc, //DestFinfo
153  &init, //DestFinfo
154  &Q, //ReadOnlyValueFinfo
155  &state, //ReadOnlyValueFinfo
156  &initialstate, //ReadOnlyValueFinfo
157  &xmin, //ValueFinfo
158  &xmax, //ValueFinfo
159  &xdivs, //ValueFinfo
160  &invdx, //ReadOnlyValueFinfo
161  &ymin, //ValueFinfo
162  &ymax, //ValueFinfo
163  &ydivs, //ValueFinfo
164  &invdy //ReadOnlyValueFinfo
165  };
166 
167  static string doc[] =
168  {
169  "Name", "MarkovSolverBase",
170  "Author", "Vishaka Datta S, 2011, NCBS",
171  "Description", "Solver for Markov Channel."
172  };
173  static Dinfo< MarkovSolverBase > dinfo;
175  "MarkovSolverBase",
177  markovSolverFinfos,
178  sizeof( markovSolverFinfos ) / sizeof( Finfo* ),
179  &dinfo,
180  doc,
181  sizeof(doc) / sizeof(string)
182  );
183 
184  return &markovSolverBaseCinfo;
185 }
186 
188 
189 MarkovSolverBase::MarkovSolverBase() : Q_(0), expMats1d_(0), expMat_(0),
190  expMats2d_(0), xMin_(DBL_MAX), xMax_(DBL_MIN), xDivs_(0u),
191  yMin_(DBL_MAX), yMax_(DBL_MIN), yDivs_(0u), size_(0u), Vm_(0),
192  ligandConc_(0), dt_(0)
193 {
194  ;
195 }
196 
198 {
199  if ( Q_ )
200  delete Q_;
201 
202  if ( !expMats1d_.empty() )
203  {
204  while ( !expMats1d_.empty() )
205  {
206  delete expMats1d_.back();
207  expMats1d_.pop_back();
208  }
209  }
210 
211  if ( !expMats2d_.empty() )
212  {
213  unsigned int n = expMats2d_.size();
214  for( unsigned int i = 0; i < n; ++i )
215  {
216  for ( unsigned int j = 0; j < expMats2d_[i].size(); ++j )
217  delete expMats2d_[i][j];
218  }
219  }
220 
221  if ( expMat_ != 0 )
222  delete expMat_;
223 }
224 
226 //Set-Get functions
229 {
230  return *Q_;
231 }
232 
234 {
235  return state_;
236 }
237 
239 {
240  return initialState_;
241 }
242 
244 {
245  initialState_ = state;
247 }
248 
249 void MarkovSolverBase::setXmin( double xMin )
250 {
251  xMin_ = xMin;
252 }
253 
255 {
256  return xMin_;
257 }
258 
259 void MarkovSolverBase::setXmax( double xMax )
260 {
261  xMax_ = xMax;
262 }
263 
265 {
266  return xMax_;
267 }
268 
269 void MarkovSolverBase::setXdivs( unsigned int xDivs )
270 {
271  xDivs_ = xDivs;
272 }
273 
274 unsigned int MarkovSolverBase::getXdivs( ) const {
275  return xDivs_;
276 }
277 
279  return invDx_;
280 }
281 
282 void MarkovSolverBase::setYmin( double yMin )
283 {
284  yMin_ = yMin;
285 }
286 
288 {
289  return yMin_;
290 }
291 
292 void MarkovSolverBase::setYmax( double yMax )
293 {
294  yMax_ = yMax;
295 }
296 
298 {
299  return yMax_;
300 }
301 
302 void MarkovSolverBase::setYdivs( unsigned int yDivs )
303 {
304  yDivs_ = yDivs;
305 }
306 
307 unsigned int MarkovSolverBase::getYdivs( ) const
308 {
309  return yDivs_;
310 }
311 
313 {
314  return invDy_;
315 }
316 
318 {
319  bool isEndOfX = false;
320  bool isEndOfY = false;
321 
322  unsigned int xIndex =
323  static_cast< unsigned int >( ( Vm_ - xMin_ ) * invDx_ );
324  unsigned int yIndex =
325  static_cast< unsigned int >( ( ligandConc_ - yMin_ ) * invDy_ );
326  double xv = (Vm_ - xMin_) * invDx_;
327  double yv = (ligandConc_ - yMin_) * invDy_;
328 
329  double xF = xv - xIndex;
330  double yF = yv - yIndex;
331  double xFyF = xF * yF;
332 
333  ( xIndex == xDivs_ ) ? isEndOfX = true : isEndOfX = false;
334  ( yIndex == yDivs_ ) ? isEndOfY = true : isEndOfY = false;
335 
336  vector< vector< Matrix* > >::const_iterator iExpQ0 =
337  expMats2d_.begin() + xIndex;
338  vector< Matrix* >::const_iterator iExpQ00 = iExpQ0->begin() + yIndex;
339  vector< Matrix* >::const_iterator iExpQ10;
340 
341  Matrix* expQ00 = *iExpQ00;
342  Matrix* expQ01;
343  Matrix* expQ10;
344  Matrix* expQ11;
345 
346 #if ENABLE_CPP1
347  // Intialization to supress compiler warning.
348  Vector *state00 = nullptr;
349  Vector *state01 = nullptr;
350  Vector *state10 = nullptr;
351  Vector *state11 = nullptr;
352  Vector *result = nullptr;
353 #else
354  Vector *state00 = NULL, *state01 = NULL
355  , *state10 = NULL, *state11 = NULL
356  , *result = NULL
357  ;
358 #endif
359 
360  state00 = vecMatMul( &state_, expQ00 );
361  if ( isEndOfX )
362  {
363  if ( isEndOfY )
364  return state00;
365  else
366  {
367  expQ01 = *(iExpQ00 + 1);
368  state01 = vecMatMul( &state_, expQ01 );
369  result = vecVecScalAdd( state00, state01,
370  (1 - yF), yF );
371  }
372  }
373  else
374  {
375  iExpQ10 = ( iExpQ0 + 1 )->begin() + yIndex;
376  expQ10 = *iExpQ10;
377  state10 = vecMatMul( &state_, expQ10 );
378 
379  if ( isEndOfY )
380  {
381  result = vecVecScalAdd( state00, state10, ( 1 - xF ), xF );
382  }
383  else
384  {
385  expQ01 = *( iExpQ00 + 1 );
386  expQ11 = *( iExpQ10 + 1 );
387 
388  state01 = vecMatMul( &state_, expQ01 );
389  state11 = vecMatMul( &state_, expQ11 );
390 
391  Vector *temp1, *temp2;
392 
393  temp1 = vecVecScalAdd( state00, state10,
394  ( 1 - xF - yF + xFyF ),
395  ( xF - xFyF )
396  );
397 
398  temp2 = vecVecScalAdd( state01, state11, ( yF - xFyF ), xFyF );
399 
400  result = vecVecScalAdd( temp1, temp2, 1.0, 1.0 );
401 
402  delete temp1;
403  delete temp2;
404  }
405  }
406 
407  if ( state00 )
408  delete state00;
409  if ( state01 )
410  delete state01;
411  if ( state10 )
412  delete state10;
413  if ( state11 )
414  delete state11;
415 
416  return result;
417 }
418 
420 {
421  double x;
422 
424  x = Vm_;
425  else
426  x = ligandConc_;
427 
428  if ( x < xMin_ )
429  return vecMatMul( &state_, expMats1d_[0] );
430  else if ( x > xMax_ )
431  return vecMatMul( &state_, expMats1d_.back() );
432 
433  unsigned int xIndex = static_cast< unsigned int >( ( x - xMin_) * invDx_ );
434 
435  double xv = ( x - xMin_ ) * invDx_;
436  double xF = xv - xIndex;
437 
438  vector< Matrix* >::const_iterator iExpQ =
439  expMats1d_.begin() + xIndex;
440 
441  Vector *state0, *state1, *result;
442 
443  state0 = vecMatMul( &state_, *iExpQ );
444  state1 = vecMatMul( &state_, *( iExpQ + 1 ) );
445 
446  result = vecVecScalAdd( state0, state1, 1 - xF, xF );
447 
448  delete state0;
449  delete state1;
450 
451  return result;
452 }
453 
454 //Computes the updated state of the system. Is called from the process function.
455 //This performs state space interpolation to calculate the state of the
456 //channel.
457 //When a value of Vm_ and ligandConc_ is provided, we find the 4 matrix
458 //exponentials that are closest to these values, and then calculate the
459 //states at each of these 4 points. We then interpolate between these
460 //states to calculate the final one.
461 //In case all rates are 1D, then, the above-mentioned interpolation is
462 //only one-dimensional in nature.
464 {
465  Vector* newState;
466  bool useBilinear = false;
467  // useLinear = false;
468 
469  if ( rateTable_->areAnyRates2d() ||
470  ( rateTable_->areAllRates1d() &&
473  ) )
474  {
475  useBilinear = true;
476  }
477  /*
478  else if ( rateTable_->areAllRatesVoltageDep() ||
479  rateTable_->areAllRatesLigandDep() )
480  {
481  useLinear = true;
482  }
483  */
484 
485  //Heavily borrows from the Interpol2D::interpolate function.
486  if ( useBilinear )
487  newState = bilinearInterpolate();
488  else
489  newState = linearInterpolate();
490 
491  state_ = *newState;
492 
493  delete newState;
494 }
495 
497  vector< unsigned int > rateIndices,
498  string rateType,
499  unsigned int xIndex,
500  unsigned int yIndex )
501 {
502  unsigned int n = rateIndices.size(), i, j;
503 
504  for ( unsigned int k = 0; k < n; ++k )
505  {
506  i = ( ( rateIndices[k] / 10 ) % 10 ) - 1;
507  j = ( rateIndices[k] % 10 ) - 1;
508 
509  (*Q_)[i][i] += (*Q_)[i][j];
510 
511  if ( rateType.compare("2D") == 0 )
512  (*Q_)[i][j] = rateTable_->lookup2dIndex( i, j, xIndex, yIndex );
513  else if ( rateType.compare("1D") == 0 )
514  (*Q_)[i][j] = rateTable_->lookup1dIndex( i, j, xIndex );
515  else if ( rateType.compare("constant") == 0 )
516  (*Q_)[i][j] = rateTable_->lookup1dValue( i, j, 1.0 );
517 
518  (*Q_)[i][j] *= dt_;
519 
520  (*Q_)[i][i] -= (*Q_)[i][j];
521  }
522 }
523 
525 {
526  double dx = (xMax_ - xMin_) / xDivs_;
527  double dy = (yMax_ - yMin_) / yDivs_;
528 
529  vector< unsigned int > listOf1dRates = rateTable_->getListOf1dRates();
530  vector< unsigned int > listOf2dRates = rateTable_->getListOf2dRates();
531  vector< unsigned int > listOfConstantRates =
533 
534  //Set constant rates in the Q matrix, if any.
535  innerFillupTable( listOfConstantRates, "constant",
536  0.0, 0.0 );
537 
538  //xIndex loops through all voltages, yIndex loops through all
539  //ligand concentrations.
540  if ( rateTable_->areAnyRates2d() ||
541  ( rateTable_->areAllRates1d() &&
544  ) )
545  {
546  double voltage = xMin_, ligandConc = yMin_;
547 
548  for ( unsigned int xIndex = 0; xIndex < xDivs_ + 1; ++xIndex )
549  {
550  ligandConc = yMin_;
551  for( unsigned int yIndex = 0; yIndex < yDivs_ + 1; ++yIndex )
552  {
553  innerFillupTable( listOf2dRates, "2D", xIndex, yIndex );
554 
555  //This is a very klutzy way of updating 1D rates as the same
556  //lookup is done multiple times. But this all occurs at setup,
557  //and lookups arent that slow either. This way is also easier
558  //to maintain.
559  innerFillupTable( listOf1dRates, "1D", xIndex, yIndex );
560 
561  expMats2d_[xIndex][yIndex] = computeMatrixExponential();
562  ligandConc += dy;
563  }
564  voltage += dx;
565  }
566  }
567  else if ( rateTable_->areAllRatesLigandDep() )
568  {
569  double x = xMin_;
570  vector< unsigned int > listOfLigandRates =
572 
573  for ( unsigned int xIndex = 0; xIndex < xDivs_ + 1; ++xIndex )
574  {
575  innerFillupTable( listOfLigandRates, "1D", xIndex, 0 );
577  x += dx;
578  }
579  }
580  else if ( rateTable_->areAllRatesVoltageDep() )
581  {
582  double x = xMin_;
583  vector< unsigned int > listOfVoltageRates =
585 
586  for ( unsigned int xIndex = 0; xIndex < xDivs_ + 1; ++xIndex )
587  {
588  innerFillupTable( listOfVoltageRates, "1D", xIndex, 0 );
590  x += dx;
591  }
592  }
593  else if ( rateTable_->areAllRatesConstant() )
594  {
596  return;
597  }
598 }
599 
601 {
602  return 0;
603 }
604 
606 //MsgDest functions
608 
610 {
611  if ( initialState_.empty() )
612  {
613  cerr << "MarkovSolverBase::reinit : Initial state has not been "
614  "set.\n";
615  return;
616  }
618 
619  stateOut()->send( e, state_ );
620 }
621 
623 {
624  computeState();
625 
626  stateOut()->send( e, state_ );
627 }
628 
629 void MarkovSolverBase::handleVm( double Vm )
630 {
631  Vm_ = Vm;
632 }
633 
634 void MarkovSolverBase::handleLigandConc( double ligandConc )
635 {
636  ligandConc_ = ligandConc;
637 }
638 
639 //Sets up the exponential lookup tables based on the rate table that is passed
640 //in. Initializes the whole object.
641 void MarkovSolverBase::init( Id rateTableId, double dt )
642 {
643  MarkovRateTable* rateTable = reinterpret_cast< MarkovRateTable* >(
644  rateTableId.eref().data() );
645 
646  size_ = rateTable->getSize();
647  rateTable_ = rateTable;
648  setLookupParams( );
649 
650  if ( rateTable->areAnyRates2d() ||
651  ( rateTable->areAllRates1d() &&
652  rateTable->areAnyRatesVoltageDep() &&
653  rateTable->areAnyRatesLigandDep()
654  ) )
655  {
656  expMats2d_.resize( xDivs_ + 1 );
657  for( unsigned int i = 0; i < xDivs_ + 1; ++i )
658  expMats2d_[i].resize( yDivs_ + 1);
659  }
660  else if ( rateTable->areAllRatesLigandDep() ||
661  rateTable->areAllRatesVoltageDep() )
662  {
663  expMats1d_.resize( xDivs_ + 1);
664  }
665  else //All rates must be constant.
666  {
667  expMat_ = matAlloc( size_ );
668  }
669 
670  //Initializing Q.
671  Q_ = matAlloc( size_ );
672 
673  //The state at t = t0 + dt is exp( dt * Q ) * [state at t = t0].
674  //Hence, we need to scale the terms of Q by dt.
675  dt_ = dt;
676 
677  //Fills up the newly setup tables with exponentials.
678  fillupTable( );
679 }
680 
682 //This function sets the limits of the final lookup table of matrix
683 //exponentials.
684 //xMin_, xMax, yMin_, yMax_, xDivs_, yDivs_ are chosen such that
685 //the longest inverval covering all the limits of the rate lookup
686 //tables is chosen.
687 //i.e. xMin_ = min( xMin of all 1D and 2D lookup tables ),
688 // xMax_ = max( xMax of all 1D and 2D lookup tables ),
689 // yMin_ = min( yMin of all 2D lookup tables ),
690 // yMax_ = max( yMax of all 2D lookup tables ),
691 // xDivs_ = min( xDivs of all 1D and 2D lookup tables ),
692 // yDivs_ = min( yDivs of all 2D lookup tables )
693 //
694 //If all the rates are constant, then all these values remain unchanged
695 //from the time the MarkovSolverBase object was constructed i.e. all are zero.
698 {
699  if ( rateTable_->areAnyRates1d() )
700  {
701  vector< unsigned int > listOfLigandRates
703  vector< unsigned int > listOfVoltageRates
705 
706  double temp;
707  double yMax = DBL_MIN, yMin = DBL_MAX;
708  unsigned int yDivs = 0u;
709  unsigned int divs, i, j;
710 
711  for( unsigned int k = 0; k < listOfLigandRates.size(); ++k )
712  {
713  i = ( ( listOfLigandRates[k] / 10 ) % 10 ) - 1;
714  j = ( listOfLigandRates[k] % 10 ) - 1;
715 
716  temp = rateTable_->getVtChildTable( i, j )->getMin();
717  if ( yMin > temp )
718  yMin = temp;
719 
720  temp = rateTable_->getVtChildTable( i, j )->getMax();
721  if ( yMax < temp )
722  yMax = temp;
723 
724  divs = rateTable_->getVtChildTable( i, j )->getDiv();
725  if ( yDivs < divs )
726  yDivs = divs;
727  }
728 
729  if ( ( rateTable_->areAllRatesLigandDep() &&
731  {
732  xMin_ = yMin;
733  xMax_ = yMax;
734  xDivs_ = yDivs;
735  invDx_ = yDivs / ( yMax - yMin );
736  }
737  else
738  {
739  yMin_= yMin;
740  yMax_ = yMax;
741  yDivs_ = yDivs;
742  invDy_ = yDivs / ( yMax - yMin );
743  }
744 
745  for( unsigned int k = 0; k < listOfVoltageRates.size(); ++k )
746  {
747  i = ( ( listOfVoltageRates[k] / 10 ) % 10 ) - 1;
748  j = ( listOfVoltageRates[k] % 10 ) - 1;
749 
750  temp = rateTable_->getVtChildTable( i, j )->getMin();
751  if ( xMin_ > temp )
752  xMin_ = temp;
753 
754  temp = rateTable_->getVtChildTable( i, j )->getMax();
755  if ( xMax_ < temp )
756  xMax_ = temp;
757 
758  divs = rateTable_->getVtChildTable( i, j )->getDiv();
759  if ( xDivs_ < divs )
760  xDivs_ = divs;
761  }
762  }
763 
764  if ( rateTable_->areAnyRates2d() )
765  {
766  vector< unsigned int > listOf2dRates = rateTable_->getListOf2dRates();
767  double temp;
768  unsigned int divs, i, j;
769 
770  for( unsigned int k = 0; k < listOf2dRates.size(); ++k )
771  {
772  i = ( ( listOf2dRates[k] / 10 ) % 10 ) - 1;
773  j = ( listOf2dRates[k] % 10 ) - 1;
774 
775  temp = rateTable_->getInt2dChildTable( i, j )->getXmin();
776  if ( xMin_ > temp )
777  xMin_ = temp;
778 
779  temp = rateTable_->getInt2dChildTable( i, j )->getXmax();
780  if ( xMax_ < temp )
781  xMax_ = temp;
782 
783  temp = rateTable_->getInt2dChildTable( i, j )->getYmin();
784  if ( yMin_ > temp )
785  yMin_ = temp;
786 
787  temp = rateTable_->getInt2dChildTable( i, j )->getYmax();
788  if ( yMax_ < temp )
789  yMax_ = temp;
790 
791  divs = rateTable_->getInt2dChildTable( i, j )->getXdivs();
792  if ( xDivs_ < divs )
793  xDivs_ = divs;
794 
795  divs = rateTable_->getInt2dChildTable( i, j )->getYdivs();
796  if ( yDivs_ < divs )
797  yDivs_ = divs;
798  }
799 
800  invDx_ = xDivs_ / ( xMax_ - xMin_ );
801  invDy_ = yDivs_ / ( yMax_ - yMin_ );
802  }
803 }
804 
805 #ifdef DO_UNIT_TESTS
806 void MarkovSolverBase::setVm( double Vm )
807 {
808  Vm_ = Vm;
809 }
810 
811 void MarkovSolverBase::setLigandConc( double ligandConc )
812 {
813  ligandConc_ = ligandConc;
814 }
815 
816 void setupInterpol2D( Interpol2D* table, unsigned int xDivs, double xMin,
817  double xMax, unsigned int yDivs, double yMin, double yMax )
818 {
819  table->setXdivs( xDivs );
820  table->setXmin( xMin );
821  table->setXmax( xMax );
822  table->setYdivs( yDivs );
823  table->setYmin( yMin );
824  table->setYmax( yMax );
825 }
826 
827 void setupVectorTable( VectorTable* table, unsigned int xDivs, double xMin,
828  double xMax )
829 {
830  table->setDiv( xDivs );
831  table->setMin( xMin );
832  table->setMax( xMax );
833 }
834 
835 #if 0
836 //Simple tests on whether the exponential lookup tables are being set
837 //to the correct size and the lookup function tests.
838 //Cannot test the interpolation routines here as there is not matrix
839 //exponential method in the base class.
840 //testMarkovSolver() defined in MarkovSolver.cpp contains this test.
841 void testMarkovSolverBase()
842 {
843 
844  const Cinfo* rateTableCinfo = MarkovRateTable::initCinfo();
845  const Cinfo* interpol2dCinfo = Interpol2D::initCinfo();
847  const Cinfo* solverBaseCinfo = MarkovSolverBase::initCinfo();
848 
849  Id vecTableId = Id::nextId();
850  Id int2dId = Id::nextId();
851 
852  vector< Id > rateTableIds;
853  vector< Id > solverBaseIds;
854 
855  vector< Element* > rateTableElements;
856  vector< Eref* > rateTableErefs;
857 
858  vector< Element* > solverBaseElements;
859  vector< Eref* > solverBaseErefs;
860 
861  vector< MarkovRateTable* > rateTables;
862  vector< MarkovSolverBase* > solverBases;
863 
864  vector< unsigned int > single;
865  string str;
866 
867  unsigned int numCopies = 4;
868 
869  for ( unsigned int i = 0; i < numCopies; ++i )
870  {
871  rateTableIds.push_back( Id::nextId() );
872  str = string("ratetable") + static_cast< char >( 65 + i );
873  rateTableElements.push_back( new Element( rateTableIds[i], rateTableCinfo,
874  str, single, 1 ) );
875  rateTableErefs.push_back( new Eref( rateTableElements[i], 0 ) );
876  rateTables.push_back( reinterpret_cast< MarkovRateTable* >(
877  rateTableErefs[i]->data() ) );
878 
879  solverBaseIds.push_back( Id::nextId() );
880  str = string("solverbase") + static_cast< char >( 65 + i );
881  solverBaseElements.push_back( new Element( solverBaseIds[i], solverBaseCinfo,
882  str, single, 1 ) );
883  solverBaseErefs.push_back( new Eref( solverBaseElements[i], 0 ) );
884  solverBases.push_back( reinterpret_cast< MarkovSolverBase* >(
885  solverBaseErefs[i]->data() ) );
886  }
887 
888  Element *eInt2d = new Element( int2dId, interpol2dCinfo, "int2d", single, 1 );
889  Element *eVecTable = new Element( vecTableId, vectorTableCinfo, "vecTable",
890  single, 1 );
891 
892  Interpol2D *int2dTable;
893  VectorTable* vecTable;
894 
895  Eref int2dEref( eInt2d, 0 );
896  int2dTable = reinterpret_cast< Interpol2D* >( int2dEref.data() );
897 
898  Eref vecTableEref( eVecTable, 0 );
899  vecTable = reinterpret_cast< VectorTable* >( vecTableEref.data() );
900 
902  //ratetables[0] //Only 2D rates.
903  //ratetables[1] //1D and 2D rates.
904  //ratetables[2] //Only ligand dependent rates.
905  //ratetables[3] //Only voltage dependent rates.
907 
909  //Case 1 :
910  //Rates (1,2) and (2,3) are ligand and voltage dependent.
912  rateTables[0]->init( 3 );
913 
914  setupInterpol2D( int2dTable, 201, -0.05, 0.10, 151, 1e-9, 50e-9 );
915  rateTables[0]->setInt2dChildTable( 1, 2, int2dId );
916 
917  setupInterpol2D( int2dTable, 175, -0.02, 0.19, 151, 3e-9, 75e-9 );
918  rateTables[0]->setInt2dChildTable( 2, 3, int2dId );
919 
920  solverBases[0]->init( rateTableIds[0], 0.1 );
921 
922  assert( solverBases[0]->getXdivs() == 201 );
923  assert( doubleEq( solverBases[0]->getXmin(), -0.05 ) );
924  assert( doubleEq( solverBases[0]->getXmax(), 0.19 ) );
925  assert( solverBases[0]->getYdivs() == 151 );
926 
927  //1D and 2D rates.
928  rateTables[1]->init( 5 );
929 
931  //Case 2 :
932  //Rates (1,2) and (1,3) are ligand and voltage dependent.
933  //Rates (2,1) and (3,1) are voltage and ligand dependent respectively.
935  setupInterpol2D( int2dTable, 250, -0.10, 0.75, 101, 10e-9, 25e-8 );
936  rateTables[1]->setInt2dChildTable( 1, 2, int2dId );
937 
938  setupInterpol2D( int2dTable, 275, -0.05, 0.55, 141, 5e-9, 40e-7 );
939  rateTables[1]->setInt2dChildTable( 1, 3, int2dId );
940 
941  //Voltage dependent.
942  setupVectorTable( vecTable, 145, -0.17, 0.73 );
943  rateTables[1]->setVtChildTable( 2, 1, vecTableId, 0 );
944 
945  //Ligand dependent
946  setupVectorTable( vecTable, 375, 7e-9, 75e-7 );
947  rateTables[1]->setVtChildTable( 3, 1, vecTableId, 1 );
948 
949  solverBases[1]->init( rateTableIds[1], 0.1 );
950 
951  assert( solverBases[1]->getXdivs() == 275 );
952  assert( solverBases[1]->getYdivs() == 375 );
953  assert( doubleEq( solverBases[1]->getXmin(), -0.17 ) );
954  assert( doubleEq( solverBases[1]->getXmax(), 0.75 ) );
955  assert( doubleEq( solverBases[1]->getYmin(), 5e-9 ) );
956  assert( doubleEq( solverBases[1]->getYmax(), 75e-7 ) );
957 
959  //Case 3 : Only ligand dependent rates.
960  //Rates (1, 2), (3, 5), (2, 4), (4, 1).
962 
963  rateTables[2]->init( 5 );
964 
965  setupVectorTable( vecTable, 155, 7e-9, 50e-9 );
966  rateTables[2]->setVtChildTable( 1, 2, vecTableId, 1 );
967 
968  setupVectorTable( vecTable, 190, 4e-9, 35e-9 );
969  rateTables[2]->setVtChildTable( 3, 5, vecTableId, 1 );
970 
971  setupVectorTable( vecTable, 120, 7e-9, 90e-9 );
972  rateTables[2]->setVtChildTable( 2, 4, vecTableId, 1 );
973 
974  setupVectorTable( vecTable, 250, 10e-9, 100e-9 );
975  rateTables[2]->setVtChildTable( 4, 1, vecTableId, 1 );
976 
977  solverBases[2]->init( rateTableIds[2], 0.1 );
978 
979  assert( doubleEq( 1e-308 * solverBases[2]->getYmin(), 1e-308 * DBL_MAX ) );
980  assert( doubleEq( 1e308 * solverBases[2]->getYmax(), 1e308 * DBL_MIN ) );
981  assert( solverBases[2]->getYdivs() == 0u );
982 
983  assert( doubleEq( solverBases[2]->getXmin(), 4e-9 ) );
984  assert( doubleEq( solverBases[2]->getXmax(), 100e-9 ) );
985  assert( solverBases[2]->getXdivs() == 250 );
986 
988  //Case 4 : Only voltage dependent rates.
989  //Rates (3,6), (5, 6), (1, 4).
991 
992  rateTables[3]->init( 7 );
993 
994  setupVectorTable( vecTable, 100, -0.05, 0.1 );
995  rateTables[3]->setVtChildTable( 3, 6, vecTableId, 1 );
996 
997  setupVectorTable( vecTable, 190, -0.15, 0.2 );
998  rateTables[3]->setVtChildTable( 5, 6, vecTableId, 1 );
999 
1000  setupVectorTable( vecTable, 140, -0.2, 0.1 );
1001  rateTables[3]->setVtChildTable( 1, 4, vecTableId, 1 );
1002 
1003  solverBases[3]->init( rateTableIds[3], 0.1 );
1004 
1005  assert( doubleEq( 1e-308 * solverBases[3]->getYmin(), 1e-308 * DBL_MAX ) );
1006  assert( doubleEq( 1e308 * solverBases[3]->getYmax(), 1e308 * DBL_MIN ) );
1007  assert( solverBases[3]->getYdivs() == 0u );
1008 
1009  assert( doubleEq( solverBases[3]->getXmin(), -0.2 ) );
1010  assert( doubleEq( solverBases[3]->getXmax(), 0.2 ) );
1011  assert( solverBases[3]->getXdivs() == 190 );
1012 
1013  for ( unsigned int i = 0; i < numCopies; ++i )
1014  {
1015  rateTableIds[i].destroy();
1016  solverBaseIds[i].destroy();
1017  delete rateTableErefs[i];
1018  delete solverBaseErefs[i];
1019  }
1020 
1021  int2dId.destroy();
1022  vecTableId.destroy();
1023 
1024  cout << "." << flush;
1025 }
1026 #endif // #if 0
1027 #endif
void init(Id, double)
char * data() const
Definition: Eref.cpp:41
vector< double > Vector
Definition: MatrixOps.h:23
vector< unsigned int > getListOf2dRates()
double getMin() const
Interpol2D * getInt2dChildTable(unsigned int, unsigned int) const
void setXmin(double value)
Definition: Interpol2D.cpp:229
void setYdivs(unsigned int value)
Definition: Interpol2D.cpp:321
Definition: Dinfo.h:60
void setMin(double)
void setInitialState(Vector)
Vector getState() const
VectorTable * getVtChildTable(unsigned int, unsigned int) const
virtual Matrix * computeMatrixExponential()
void setYdivs(unsigned int)
Eref eref() const
Definition: Id.cpp:125
Matrix getQ() const
vector< unsigned int > getListOfConstantRates()
double getXmin() const
Definition: Interpol2D.cpp:238
void setXdivs(unsigned int value)
Definition: Interpol2D.cpp:257
MarkovRateTable * rateTable_
unsigned int getYdivs() const
static const Cinfo * vectorTableCinfo
double getXmin() const
void destroy() const
Definition: Id.cpp:176
Vector * vecVecScalAdd(const Vector *v1, const Vector *v2, double alpha, double beta)
Definition: MatrixOps.cpp:249
unsigned int getXdivs() const
Definition: Interpol2D.cpp:262
Definition: OpFunc.h:40
static const Cinfo * initCinfo()
Vector * vecMatMul(const Vector *v, Matrix *A)
Definition: MatrixOps.cpp:201
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
static Id nextId()
Definition: Id.cpp:132
double getYmin() const
Definition: Interpol2D.cpp:302
void setXdivs(unsigned int)
vector< unsigned int > getListOf1dRates()
vector< Matrix * > expMats1d_
void innerFillupTable(vector< unsigned int >, string, unsigned int, unsigned int)
unsigned int yDivs_
Vector getInitialState() const
unsigned int getXdivs() const
static const Cinfo * initCinfo()
vector< unsigned int > getListOfVoltageRates()
void setMax(double)
double getYmax() const
Definition: Interpol2D.cpp:316
double getInvDx() const
unsigned int getDiv() const
Vector * linearInterpolate() const
unsigned int getYdivs() const
Definition: Interpol2D.cpp:325
void setYmax(double value)
Definition: Interpol2D.cpp:307
Definition: OpFunc.h:27
Definition: Eref.h:26
double getXmax() const
static const Cinfo * initCinfo()
Definition: Interpol2D.cpp:25
unsigned int size_
double getInvDy() const
vector< vector< Matrix * > > expMats2d_
vector< vector< T > > resize(vector< vector< T > >table, unsigned int n, T init)
vector< vector< double > > Matrix
Definition: MatrixOps.h:22
Vector * bilinearInterpolate() const
unsigned int getSize() const
Definition: Id.h:17
void handleLigandConc(double)
void reinit(const Eref &, ProcPtr)
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
static const Cinfo * initCinfo()
Definition: VectorTable.cpp:18
void setYmin(double value)
Definition: Interpol2D.cpp:293
unsigned int xDivs_
vector< unsigned int > getListOfLigandRates()
double lookup2dIndex(unsigned int, unsigned int, unsigned int, unsigned int)
void setDiv(unsigned int)
double getYmin() const
double getXmax() const
Definition: Interpol2D.cpp:252
SrcFinfo1< Vector > * stateOut()
Definition: Cinfo.h:18
Matrix * matAlloc(unsigned int n)
Definition: MatrixOps.cpp:480
void setXmax(double value)
Definition: Interpol2D.cpp:243
static const Cinfo * markovSolverBaseCinfo
void process(const Eref &, ProcPtr)
double lookup1dValue(unsigned int, unsigned int, double)
double lookup1dIndex(unsigned int, unsigned int, unsigned int)
double getYmax() const
double getMax() const
Definition: Finfo.h:12