float *pasoRungerKutta4(float *ks,float posicionesX, float posicionesY, float h,float alpha, float beta, float gamma, float epsilon){ float k1,k2,k3,k4,kF; float l1,l2,l3,l4,lF; float inter1x,inter2x,inter3x, inter1y,inter2y,inter3y; k1 = xprime(posicionesX, posicionesY,alpha,beta); l1 = yprime(posicionesX, posicionesY,gamma,epsilon); inter1x = posicionesX+0.5*h*k1; inter1y = posicionesY+0.5*h*l1; k2 = xprime(inter1x,inter1y,alpha,beta); l2 = yprime(inter1x,inter1y,gamma,epsilon); inter2x = posicionesX+0.5*h*k2; inter2y = posicionesY+0.5*h*l2; k3 = xprime(inter2x,inter2y,alpha,beta); l3 = yprime(inter2x,inter2y,gamma,epsilon); inter3x = posicionesX+h*k3; inter3y = posicionesY+h*l3; k4 = xprime(inter3x,inter3y,alpha,beta); l4 = yprime(inter3x,inter3y,gamma,epsilon); ks[0] = (1.0/6.0)*(k1+2*k2+2*k3+k4); ks[1] = (1.0/6.0)*(l1+2*l2+2*l3+l4); return ks; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { double *yp; double *t,*y; size_t m,n; /* Check for proper number of arguments */ if (nrhs != 2) { mexErrMsgIdAndTxt( "MATLAB:yprime:invalidNumInputs", "Two input arguments required."); } else if (nlhs > 1) { mexErrMsgIdAndTxt( "MATLAB:yprime:maxlhs", "Too many output arguments."); } /* Check the dimensions of Y. Y can be 4 X 1 or 1 X 4. */ m = mxGetM(Y_IN); n = mxGetN(Y_IN); if (!mxIsDouble(Y_IN) || mxIsComplex(Y_IN) || (MAX(m,n) != 4) || (MIN(m,n) != 1)) { mexErrMsgIdAndTxt( "MATLAB:yprime:invalidY", "YPRIME requires that Y be a 4 x 1 vector."); } /* Create a matrix for the return argument */ YP_OUT = mxCreateDoubleMatrix( (mwSize)m, (mwSize)n, mxREAL); /* Assign pointers to the various parameters */ yp = mxGetPr(YP_OUT); t = mxGetPr(T_IN); y = mxGetPr(Y_IN); /* Do the actual computations in a subroutine */ yprime(yp,t,y); return; }
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 }