gsl_eigen_nonsymm_workspace * gsl_eigen_nonsymm_alloc(const size_t n) { gsl_eigen_nonsymm_workspace *w; if (n == 0) { GSL_ERROR_NULL ("matrix dimension must be positive integer", GSL_EINVAL); } w = (gsl_eigen_nonsymm_workspace *) calloc (1, sizeof (gsl_eigen_nonsymm_workspace)); if (w == 0) { GSL_ERROR_NULL ("failed to allocate space for workspace", GSL_ENOMEM); } w->size = n; w->Z = NULL; w->do_balance = 0; w->diag = gsl_vector_alloc(n); if (w->diag == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for balancing vector", GSL_ENOMEM); } w->tau = gsl_vector_alloc(n); if (w->tau == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for hessenberg coefficients", GSL_ENOMEM); } w->francis_workspace_p = gsl_eigen_francis_alloc(); if (w->francis_workspace_p == 0) { gsl_eigen_nonsymm_free(w); GSL_ERROR_NULL ("failed to allocate space for francis workspace", GSL_ENOMEM); } return (w); } /* gsl_eigen_nonsymm_alloc() */
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 eigenscan_stepIM(double partial[EdgeN],long unsigned int sam,double point,double*eigen){ 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 ++ ){ if ( fabs(GSL_IMAG( gsl_vector_complex_get( eval, i ))) > 1e-15 && GSL_REAL( gsl_vector_complex_get( eval, i ) ) > 0 ) { *eigen=GSL_REAL( gsl_vector_complex_get( eval, i )); gsl_vector_complex_free(eval); gsl_eigen_nonsymm_free (w); return GSL_SUCCESS; } } gsl_vector_complex_free(eval); gsl_eigen_nonsymm_free (w); return GSL_CONTINUE; }
void gsl_eigen_nonsymmv_free (gsl_eigen_nonsymmv_workspace * w) { if (w->nonsymm_workspace_p) gsl_eigen_nonsymm_free(w->nonsymm_workspace_p); if (w->work) gsl_vector_free(w->work); if (w->work2) gsl_vector_free(w->work2); if (w->work3) gsl_vector_free(w->work3); free(w); } /* gsl_eigen_nonsymmv_free() */
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; }
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 }