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.

Related topics

Topic contents

Introduction and outline

Under construction: more content to follow...

[back to topic contents]

Run-level results

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.

[back to topic contents]

Overriding run-level results

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:

  1. The introductory //EXPR single-line comment
  2. The two-part name of a table measure
  3. 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 to 1.0.
  • The cell E2 is set to the number of the sub {0,1,2, ...}.
  • The cell E0 is set to the quotient E1 / 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

[back to topic contents]

⚠️ **GitHub.com Fallback** ⚠️