MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
FastMatrixElim Class Reference

#include <FastMatrixElim.h>

+ Inheritance diagram for FastMatrixElim:
+ Collaboration diagram for FastMatrixElim:

Public Member Functions

void buildBackwardSub (vector< unsigned int > &diag, vector< Triplet< double > > &bops, vector< double > &diagVal)
 
bool buildForDiffusion (const vector< unsigned int > &parentVoxel, const vector< double > &volume, const vector< double > &area, const vector< double > &length, double diffConst, double motorConst, double dt)
 This function makes the diffusion matrix. More...
 
void buildForwardElim (vector< unsigned int > &diag, vector< Triplet< double > > &fops)
 
bool checkSymmetricShape () const
 
 FastMatrixElim ()
 
 FastMatrixElim (unsigned int nrows, unsigned int ncolumns)
 
 FastMatrixElim (const SparseMatrix< double > &orig)
 
bool hinesReorder (const vector< unsigned int > &parentVoxel, vector< unsigned int > &lookupOldRowsFromNew)
 
bool isSymmetric () const
 
void makeTestMatrix (const double *test, unsigned int numCompts)
 
bool operator== (const FastMatrixElim &other) const
 
void setDiffusionAndTransport (const vector< unsigned int > &parentVoxel, double diffConst, double motorConst, double dt)
 
void shuffleRows (const vector< unsigned int > &lookupOldRowFromNew)
 
- Public Member Functions inherited from SparseMatrix< double >
void addRow (unsigned int rowNum, const vector< double > &row)
 
void addRow (unsigned int rowNum, const vector< double > &entry, const vector< unsigned int > &colIndexArg)
 
void clear ()
 
const vector< unsigned int > & colIndex () const
 
double get (unsigned int row, unsigned int column) const
 
unsigned int getColumn (unsigned int col, vector< double > &entry, vector< unsigned int > &rowIndex) const
 
unsigned int getRow (unsigned int row, const double **entry, const unsigned int **colIndex) const
 
unsigned int getRow (unsigned int row, vector< double > &e, vector< unsigned int > &c) const
 
const vector< double > & matrixEntry () const
 Here we expose the sparse matrix for MOOSE use. More...
 
unsigned int nColumns () const
 
unsigned int nEntries () const
 
unsigned int nRows () const
 
void pairFill (const vector< unsigned int > &row, const vector< unsigned int > &col, doublevalue)
 
void print () const
 
void printInternal () const
 
void printTriplet (const vector< Triplet< double > > &t)
 
void reorderColumns (const vector< unsigned int > &colMap)
 
const vector< unsigned int > & rowStart () const
 
void set (unsigned int row, unsigned int column, doublevalue)
 
void setSize (unsigned int nrows, unsigned int ncolumns)
 
 SparseMatrix ()
 
 SparseMatrix (unsigned int nrows, unsigned int ncolumns)
 
void transpose ()
 
void tripletFill (const vector< unsigned int > &row, const vector< unsigned int > &col, const vector< double > &z, bool retainSize=false)
 
void unset (unsigned int row, unsigned int column)
 

Static Public Member Functions

static void advance (vector< double > &y, const vector< Triplet< double > > &ops, const vector< double > &diagVal)
 
static void opsReorder (const vector< unsigned int > &lookupOldRowsFromNew, vector< Triplet< double > > &ops, vector< double > &diagVal)
 

Additional Inherited Members

- Protected Attributes inherited from SparseMatrix< double >
vector< unsigned int > colIndex_
 Non-zero entries in the SparseMatrix. More...
 
vector< double > N_
 
unsigned int ncolumns_
 
unsigned int nrows_
 
vector< unsigned int > rowStart_
 Start index in the N_ and colIndex_ vectors, of each row. More...
 

Detailed Description

Definition at line 10 of file FastMatrixElim.h.

Constructor & Destructor Documentation

