예제 #1
0
/**
* Returns a boolean representation of the value associated with the required
* property name. If the property name is not valid then false is returned.
* @param propertyName string containing the property name
* @returns a boolean representation of the value for the property
*/
bool Match::getValueAsBool(const string &propertyName) {
	return getValueAsBool(propertyName.c_str());
}
예제 #2
0
	double GillespieIntegrator::integrate(double t, double hstep)
	{
		double tf = 0;
		bool singleStep;

		assert(hstep > 0 && "hstep must be > 0");

		if (getValue("variable_step_size").convert<bool>())
		{
			if (getValue("minimum_time_step").convert<double>() > 0.0)
			{
				tf = t + getValue("minimum_time_step").convert<double>();
				singleStep = false;
			}
			else
			{
				tf = t + hstep;
				singleStep = true;
			}
		}
		else
		{
			tf = t + hstep;
			singleStep = false;
		}

		Log(Logger::LOG_DEBUG) << "ssa(" << t << ", " << tf << ")";

		// get the initial state vector
		model->setTime(t);
		model->getStateVector(stateVector);

		while (t < tf)
		{
			// random uniform numbers
			double r1 = urand();
			double r2 = urand();

			assert(r1 > 0 && r1 <= 1 && r2 >= 0 && r2 <= 1);

			// sum of propensities
			double s = 0;

			// next time
			double tau = 0;

			// get the 'propensity' -- reaction rates
			model->getReactionRates(nReactions, 0, reactionRates);

			// sum the propensity
			for (int k = 0; k < nReactions; k++)
			{
				Log(Logger::LOG_DEBUG) << "reac rate: " << k << ": "
					<< reactionRates[k];

				// if reaction rate is negative, that means reaction goes in reverse,
				// this is fine, we just have to reverse the stoichiometry,
				// but still need to sum the absolute value of the propensities
				// to get tau.
				s += std::abs(reactionRates[k]);
			}

			// sample tau
			if (s > 0)
			{
				tau = -log(r1) / s;
			}
			else
			{
				// no reaction occurs
				return std::numeric_limits<double>::infinity();
			}

			t = t + tau;

			// select reaction
			int reaction = -1;
			double sp = 0.0;

			r2 = r2 * s;
			for (int i = 0; i < nReactions; ++i)
			{
				sp += std::abs(reactionRates[i]);
				if (r2 < sp)
				{
					reaction = i;
					break;
				}
			}

			assert(reaction >= 0 && reaction < nReactions);

			// update chemical species
			// if rate is negative, means reaction goes in reverse, so
			// multiply by sign
			double sign = (reactionRates[reaction] > 0)
				- (reactionRates[reaction] < 0);

			bool skip = false;

			if (getValueAsBool("nonnegative")) {
				// skip reactions which cause species amts to become negative
				for (int i = floatingSpeciesStart; i < stateVectorSize; ++i) {
					if (stateVector[i]
						+ getStoich(i - floatingSpeciesStart, reaction)
						* stoichScale * sign < 0.0) {
							skip = true;
							break;
						}
				}
			}

			if (!skip) {
				for (int i = floatingSpeciesStart; i < stateVectorSize; ++i)
				{
					stateVector[i] = stateVector[i]
						+ getStoich(i - floatingSpeciesStart, reaction)
						* stoichScale * sign;

					if (stateVector[i] < 0.0) {
						Log(Logger::LOG_WARNING) << "Error, negative value of "
							<< stateVector[i]
							<< " encountred for floating species "
							<< model->getFloatingSpeciesId(i - floatingSpeciesStart);
						t = std::numeric_limits<double>::infinity();
					}
				}
			}

			// rates could be time dependent
			model->setTime(t);
			model->setStateVector(stateVector);

      // events
      bool triggered = false;

      model->getEventTriggers(eventStatus.size(), NULL, eventStatus.size() ? &eventStatus[0] : NULL);
      for(int k_=0; k_<eventStatus.size(); ++k_) {
        if (eventStatus.at(k_))
          triggered = true;
      }

      if (triggered) {
        applyEvents(t, previousEventStatus);
      }

      if (eventStatus.size())
        memcpy(&previousEventStatus[0], &eventStatus[0], eventStatus.size()*sizeof(unsigned char));


			if (singleStep)
			{
				return t;
			}
		}

		return t;
	}
예제 #3
0
/**
* Returns a boolean representation of the value associated with the required
* property name. If the property name is not valid then false is returned.
* @param propertyName string containing the property name
* @returns a boolean representation of the value for the property
*/
bool Match::getValueAsBool(const char* propertyName) {
	return getValueAsBool(
		fiftyoneDegreesGetRequiredPropertyIndex(
			offsets->active->dataSet, 
			propertyName));
}