Ignore:
Timestamp:
Feb 3, 2011, 9:51:19 AM (15 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, Candidate_v1.7.0, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
1d5a871
Parents:
3f9eba
git-author:
Frederik Heber <heber@…> (01/03/11 14:01:22)
git-committer:
Frederik Heber <heber@…> (02/03/11 09:51:19)
Message:

Bigger rewrite of RandomNumbers ... due to cloning of prototypes.

  • in order to copy the prototypes and not use the original instance, we have implemented a new pattern called "Creator" that wraps a templated class in a creation interface class such that this abstract class can instaniate the particular types (see here http://stackoverflow.com/questions/3506026/c-clone-abstract-base-class-without-meddling-with-derived). This is also wrapped up in ..._Creator.hpp files.
  • meanwhile we also tried to have factories for Engine and Distribution but this failed due to boost::variate_operator<> having to know the particular types of engine and distribution. One could go forth with some cast's but this is very unclean and not what we want. ... Downside is that we can't set global options for engines or distributions as of now.
  • For the moment Engine- and DistributionFactory both have a prototype table, i.e. the same wrapped ones as above, but they are not used for the GeneratorFactory.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/RandomNumbers/RandomNumberGeneratorFactory.cpp

    r3f9eba rc9bc2b7  
    2525
    2626#include "TemplatePowerSetGenerator.hpp"
     27#include "EmptyPrototypeTable.hpp"
    2728
    28 #include "RandomNumberEngine_Encapsulation.hpp"
    29 #include "RandomNumberDistribution_Encapsulation.hpp"
     29#include "RandomNumberEngineFactory.hpp"
     30#include "RandomNumberDistributionFactory.hpp"
    3031#include "RandomNumberGenerator_Encapsulation.hpp"
    3132
    3233#include <boost/preprocessor/facilities/empty.hpp>
    3334#include <boost/preprocessor/punctuation/paren.hpp>
     35#include <boost/preprocessor/seq/for_each_product.hpp>
     36#include <boost/preprocessor/facilities/identity.hpp>
     37#include <boost/preprocessor/facilities/expand.hpp>
     38#include <boost/preprocessor/seq/seq.hpp>
     39
    3440
    3541#include "RandomNumberGeneratorFactory.hpp"
    36 #include "RandomNumberGeneratorFactory.def"
     42#include "RandomNumberDistributionFactory.def"
     43#include "RandomNumberEngineFactory.def"
    3744
    38 enum RandomNumberGeneratorFactory::Engine RandomNumberGeneratorFactory::engine = (enum RandomNumberGeneratorFactory::Engine) 0;
    39 enum RandomNumberGeneratorFactory::Distribution RandomNumberGeneratorFactory::distribution = (enum RandomNumberGeneratorFactory::Distribution) 0;
    40 RandomNumberGeneratorFactory::EngineMap RandomNumberGeneratorFactory::engines;
    41 RandomNumberGeneratorFactory::EngineNamesMap RandomNumberGeneratorFactory::engineNames;
    42 RandomNumberGeneratorFactory::DistributionMap RandomNumberGeneratorFactory::distributions;
    43 RandomNumberGeneratorFactory::DistributionNamesMap RandomNumberGeneratorFactory::distributionNames;
    44 RandomNumberGeneratorFactory::EngineTable RandomNumberGeneratorFactory::EnginePrototypeTable;
    45 RandomNumberGeneratorFactory::DistributionTable RandomNumberGeneratorFactory::DistributionPrototypeTable;
     45enum RandomNumberDistributionFactory::Distribution RandomNumberGeneratorFactory::distribution = (enum RandomNumberDistributionFactory::Distribution) 0;
     46enum RandomNumberEngineFactory::Engine RandomNumberGeneratorFactory::engine = (enum RandomNumberEngineFactory::Engine) 0;
    4647RandomNumberGeneratorFactory::EngineDistributionTable RandomNumberGeneratorFactory::GeneratorPrototypeTable;
    47 
    4848
    4949RandomNumberGeneratorFactory::RandomNumberGeneratorFactory()
    5050{
    51   // insert all known engines
    52 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq, engines)
    53 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
    54 #include BOOST_PP_LOCAL_ITERATE()
    55 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq_a, engines)
    56 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
    57 #include BOOST_PP_LOCAL_ITERATE()
    58   for (EngineMap::const_iterator iter = engines.begin();
    59       iter != engines.end();
    60       ++iter) {
    61     engineNames.insert(make_pair(iter->second, iter->first));
    62   }
    63 
    64         // insert all known distributions
    65 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, distribution_seq, distributions)
    66 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
    67 #include BOOST_PP_LOCAL_ITERATE()
    68   for (DistributionMap::const_iterator iter = distributions.begin();
    69       iter != distributions.end();
    70       ++iter) {
    71     distributionNames.insert(make_pair(iter->second, iter->first));
    72   }
    73 
    74         FillPrototypeTables();
     51        FillPrototypeTable();
    7552}
    76 
    77 /** Removes all pointers to instances from a table while free'ing memory.
    78  *
    79  * I.e. we assume class T to be a map of some key with its values pointers to
    80  * some classes that have to be free'd.
    81  *
    82  * \param _PrototypeTable table to empty
    83  */
    84 template <class T>
    85 void EmptyPrototypeTable(T &_PrototypeTable)
    86 {
    87   for (typename T::iterator iter = _PrototypeTable.begin();
    88       !_PrototypeTable.empty();
    89       iter = _PrototypeTable.begin()) {
    90     delete (iter->second);
    91     _PrototypeTable.erase(iter);
    92   }
    93   _PrototypeTable.clear();
    94 }
    95 
    96 
    9753
    9854RandomNumberGeneratorFactory::~RandomNumberGeneratorFactory()
     
    10056  // clear out factories map to allow boost::shared_ptr to do their work (i.e. to release mem)
    10157  // this is necessary as factories is a object
    102   engines.clear();
    103   engineNames.clear();
    104   EmptyPrototypeTable<EngineTable> (EnginePrototypeTable);
    105   distributions.clear();
    106   distributionNames.clear();
    107   EmptyPrototypeTable<DistributionTable> (DistributionPrototypeTable);
    10858  for (EngineDistributionTable::iterator iter = GeneratorPrototypeTable.begin();
    10959      !GeneratorPrototypeTable.empty();
    11060      iter = GeneratorPrototypeTable.begin()) {
    111     EmptyPrototypeTable< std::map<enum Distribution,RandomNumberGenerator *> > (iter->second);
     61    EmptyPrototypeTable< std::map<enum RandomNumberDistributionFactory::Distribution,IRandomNumberGenerator_Creator *> > (iter->second);
    11262    GeneratorPrototypeTable.erase(iter);
    11363  }
     
    11565}
    11666
    117 void RandomNumberGeneratorFactory::FillPrototypeTables()
     67void RandomNumberGeneratorFactory::FillPrototypeTable()
    11868{
    119   // fill EnginePrototypeTable
    120 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq, EnginePrototypeTable, new RandomNumberEngine_Encapsulation, boost::, )
    121 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
    122 #include BOOST_PP_LOCAL_ITERATE()
    123 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq_a, EnginePrototypeTable, new RandomNumberEngine_Encapsulation, boost::, )
    124 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
    125 #include BOOST_PP_LOCAL_ITERATE()
     69  // fill GeneratorPrototypeTable
     70#define SequenceElementizer(z,data) (data)
    12671
    127   // fill DistributionPrototypeTable
    128 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, distribution_seq, DistributionPrototypeTable, new RandomNumberDistribution_Encapsulation, boost::, <>)
    129 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
    130 #include BOOST_PP_LOCAL_ITERATE()
     72#define distributionengine_seqseq \
     73  BOOST_PP_SEQ_FOR_EACH_PRODUCT(SequenceElementizer, (engine_seq)(distribution_seq))
     74#define distributionengine_seqseq_a \
     75  BOOST_PP_SEQ_FOR_EACH_PRODUCT(SequenceElementizer, (engine_seq_a)(distribution_seq))
    13176
    132   // fill GeneratorPrototypeTable
    133 #define DoubleElementSequenceElementizer(z,data,elem) ((data)(elem))
     77#define suffixseq ()(<> > )
     78#define tableseq (*EnginePrototypeTable)(*DistributionPrototypeTable)
     79#define name_spaces_seq (RandomNumberEngineFactory::)(RandomNumberDistributionFactory::)
    13480
    135 #define seqseqiterate(z,n,seq) BOOST_PP_SEQ_FOR_EACH(DoubleElementSequenceElementizer, BOOST_PP_SEQ_ELEM(n,seq), distribution_seq)
    136 
    137 #define distributionengine_seqseq BOOST_PP_REPEAT( \
    138   BOOST_PP_SEQ_SIZE(engine_seq), seqseqiterate, engine_seq )
    139 
    140 #define distributionengine_seqseq_a BOOST_PP_REPEAT( \
    141   BOOST_PP_SEQ_SIZE(engine_seq_a), seqseqiterate, engine_seq_a )
    142 
    143 #define suffixseq ()(<>)
    144 #define tableseq (*EnginePrototypeTable)(*DistributionPrototypeTable)
     81#define size_tupels BOOST_PP_SEQ_SIZE(tableseq)
    14582
    14683#define TableItemPrinter(z,n,sequence) \
     84  [ \
     85  BOOST_PP_SEQ_ELEM(n,name_spaces_seq) \
     86  BOOST_PP_SEQ_ELEM(n,sequence) \
     87  ]
     88
     89#define TemplateItemPrinter(z,n,sequence) \
    14790  BOOST_PP_COMMA_IF(n) \
    14891  boost:: \
     
    15093  BOOST_PP_SEQ_ELEM(n,suffixseq)
    15194
    152 #define ParamItemPrinter(z,n,sequence) \
    153   BOOST_PP_COMMA_IF(n) \
    154   BOOST_PP_SEQ_ELEM(n,tableseq) \
    155   [ \
    156   BOOST_PP_SEQ_ELEM(n,sequence) \
    157   ]
     95#define ParamItemPrinter(z,n,sequence)
    15896
    159 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, distributionengine_seqseq, GeneratorPrototypeTable, new RandomNumberGenerator_Encapsulation, TableItemPrinter, ParamItemPrinter)
     97#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, size_tupels, distributionengine_seqseq, GeneratorPrototypeTable, TableItemPrinter, new RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation , TemplateItemPrinter, ParamItemPrinter)
    16098#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distributionengine_seqseq)-1 )
    16199#include BOOST_PP_LOCAL_ITERATE()
    162100
    163 #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, distributionengine_seqseq_a, GeneratorPrototypeTable, new RandomNumberGenerator_Encapsulation, TableItemPrinter, ParamItemPrinter)
     101#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, size_tupels, distributionengine_seqseq_a, GeneratorPrototypeTable, TableItemPrinter, new RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation , TemplateItemPrinter, ParamItemPrinter)
    164102#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distributionengine_seqseq_a)-1 )
    165103#include BOOST_PP_LOCAL_ITERATE()
    166104}
    167105
    168 RandomNumberGenerator& RandomNumberGeneratorFactory::makeRandomNumberGenerator() const
     106RandomNumberGenerator* RandomNumberGeneratorFactory::makeRandomNumberGenerator() const
    169107{
    170108  // Instantiate and return (implicitly creates a copy of the stored prototype)
    171   return *GeneratorPrototypeTable[engine][distribution];
     109  return (GeneratorPrototypeTable[engine][distribution]->create());
    172110}
    173111
    174 RandomNumberGenerator& RandomNumberGeneratorFactory::makeRandomNumberGenerator(std::string engine_type, std::string distribution_type) const
     112RandomNumberGenerator* RandomNumberGeneratorFactory::makeRandomNumberGenerator(
     113    std::string engine_type,
     114    std::string distribution_type
     115    ) const
    175116{
    176   enum Engine eng_type;
    177   enum Distribution dis_type;
     117  enum RandomNumberEngineFactory::Engine eng_type;
     118  enum RandomNumberDistributionFactory::Distribution dis_type;
    178119
    179120  // Instantiate and return (implicitly creates a copy of the stored prototype)
    180121  if (!engine_type.empty()) {
    181     ASSERT(engines.count(engine_type) != 0,
    182       "RandomNumberGeneratorFactory::makeRandomNumberGenerator() - Selected engine "+engine_type+"is not registered.");
    183     eng_type = engines[engine_type];
     122    eng_type = RandomNumberEngineFactory::getInstance().getEnum(engine_type);
    184123  } else
    185124    eng_type = engine;
    186125  if (!distribution_type.empty()) {
    187     ASSERT(distributions.count(distribution_type) != 0,
    188         "RandomNumberGeneratorFactory::makeRandomNumberGenerator() - Selected distribution "+distribution_type+"is not registered.");
    189     dis_type = distributions[distribution_type];
     126    dis_type = RandomNumberDistributionFactory::getInstance().getEnum(distribution_type);
    190127  } else
    191128    dis_type = distribution;
    192   return *GeneratorPrototypeTable[ eng_type ][ dis_type ];
     129  return (GeneratorPrototypeTable[ eng_type ][ dis_type ]->create());
    193130}
    194131
    195132void RandomNumberGeneratorFactory::setEngine(std::string engine_type)
    196133{
    197   ASSERT(engines.count(engine_type) != 0,"Selected engine "+engine_type+"is not registered.");
    198   engine = engines[engine_type];
     134  engine = RandomNumberEngineFactory::getInstance().getEnum(engine_type);
    199135}
    200136
    201 const std::string &RandomNumberGeneratorFactory::getEngine() const
     137const std::string &RandomNumberGeneratorFactory::getEngineName() const
    202138{
    203   return engineNames[engine];
     139  return RandomNumberEngineFactory::getInstance().getName(engine);
    204140}
    205141
    206142void RandomNumberGeneratorFactory::setDistribution(std::string distribution_type)
    207143{
    208   ASSERT(distributions.count(distribution_type) != 0 ,"Selected distribution "+distribution_type+"is not registered.");
    209   distribution = distributions[distribution_type];
     144  distribution = RandomNumberDistributionFactory::getInstance().getEnum(distribution_type);
    210145}
    211146
    212 const std::string &RandomNumberGeneratorFactory::getDistribution() const
     147const std::string &RandomNumberGeneratorFactory::getDistributionName() const
    213148{
    214   return distributionNames[distribution];
     149  return RandomNumberDistributionFactory::getInstance().getName(distribution);
    215150}
    216151
    217152CONSTRUCT_SINGLETON(RandomNumberGeneratorFactory)
    218153
    219 #include "RandomNumberGeneratorFactory.undef"
     154#include "RandomNumberDistributionFactory.undef"
     155#include "RandomNumberEngineFactory.undef"
    220156
Note: See TracChangeset for help on using the changeset viewer.