19 #include "../basecode/SparseMatrix.h"
20 #include "../basecode/doubleEq.h"
42 vector< unsigned int >& col, vector< double >& entry );
58 N_.size() == temp.
N_.size() &&
69 N_.size() == other.
N_.size() &&
72 for (
unsigned int i = 0; i <
N_.size(); ++i )
84 return ( temp == *
this );
140 const vector< unsigned int >& parentVoxel,
141 vector< unsigned int >& lookupOldRowFromNew
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 ) {
153 numKids[ parentVoxel[i] ]++;
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;
161 unsigned int pa = parentVoxel[i];
164 assert( rowPending[pa] );
165 rowPending[pa] =
false;
167 lookupOldRowFromNew.push_back( pa );
168 pa = parentVoxel[pa];
171 assert( numKids[pa] > 0 );
194 const vector< unsigned int >& lookupOldRowFromNew )
196 vector< unsigned int > lookupNewRowFromOld(
nrows_ );
197 for (
unsigned int i = 0; i <
nrows_; ++i )
198 lookupNewRowFromOld[ lookupOldRowFromNew[i] ] = i;
203 for (
unsigned int i = 0; i < lookupOldRowFromNew.size(); ++i ) {
204 vector< unsigned int > c;
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] ];
223 void sortByColumn( vector< unsigned int >& col, vector< double >& entry )
225 unsigned int num = col.size();
226 assert( num == entry.size() );
229 for (
unsigned int i = 0; i < num; ++i ) {
230 for (
unsigned int j = 1; j < num; ++j ) {
231 if ( col[j] < col[j-1] ) {
232 unsigned int temp = col[j];
236 entry[j] = entry[j-1];
245 const double* test,
unsigned int numCompts )
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 ) {
254 N_.push_back( test[k] );
278 vector< vector< unsigned int > > rowsToElim(
nrows_ );
280 for (
unsigned int i = 0; i <
nrows_; ++i ) {
283 for (
unsigned int j = rs; j < re; ++j ) {
287 }
else if ( k > i ) {
288 rowsToElim[ i ].push_back( k );
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;
304 double ratio =
get( erow, i ) / d;
306 for (
unsigned int k = diag[i]+1; k < diagend; ++k ) {
309 for (
unsigned int q = rs; q < re; ++q ) {
311 N_[q] -=
N_[k] * ratio;
348 vector< vector< unsigned int > > rowsToSub(
nrows_ );
350 for (
unsigned int i = 0; i <
nrows_; ++i ) {
351 unsigned int d = diag[i] + 1;
353 for (
unsigned int j = d; j < re; ++j ) {
357 rowsToSub[ k ].push_back( i );
372 for (
unsigned int i = 0; i !=
nrows_ ; ++i ) {
373 diagVal.push_back( 1.0 /
N_[diag[i]] );
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 );
406 const vector< unsigned int >& parentVoxel,
407 double diffConst,
double motorConst,
414 for (
unsigned int i = 1; i <=
nrows_; ++i ) {
418 for (
unsigned int i = 0; i <
nrows_; ++i ) {
419 double proximalTerms = 0.0;
420 double distalTerms = 0.0;
422 bool pendingDiagonal =
true;
429 term =
N_[j] * dt * ( diffConst + motorConst );
430 proximalTerms +=
N_[j];
432 term =
N_[j] * dt * diffConst;
433 distalTerms +=
N_[j];
437 m.
N_.push_back( term );
441 if ( pendingDiagonal ) {
442 pendingDiagonal =
false;
443 diagonalIndex = m.
N_.size();
448 m.
N_.push_back( term );
451 if ( pendingDiagonal ) {
452 diagonalIndex = m.
N_.size();
457 m.
N_[diagonalIndex] = 1.0 - dt * (
458 diffConst * ( proximalTerms + distalTerms ) +
459 motorConst * distalTerms
474 const vector< double >& diagVal )
477 i = ops.begin(); i != ops.end(); ++i )
478 y[i->c_] -= y[i->b_] * i->a_;
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 )
492 const vector< unsigned int >& lookupOldRowsFromNew,
494 vector< double >& diagVal )
496 vector< double > oldDiag = diagVal;
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_ ];
503 for (
unsigned int i = 0; i < diagVal.size(); ++i ) {
504 diagVal[ lookupOldRowsFromNew[i] ] = oldDiag[i];
511 const vector< unsigned int >& parentVoxel,
512 vector< vector< unsigned int > >& colIndex
516 colIndex.resize( nrows );
517 for (
unsigned int i = 0; i < nrows; ++i ) {
519 colIndex[i].push_back( parentVoxel[i] );
520 colIndex[ parentVoxel[i] ].push_back( i );
522 colIndex[i].push_back( i );
524 for (
unsigned int i = 0; i < nrows; ++i ) {
525 vector< unsigned int >& c = colIndex[i];
526 sort( c.begin(), c.end() );
528 for (
unsigned int j = 1; j < c.size(); ++j ) {
529 assert( c[j -1 ] != c[j] );
539 const vector< unsigned int >& parentVoxel,
540 const vector< double >& area )
542 unsigned int nrows = parentVoxel.size();
543 vector< double > sumAreaOfChildren( nrows, 0.0 );
544 for (
unsigned int i = 0; i < nrows; ++i ) {
546 sumAreaOfChildren[ parentVoxel[i] ] += area[i];
548 for (
unsigned int i = 0; i < nrows; ++i ) {
550 areaProportion[i] = area[i]/sumAreaOfChildren[ parentVoxel[i] ];
552 areaProportion[i] = 1.0;
558 const vector< unsigned int >& parentVoxel,
559 const vector< double >& volume,
560 const vector< double >& area,
561 const vector< double >& length,
562 double diffConst,
double motorConst,
double dt )
565 if ( diffConst < 1e-18 && fabs( motorConst ) < 1e-12 )
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;
574 vector< bool > isTwig(
nrows_,
true );
575 for (
unsigned int i = 0; i <
nrows_; ++i ) {
577 isTwig[ parentVoxel[i] ] =
false;
580 vector< double > areaProportion( nrows_, 1.0 );
584 for (
unsigned int i = 0; i <
nrows_; ++i ) {
585 vector< unsigned int >& c = colIndex[i];
586 vector< double > e( c.size(), 0.0 );
588 for (
unsigned int j = 0; j < c.size(); ++j ) {
589 unsigned int k = c[j];
590 double vol = volume[k];
592 double len = length[k];
596 for (
unsigned int p = 0; p < c.size(); ++p ) {
597 unsigned int q = c[p];
599 e[j] -= (area[q] + a)/(length[q] + len )/vol;
604 if ( i > 0 && motorConst < 0 ) {
605 e[j] += motorConst / len;
607 if ( !isTwig[i] && motorConst > 0 ) {
608 e[j] -= motorConst / len;
615 (area[i] + a)/(length[i] + len )/vol;
618 if ( k == parentVoxel[i] && motorConst > 0 ) {
619 e[j] += areaProportion[i] * motorConst / len;
621 if ( i == parentVoxel[k] && motorConst < 0 ) {
622 e[j] -= motorConst / length[k];
void buildBackwardSub(vector< unsigned int > &diag, vector< Triplet< double > > &bops, vector< double > &diagVal)
static void advance(vector< double > &y, const vector< Triplet< double > > &ops, const vector< double > &diagVal)
unsigned int getRow(unsigned int row, const T **entry, const unsigned int **colIndex) const
bool hinesReorder(const vector< unsigned int > &parentVoxel, vector< unsigned int > &lookupOldRowsFromNew)
void shuffleRows(const vector< unsigned int > &lookupOldRowFromNew)
bool doubleEq(double x, double y)
void findAreaProportion(vector< double > &areaProportion, const vector< unsigned int > &parentVoxel, const vector< double > &area)
void addRow(unsigned int rowNum, const vector< double > &row)
const vector< unsigned int > & colIndex() const
bool operator==(const FastMatrixElim &other) const
static void opsReorder(const vector< unsigned int > &lookupOldRowsFromNew, vector< Triplet< double > > &ops, vector< double > &diagVal)
bool checkSymmetricShape() const
void setSize(unsigned int nrows, unsigned int ncolumns)
void makeTestMatrix(const double *test, unsigned int numCompts)
void setDiffusionAndTransport(const vector< unsigned int > &parentVoxel, double diffConst, double motorConst, double dt)
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.
vector< unsigned int > colIndex_
Non-zero entries in the SparseMatrix.
static const unsigned int EMPTY_VOXEL(-1)
void buildColIndex(unsigned int nrows, const vector< unsigned int > &parentVoxel, vector< vector< unsigned int > > &colIndex)
void buildForwardElim(vector< unsigned int > &diag, vector< Triplet< double > > &fops)
vector< unsigned int > rowStart_
Start index in the N_ and colIndex_ vectors, of each row.
void sortByColumn(vector< unsigned int > &col, vector< double > &entry)