This page will look better in a graphical browser that supports web standards, but is accessible to any browser or internet device.

Served by Samwise.

# Events in MML

## Introduction

MML events model discrete changes of physical and physiological state such as voltage transitions, heart beats, etc. Events also provide a mechanism for calculation of recursive functions, such as Fibonacci numbers. Event-driven variables can freely intermix with continuous (e.g. ODE-calculated) variables, allowing you to model hybrid discrete/continuous systems.

Prerequisites:

Contents:

## Overview

An MML event consists of a realDomain t (which usually represents time), a boolean trigger expression which is a function of t and a series of action assignments. The trigger is tested for each value of t, and the event is fired if the value of the trigger evaluates to true. When the event fires, the action assignments are executed in the order specified.

Action assignments are of the form "v = expression;" where v is a realState, intState or ODE variable. A realState and intState variable v(t) must be assigned an initial value when t=t.min and subsequent values of v(t) are calculate by carrying the value from the previous time step forward, and then altering it based upon any triggered events. An ODE variable is assigned an initial value when t=t.min and subsequent values are calculated via an ODE starting with the previous t value. Once the ODE calculation is complete, v(t) is altered based upon any triggered events.

## State variables and a simple example

Here is a simple example that counts the number of times an externally provided voltage V exceeds a threshold voltage V0:

```// event to count voltages above threshhold
math count {
realDomain t;
t.min=0; t.max=10; t.delta=1;
real V0 = 0.5;
extern real V(t);
intState ct(t);
when (t=t.min) ct=0;
event (V>V0) ct=ct+1;
}
```
(Java plugin required)

The state variable ct(t) is initialized to 0 at time zero, and is incremented each time the event (V>V0) is triggered. The event contains a single event action "ct=ct+1". The statement "ct=ct+1" would be nonsense as an MML equation, but is acceptable as an event action.

## Gate Example 1

The following model describes a gate that opens when an external voltage exceeds threshold V1, and closes when it drops below threshold V0:

```// event models gate opening/closing
math main {
realDomain t;
t.min=0; t.max=10; t.delta=0.1;
extern real V(t);
real V1 = 10;
real V0 = 5;
intState open(t);
when (t=t.min) open = 0;
event (open=0 and V>V1) open = 1;
event (open>0 and V<V0) open = 0;
}
```
(Java plugin required)

By using two events, we have introduced memory into the system. The value of "open" for V between V0 and V1 is dependent not upon the current value of V, but upon previous values.

## Gate example 2

The event triggers in gate example 1 are slightly redundant. The gate opening trigger "V>V1" would have the same effect as the one given "open=0 and V>V1". However, by using the longer form, we can ensure that the events "gate opening" and "gate closing" happen alternately, which is useful in the following model. A running count is kept of the number of gate openings is kept in variable ct. The time of the latest gate closure is kept in variable tlast. Multiple actions may be associated with a single event by enclosing them in curly braces.

```// ensuring gate openings/closings occur alternately
math main {
realDomain t;
t.min=0; t.max=10; t.delta=0.1;
extern real V(t);
real V1 = 10;
real V0 = 5;
intState open(t);
intState ct(t);
realState tlast(t);
when (t=t.min) {
open = 0;
ct = 0;
tlast = -1;
}
event (open=0 and V>V1) {
open = 1;
ct = ct+1;
}
event (open>0 and V<V0) {
open = 0;
tlast = t;
}
}
```
(Java plugin required)

## Gate example 3

Event-driven variables become more useful for modeling when their values drive the calculation of other system variables which, in turn, trigger events. In the following example, V either grows or shrinks exponentially based up whether the gate is open. Whether the gate is open depends upon current and previous values of V:

```// gate opening/closing drives model ODE
math main {
realDomain t;
t.min=0; t.max=10; t.delta=0.1;
real V(t);
real V1 = 10;
real V0 = 5;
intState open(t);
when (t=t.min) {
open = 0;
V=1;
}
V:t = if (open>0) -V else V;
event (open=0 and V>V1) open = 1;
event (open>0 and V<V0) open = 0;
}
```
(Java plugin required)

## Events using ODE variables

Events may act upon ODE variables (this is a new feature for JSim version 2). In the example below, the u decays exponentially starting a u(t.min)=1. When u fall below .2, an event resets it back to 1, resulting in a periodic wave form:

```// Event on ODE variable

math main {
realDomain t;
t.min=0; t.max=5; t.delta=.1;
real u(t);
when (t=t.min) u=1;
u:t = -u;
event (u<.2) u=1;
}
```
(Java plugin required)

## Recursive functions

JSim events support calculation of recursive functions which are not supported elsewhere in MML. The following example calculates the Fibonacci numbers:

```// event construct for recursive function call
math main {
realDomain n;
n.min=1; n.max=10; n.delta=1;
intState f(n);
when (n=n.min) f=1;
event (n>2) f = f(n-1) + f(n-2);
}
```
(Java plugin required)

## Some cautions

Event triggers are tested once per time step. At any given time-step, zero, one or more than one events may be triggered. If multiple events are triggered at a time-step, the order in which they are triggered is undefined. However, the actions within an event always take place in the declared order when that event is triggered. It is up to the MML author to write their events and triggers in such a way so that the result is well defined.

Here's a simplified version of a problem that can easily occur. If the triggers in gated example 2:

```event (open=0 and V>V1) {
open = 1;
ct = ct+1;
}
```

```event (open=0 and V>V1) open = 1;