FastMatrixElim::FastMatrixElim ( )

Definition at line 29 of file FastMatrixElim.cpp.

FastMatrixElim::FastMatrixElim ( unsigned int  nrows,
unsigned int  ncolumns 
)

Definition at line 33 of file FastMatrixElim.cpp.

34  : SparseMatrix< double >( nrows, ncolumns )
35 {;}
FastMatrixElim::FastMatrixElim ( const SparseMatrix< double > &  orig)

Definition at line 37 of file FastMatrixElim.cpp.

Member Function Documentation

void FastMatrixElim::advance ( vector< double > &  y,
const vector< Triplet< double > > &  ops,
const vector< double > &  diagVal 
)
static

Does the actual computation of the matrix inversion, which is equivalent to advancing one timestem in Backward Euler. Static function here to keep namespaces clean.

Definition at line 472 of file FastMatrixElim.cpp.

Referenced by testFastMatrixElim().

475 {
476  for ( vector< Triplet< double > >::const_iterator
477  i = ops.begin(); i != ops.end(); ++i )
478  y[i->c_] -= y[i->b_] * i->a_;
479 
480  assert( y.size() == diagVal.size() );
481  vector< double >::iterator iy = y.begin();
482  for ( vector< double >::const_iterator
483  i = diagVal.begin(); i != diagVal.end(); ++i )
484  *iy++ *= *i;
485 }

+ Here is the caller graph for this function:

void FastMatrixElim::buildBackwardSub ( vector< unsigned int > &  diag,
vector< Triplet< double > > &  bops,
vector< double > &  diagVal 
)

Reduces the backward substitution phase into a series of operations defined by the bops vector, and by the list of values on the diagonal.

Operations to be done on the RHS for the back sub are generated and put into the bops (backward ops) vector. col > row here, row is the entry being operated on, and col is given by rowsToSub. offDiagVal is the value on the off-diagonal at row,col. diagVal is the value on the diagonal at [row][row]. RHS[row] = ( RHS[row] - offDiagVal * RHS[col] ) / diagVal

Definition at line 342 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< double >::N_, SparseMatrix< double >::nrows_, and SparseMatrix< double >::rowStart_.

Referenced by Dsolve::build(), and testFastMatrixElim().

344 {
345  // This vec tells the routine which rows below have to be back-subbed.
346  // This includes the rows if any in the tridiagonal band and also
347  // rows, if any, on branches.
348  vector< vector< unsigned int > > rowsToSub( nrows_ );
349 
350  for ( unsigned int i = 0; i < nrows_; ++i ) {
351  unsigned int d = diag[i] + 1;
352  unsigned int re = rowStart_[i+1];
353  for ( unsigned int j = d; j < re; ++j ) {
354  unsigned int k = colIndex_[j];
355  // At this point the row to sub is at (i, k). We need to go down
356  // to the (k,k) diagonal to sub it out.
357  rowsToSub[ k ].push_back( i );
358  }
359  }
360  /*
361  for ( unsigned int i = 0; i < rowsToSub.size(); ++i ) {
362  cout << i << " : ";
363  for ( unsigned int j = 0; j < rowsToSub[i].size(); ++j ) {
364  cout << rowsToSub[i][j] << " ";
365  }
366  cout << endl;
367  }
368  */
369 
370  diagVal.resize( 0 );
371  // Fill in the diagonal terms. Here we do all entries.
372  for ( unsigned int i = 0; i != nrows_ ; ++i ) {
373  diagVal.push_back( 1.0 / N_[diag[i]] );
374  }
375 
376  // Fill in the back-sub operations. Note we don't need to check zero.
377  for ( unsigned int i = nrows_-1; i != 0 ; --i ) {
378  for ( int j = rowsToSub[i].size() - 1; j != -1; --j ) {
379  unsigned int k = rowsToSub[i][j];
380  double val = get( k, i ); //k is the row to go, i is the diag.
381  bops.push_back( Triplet< double >( val * diagVal[i], i, k ) );
382  }
383  }
384 
385  /*
386  for ( unsigned int i = 0; i < bops.size(); ++i ) {
387  cout << i << ": " << bops[i].a_ << " " <<
388  bops[i].b_ << " " << // diagonal index
389  bops[i].c_ << " " << // off-diagonal index
390  1.0 / diagVal[bops[i].b_] << // diagonal value.
391  endl;
392  }
393  */
394 }
vector< double > N_
Definition: SparseMatrix.h:703
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the caller graph for this function:

