Tables - openmpp/openmpp.github.io GitHub Wiki
Home > Model Development Topics > Tables
This topic is under construction and/or revision.
Topic summary, two sentences max.
- Entity Tables: Entity tables
- Derived Tables: Derived tables
- Model Output Expressions: Model Output Expressions
Under construction: more content to follow...
OpenM++ computes the run-level value of a table cell by aggregating the values of the table cell over the subs/replicates/members of the run.
The aggregation method depends on the kind of model (case-based or time-based),
the measures_method option,
the kind of table (entity or derived),
and for entity tables the measure statistic (count, sum, etc.).
Under construction: more content to follow...
Model code computes the values of a derived table, so for derived tables, OpenM++ sets the run-level aggregated result to the average of the sub values.
The formula to compute run-level results can be specified explicitly for a table measure by providing an expression in model code, as illustrated by the following example:
//EXPR T00_Test.E0 OM_SUM(acc1) / OM_DIV_BY(acc2)The syntax has three parts:
- The introductory
//EXPRsingle-line comment - The two-part name of a table measure
- The expression used to compute the run-level value for that measure, in model output expression syntax using the table's accumulators.
Here's a worked example,
using a derived table named T00_Test:
derived_table T00_Test
{
{
E0, //EN quotient
E1, //EN numerator
E2 //EN denominator
}
};This table has no enumeration dimensions, so consists of a single cell (not counting the measure dimension).
The measure dimension has 3 measures/expressions: E0, E1, and E2.
As with all derived tables,
each measure has an implicit associated 'fake' accumulator which for this table are named acc0, acc1, and acc2.
In this example, model code populates the cells mechanically for each sub as follows:
- The cell
E1is always set to1.0. - The cell
E2is set to the number of the sub{0,1,2, ...}. - The cell
E0is set to the quotientE1 / E2.
Here are the values of T00_Test for each sub for a 2-sub run:
| Sub | E0 | E1 | E2 |
|---|---|---|---|
| 0 | 1.0 | 1.0 | 1.0 |
| 1 | 0.5 | 1.0 | 2.0 |
Here's the model code which populates `T00_Test` for each sub:
void UserTables()
{
auto n = GetUserTableSubSample();
double numerator = 1.0;
double denominator = n + 1;
double quotient = numerator / denominator;
SetTableValue("T00_Test.E0", quotient);
SetTableValue("T00_Test.E1", numerator);
SetTableValue("T00_Test.E2", denominator);
}Because T00_Test is a derived table,
the run-level value is normally calculated using the OM_AVG() aggregation function, as follows:
| Sub | E0 | E1 | E2 |
|---|---|---|---|
| 0 | 1.0 | 1.0 | 1.0 |
| 1 | 0.5 | 1.0 | 2.0 |
| Run-level formula | OM_AVG(acc0) |
OM_AVG(acc1) |
OM_AVG(acc2) |
| Run-level value | 0.75 | 1.0 | 1.5 |
In words, the default formula computes E0 by averaging the ratios in E0 over the subs.
The run result for E0 is
E0 = ((1/1) + (1/2))/2
= (1.0 + 0.5) / 2
= 1.5 / 2
= 0.75
If the formula to compute E0 at the run-level is overridden by
//EXPR T00_Test.E0 OM_SUM(acc1) / OM_DIV_BY(acc2)
the calculation instead becomes
| Sub | E0 | E1 | E2 |
|---|---|---|---|
| 0 | 1.0 | 1.0 | 1.0 |
| 1 | 0.5 | 1.0 | 2.0 |
| Run-level formula | OM_SUM(acc1) / OM_DIV_BY(acc2) |
OM_AVG(acc1) |
OM_AVG(acc2) |
| Run-level value | 0.66666 | 1.0 | 1.5 |
In words, the override formula computes E0 by summing the numerators over the subs,
summing the denominators over the subs, and then computing the quotient.
The run result for E0 is
E0 = (1+1)/(1+2)
= 2.0 / 3.0
= 0.66666