Changeset 313f83


Ignore:
Timestamp:
Feb 15, 2013, 5:09:58 PM (12 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:
1f1f80
Parents:
fb3485
git-author:
Frederik Heber <heber@…> (01/31/13 13:26:34)
git-committer:
Frederik Heber <heber@…> (02/15/13 17:09:58)
Message:

SamplingGrid::operator*=() can now deal with incongruent windows.

  • new functions shrinkWindow() and AddIntoWindow() help to allow for shrinking the window to the minimum size of either window, copying the old values onto and multiplying with the other ones from a possibly larger window.
Location:
src/Jobs/Grid
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/Jobs/Grid/SamplingGrid.cpp

    rfb3485 r313f83  
    135135}
    136136
     137static void multiplyElements(
     138    double &dest,
     139    const double &source,
     140    const double prefactor)
     141{
     142  dest *= prefactor*(source);
     143}
     144
     145
    137146SamplingGrid& SamplingGrid::operator*=(const SamplingGrid& other)
    138147{
    139148  // check that grids are compatible
    140   if (isCongruent(other)) {
    141     sampledvalues_t::iterator iter = sampled_grid.begin();
    142     sampledvalues_t::const_iterator otheriter = other.sampled_grid.begin();
    143     for(; iter != sampled_grid.end(); ++iter, ++otheriter )
    144       *iter *= (*otheriter);
     149  if (isCompatible(other)) {
     150    /// get minimum of window
     151    double min_begin_window[3];
     152    double min_end_window[3];
     153    bool doShrink = false;
     154    for (size_t index=0; index<3;++index) {
     155      if (begin_window[index] <= other.begin_window[index]) {
     156        min_begin_window[index] = other.begin_window[index];
     157        doShrink = true;
     158      } else {
     159        min_begin_window[index] = begin_window[index];
     160      }
     161      if (end_window[index] <= other.end_window[index]) {
     162        min_end_window[index] = end_window[index];
     163      } else {
     164        min_end_window[index] = other.end_window[index];
     165        doShrink = true;
     166      }
     167    }
     168    LOG(2, "DEBUG: min begin is " << min_begin_window[0] << "," << min_begin_window[1] << "," << min_begin_window[2] << ".");
     169    LOG(2, "DEBUG: min end is " << min_end_window[0] << "," << min_end_window[1] << "," << min_end_window[2] << ".");
     170    if (doShrink)
     171      shrinkWindow(min_begin_window, min_end_window);
     172    addWindowOntoWindow(
     173        other.begin_window,
     174        other.end_window,
     175        begin_window,
     176        end_window,
     177        sampled_grid,
     178        other.sampled_grid,
     179        boost::bind(multiplyElements, _1, _2, 1.),
     180        sourcewindow);
    145181  } else {
    146182    ASSERT(0, "SamplingGrid::operator*=() - multiplying incongruent grids is so far not in the cards.");
     
    334370}
    335371
     372void SamplingGrid::shrinkWindow(
     373    const double _begin_window[3],
     374    const double _end_window[3])
     375{
     376#ifndef NDEBUG
     377  for(size_t index=0;index < 3; ++index) {
     378    // check that we truly have to shrink the window
     379    ASSERT ( begin_window[index] <= _begin_window[index],
     380        "SamplingGrid::shrinkWindow() - component "+toString(index)+
     381        " of window start is less than old value.");
     382    ASSERT ( end_window[index] >= _end_window[index],
     383        "SamplingGrid::shrinkWindow() - component "+toString(index)+
     384        " of window end is greater than old value.");
     385
     386    // check that we are still less than domain
     387    ASSERT ( _begin_window[index] >= begin[index],
     388        "SamplingGrid::shrinkWindow() - component "+toString(index)+
     389        " of window start is less than domain start.");
     390    ASSERT ( _end_window[index] <= end[index],
     391        "SamplingGrid::shrinkWindow() - component "+toString(index)+
     392        " of window end is greater than domain end.");
     393  }
     394#endif
     395  // copy old window size and values
     396  double old_begin_window[3];
     397  double old_end_window[3];
     398  for(size_t index=0;index<3;++index) {
     399    old_begin_window[index] = begin_window[index];
     400    old_end_window[index] = end_window[index];
     401  }
     402  sampledvalues_t old_values(sampled_grid);
     403  // set new window
     404  setWindow(_begin_window,_end_window);
     405  // now extend it ...
     406  addIntoWindow(old_begin_window, old_end_window, old_values, +1.);
     407  LOG(2, "DEBUG: Grid after extension is " << sampled_grid << ".");
     408}
     409
    336410static void addElements(
    337411    double &dest,
     
    356430      _sampled_grid,
    357431      boost::bind(addElements, _1, _2, boost::cref(prefactor)),
    358       thiswindow);
     432      destwindow);
     433}
     434
     435void SamplingGrid::addIntoWindow(
     436    const double _begin_window[3],
     437    const double _end_window[3],
     438    const sampledvalues_t &_sampled_grid,
     439    const double prefactor)
     440{
     441  addWindowOntoWindow(
     442      _begin_window,
     443      _end_window,
     444      begin_window,
     445      end_window,
     446      sampled_grid,
     447      _sampled_grid,
     448      boost::bind(addElements, _1, _2, boost::cref(prefactor)),
     449      sourcewindow);
    359450}
    360451
    361452void SamplingGrid::addWindowOntoWindow(
    362     const double wbegin[3],
    363     const double wend[3],
    364     const double other_wbegin[3],
    365     const double other_wend[3],
    366     sampledvalues_t &sampled_grid,
    367     const sampledvalues_t &other_sampled_grid,
     453    const double larger_wbegin[3],
     454    const double larger_wend[3],
     455    const double smaller_wbegin[3],
     456    const double smaller_wend[3],
     457    sampledvalues_t &dest_sampled_grid,
     458    const sampledvalues_t &source_sampled_grid,
    368459    boost::function<void (double &, const double &)> op,
    369     enum LargerWindow choice)
     460    enum eLargerWindow larger_window)
    370461{
    371462#ifndef NDEBUG
    372463  for(size_t index=0;index<3;++index) {
    373     ASSERT( other_wbegin[index] >= wbegin[index],
     464    ASSERT( smaller_wbegin[index] >= larger_wbegin[index],
    374465        "SamplingGrid::addWindowOntoWindow() - given smaller window starts earlier than larger window in component "
    375466        +toString(index)+".");
    376     ASSERT( other_wend[index] <= wend[index],
     467    ASSERT( smaller_wend[index] <= larger_wend[index],
    377468        "SamplingGrid::addWindowOntoWindow() - given smaller window ends later than larger window in component "
    378469        +toString(index)+".");
     
    394485    const double delta = (double)gridpoints_axis/(end[index] - begin[index]);
    395486    // delta is conversion factor from box length to discrete length, i.e. number of points
    396     pre_offset[index] = delta*(other_wbegin[index] - wbegin[index])+round_offset;
    397     length[index] = delta*(other_wend[index] - other_wbegin[index])+round_offset;
    398     post_offset[index] = delta*(wend[index] - other_wend[index])+round_offset;
    399     total[index] = delta*(wend[index] - wbegin[index])+round_offset;
     487    pre_offset[index] = delta*(smaller_wbegin[index] - larger_wbegin[index])+round_offset;
     488    length[index] = delta*(smaller_wend[index] - smaller_wbegin[index])+round_offset;
     489    post_offset[index] = delta*(larger_wend[index] - smaller_wend[index])+round_offset;
     490    total[index] = delta*(larger_wend[index] - larger_wbegin[index])+round_offset;
    400491    // total is used as safe-guard against loss due to discrete conversion
    401492    ASSERT( pre_offset[index]+post_offset[index]+length[index] == total[index],
     
    406497#ifndef NDEBUG
    407498  const size_t calculated_size = length[0]*length[1]*length[2];
    408   ASSERT( calculated_size == other_sampled_grid.size(),
    409       "SamplingGrid::addWindowOntoWindow() - not enough sampled values given: "
    410       +toString(calculated_size)+" != "+toString(other_sampled_grid.size())+".");
    411   ASSERT( calculated_size <=  sampled_grid.size(),
    412       "SamplingGrid::addWindowOntoWindow() - not enough sampled values available: "
    413       +toString(calculated_size)+" <= "+toString(sampled_grid.size())+".");
     499  if (larger_window == destwindow) {
     500    ASSERT( calculated_size == source_sampled_grid.size(),
     501        "SamplingGrid::addWindowOntoWindow() - not enough source sampled values given: "
     502        +toString(calculated_size)+" != "+toString(source_sampled_grid.size())+".");
     503    ASSERT( calculated_size <= dest_sampled_grid.size(),
     504        "SamplingGrid::addWindowOntoWindow() - not enough sampled values available: "
     505        +toString(calculated_size)+" <= "+toString(dest_sampled_grid.size())+".");
     506  } else {
     507    ASSERT( calculated_size == dest_sampled_grid.size(),
     508        "SamplingGrid::addWindowOntoWindow() - not enough dest sampled values given: "
     509        +toString(calculated_size)+" != "+toString(dest_sampled_grid.size())+".");
     510    ASSERT( calculated_size <= source_sampled_grid.size(),
     511        "SamplingGrid::addWindowOntoWindow() - not enough source sampled values available: "
     512        +toString(calculated_size)+" <= "+toString(source_sampled_grid.size())+".");
     513  }
    414514  const size_t total_size = total[0]*total[1]*total[2];
    415   ASSERT( total_size == sampled_grid.size(),
    416       "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present points: "
    417       +toString(total_size)+" != "+toString(sampled_grid.size())+".");
     515  if (larger_window == destwindow) {
     516    ASSERT( total_size == dest_sampled_grid.size(),
     517        "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present dest points: "
     518        +toString(total_size)+" != "+toString(dest_sampled_grid.size())+".");
     519  } else {
     520    ASSERT( total_size == source_sampled_grid.size(),
     521        "SamplingGrid::addWindowOntoWindow() - total size is not equal to number of present source points: "
     522        +toString(total_size)+" != "+toString(source_sampled_grid.size())+".");
     523  }
    418524#endif
    419525  size_t N[3];
    420526//  size_t counter = 0;
    421   sampledvalues_t::iterator griditer = sampled_grid.begin();
    422   sampledvalues_t::const_iterator copyiter = other_sampled_grid.begin();
    423   if (choice == thiswindow)
    424     std::advance(griditer, pre_offset[0]*total[1]*total[2]);
     527  sampledvalues_t::iterator destiter = dest_sampled_grid.begin();
     528  sampledvalues_t::const_iterator sourceiter = source_sampled_grid.begin();
     529  if (larger_window == destwindow)
     530    std::advance(destiter, pre_offset[0]*total[1]*total[2]);
    425531  else
    426     std::advance(copyiter, pre_offset[0]*total[1]*total[2]);
     532    std::advance(sourceiter, pre_offset[0]*total[1]*total[2]);
    427533  for(N[0]=0; N[0] < length[0]; ++N[0]) {
    428     if (choice == thiswindow)
    429       std::advance(griditer, pre_offset[1]*total[2]);
     534    if (larger_window == destwindow)
     535      std::advance(destiter, pre_offset[1]*total[2]);
    430536    else
    431       std::advance(copyiter, pre_offset[1]*total[2]);
     537      std::advance(sourceiter, pre_offset[1]*total[2]);
    432538    for(N[1]=0; N[1] < length[1]; ++N[1]) {
    433       if (choice == thiswindow)
    434         std::advance(griditer, pre_offset[2]);
     539      if (larger_window == destwindow)
     540        std::advance(destiter, pre_offset[2]);
    435541      else
    436         std::advance(copyiter, pre_offset[2]);
     542        std::advance(sourceiter, pre_offset[2]);
    437543      for(N[2]=0; N[2] < length[2]; ++N[2]) {
    438         ASSERT( griditer != sampled_grid.end(),
    439             "SamplingGrid::addWindowOntoWindow() - griditer is already at end of window.");
    440         ASSERT( copyiter != other_sampled_grid.end(),
    441             "SamplingGrid::addWindowOntoWindow() - griditer is already at end of window.");
    442         op(*griditer, *copyiter);
    443         ++griditer;
    444         ++copyiter;
     544        ASSERT( destiter != dest_sampled_grid.end(),
     545            "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
     546        ASSERT( sourceiter != source_sampled_grid.end(),
     547            "SamplingGrid::addWindowOntoWindow() - destiter is already at end of window.");
     548        op(*destiter, *sourceiter);
     549        ++destiter;
     550        ++sourceiter;
    445551      }
    446       if (choice == thiswindow)
    447         std::advance(griditer, post_offset[2]);
     552      if (larger_window == destwindow)
     553        std::advance(destiter, post_offset[2]);
    448554      else
    449         std::advance(copyiter, post_offset[2]);
     555        std::advance(sourceiter, post_offset[2]);
    450556    }
    451     if (choice == thiswindow)
    452       std::advance(griditer, post_offset[1]*total[2]);
     557    if (larger_window == destwindow)
     558      std::advance(destiter, post_offset[1]*total[2]);
    453559    else
    454       std::advance(copyiter, post_offset[1]*total[2]);
     560      std::advance(sourceiter, post_offset[1]*total[2]);
    455561  }
    456562#ifndef NDEBUG
    457   if (choice == thiswindow)
    458     std::advance(griditer, post_offset[0]*total[1]*total[2]);
     563  if (larger_window == destwindow)
     564    std::advance(destiter, post_offset[0]*total[1]*total[2]);
    459565  else
    460     std::advance(copyiter, post_offset[0]*total[1]*total[2]);
    461   ASSERT( griditer == sampled_grid.end(),
    462       "SamplingGrid::addWindowOntoWindow() - griditer is not at end of window.");
    463   ASSERT( copyiter == other_sampled_grid.end(),
    464       "SamplingGrid::addWindowOntoWindow() - copyiter is not at end of window.");
     566    std::advance(sourceiter, post_offset[0]*total[1]*total[2]);
     567  ASSERT( destiter == dest_sampled_grid.end(),
     568      "SamplingGrid::addWindowOntoWindow() - destiter is not at end of window.");
     569  ASSERT( sourceiter == source_sampled_grid.end(),
     570      "SamplingGrid::addWindowOntoWindow() - sourceiter is not at end of window.");
    465571#endif
    466   LOG(2, "DEBUG: Grid after adding other is " << sampled_grid << ".");
     572  LOG(2, "DEBUG: Grid after adding other is " << dest_sampled_grid << ".");
    467573}
    468574
  • TabularUnified src/Jobs/Grid/SamplingGrid.hpp

    rfb3485 r313f83  
    128128  /** Element-wise multiplication operator with another SamplingGrid instance \a other.
    129129   *
     130   * With non-zero windows we have to pay some more attention here.
     131   * Now, the windows may not be congruent but we have to find the intersection
     132   * of the two windows and then construct the new window only of this size and
     133   * multiply. The trick then is not to copy&change the other grid but to
     134   * access it properly.
     135   *
    130136   * \param other other instance to sum onto this one.
    131137   * \return ref to this instance
     
    251257  void extendWindow(const double _begin_window[3], const double _end_window[3]);
    252258
    253   /** Adds another window onto the one in this instance.
     259  /** Shrinks the window while keeping the values.
     260   *
     261   * \param _begin_window new start of window
     262   * \param _end_window new end of window
     263   */
     264  void shrinkWindow(const double _begin_window[3], const double _end_window[3]);
     265
     266  /** Adds another (smaller) window onto the one in this instance.
    254267   *
    255268   * \note We assume here that the given window fits on the this one.
     
    266279      const double prefactor);
    267280
     281  /** Adds another (larger) window into the one in this instance.
     282   *
     283   * \note We assume here that the given window is larger than this one.
     284   *
     285   * \param _begin_window start of other window
     286   * \param _end_window end of other window
     287   * \param _sampled_grid other set of sampled values
     288   * @param prefactor +1. is then addition, -1. is subtraction.
     289   */
     290  void addIntoWindow(
     291      const double _begin_window[3],
     292      const double _end_window[3],
     293      const sampledvalues_t &_sampled_grid,
     294      const double prefactor);
     295
    268296  /** Enum to help in addWindowOntoWindow() decide which iterator needs to be
    269297   * advanced.
    270298   */
    271   enum LargerWindow {
    272     thiswindow,
    273     otherwindow
     299  enum eLargerWindow {
     300    destwindow,
     301    sourcewindow
    274302  };
    275303
     
    280308   * one of them being constant, hence the source values
    281309   *
    282    * \param wbegin start of larger window
    283    * \param wend end of larger window
    284    * \param other_wbegin start of smaller window
    285    * \param other_wend end of smaller window
    286    * \param sampled_grid larger set of sampled values
    287    * \param other_sampled_grid smaller set of sampled values
     310   * \param larger_wbegin start of larger window
     311   * \param larger_wend end of larger window
     312   * \param smaller_wbegin start of smaller window
     313   * \param smaller_wend end of smaller window
     314   * \param dest_sampled_grid larger set of sampled values
     315   * \param source_sampled_grid smaller set of sampled values
    288316   * \param op operation to perform with the two elements
    289    * \param choice indicates which is the larger window
     317   * \param larger_window indicates which is the larger window
    290318   */
    291319  void addWindowOntoWindow(
    292       const double wbegin[3],
    293       const double wend[3],
    294       const double other_wbegin[3],
    295       const double other_wend[3],
    296       sampledvalues_t &sampled_grid,
    297       const sampledvalues_t &other_sampled_grid,
     320      const double larger_wbegin[3],
     321      const double larger_wend[3],
     322      const double smaller_wbegin[3],
     323      const double smaller_wend[3],
     324      sampledvalues_t &dest_sampled_grid,
     325      const sampledvalues_t &source_sampled_grid,
    298326      boost::function<void (double &, const double &)> op,
    299       enum LargerWindow choice);
     327      enum eLargerWindow larger_window);
    300328
    301329  /** Helper function that contains all the logic of how to superpose two
Note: See TracChangeset for help on using the changeset viewer.