bool FastMatrixElim::buildForDiffusion ( const vector< unsigned int > &  parentVoxel,
const vector< double > &  volume,
const vector< double > &  area,
const vector< double > &  length,
double  diffConst,
double  motorConst,
double  dt 
)

This function makes the diffusion matrix.

This function makes the matrix for computing diffusion and transport equations.

Definition at line 557 of file FastMatrixElim.cpp.

References SparseMatrix< double >::addRow(), buildColIndex(), SparseMatrix< double >::colIndex(), EMPTY_VOXEL(), findAreaProportion(), and SparseMatrix< double >::nrows_.

Referenced by Dsolve::build().

563 {
564  // Too slow to matter.
565  if ( diffConst < 1e-18 && fabs( motorConst ) < 1e-12 )
566  return false;
567  assert( nrows_ == parentVoxel.size() );
568  assert( nrows_ == volume.size() );
569  assert( nrows_ == area.size() );
570  assert( nrows_ == length.size() );
571  vector< vector< unsigned int > > colIndex;
572 
573  buildColIndex( nrows_, parentVoxel, colIndex );
574  vector< bool > isTwig( nrows_, true );
575  for ( unsigned int i = 0; i < nrows_; ++i ) {
576  if ( parentVoxel[i] != EMPTY_VOXEL )
577  isTwig[ parentVoxel[i] ] = false;
578  }
579 
580  vector< double > areaProportion( nrows_, 1.0 );
581  findAreaProportion( areaProportion, parentVoxel, area );
582 
583  // Fill in the matrix entries for each colIndex
584  for ( unsigned int i = 0; i < nrows_; ++i ) {
585  vector< unsigned int >& c = colIndex[i];
586  vector< double > e( c.size(), 0.0 );
587 
588  for ( unsigned int j = 0; j < c.size(); ++j ) {
589  unsigned int k = c[j]; // This is the colIndex, in order.
590  double vol = volume[k];
591  double a = area[k];
592  double len = length[k];
593  if ( k == i ) { // Diagonal term
594  e[j] = 0.0 ;
595  // Fill in diffusion from all connected voxels.
596  for ( unsigned int p = 0; p < c.size(); ++p ) {
597  unsigned int q = c[p];
598  if ( q != i ) { // Skip self
599  e[j] -= (area[q] + a)/(length[q] + len )/vol;
600  }
601  }
602  e[j] *= diffConst;
603  // Fill in motor transport
604  if ( i > 0 && motorConst < 0 ) { // Towards soma
605  e[j] += motorConst / len;
606  }
607  if ( !isTwig[i] && motorConst > 0 ) { // Toward twigs
608  e[j] -= motorConst / len;
609  }
610  e[j] *= -dt; // The previous lot is the rate, so scale by dt
611  e[j] += 1.0; // term for self.
612  } else { // Not diagonal.
613  // Fill in diffusion from this entry to i.
614  e[j] = diffConst *
615  (area[i] + a)/(length[i] + len )/vol;
616 
617  // Fill in motor transport
618  if ( k == parentVoxel[i] && motorConst > 0 ) { //toward twig
619  e[j] += areaProportion[i] * motorConst / len;
620  }
621  if ( i == parentVoxel[k] && motorConst < 0 ) { //toward soma
622  e[j] -= motorConst / length[k];
623  }
624  e[j] *= -dt; // Scale the whole thing by dt.
625  }
626  }
627  // Now put it all in the sparase matrix.
628  addRow( i, e, c );
629  }
630  return true;
631 }
void findAreaProportion(vector< double > &areaProportion, const vector< unsigned int > &parentVoxel, const vector< double > &area)
void addRow(unsigned int rowNum, const vector< double > &row)
Definition: SparseMatrix.h:387
const vector< unsigned int > & colIndex() const
Definition: SparseMatrix.h:431
static const unsigned int EMPTY_VOXEL(-1)
void buildColIndex(unsigned int nrows, const vector< unsigned int > &parentVoxel, vector< vector< unsigned int > > &colIndex)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FastMatrixElim::buildForwardElim ( vector< unsigned int > &  diag,
vector< Triplet< double > > &  fops 
)

