This is a basic question about what options are available for defining the scope of some parameters. I’d particularly like to have a sense of the tradeoffs in speed, memory, code clarity, ease of implementation, and code safety. My programming experience is clearly modest, and I have little formal training. I suspect one or two options will be obvious ‘right’ answers.
I have a simulation encapsulated in its own class called Simulation. Some of the parameters used in the simulation are read in from a set of files when the Simulation is initialized, and these parameters are currently stored in a few two-dimensional arrays. These arrays, demPMFs and serotypePars, are currently both private members of Simulation:
// Simulation.h
class Simulation
{
Simulation( int simID );
~Simulation();
public:
// ...[code snipped]...
private:
double demPMFs[ NUM_SOCIODEM_FILES ][ INIT_NUM_AGE_CATS ];
double serotypePars[ NUM_EPID_FILES ][ INIT_NUM_STYPES ];
// ...[code snipped]...
};
The simulations mostly involve modifying instances of class Host. Member functions of class Host frequently need access to parameter values stored in serotypePars. Previously, I had all the data now in serotypePars stored as const numerics interpreted at compile time, but now that these parameters are read from a file, things are a little more complicated (for me, anyway).
What is the fastest and safest way for me to grant all members of class Host ‘read-only’ access to serotypePars? Fastest deserves priority: There are no other classes in my program, so global is a (crude) potential solution; all simulations will run from identical parameter sets. I’m reluctant to pass the array to individual functions that act on Host members, since there are probably a dozen and some are quite nested. (For example, I have intermediate wrapper structs that cannot take two-dimensional arrays as arguments, and I’m unsure what syntactical work-arounds there might be. I would like to stick with arrays for speed purposes, and my non-uniform prng generators all expect arrays.)
I would greatly appreciate knowing what would require the least modification of the existing code while not introducing huge dangers.
Thanks for any insight you can offer.
A related challenge I have is not knowing exactly how to access Simulation members from the Host class, unless these members are passed to the Host function. Here’s basically what happens:
// main.cpp
int main() {
for ( int s = 1; s < NUM_SIMS+1; s++ ) {
Simulation thisSim(s);
thisSim.runDemSim();
thisSim.runEpidSim();
// ... code snipped ...
}
}
Function Simulation::runDemSim() and Simulation::runEpidSim() create, modify, and destroy many instances of class Host. Pointers to these instances are stored in a Boost MultiIndex container, which is where the intermediate wrapper functions come in. One of the many modifications involves ultimately calling Host::calcRecovery, which needs access to serotypePars:
// Host.cpp
// ... code snipped ...
double Host::calcRecovery( int s, double currentTime, double infectionTime, boost::mt19937& rng ) {
// ...code snipped...
effectiveMean = serotypePars[ MEAN_DURATION_INDEX ][ s ] * currentInfections * pastInfections;
double rt = rgamma( effectiveMean, serotypePars[ VAR_DURATION_INDEX ][ s ], rng );
}
(Apologies if TMI.) Simply declaring serotypePars public in the Simulation class definition resulted in a “serotypePars was not declared in this scope” error in Host.cpp.
Solution summary
GMan’s suggestion that I package all the simulation parameters in a private class, e.g., SimulationPars, seems like the most elegant and extensible route. An instance of SimulationPars could belong in every Simulation, and a pointer to SimulationPars can be passed to the constructor of every Host within a given Simulation. Thanks to everyone for the thoughtful discussions.
This is normal: