An event trigger is a Boolean expression. The exact moment at which the expression value changes from
TRUE
to
FALSE
is the time point when the event is
fired. The Boolean expression must not use any of the random functions (uniform() and normal()) COPASI provides.
Implementation Issues
Comparing for Equality
The Boolean expression
A == B
is numerically hard to evaluate for floating point numbers. To avoid this problem we internally modify the event trigger and change the trigger expressions to
A ≤ B
and
B ≤ A
. The same numerical problem occurs for the Boolean expression
A != B
, which we solve similarly by internally changing the trigger expressions to
A < B
or
B < A
Difference between ≥ and >
Numerically the solutions for both trigger expressions are equivalent except for the
execution point of the target assignment. The
execution point for
A ≥ B
is the point in time when
A = B
(plus eventual delay) whereas the
execution point for
A > B
is infinitesimal larger. This means we need to assure that the
execution for
A > B
takes place after eventual other processing (e.g. reporting). For reporting we will have to check whether the
execution point is equal to a reporting point. This is again a numerically tough problem for floating point numbers. We need to evaluate approximate equality, which currently in COPASI is defined as:
B - 100 (DBL_EPSILON * |B| + DBL_MIN) ≤ A ≤ B + 100 (DBL_EPSILON * |B| + DBL_MIN)
To decide whether the
execution has to be done prior or after other processing we can not use the result of the trigger expression as this does not suffice to distinguish between the two cases. This means we have to analyze the structure of the trigger expression by using the following logic.
Boolean Expression | Execution PRIOR to Processing |
A < B | false |
A ≤ B | true |
A > B | false |
A ≥ B | true |
For the boolean operators we simply apply them. The above logic is static (independent from the values of
A
and
B
and can therefor be evaluated once during initialization. We do not need to deal with the comparison operators
==
and
!=
since they have been converted.
Time Course
Deterministic Integration
The method for deterministic integration of models which contain events should switches from LSODA to LSODAR. The R stand for an additional root finding routine which determines the exact point at which the trigger
fires. This root finding routine requires as input continuous functions. It will look for roots of this function with odd degree, i.e., points where the continuous function changes sign. To provide this we need to translate the Boolean expression of the trigger into a continuous function which changes sign from
minus
to
plus
if and only if the trigger expression changes from
FALSE
to
TRUE
. The Boolean expression may be complicated however we know that the decision whether a trigger fires depends eventually on the comparison of 2 numbers, which may be calculated by an arbitrary numerical expression. COPASI supports the following comparison between numbers which are easily translated into roots:
Boolean Expression | Continuous Root Finding Function |
A < B | B - A |
A ≤ B | B - A |
A > B | A - B |
A ≥ B | A - B |
To determine whether the root found by the above mechanism leads to
firing of an event or to
recharge we need to know the slop of the continuous function with respect to t. We do not have access to this information however we can remember the state a trigger is in.
Stochastic Integration
For the Gibson & Bruck method we add a step which calculates the trigger expression after each reaction event and determines whether the trigger expression changed from
FALSE
to
TRUE
. If the trigger expression is time dependent and leads to an
execution prior to the current time we need to discard the current reaction event and update the priority queue.
The τ-Leap method should not be allowed for models with events.
Steady State
A steady state for a model with events may no be calculated with the Newton method or backwards integration. This leaves as the only method forward integration.