Skip to content

HIGHLIGHT Simplified iteration of range, classification, partition

esseff edited this page Jun 1, 2025 · 3 revisions

Home > Model Development Topics > Highlight Topic

OpenM++ implements enhancements which can simplify model code which iterates ranges, classifications, or partitions. This was implemented some time ago, when ranges, classifications, and partitions were originally implemented in OpenM++ circa 2015.

The enhancement is not Modgen-compatible, so was of limited interest at the time. But it’s of greater interest now, with Modgen in the rear-view mirror.

The wiki reference subtopic is Iterating enumerations. Here’s a sketch and some examples:

In OpenM++, any range, classification, or partition has a special member function indices(), which is designed to be used in a C++ “range-based for” statement. Here’s an example from GMM, where RISK_FACTOR is a classification:

// Verify that SimulateRiskFactor is true if the risk factor is passed to Boadicea in RA_BoadiceaUseRiskFactor.
for (auto j : RISK_FACTOR::indices()) {
    if (RA_BoadiceaUseRiskFactor[j] && !SimulateRiskFactor[j]) {
        ModelExit("Risk factors passed to Boadicea in RA_BoadiceaUseRiskFactor must be simulated in SimulateRiskFactor");
        break; // not reached
    }
}

The auto keyword is not required, one could use int (or size_t for the illuminati). It can make sense to use auto wherever it works, for code simplicity and generality. auto is a message from the coder to the C++ compiler which says: “You know what I mean, figure it out yourself”.

Here’s another example, where ONCOGENESIS_AGE_GROUP is a partition, and ONCOGENESIS_LAG is a range:

for (auto j : ONCOGENESIS_AGE_GROUP::indices()) {
    for (auto k : ONCOGENESIS_LAG::indices()) {
        double dValue = OncogenesisLags[j][k];
        SetTableValue("IM_OncogenesisLags.VALUE", dValue, j, k);
    }
}

For ranges, OpenM++ also includes the member function values(), which iterates the values of the range rather than the indices. Here’s an example where YEAR is a range:

for (auto year : YEAR::values()) {
    if (year == 1970) {
        theLog->logMsg("begin peak disco decade");
    }
}

A possible OpenM++ enhancement might be a member function for ranges which iterates indices and values as a std::pair, allowing one to access either inside the same range-based for, something like:

for (auto pr : YEAR::indices_values()) {
    auto j = pr.first();
    auto year = pr.second();
    …
}

Home

Getting Started

Model development in OpenM++

Using OpenM++

Model Development Topics

OpenM++ web-service: API and cloud setup

Using OpenM++ from Python and R

Docker

OpenM++ Development

OpenM++ Design, Roadmap and Status

OpenM++ web-service API

GET Model Metadata

GET Model Extras

GET Model Run results metadata

GET Model Workset metadata: set of input parameters

Read Parameters, Output Tables or Microdata values

GET Parameters, Output Tables or Microdata values

GET Parameters, Output Tables or Microdata as CSV

GET Modeling Task metadata and task run history

Update Model Profile: set of key-value options

Update Model Workset: set of input parameters

Update Model Runs

Update Modeling Tasks

Run Models: run models and monitor progress

Download model, model run results or input parameters

Upload model runs or worksets (input scenarios)

Download and upload user files

User: manage user settings

Model run jobs and service state

Administrative: manage web-service state

Clone this wiki locally