Recursively scans the current matrix, to build tree of parent voxels using the contents of the sparase matrix to indicate connectivity. Emits warning noises and returns an empty vector if the entire tree cannot be traversed, or if the current matrix is not tree-like. Assumes row 0 is root row. User should always call with parentRow == 0; Doesn't work yet. bool buildTree( unsigned int parentRow, vector< unsigned int >& parentVoxel ) const; Reduces the forward elimination phase into a series of operations defined by the fops vector.

Builds the vector of forward ops: ratio, i, j RHS[i] = RHS[i] - RHS[j] * ratio This vec tells the routine which rows below have to be eliminated. This includes the rows if any in the tridiagonal band and also rows, if any, on branches.

Definition at line 275 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< double >::N_, SparseMatrix< double >::nrows_, and SparseMatrix< double >::rowStart_.

Referenced by Dsolve::build(), and testFastMatrixElim().

277 {
278  vector< vector< unsigned int > > rowsToElim( nrows_ );
279  diag.clear();
280  for ( unsigned int i = 0; i < nrows_; ++i ) {
281  unsigned int rs = rowStart_[i];
282  unsigned int re = rowStart_[i+1];
283  for ( unsigned int j = rs; j < re; ++j ) {
284  unsigned int k = colIndex_[j];
285  if ( k == i ) {
286  diag.push_back(j);
287  } else if ( k > i ) {
288  rowsToElim[ i ].push_back( k );
289  }
290  }
291  }
292  assert( diag.size() == nrows_ );
293  for ( unsigned int i = 0; i < nrows_; ++i ) {
294  double d = N_[diag[i]];
295  unsigned int diagend = rowStart_[ i + 1 ];
296  assert( diag[i] < diagend );
297  vector< unsigned int >& elim = rowsToElim[i];
298  for ( unsigned int j = 0; j < elim.size(); ++j ) {
299  unsigned int erow = elim[j];
300  if ( erow == i ) continue;
301  unsigned int rs = rowStart_[ erow ];
302  unsigned int re = rowStart_[ erow+1 ];
303  // assert( colIndex_[rs] == i );
304  double ratio = get( erow, i ) / d;
305  // double ratio = N_[rs]/N_[diag[i]];
306  for ( unsigned int k = diag[i]+1; k < diagend; ++k ) {
307  unsigned int col = colIndex_[k];
308  // findElimEntry, subtract it out.
309  for ( unsigned int q = rs; q < re; ++q ) {
310  if ( colIndex_[q] == col ) {
311  N_[q] -= N_[k] * ratio;
312  }
313  }
314  }
315  fops.push_back( Triplet< double >( ratio, i, erow) );
316  }
317  }
318  /*
319  for ( unsigned int i = 0; i < rowsToElim.size(); ++i ) {
320  cout << i << " : ";
321  for ( unsigned int j = 0; j < rowsToElim[i].size(); ++j ) {
322  cout << rowsToElim[i][j] << " ";
323  }
324  cout << endl;
325  }
326  for ( unsigned int i = 0; i < fops.size(); ++i ) {
327  cout << "fops[" << i << "]= " << fops[i].b_ << " " << fops[i].c_ <<
328  " " << fops[i].a_ << endl;
329  }
330  */
331 }
vector< double > N_
Definition: SparseMatrix.h:703
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the caller graph for this function:

