Changeset 7c1091


Ignore:
Timestamp:
Jul 8, 2013, 2:22:03 PM (11 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, 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:
baccf6
Parents:
c5e63a
git-author:
Frederik Heber <heber@…> (05/09/13 19:25:45)
git-committer:
Frederik Heber <heber@…> (07/08/13 14:22:03)
Message:

Extended CompoundPotential for multiple occurences of argument bunches.

  • added HomologyGraph::hasGreaterEqualTimesAtomicNumber() has model might have multiple matching arguments within a single fragment.
  • i.e. when there is more than one argument bunch for a given model. Hence, we check the stream whether upcoming arguments match current and next model. Note however that models are not necessarily sorted by particle_types' size. Hence, we must trick a little and need a specific map comparator.
Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Homology/HomologyGraph.cpp

    rc5e63a r7c1091  
    114114}
    115115
     116bool HomologyGraph::hasGreaterEqualTimesAtomicNumber(const size_t _number, const size_t _times) const
     117{
     118  size_t count = 0;
     119  for (nodes_t::const_iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
     120    if ((iter->first).getAtomicNumber() == _number)
     121      count += iter->second;
     122  }
     123  return (count >= _times);
     124}
     125
    116126std::ostream& operator<<(std::ostream& ost, const HomologyGraph &graph)
    117127{
  • src/Fragmentation/Homology/HomologyGraph.hpp

    rc5e63a r7c1091  
    129129  bool hasTimesAtomicNumber(const size_t _number, const size_t _times) const;
    130130
     131  /** Checks whether this graph has \b greater equal \a _times nodes with \a _number
     132   * atomic number.
     133   *
     134   * @param _number desired atomic number
     135   * @param _times number this must occur
     136   * @return true - graph has greater equal \a _times nodes with \a _number, false - else
     137   */
     138  bool hasGreaterEqualTimesAtomicNumber(const size_t _number, const size_t _times) const;
     139
    131140  /** Assignment operator for class HomologyGraph.
    132141   *
  • src/Potentials/CompoundPotential.cpp

    rc5e63a r7c1091  
    8484    Extractors::elementcounts_t::const_iterator countiter = counts_per_charge.begin();
    8585    for (; countiter != counts_per_charge.end(); ++countiter)
    86       if (!graph.hasTimesAtomicNumber(
     86      if (!graph.hasGreaterEqualTimesAtomicNumber(
    8787          static_cast<size_t>(countiter->first),
    8888          static_cast<size_t>(countiter->second))
     
    115115  parameters_t::const_iterator iter = _params.begin();
    116116  BOOST_FOREACH( FunctionModel* model, models) {
    117     const parameters_t &model_params = model->getParameters();
    118     const size_t model_dim = model_params.size();
     117    const size_t model_dim = model->getParameterDimension();
    119118    if (dim > 0) {
    120119      parameters_t subparams;
     
    131130    }
    132131  }
     132
     133#ifndef NDEBUG
     134  parameters_t check_params(getParameters());
     135  check_params.resize(_params.size()); // truncate to same size
     136  ASSERT( check_params == _params,
     137      "CompoundPotential::setParameters() - failed, mismatch in to be set "
     138      +toString(_params)+" and set "+toString(check_params)+" params.");
     139#endif
    133140}
    134141
     
    140147  BOOST_FOREACH( const FunctionModel* model, models) {
    141148    const CompoundPotential::parameters_t &params = model->getParameters();
    142     std::copy(params.begin(), params.end(), iter);
    143149    ASSERT( iter != parameters.end(),
    144150        "CompoundPotential::getParameters() - iter already at end.");
    145   }
     151    iter = std::copy(params.begin(), params.end(), iter);
     152  }
     153  ASSERT( iter == parameters.end(),
     154      "CompoundPotential::getParameters() - iter not at end.");
    146155  return parameters;
    147156}
     
    169178}
    170179
    171 std::vector<CompoundPotential::arguments_t> CompoundPotential::splitUpArgumentsByModels(
     180bool CompoundPotential::areValidArguments(
     181    const SerializablePotential::ParticleTypes_t &_types,
     182    const arguments_t &args) const
     183{
     184  // /this function does much the same as Extractors::reorderArgumentsByParticleTypes()
     185  typedef std::list< argument_t > ListArguments_t;
     186  ListArguments_t availableList(args.begin(), args.end());
     187
     188  /// basically, we have two choose any two pairs out of types but only those
     189  /// where the first is less than the letter. Hence, we start the second
     190  /// iterator at the current position of the first one and skip the equal case.
     191  for (SerializablePotential::ParticleTypes_t::const_iterator firstiter = _types.begin();
     192      firstiter != _types.end();
     193      ++firstiter) {
     194    for (SerializablePotential::ParticleTypes_t::const_iterator seconditer = firstiter;
     195        seconditer != _types.end();
     196        ++seconditer) {
     197      if (seconditer == firstiter)
     198        continue;
     199
     200      // search the right one in _args (we might allow switching places of
     201      // firstiter and seconditer, as distance is symmetric).
     202      // we remove the matching argument to make sure we don't pick it twice
     203      ListArguments_t::iterator iter = availableList.begin();
     204      for (;iter != availableList.end(); ++iter) {
     205        LOG(3, "DEBUG: Current args is " << *iter << ".");
     206        if ((iter->types.first == *firstiter)
     207              && (iter->types.second == *seconditer)) {
     208          availableList.erase(iter);
     209          break;
     210        }
     211        else if ((iter->types.first == *seconditer)
     212              && (iter->types.second == *firstiter)) {
     213          availableList.erase(iter);
     214          break;
     215        }
     216      }
     217      if ( iter == availableList.end())
     218        return false;
     219    }
     220  }
     221
     222  return true;
     223}
     224
     225CompoundPotential::arguments_by_model_t CompoundPotential::splitUpArgumentsByModels(
    172226    const arguments_t &arguments) const
    173227{
    174   std::vector<arguments_t> partial_args(models.size());
    175   std::vector<arguments_t>::iterator partialiter = partial_args.begin();
     228  arguments_by_model_t partial_args;
    176229  arguments_t::const_iterator argiter = arguments.begin();
    177   BOOST_FOREACH( const SerializablePotential::ParticleTypes_t &types, particletypes_per_model) {
    178     // we always expect N(N-1)/2 distances for N particle types
    179     arguments_t::const_iterator enditer = argiter+(types.size()*(types.size()-1)/2);
    180     ASSERT( argiter != arguments.end(),
    181         "CompoundPotential::splitUpArgumentsByModels() - incorrect number of arguments.");
    182     std::copy(argiter, enditer, std::back_inserter(*partialiter++));
    183     argiter = enditer;
    184   }
    185   ASSERT( argiter == arguments.end(),
    186       "CompoundPotential::splitUpArgumentsByModels() - incorrect number of arguments.");
     230  particletypes_per_model_t::const_iterator typesiter = particletypes_per_model.begin();
     231  models_t::const_iterator modeliter = models.begin();
     232
     233  // add constant model (which is always first model) with empty args if present
     234  if (typesiter->empty()) {
     235    partial_args.push_back(
     236        std::pair<FunctionModel *, arguments_t>(*modeliter, arguments_t())
     237        );
     238    ++modeliter;
     239    ++typesiter;
     240  }
     241  // then check other models
     242  while (argiter != arguments.end()) {
     243    if (typesiter+1 != particletypes_per_model.end()) {
     244      // check whether next argument bunch is for same model or different one
     245      // we extract both partial_arguments, if the latter fits, we take the latter.
     246      const SerializablePotential::ParticleTypes_t &types = *typesiter;
     247      const SerializablePotential::ParticleTypes_t &nexttypes = *(typesiter+1);
     248
     249      // we always expect N(N-1)/2 distances for N particle types
     250      arguments_t::const_iterator enditer = argiter+(types.size()*(types.size()-1)/2);
     251      arguments_t::const_iterator nextenditer = argiter+(nexttypes.size()*(nexttypes.size()-1)/2);
     252      arguments_t args(argiter, enditer);
     253      arguments_t nextargs(argiter, nextenditer);
     254      if (types.size() < nexttypes.size()) {
     255        if (areValidArguments(nexttypes, nextargs)) {
     256          // latter matches, increment
     257          ++typesiter;
     258          partial_args.push_back(
     259              std::make_pair(*(++modeliter), arguments_t(argiter, nextenditer))
     260              );
     261          argiter = nextenditer;
     262        } else if (areValidArguments(types, args)) {
     263          // only former matches, don't increment
     264          partial_args.push_back(
     265              std::make_pair(*modeliter, arguments_t(argiter, enditer))
     266              );
     267          argiter = enditer;
     268        } else
     269          ASSERT(0,
     270              "CompoundPotential::splitUpArgumentsByModels() - neither type matches its argument bunch.");
     271      } else {
     272        if (areValidArguments(types, args)) {
     273          // only former matches, don't increment
     274          partial_args.push_back(
     275              std::make_pair(*modeliter, arguments_t(argiter, enditer))
     276              );
     277          argiter = enditer;
     278        } else if (areValidArguments(nexttypes, nextargs)) {
     279          // latter matches, increment
     280          ++typesiter;
     281          partial_args.push_back(
     282              std::make_pair(*(++modeliter), arguments_t(argiter, nextenditer))
     283              );
     284          argiter = nextenditer;
     285        }
     286      }
     287    } else {
     288      const SerializablePotential::ParticleTypes_t &types = *typesiter;
     289      // we always expect N(N-1)/2 distances for N particle types
     290      arguments_t::const_iterator enditer = argiter+(types.size()*(types.size()-1)/2);
     291      partial_args.push_back(
     292          std::make_pair(*modeliter, arguments_t(argiter, enditer))
     293          );
     294      argiter = enditer;
     295    }
     296  }
     297
    187298  return partial_args;
    188299}
     
    190301CompoundPotential::results_t CompoundPotential::operator()(const arguments_t &arguments) const
    191302{
    192   // first, we have to split up the given arguments
    193   std::vector<arguments_t> partial_args =
     303  /// first, we have to split up the given arguments
     304  arguments_by_model_t partial_args =
    194305      splitUpArgumentsByModels(arguments);
    195   // then, with each bunch of arguments, we call the specific model
     306  // print split up argument list for debugging
     307  if (DoLog(4)) {
     308    LOG(4, "Arguments by model are: ");
     309    for(arguments_by_model_t::const_iterator iter = partial_args.begin();
     310        iter != partial_args.end(); ++iter) {
     311      LOG(4, "\tModel with " << iter->first->getParameterDimension()
     312          << " parameters " << iter->first->getParameters()
     313          << " and arguments: " << iter->second);
     314    }
     315  }
     316
     317  /// then, with each bunch of arguments, we call the specific model
    196318  results_t results(1,0.);
    197   std::vector<results_t> partial_results(models.size());
    198   std::transform(
    199       models.begin(), models.end(),
    200       partial_args.begin(),
    201       partial_results.begin(),
    202       boost::bind(&FunctionModel::operator(), _1, _2)
    203   );
    204   std::for_each(partial_results.begin(), partial_results.end(),
    205       std::cout << (boost::lambda::_1)[0] << "\t");
     319  std::vector<results_t> partial_results;
     320  for(arguments_by_model_t::const_iterator iter = partial_args.begin();
     321      iter != partial_args.end(); ++iter) {
     322    partial_results.push_back(
     323        (*iter->first)(iter->second)
     324    );
     325  }
     326  // print partial results for debugging
     327  if (DoLog(4)) {
     328    std::stringstream output;
     329    output << "Partial results are: ";
     330    std::for_each(partial_results.begin(), partial_results.end(),
     331        output << (boost::lambda::_1)[0] << "\t");
     332    LOG(4, output.str());
     333  }
     334
     335  /// Finally, sum up all results and return
    206336  std::for_each(partial_results.begin(), partial_results.end(),
    207337      results[0] += (boost::lambda::_1)[0]);
     
    212342{
    213343  // first, we have to split up the given arguments
    214   std::vector<arguments_t> partial_args =
     344  arguments_by_model_t partial_args =
    215345      splitUpArgumentsByModels(arguments);
    216346  // then, with each bunch of arguments, we call the specific model
     
    223353  std::partial_sum(dimensions.begin(), dimensions.end(), dimensions.begin());
    224354
    225   // look for value not less than index
     355  // look for first value greater than index
    226356  std::vector<size_t>::const_iterator iter =
    227       std::lower_bound(dimensions.begin(), dimensions.end(), index);
     357      std::upper_bound(dimensions.begin(), dimensions.end(), index);
    228358
    229359  // step forward to same model
     
    231361  std::advance(modeliter,
    232362      std::distance(const_cast<const std::vector<size_t> &>(dimensions).begin(), iter) );
    233   std::vector<arguments_t>::const_iterator argiter = partial_args.begin();
    234   std::advance(argiter,
    235       std::distance(const_cast<const std::vector<size_t> &>(dimensions).begin(), iter) );
    236 
    237   // evaluate with correct relative index and return
    238   const size_t indexbase = (iter == dimensions.begin()) ? 0 : *(--iter);
    239   CompoundPotential::results_t results =
    240       (*modeliter)->parameter_derivative(*argiter, index-indexbase);
    241   return results;
     363
     364  CompoundPotential::results_t returnresults;
     365  for(arguments_by_model_t::const_iterator argiter = partial_args.begin();
     366      argiter != partial_args.end(); ++argiter) {
     367    const FunctionModel *model = argiter->first;
     368
     369    // for every matching model evaluate
     370    if (model == *modeliter) {
     371      // evaluate with correct relative index and return
     372      const size_t indexbase = (iter == dimensions.begin()) ? 0 : *(iter-1);
     373      CompoundPotential::results_t results =
     374          model->parameter_derivative(argiter->second, index-indexbase);
     375
     376      // either set results or add
     377      if (returnresults.empty())
     378        returnresults = results;
     379      else
     380        std::transform(
     381            results.begin(), results.end(),
     382            returnresults.begin(),
     383            returnresults.begin(),
     384            std::plus<FunctionModel::result_t>());
     385    }
     386  }
     387
     388  return returnresults;
    242389}
    243390
     
    258405  BOOST_FOREACH( FunctionModel* model, models) {
    259406    const CompoundPotential::parameters_t params = model->getLowerBoxConstraints();
    260     std::copy(params.begin(), params.end(), iter);
    261407    ASSERT( iter != constraints.end(),
    262         "CompoundPotential::getParameters() - iter already at end.");
    263   }
     408        "CompoundPotential::getLowerBoxConstraints() - iter already at end.");
     409    iter = std::copy(params.begin(), params.end(), iter);
     410  }
     411  ASSERT( iter == constraints.end(),
     412      "CompoundPotential::getLowerBoxConstraints() - iter not at end.");
    264413  return constraints;
    265414}
     
    272421  BOOST_FOREACH( FunctionModel* model, models) {
    273422    const CompoundPotential::parameters_t params = model->getUpperBoxConstraints();
    274     std::copy(params.begin(), params.end(), iter);
    275423    ASSERT( iter != constraints.end(),
    276         "CompoundPotential::getParameters() - iter already at end.");
    277   }
     424        "CompoundPotential::getUpperBoxConstraints() - iter already at end.");
     425    iter = std::copy(params.begin(), params.end(), iter);
     426  }
     427  ASSERT( iter == constraints.end(),
     428      "CompoundPotential::getUpperBoxConstraints() - iter not at end.");
    278429  return constraints;
    279430}
  • src/Potentials/CompoundPotential.hpp

    rc5e63a r7c1091  
    132132
    133133private:
     134  //!> typedef for split up arguments, each associated to a model
     135  typedef std::vector< std::pair<FunctionModel *, arguments_t> > arguments_by_model_t;
     136
    134137  /** Helper function to split up concatenated arguments for operator() calls.
    135138   *
    136139   * \param arguments arguments to split up
    137    * \return vector of partial arguments
     140   * \return vector of partial arguments with associated model
    138141   */
    139   std::vector<arguments_t> splitUpArgumentsByModels(const arguments_t &arguments) const;
     142  arguments_by_model_t splitUpArgumentsByModels(const arguments_t &arguments) const;
     143
     144  /** Helper function to check whether split up argument bunch matches with types.
     145   *
     146   * \param types types of potential to check whether args match
     147   * \param args vector of argument whose types to check
     148   */
     149  bool areValidArguments(
     150      const SerializablePotential::ParticleTypes_t &types,
     151      const arguments_t &args) const;
    140152
    141153private:
  • src/Potentials/unittests/CompoundPotentialUnitTest.cpp

    rc5e63a r7c1091  
    9292  }
    9393
    94   // create graph
     94  // create graph (i.e. this simulates a water molecule)
    9595  {
    9696    // add nodes
    9797    nodes +=
    98         std::make_pair(FragmentNode(0,1),1),
    99         std::make_pair(FragmentNode(1,1),1);
     98        std::make_pair(FragmentNode(0,2),1),
     99        std::make_pair(FragmentNode(1,1),2);
    100100
    101101    // add edges
    102102    edges +=
    103         std::make_pair(FragmentEdge(0,1),1);
     103        std::make_pair(FragmentEdge(0,1),2);
    104104
    105105    // construct graph
     
    125125      4.46595;
    126126  output +=
    127       -78.5211,
    128       -78.8049,
    129       -78.935,
    130       -78.9822,
    131       -78.9867,
    132       -78.971,
    133       -78.9475,
    134       -78.9225,
    135       -78.899,
    136       -78.8784;
     127      2.*0.467226+d,
     128      2.*0.183388+d,
     129      2.*0.0532649+d,
     130      2.*0.00609808+d,
     131      2.*0.00160056+d,
     132      2.*0.0172506+d,
     133      2.*0.0407952+d,
     134      2.*0.0658475+d,
     135      2.*0.0893157+d,
     136      2.*0.109914+d;
    137137
    138138  CPPUNIT_ASSERT_EQUAL( input.size(), output.size() );
     
    157157  compound.setParameters(params);
    158158  for (size_t index = 0; index < input.size(); ++index) {
    159     argument_t arg(argument_t::indices_t(0,1), argument_t::types_t(0,1), input[index]);
    160     const double result = compound( FunctionModel::arguments_t(1,arg) )[0];
     159    argument_t firstarg(argument_t::indices_t(0,1), argument_t::types_t(0,1), input[index]);
     160    argument_t secondarg(argument_t::indices_t(0,2), argument_t::types_t(0,1), input[index]);
     161    FunctionModel::arguments_t args;
     162    args += firstarg,secondarg;
     163    const double result = compound( args )[0];
    161164    CPPUNIT_ASSERT(
    162165        Helpers::isEqual(
     
    177180//  params += d,a,c,D;
    178181//  compound.setParameters(params);
    179 //  argument_t arg(argument_t::indices_t(0,1), argument_t::types_t(0,1), c);
    180 //  const double result = compound.derivative(FunctionModel::arguments_t(1,arg))[0]
     182//  argument_t firstarg(argument_t::indices_t(0,1), argument_t::types_t(0,1), input[index]);
     183//  argument_t secondarg(argument_t::indices_t(0,2), argument_t::types_t(0,1), input[index]);
     184//  FunctionModel::arguments_t args;
     185//  args += firstarg,secondarg;
     186//  const double result = compound.derivative( args )[0]
    181187//  CPPUNIT_ASSERT(
    182188//      Helpers::isEqual(
     
    197203  params += d,a,c,D;
    198204  compound.setParameters(params);
    199   argument_t arg(argument_t::indices_t(0,1), argument_t::types_t(0,1), c);
    200   {
    201     const double result =
    202         compound.parameter_derivative(
    203             FunctionModel::arguments_t(1,arg),
     205  argument_t firstarg(argument_t::indices_t(0,1), argument_t::types_t(0,1), c);
     206  argument_t secondarg(argument_t::indices_t(0,2), argument_t::types_t(0,1), c);
     207  FunctionModel::arguments_t args;
     208  args += firstarg,secondarg;
     209  {
     210    const double result =
     211        compound.parameter_derivative(
     212            args,
    204213            0)[0];
    205214    CPPUNIT_ASSERT(
     
    214223    const double result =
    215224        compound.parameter_derivative(
    216             FunctionModel::arguments_t(1,arg),
     225            args,
    217226            1)[0];
    218227    CPPUNIT_ASSERT(
     
    227236    const double result =
    228237        compound.parameter_derivative(
    229             FunctionModel::arguments_t(1,arg),
     238            args,
    230239            2)[0];
    231240    CPPUNIT_ASSERT(
     
    240249    const double result =
    241250        compound.parameter_derivative(
    242             FunctionModel::arguments_t(1,arg),
     251            args,
    243252            3)[0];
    244253    CPPUNIT_ASSERT(
Note: See TracChangeset for help on using the changeset viewer.