void eigen_setIM(double partial[EdgeN],struct RootSet RS[SampleN][MultiRootN],double point,long unsigned int sam,long unsigned int samwork,int rn, int realInterval, int imageInterval){ double kappa; double data[EdgeN]; int i; kappa = EIGENVALUESCAN_MINKAPPA * pow(EIGENVALUESCAN_MAXKAPPA/EIGENVALUESCAN_MINKAPPA, point); for (i=0;i<EdgeN;i++){ data[i]=partial[i]; if( (int)i/NodeN == i%NodeN ) data[i]-=kappa*Sample[sam].D[(int)i/NodeN]; } gsl_matrix_view m; gsl_vector_complex * eval; gsl_eigen_nonsymm_workspace * w; m = gsl_matrix_view_array (data, NodeN, NodeN); eval = gsl_vector_complex_alloc (NodeN); w = gsl_eigen_nonsymm_alloc (NodeN); gsl_eigen_nonsymm (&m.matrix, eval, w); for ( i = 0; i < NodeN; i ++ ) { RS[samwork][rn].RE[realInterval].IM[imageInterval].eigenIM[i][0]=GSL_REAL( gsl_vector_complex_get( eval, i )); RS[samwork][rn].RE[realInterval].IM[imageInterval].eigenIM[i][1]=GSL_IMAG( gsl_vector_complex_get( eval, i )); } gsl_vector_complex_free(eval); gsl_eigen_nonsymm_free (w); }
int gsl_eigen_nonsymm_Z (gsl_matrix * A, gsl_vector_complex * eval, gsl_matrix * Z, gsl_eigen_nonsymm_workspace * w) { /* check matrix and vector sizes */ if (A->size1 != A->size2) { GSL_ERROR ("matrix must be square to compute eigenvalues", GSL_ENOTSQR); } else if (eval->size != A->size1) { GSL_ERROR ("eigenvalue vector must match matrix size", GSL_EBADLEN); } else if ((Z->size1 != Z->size2) || (Z->size1 != A->size1)) { GSL_ERROR ("Z matrix has wrong dimensions", GSL_EBADLEN); } else { int s; w->Z = Z; s = gsl_eigen_nonsymm(A, eval, w); w->Z = NULL; return s; } } /* gsl_eigen_nonsymm_Z() */
bool eigenValues(const Matrix &m, Matrix& real, Matrix& imag){ // check if m is square assert(m.getM() == m.getN()); gsl_matrix* m_gsl = toGSL(m); gsl_eigen_nonsymm_workspace* w = gsl_eigen_nonsymm_alloc (m.getM()); gsl_vector_complex *eval = gsl_vector_complex_alloc (m.getM()); gsl_eigen_nonsymm (m_gsl, eval, w); gsl_eigen_nonsymm_free (w); gsl_eigen_nonsymmv_sort (eval, 0, GSL_EIGEN_SORT_ABS_DESC); gsl_vector_view eval_real = gsl_vector_complex_real(eval); gsl_vector_view eval_imag = gsl_vector_complex_imag(eval); real = fromGSL(&eval_real.vector); imag = fromGSL(&eval_imag.vector); return true; }
int eigenscan_step(double partial[EdgeN],long unsigned int sam,double point,double*eigen){ double kappa,max_eigen=0; double data[EdgeN]; int i,sign=0; kappa = EIGENVALUESCAN_MINKAPPA * pow(EIGENVALUESCAN_MAXKAPPA/EIGENVALUESCAN_MINKAPPA, point); for (i=0;i<EdgeN;i++){ data[i]=partial[i]; if( (int)i/NodeN == i%NodeN ) data[i]-=kappa*Sample[sam].D[(int)i/NodeN]; } gsl_matrix_view m; gsl_vector_complex * eval; gsl_eigen_nonsymm_workspace * w; m = gsl_matrix_view_array (data, NodeN, NodeN); eval = gsl_vector_complex_alloc (NodeN); w = gsl_eigen_nonsymm_alloc (NodeN); gsl_eigen_nonsymm (&m.matrix, eval, w); for ( i = 0; i < NodeN; i ++ ) if ( fabs(GSL_IMAG( gsl_vector_complex_get( eval, i )))<1e-15 && GSL_REAL( gsl_vector_complex_get( eval, i ) ) > 0) { sign = 1; if(max_eigen<GSL_REAL( gsl_vector_complex_get( eval, i ))) max_eigen=GSL_REAL( gsl_vector_complex_get( eval, i )); } gsl_vector_complex_free(eval); gsl_eigen_nonsymm_free (w); if (sign==1) { *eigen=max_eigen; return GSL_SUCCESS; } else { *eigen=-1; return GSL_CONTINUE; } }
void SteadyState::classifyState( const double* T ) { #ifdef USE_GSL // unsigned int nConsv = numVarPools_ - rank_; gsl_matrix* J = gsl_matrix_calloc ( numVarPools_, numVarPools_ ); // double* yprime = new double[ numVarPools_ ]; // vector< double > yprime( numVarPools_, 0.0 ); // Generate an approximation to the Jacobean by generating small // increments to each of the molecules in the steady state, one // at a time, and putting the resultant rate vector into a column // of the J matrix. // This needs a bit of heuristic to decide what is a 'small' increment. // Use the CoInits for this. Stoichiometry shouldn't matter too much. // I used the totals from consv rules earlier, but that can have // negative values. double tot = 0.0; Stoich* s = reinterpret_cast< Stoich* >( stoich_.eref().data() ); vector< double > nVec = LookupField< unsigned int, vector< double > >::get( s->getKsolve(), "nVec", 0 ); for ( unsigned int i = 0; i < numVarPools_; ++i ) { tot += nVec[i]; } tot *= DELTA; vector< double > yprime( nVec.size(), 0.0 ); // Fill up Jacobian for ( unsigned int i = 0; i < numVarPools_; ++i ) { double orig = nVec[i]; if ( isnan( orig ) ) { cout << "Warning: SteadyState::classifyState: orig=nan\n"; solutionStatus_ = 2; // Steady state OK, eig failed gsl_matrix_free ( J ); return; } if ( isnan( tot ) ) { cout << "Warning: SteadyState::classifyState: tot=nan\n"; solutionStatus_ = 2; // Steady state OK, eig failed gsl_matrix_free ( J ); return; } nVec[i] = orig + tot; /// Here we assume we always use voxel zero. s->updateRates( &nVec[0], &yprime[0], 0 ); nVec[i] = orig; // Assign the rates for each mol. for ( unsigned int j = 0; j < numVarPools_; ++j ) { gsl_matrix_set( J, i, j, yprime[j] ); } } // Jacobian is now ready. Find eigenvalues. gsl_vector_complex* vec = gsl_vector_complex_alloc( numVarPools_ ); gsl_eigen_nonsymm_workspace* workspace = gsl_eigen_nonsymm_alloc( numVarPools_ ); int status = gsl_eigen_nonsymm( J, vec, workspace ); eigenvalues_.clear(); eigenvalues_.resize( numVarPools_, 0.0 ); if ( status != GSL_SUCCESS ) { cout << "Warning: SteadyState::classifyState failed to find eigenvalues. Status = " << status << endl; solutionStatus_ = 2; // Steady state OK, eig classification failed } else { // Eigenvalues are ready. Classify state. nNegEigenvalues_ = 0; nPosEigenvalues_ = 0; for ( unsigned int i = 0; i < numVarPools_; ++i ) { gsl_complex z = gsl_vector_complex_get( vec, i ); double r = GSL_REAL( z ); nNegEigenvalues_ += ( r < -EPSILON ); nPosEigenvalues_ += ( r > EPSILON ); eigenvalues_[i] = r; // We have a problem here because numVarPools_ usually > rank // This means we have several zero eigenvalues. } if ( nNegEigenvalues_ == rank_ ) stateType_ = 0; // Stable else if ( nPosEigenvalues_ == rank_ ) // Never see it. stateType_ = 1; // Unstable else if (nPosEigenvalues_ == 1) stateType_ = 2; // Saddle else if ( nPosEigenvalues_ >= 2 ) stateType_ = 3; // putative oscillatory else if ( nNegEigenvalues_ == ( rank_ - 1) && nPosEigenvalues_ == 0 ) stateType_ = 4; // one zero or unclassified eigenvalue. Messy. else stateType_ = 5; // Other } gsl_vector_complex_free( vec ); gsl_matrix_free ( J ); gsl_eigen_nonsymm_free( workspace ); #endif }