Changeset cb80d4 for src


Ignore:
Timestamp:
Jul 20, 2017, 9:38:38 AM (8 years ago)
Author:
Frederik Heber <frederik.heber@…>
Branches:
ForceAnnealing_with_BondGraph_continued
Children:
d3d964
Parents:
461a7f
git-author:
Frederik Heber <frederik.heber@…> (06/29/17 14:53:38)
git-committer:
Frederik Heber <frederik.heber@…> (07/20/17 09:38:38)
Message:

Extracted calculation of weights per atom into BondVectors.

Location:
src/Dynamics
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Dynamics/BondVectors.cpp

    r461a7f rcb80d4  
    3939
    4040#include <algorithm>
     41#include <functional>
    4142#include <iterator>
     43#include <numeric>
    4244
    4345#include "CodePatterns/Assert.hpp"
     
    4648#include "Atom/atom.hpp"
    4749#include "Bond/bond.hpp"
     50#include "Helpers/defs.hpp"
    4851
    4952void BondVectors::recalculateBondVectorsAtStep(
     
    107110  return BondVectors;
    108111}
     112
     113BondVectors::weights_t BondVectors::getWeightsForAtomAtStep(
     114    const atom &_walker,
     115    const size_t &_step) const
     116{
     117  const std::vector<Vector> BondVectors =
     118      getAtomsBondVectorsAtStep(_walker, _step);
     119
     120  weights_t weights;
     121  for (std::vector<Vector>::const_iterator iter = BondVectors.begin();
     122      iter != BondVectors.end(); ++iter) {
     123    std::vector<double> scps;
     124    scps.reserve(BondVectors.size());
     125    std::transform(
     126        BondVectors.begin(), BondVectors.end(),
     127        std::back_inserter(scps),
     128        boost::bind(static_cast< double (*)(double) >(&fabs),
     129            boost::bind(&Vector::ScalarProduct, boost::cref(*iter), _1))
     130        );
     131    const double scp_sum = std::accumulate(scps.begin(), scps.end(), 0.);
     132    ASSERT( (scp_sum-1.) > -MYEPSILON,
     133        "ForceAnnealing() - sum of weights must be equal or larger one but is "
     134        +toString(scp_sum));
     135    weights.push_back( 1./scp_sum );
     136  }
     137  LOG(4, "DEBUG: Weights for atom #" << _walker.getId() << ": " << weights);
     138
     139  // for testing we check whether all weighted scalar products now come out as 1.
     140#ifndef NDEBUG
     141  for (std::vector<Vector>::const_iterator iter = BondVectors.begin();
     142      iter != BondVectors.end(); ++iter) {
     143    std::vector<double> scps;
     144    scps.reserve(BondVectors.size());
     145    std::transform(
     146        BondVectors.begin(), BondVectors.end(),
     147        weights.begin(),
     148        std::back_inserter(scps),
     149        boost::bind(static_cast< double (*)(double) >(&fabs),
     150            boost::bind(std::multiplies<double>(),
     151                boost::bind(&Vector::ScalarProduct, boost::cref(*iter), _1),
     152                _2))
     153        );
     154    const double scp_sum = std::accumulate(scps.begin(), scps.end(), 0.);
     155    ASSERT( fabs(scp_sum - 1.) < MYEPSILON,
     156        "ForceAnnealing::operator() - for BondVector "+toString(*iter)
     157        +" we have weighted scalar product of "+toString(scp_sum)+" != 1.");
     158  }
     159#endif
     160  return weights;
     161}
  • src/Dynamics/BondVectors.hpp

    r461a7f rcb80d4  
    8383      const size_t &_step) const;
    8484
     85  //!> typedef for the weights for the Bondvectors of a single atom
     86  typedef std::deque<double> weights_t;
     87
     88  /** Calculates the weights for a frame where each Bondvector of the
     89   * given atom is a vector of the frame.
     90   *
     91   * The idea is that we can represent any vector by appropriate weights such
     92   * that is still sums up to one.
     93   *
     94   * \param _walker atom to get BondVectors for
     95   * \param _step time step for which the bond vector is request
     96   */
     97  weights_t getWeightsForAtomAtStep(
     98      const atom &_walker,
     99      const size_t &_step) const;
     100
    85101private:
    86102  /** Calculates the bond vector for each bond in the internal container.
  • src/Dynamics/ForceAnnealing.hpp

    r461a7f rcb80d4  
    278278
    279279    // for each atom we need to gather weights and then project the gradient
    280     typedef std::deque<double> weights_t;
    281     typedef std::map<atomId_t, weights_t > weights_per_atom_t;
     280    typedef std::map<atomId_t, BondVectors::weights_t > weights_per_atom_t;
    282281    std::vector<weights_per_atom_t> weights_per_atom(2);
    283282    for (size_t timestep = 0; timestep <= 1; ++timestep) {
     
    297296
    298297          // gather subset of BondVectors for the current atom
    299           std::vector<Vector> BondVectors = bv.getAtomsBondVectorsAtStep(walker, CurrentStep);
     298          const std::vector<Vector> BondVectors =
     299              bv.getAtomsBondVectorsAtStep(walker, CurrentStep);
    300300
    301301          // go through all its bonds and calculate what magnitude is represented
    302302          // by the others i.e. sum of scalar products against other bonds
    303           std::pair<weights_per_atom_t::iterator, bool> inserter =
     303          const std::pair<weights_per_atom_t::iterator, bool> inserter =
    304304              weights_per_atom[timestep].insert(
    305                   std::make_pair(walker.getId(), weights_t()) );
     305                  std::make_pair(walker.getId(),
     306                  bv.getWeightsForAtomAtStep(walker, CurrentStep)) );
    306307          ASSERT( inserter.second,
    307308              "ForceAnnealing::operator() - weight map for atom "+toString(walker)
    308309              +" and time step "+toString(timestep)+" already filled?");
    309           weights_t &weights = inserter.first->second;
    310           for (std::vector<Vector>::const_iterator iter = BondVectors.begin();
    311               iter != BondVectors.end(); ++iter) {
    312             std::vector<double> scps;
    313             scps.reserve(BondVectors.size());
    314             std::transform(
    315                 BondVectors.begin(), BondVectors.end(),
    316                 std::back_inserter(scps),
    317                 boost::bind(static_cast< double (*)(double) >(&fabs),
    318                     boost::bind(&Vector::ScalarProduct, boost::cref(*iter), _1))
    319                 );
    320             const double scp_sum = std::accumulate(scps.begin(), scps.end(), 0.);
    321             ASSERT( (scp_sum-1.) > -MYEPSILON,
    322                 "ForceAnnealing() - sum of weights must be equal or larger one but is "
    323                 +toString(scp_sum));
    324             weights.push_back( 1./scp_sum );
    325           }
    326           LOG(4, "DEBUG: Weights for atom #" << walker.getId() << ": " << weights);
    327 
    328           // for testing we check whether all weighted scalar products now come out as 1.
    329 #ifndef NDEBUG
    330           for (std::vector<Vector>::const_iterator iter = BondVectors.begin();
    331               iter != BondVectors.end(); ++iter) {
    332             std::vector<double> scps;
    333             scps.reserve(BondVectors.size());
    334             std::transform(
    335                 BondVectors.begin(), BondVectors.end(),
    336                 weights.begin(),
    337                 std::back_inserter(scps),
    338                 boost::bind(static_cast< double (*)(double) >(&fabs),
    339                     boost::bind(std::multiplies<double>(),
    340                         boost::bind(&Vector::ScalarProduct, boost::cref(*iter), _1),
    341                         _2))
    342                 );
    343             const double scp_sum = std::accumulate(scps.begin(), scps.end(), 0.);
    344             ASSERT( fabs(scp_sum - 1.) < MYEPSILON,
    345                 "ForceAnnealing::operator() - for BondVector "+toString(*iter)
    346                 +" we have weighted scalar product of "+toString(scp_sum)+" != 1.");
    347           }
    348 #endif
     310          BondVectors::weights_t &weights = inserter.first->second;
     311          ASSERT( weights.size() == ListOfBonds.size(),
     312              "ForceAnnealing::operator() - number of weights "
     313              +toString(weights.size())+" does not match number of bonds "
     314              +toString(ListOfBonds.size())+", error in calculation?");
    349315
    350316          // projected gradient over all bonds and place in one of projected_forces
    351317          // using the obtained weights
    352318          {
    353             weights_t::const_iterator weightiter = weights.begin();
     319            BondVectors::weights_t::const_iterator weightiter = weights.begin();
    354320            std::vector<Vector>::const_iterator vectoriter = BondVectors.begin();
    355321            Vector forcesum_check;
Note: See TracChangeset for help on using the changeset viewer.