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
//EXPR
single-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
E1
is always set to1.0
. - The cell
E2
is set to the number of the sub{0,1,2, ...}
. - The cell
E0
is 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