bool FastMatrixElim::checkSymmetricShape ( ) const

Checks that the matrix shape (but not necessarily values) are symmetric, returns true if symmetric.

Definition at line 51 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< T >::colIndex_, SparseMatrix< double >::N_, SparseMatrix< T >::N_, SparseMatrix< T >::ncolumns_, SparseMatrix< double >::ncolumns_, SparseMatrix< double >::nrows_, SparseMatrix< T >::nrows_, SparseMatrix< double >::rowStart_, SparseMatrix< T >::rowStart_, and SparseMatrix< T >::transpose().

Referenced by Dsolve::build().

52 {
53  FastMatrixElim temp = *this;
54  temp.transpose();
55  return (
56  nrows_ == temp.nrows_ &&
57  ncolumns_ == temp.ncolumns_ &&
58  N_.size() == temp.N_.size() &&
59  rowStart_ == temp.rowStart_ &&
60  colIndex_ == temp.colIndex_
61  );
62 }
unsigned int ncolumns_
Definition: SparseMatrix.h:702
void transpose()
Definition: SparseMatrix.h:456
vector< double > N_
Definition: SparseMatrix.h:703
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool FastMatrixElim::hinesReorder ( const vector< unsigned int > &  parentVoxel,
vector< unsigned int > &  lookupOldRowFromNew 
)

Takes the tree specification in the form of a list of parent entries for each tree node, and reorders the matrix into the twig-first sequence required for fast elimination. Returns true if it succeeded in doing this; many matrices will not reorder correctly.

