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;
}
Ejemplo n.º 2
0
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;
    
}
Ejemplo n.º 3
0
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
}