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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.