Scans the current matrix starting from index 0, to build tree of parent voxels using the contents of the sparase matrix to indicate connectivity. Emits warning noises and returns an empty vector if the entire tree cannot be traversed, or if the current matrix is not tree-like. This still doesn't work. Fails because it cannot detect branches in the tree, where sibling compartments would have cross talk. So we still rely on getParentVoxel function. bool FastMatrixElim::buildTree( unsigned int parentRow, vector< unsigned int >& parentVoxel ) const { assert( nRows() == nColumns() ); if ( parentRow == 0 ) { parentVoxel.assign( nRows, EMPTY_VOXEL ); if ( !checkSymmetricShape() ) return false; // shape of matrix should be symmetric. } const double* entry; const unsigned int* colIndex; unsigned int numEntries = getRow( parentRow, &entry, &colIndex ); for ( unsigned int j = 0; j < numEntries; ++j ) { if ( colIndex[j] <= parentRow ) continue; // ignore lower diagonal if ( parentVoxel[ colIndex[j] ] == EMPTY_VOXEL ) { parentVoxel[ colIndex[j] ] = parentRow; } else { if ( parentVoxel[ colIndex[j] ] == parentVoxel[ parentRow ] ) continue; // OK, these are sibling compartments return false; // Error: the matrix isn't a clean tree. } } for ( unsigned int j = 0; j < numEntries; ++j ) { if ( colIndex[j] <= parentRow ) continue; if !buildTree( colIndex[j], parentVoxel ) return false; // Propagate error from child row. } if ( parentRow > 0 ) return true; Now done with all child branches, test if whole matrix is in tree. for ( unsigned int j = 1; j < nRows(); ++j ) if ( parentVoxel[j] == EMPTY_VOXEL ) return false; // One or more rows is disconnected from tree

return true; // All is well, have yourself a nice parentVoxel tree. } Reorders rows and columns to put the matrix in the form suitable for rapid single-pass inversion. Returns 0 on failure, but at this point I don't have a proper test for this.

Definition at line 139 of file FastMatrixElim.cpp.

References EMPTY_VOXEL(), SparseMatrix< double >::nrows_, and shuffleRows().

Referenced by Dsolve::build(), and testFastMatrixElim().

143 {
144  // First we fill in the vector that specifies the old row number
145  // assigned to each row of the reordered matrix.
146  assert( parentVoxel.size() == nrows_ );
147  lookupOldRowFromNew.clear();
148  vector< unsigned int > numKids( nrows_, 0 );
149  vector< bool > rowPending( nrows_, true );
150  unsigned int numDone = 0;
151  for ( unsigned int i = 0; i < nrows_; ++i ) {
152  if ( parentVoxel[i] != EMPTY_VOXEL )
153  numKids[ parentVoxel[i] ]++;
154  }
155  while ( numDone < nrows_ ) {
156  for ( unsigned int i = 0; i < nrows_; ++i ) {
157  if ( rowPending[i] && numKids[i] == 0 ) {
158  lookupOldRowFromNew.push_back( i );
159  rowPending[i] = false;
160  numDone++;
161  unsigned int pa = parentVoxel[i];
162  // root parent is EMPTY_VOXEL
163  while ( pa != EMPTY_VOXEL && numKids[pa] == 1 ) {
164  assert( rowPending[pa] );
165  rowPending[pa] = false;
166  numDone++;
167  lookupOldRowFromNew.push_back( pa );
168  pa = parentVoxel[pa];
169  }
170  if ( pa != EMPTY_VOXEL ) {
171  assert( numKids[pa] > 0 );
172  numKids[pa]--;
173  }
174  }
175  }
176  }
177 
178  /*
179  cout << setprecision(4);
180  cout << "oldRowFromNew= {" ;
181  for ( unsigned int i = 0; i < nrows_; ++i )
182  cout << lookupOldRowFromNew[i] << ", ";
183  cout << "}\n";
184  */
185  // Then we fill in the reordered matrix. Note we need to reorder
186  // columns too.
187  shuffleRows( lookupOldRowFromNew );
188  return true;
189 }
void shuffleRows(const vector< unsigned int > &lookupOldRowFromNew)
static const unsigned int EMPTY_VOXEL(-1)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool FastMatrixElim::isSymmetric ( ) const

Definition at line 80 of file FastMatrixElim.cpp.

References SparseMatrix< T >::transpose().

81 {
82  FastMatrixElim temp = *this;
83  temp.transpose();
84  return ( temp == *this );
85 }
void transpose()
Definition: SparseMatrix.h:456

+ Here is the call graph for this function:

void FastMatrixElim::makeTestMatrix ( const double *  test,
unsigned int  numCompts 
)

Definition at line 244 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< double >::N_, SparseMatrix< double >::rowStart_, and SparseMatrix< double >::setSize().

Referenced by testFastMatrixElim(), and testSetDiffusionAndTransport().

246 {
247  setSize( numCompts, numCompts );
248  vector< double > row( numCompts, ~0 );
249  for ( unsigned int i = 0; i < numCompts; ++i ) {
250  for ( unsigned int j = 0; j < numCompts; ++j ) {
251  unsigned int k = i * numCompts + j;
252  if ( test[k] < 0.1 ) {
253  } else {
254  N_.push_back( test[k] );
255  colIndex_.push_back( j );
256  }
257  }
258  rowStart_[i + 1] = N_.size();
259  }
260 }
vector< double > N_
Definition: SparseMatrix.h:703
void setSize(unsigned int nrows, unsigned int ncolumns)
Definition: SparseMatrix.h:126
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool FastMatrixElim::operator== ( const FastMatrixElim other) const

Definition at line 64 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< T >::colIndex_, doubleEq(), SparseMatrix< double >::N_, SparseMatrix< T >::N_, SparseMatrix< double >::ncolumns_, SparseMatrix< T >::ncolumns_, SparseMatrix< T >::nrows_, SparseMatrix< double >::nrows_, SparseMatrix< T >::rowStart_, and SparseMatrix< double >::rowStart_.

65 {
66  if (
67  nrows_ == other.nrows_ &&
68  ncolumns_ == other.ncolumns_ &&
69  N_.size() == other.N_.size() &&
70  rowStart_ == other.rowStart_ &&
71  colIndex_ == other.colIndex_ ) {
72  for ( unsigned int i = 0; i < N_.size(); ++i )
73  if ( !doubleEq( N_[i], other.N_[i] ) )
74  return false;
75  return true;
76  }
77  return false;
78 }
unsigned int ncolumns_
Definition: SparseMatrix.h:702
bool doubleEq(double x, double y)
Definition: doubleEq.cpp:16
vector< double > N_
Definition: SparseMatrix.h:703
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the call graph for this function:

void FastMatrixElim::opsReorder ( const vector< unsigned int > &  lookupOldRowsFromNew,
vector< Triplet< double > > &  ops,
vector< double > &  diagVal 
)
static

static function. Reorders the ops and diagVal vectors so as to restore the original indexing of the input vectors.

Definition at line 491 of file FastMatrixElim.cpp.

Referenced by Dsolve::build().

495 {
496  vector< double > oldDiag = diagVal;
497 
498  for ( unsigned int i = 0; i < ops.size(); ++i ) {
499  ops[i].b_ = lookupOldRowsFromNew[ ops[i].b_ ];
500  ops[i].c_ = lookupOldRowsFromNew[ ops[i].c_ ];
501  }
502 
503  for ( unsigned int i = 0; i < diagVal.size(); ++i ) {
504  diagVal[ lookupOldRowsFromNew[i] ] = oldDiag[i];
505  }
506 }

+ Here is the caller graph for this function:

void FastMatrixElim::setDiffusionAndTransport ( const vector< unsigned int > &  parentVoxel,
double  diffConst,
double  motorConst,
double  dt 
)

This function incorporates molecule-specific diffusion and motor transport terms into the matrix.

Put in diff and transport terms and also fill in the diagonal The terms are: n-1: dt*(D+M)*adx(-) n: 1 -dt*[ D*adx(-) +D*adx(+) + M*adx(+) ] n+1: dt*D*adx(+) Note that there will be only one parent term but possibly many distal terms.

Definition at line 405 of file FastMatrixElim.cpp.

References SparseMatrix< double >::colIndex_, SparseMatrix< T >::colIndex_, EMPTY_VOXEL(), SparseMatrix< double >::N_, SparseMatrix< T >::N_, SparseMatrix< T >::ncolumns_, SparseMatrix< T >::nrows_, SparseMatrix< double >::nrows_, SparseMatrix< double >::rowStart_, and SparseMatrix< T >::rowStart_.

Referenced by testSetDiffusionAndTransport().

409 {
410  FastMatrixElim m;
411  m.nrows_ = m.ncolumns_ = nrows_;
412  m.rowStart_.resize( nrows_ + 1 );
413  m.rowStart_[0] = 0;
414  for ( unsigned int i = 1; i <= nrows_; ++i ) {
415  // Insert an entry for diagonal in each.
416  m.rowStart_[i] = rowStart_[i] + i;
417  }
418  for ( unsigned int i = 0; i < nrows_; ++i ) {
419  double proximalTerms = 0.0;
420  double distalTerms = 0.0;
421  double term = 0.0;
422  bool pendingDiagonal = true;
423  unsigned int diagonalIndex = EMPTY_VOXEL;
424  for ( unsigned int j = rowStart_[i]; j < rowStart_[i+1]; ++j ) {
425  // Treat transport as something either to or from soma.
426  // The motor direction is based on this.
427  // Assume no transport between sibling compartments.
428  if ( parentVoxel[colIndex_[j]] == i ) {
429  term = N_[j] * dt * ( diffConst + motorConst );
430  proximalTerms += N_[j];
431  } else {
432  term = N_[j] * dt * diffConst;
433  distalTerms += N_[j];
434  }
435  if ( colIndex_[j] < i ) {
436  m.colIndex_.push_back( colIndex_[j] );
437  m.N_.push_back( term );
438  } else if ( colIndex_[j] == i ) {
439  assert( 0 );
440  } else {
441  if ( pendingDiagonal ) {
442  pendingDiagonal = false;
443  diagonalIndex = m.N_.size();
444  m.colIndex_.push_back( i ); // diagonal
445  m.N_.push_back( 0 ); // placeholder
446  }
447  m.colIndex_.push_back( colIndex_[j] );
448  m.N_.push_back( term );
449  }
450  }
451  if ( pendingDiagonal ) {
452  diagonalIndex = m.N_.size();
453  m.colIndex_.push_back( i ); // diagonal
454  m.N_.push_back( 0 ); // placeholder
455  }
456  assert( diagonalIndex != EMPTY_VOXEL );
457  m.N_[diagonalIndex] = 1.0 - dt * (
458  diffConst * ( proximalTerms + distalTerms ) +
459  motorConst * distalTerms
460  );
461  }
462  *this = m;
463 }
unsigned int ncolumns_
Definition: SparseMatrix.h:702
vector< double > N_
Definition: SparseMatrix.h:703
unsigned int nrows_
Definition: SparseMatrix.h:701
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
Definition: SparseMatrix.h:709
static const unsigned int EMPTY_VOXEL(-1)
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
Definition: SparseMatrix.h:712

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void FastMatrixElim::shuffleRows ( const vector< unsigned int > &  lookupOldRowFromNew)

Reorders rows of the matrix according to the vector lookupOldRowFromNew. The vector tells the function which old row to put in the ith row of the new matrix. Since the matrix has matching column entries, those get shuffled too.

Definition at line 193 of file FastMatrixElim.cpp.

References SparseMatrix< double >::addRow(), SparseMatrix< double >::clear(), SparseMatrix< T >::getRow(), SparseMatrix< double >::nrows_, SparseMatrix< T >::nrows_, SparseMatrix< double >::setSize(), and sortByColumn().

Referenced by hinesReorder().

195 {
196  vector< unsigned int > lookupNewRowFromOld( nrows_ );
197  for ( unsigned int i = 0; i < nrows_; ++i )
198  lookupNewRowFromOld[ lookupOldRowFromNew[i] ] = i;
199 
200  FastMatrixElim temp = *this;
201  clear();
202  setSize( temp.nrows_, temp.nrows_ );
203  for ( unsigned int i = 0; i < lookupOldRowFromNew.size(); ++i ) {
204  vector< unsigned int > c;
205  vector< double > e;
206  unsigned int num = temp.getRow( lookupOldRowFromNew[i], e, c );
207  vector< unsigned int > newc( num );
208  vector< double > newe( num );
209  for ( unsigned int j = 0; j < num; ++j ) {
210  newc[j] = lookupNewRowFromOld[ c[j] ];
211  newe[j] = e[j];
212  }
213  // Now we need to sort the new row entries in increasing col order.
214  /*
215  sortByColumn( newc, newe );
216  addRow( i, newe, newc );
217  */
218  sortByColumn( newc, e );
219  addRow( i, e, newc );
220  }
221 }
unsigned int getRow(unsigned int row, const T **entry, const unsigned int **colIndex) const
Definition: SparseMatrix.h:288
void addRow(unsigned int rowNum, const vector< double > &row)
Definition: SparseMatrix.h:387
void setSize(unsigned int nrows, unsigned int ncolumns)
Definition: SparseMatrix.h:126
void sortByColumn(vector< unsigned int > &col, vector< double > &entry)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:


The documentation for this class was generated from the following files: