private static Dimension getPolicyDimension() {
.Builder builder = FunctionalDimensionData.builder();//
FunctionalDimensionData
List<Double> schoolClosingInfectionRates = new ArrayList<>();
.add(0.05);
schoolClosingInfectionRates.add(0.10);
schoolClosingInfectionRates.add(0.15);
schoolClosingInfectionRates.add(0.20);
schoolClosingInfectionRates
for (int i = 0; i < schoolClosingInfectionRates.size(); i++) {
Double schoolClosingInfectionRate = schoolClosingInfectionRates.get(i);
.addValue("Level_" + i, (context) -> {
builder.Builder pluginDataBuilder = context
PolicyPluginData.getPluginDataBuilder(PolicyPluginData.Builder.class);
.setSchoolClosingInfectionRate(schoolClosingInfectionRate);
pluginDataBuilder
ArrayList<String> result = new ArrayList<>();
.add(Double.toString(schoolClosingInfectionRate));
result
return result;
});//
}
.addMetaDatum("school_closing_infection_rate");//
builder
= builder.build();
FunctionalDimensionData functionalDimensionData return new FunctionalDimension(functionalDimensionData);
}
3 Stochastics Plugin
The stochastics plugin provides for the management of random number generators. It contains a default random number generator (RNG) as well as any number of RNGs associated with identifiers.
3.1 Plugin Data Initialization
The plugin is initialized using a StochasticsPluginData object that collects starting seed values for the default RNG as well as any number of RNG identifiers. These identifiers are implemented via the RandomGeneratorId interface which only specifies that such an identifier have a non-null, non-empty and stable implementation of the Object.toString() method.
All RNGs in GCM are implemented using the org.apache.commons.math3.random.Well44497b random number generator. GCM introduces the class Well.java that extends the Well44497b to allow for the serialization of its internal state. The data that supports this serialization is contained in the WellState.java class that uses a standard builder pattern. Serialization concerns are beyond the scope of this chapter, so all WellState objects will be seeded with long values only.
3.2 Plugin Behavior
The plugin adds a single data manager to the simulation as an instance of the StochasticsDataManager that is initialized with the StochasticsPluginData.
3.3 Data Manager
The data manager provides access to its RNGs via various getter methods.
3.4 (Lesson 11) Example 11A
Our first example lesson uses the disease, model and policy plugins again. This time we will have the single ModelActor schedule three random times to set the R0 value to a random number between 1 and 2. Four scenarios will result from a policy based dimension that alters the school closing infection rates, which will not influence the ModelActor.
public static void main(String[] args) {
= getDiseasePluginData();
DiseasePluginData diseasePluginData = DiseasePlugin.getDiseasePlugin(diseasePluginData);
Plugin diseasePlugin
= getPolicyPluginData();
PolicyPluginData policyPluginData = PolicyPlugin.getPolicyPlugin(policyPluginData);
Plugin policyPlugin
= ModelPlugin.getModelPlugin();
Plugin modelPlugin
= WellState.builder().setSeed(0).build();
WellState wellState = StochasticsPluginData.builder().setMainRNGState(wellState)
StochasticsPluginData stochasticsPluginData .build();
= StochasticsPlugin.getStochasticsPlugin(stochasticsPluginData);
Plugin stochasticsPlugin
Dimension policyDimension = getPolicyDimension();
= ExperimentParameterData.builder()//
ExperimentParameterData experimentParameterData .setThreadCount(4)//
.setHaltOnException(true)//
.build();
.builder()//
Experiment.addPlugin(stochasticsPlugin)//
.addPlugin(diseasePlugin)//
.addPlugin(modelPlugin)//
.addPlugin(policyPlugin)//
.addDimension(policyDimension)//
.addExperimentContextConsumer(new SimpleOutputConsumer())//
.setExperimentParameterData(experimentParameterData)//
.build()//
.execute();
}
The stochastics plugin is initialized with a seed value of zero and that seed will be used in each scenario as the initial seeding for the default random generator. Thus we expect that each scenario will have identical output.
scenario | school_closing_infection_rate | output |
---|---|---|
1 | 0.10 | setting R0 to 1.432233562051883 at time = 3.252869296309885 |
1 | 0.10 | setting R0 to 1.1828080336720215 at time = 4.115633147309184 |
0 | 0.05 | setting R0 to 1.432233562051883 at time = 3.252869296309885 |
3 | 0.20 | setting R0 to 1.432233562051883 at time = 3.252869296309885 |
1 | 0.10 | setting R0 to 1.895526664357549 at time = 8.614888683848772 |
0 | 0.05 | setting R0 to 1.1828080336720215 at time = 4.115633147309184 |
2 | 0.15 | setting R0 to 1.432233562051883 at time = 3.252869296309885 |
3 | 0.20 | setting R0 to 1.1828080336720215 at time = 4.115633147309184 |
0 | 0.05 | setting R0 to 1.895526664357549 at time = 8.614888683848772 |
2 | 0.15 | setting R0 to 1.1828080336720215 at time = 4.115633147309184 |
3 | 0.20 | setting R0 to 1.895526664357549 at time = 8.614888683848772 |
2 | 0.15 | setting R0 to 1.895526664357549 at time = 8.614888683848772 |
3.5 Example 11B
Our next example lesson adds a dimension used to alter the initial seed value of the stochastics plugin data to one of three values. Combined with the policy dimension, this will result in 12 scenarios.
private static Dimension getStochasticsDimension(long seed) {
.Builder builder = FunctionalDimensionData.builder();//
FunctionalDimensionData
Random random = new Random(seed);
List<Long> seedValues = new ArrayList<>();
for (int i = 0; i < 3; i++) {
.add(random.nextLong());
seedValues}
.range(0, seedValues.size()).forEach((i) -> {
IntStream.addValue("Level_" + i, (context) -> {
builder.Builder stochasticsPluginDataBuilder = context
StochasticsPluginData.getPluginDataBuilder(StochasticsPluginData.Builder.class);
long seedValue = seedValues.get(i);
= WellState.builder().setSeed(seedValue).build();
WellState wellState .setMainRNGState(wellState);
stochasticsPluginDataBuilder
ArrayList<String> result = new ArrayList<>();
.add(Integer.toString(i));
result.add(Long.toString(seedValue) + "L");
result
return result;
});
});
.addMetaDatum("seed index");//
builder.addMetaDatum("seed value");//
builder
= builder.build();
FunctionalDimensionData functionalDimensionData return new FunctionalDimension(functionalDimensionData);
}
public static void main(String[] args) {
= getDiseasePluginData();
DiseasePluginData diseasePluginData = DiseasePlugin.getDiseasePlugin(diseasePluginData);
Plugin diseasePlugin
= getPolicyPluginData();
PolicyPluginData policyPluginData = PolicyPlugin.getPolicyPlugin(policyPluginData);
Plugin policyPlugin
= ModelPlugin.getModelPlugin();
Plugin modelPlugin = WellState.builder().setSeed(0).build();
WellState wellState = StochasticsPluginData.builder().setMainRNGState(wellState)
StochasticsPluginData stochasticsPluginData .build();
= StochasticsPlugin.getStochasticsPlugin(stochasticsPluginData);
Plugin stochasticsPlugin
Dimension policyDimension = getPolicyDimension();
Dimension stochasticsDimension = getStochasticsDimension(539847398756272L);
= ExperimentParameterData.builder()//
ExperimentParameterData experimentParameterData .setThreadCount(4)//
.build();
.builder()//
Experiment.addPlugin(stochasticsPlugin)//
.addPlugin(diseasePlugin)//
.addPlugin(modelPlugin)//
.addPlugin(policyPlugin)//
.addDimension(policyDimension)//
.addDimension(stochasticsDimension)//
.addExperimentContextConsumer(new SimpleOutputConsumer())//
.setExperimentParameterData(experimentParameterData)//
.build()//
.execute();
}
The resulting output shows the varying random number generation:
scenario | school_closing_infection_rate | seed_index | seed_value | output |
---|---|---|---|---|
3 | 0.2 | 0 | 1768604912325913878L | setting R0 to 1.4595120508977955 at time = 5.672294645832067 |
2 | 0.15 | 0 | 1768604912325913878L | setting R0 to 1.4595120508977955 at time = 5.672294645832067 |
3 | 0.2 | 0 | 1768604912325913878L | setting R0 to 1.672857576347001 at time = 9.396161237311702 |
1 | 0.1 | 0 | 1768604912325913878L | setting R0 to 1.4595120508977955 at time = 5.672294645832067 |
0 | 0.05 | 0 | 1768604912325913878L | setting R0 to 1.4595120508977955 at time = 5.672294645832067 |
3 | 0.2 | 0 | 1768604912325913878L | setting R0 to 1.4552243930124602 at time = 9.545450999459224 |
1 | 0.1 | 0 | 1768604912325913878L | setting R0 to 1.672857576347001 at time = 9.396161237311702 |
2 | 0.15 | 0 | 1768604912325913878L | setting R0 to 1.672857576347001 at time = 9.396161237311702 |
0 | 0.05 | 0 | 1768604912325913878L | setting R0 to 1.672857576347001 at time = 9.396161237311702 |
1 | 0.1 | 0 | 1768604912325913878L | setting R0 to 1.4552243930124602 at time = 9.545450999459224 |
2 | 0.15 | 0 | 1768604912325913878L | setting R0 to 1.4552243930124602 at time = 9.545450999459224 |
0 | 0.05 | 0 | 1768604912325913878L | setting R0 to 1.4552243930124602 at time = 9.545450999459224 |
4 | 0.05 | 1 | 2407662077113051075L | setting R0 to 1.7124977513361193 at time = 1.878219018807409 |
4 | 0.05 | 1 | 2407662077113051075L | setting R0 to 1.4297609713254456 at time = 2.4215934269433106 |
4 | 0.05 | 1 | 2407662077113051075L | setting R0 to 1.5167619787625548 at time = 5.992476899450338 |
5 | 0.1 | 1 | 2407662077113051075L | setting R0 to 1.7124977513361193 at time = 1.878219018807409 |
5 | 0.1 | 1 | 2407662077113051075L | setting R0 to 1.4297609713254456 at time = 2.4215934269433106 |
5 | 0.1 | 1 | 2407662077113051075L | setting R0 to 1.5167619787625548 at time = 5.992476899450338 |
6 | 0.15 | 1 | 2407662077113051075L | setting R0 to 1.7124977513361193 at time = 1.878219018807409 |
6 | 0.15 | 1 | 2407662077113051075L | setting R0 to 1.4297609713254456 at time = 2.4215934269433106 |
6 | 0.15 | 1 | 2407662077113051075L | setting R0 to 1.5167619787625548 at time = 5.992476899450338 |
7 | 0.2 | 1 | 2407662077113051075L | setting R0 to 1.7124977513361193 at time = 1.878219018807409 |
7 | 0.2 | 1 | 2407662077113051075L | setting R0 to 1.4297609713254456 at time = 2.4215934269433106 |
7 | 0.2 | 1 | 2407662077113051075L | setting R0 to 1.5167619787625548 at time = 5.992476899450338 |
9 | 0.1 | 2 | -2698580492431892402L | setting R0 to 1.9665140789775497 at time = 4.990978097055602 |
9 | 0.1 | 2 | -2698580492431892402L | setting R0 to 1.9525439902956225 at time = 6.227836574620975 |
9 | 0.1 | 2 | -2698580492431892402L | setting R0 to 1.8972135699711736 at time = 7.764180353240558 |
8 | 0.05 | 2 | -2698580492431892402L | setting R0 to 1.9665140789775497 at time = 4.990978097055602 |
8 | 0.05 | 2 | -2698580492431892402L | setting R0 to 1.9525439902956225 at time = 6.227836574620975 |
8 | 0.05 | 2 | -2698580492431892402L | setting R0 to 1.8972135699711736 at time = 7.764180353240558 |
10 | 0.15 | 2 | -2698580492431892402L | setting R0 to 1.9665140789775497 at time = 4.990978097055602 |
10 | 0.15 | 2 | -2698580492431892402L | setting R0 to 1.9525439902956225 at time = 6.227836574620975 |
10 | 0.15 | 2 | -2698580492431892402L | setting R0 to 1.8972135699711736 at time = 7.764180353240558 |
11 | 0.2 | 2 | -2698580492431892402L | setting R0 to 1.9665140789775497 at time = 4.990978097055602 |
11 | 0.2 | 2 | -2698580492431892402L | setting R0 to 1.9525439902956225 at time = 6.227836574620975 |
11 | 0.2 | 2 | -2698580492431892402L | setting R0 to 1.8972135699711736 at time = 7.764180353240558 |