Changeset 301dbf


Ignore:
Timestamp:
Feb 24, 2013, 12:58:53 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:
bc6705
Parents:
4a77be7
git-author:
Frederik Heber <heber@…> (10/22/12 13:38:33)
git-committer:
Frederik Heber <heber@…> (02/24/13 12:58:53)
Message:

Refactored gatherDistanceOfTuples().

  • it is now able to work on arbitrary vectors of elements, not just tuples of two.
Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/FunctionApproximation/Extractors.cpp

    r4a77be7 r301dbf  
    4040#include <boost/assign.hpp>
    4141
     42#include "CodePatterns/Assert.hpp"
    4243#include "CodePatterns/Log.hpp"
    4344
     
    8182}
    8283
    83 FunctionModel::arguments_t
    84 Extractors::gatherFirstDistance(
    85     const Fragment& fragment,
    86     const size_t index,
    87     const size_t firstelement,
    88     const size_t secondelement
    89     ) {
    90   const Fragment::charges_t charges = fragment.getCharges();
    91   const Fragment::positions_t positions = fragment.getPositions();
    92   typedef Fragment::charges_t::const_iterator chargeiter_t;
    93   std::vector< chargeiter_t > firstpair;
    94   firstpair.reserve(2);
    95   firstpair +=
    96       std::find(charges.begin(), charges.end(), firstelement),
    97       std::find(charges.begin(), charges.end(), secondelement);
    98   if ((firstpair[0] == charges.end()) || (firstpair[1] == charges.end())) {
    99     // complain if tuple not found
    100     ELOG(1, "Could not find pair " << firstelement << "," << secondelement
    101         << " in fragment " << fragment);
    102     return FunctionModel::arguments_t();
    103   }
    104   // convert position_t to Vector
    105   std::vector< std::pair<Vector, size_t> > DistancePair;
    106   for (std::vector<chargeiter_t>::const_iterator firstpairiter = firstpair.begin();
    107       firstpairiter != firstpair.end(); ++firstpairiter) {
     84Fragment::positions_t Extractors::_detail::gatherPositionsFromCharges(
     85    const Fragment::positions_t &positions,
     86    const Fragment::charges_t &charges,
     87    const chargeiters_t targets
     88    )
     89{
     90  Fragment::positions_t filtered_positions;
     91  for (chargeiters_t::const_iterator firstpairiter = targets.begin();
     92      firstpairiter != targets.end(); ++firstpairiter) {
    10893    Fragment::positions_t::const_iterator positer = positions.begin();
    10994    const size_t steps = std::distance(charges.begin(), *firstpairiter);
    11095    std::advance(positer, steps);
    111     DistancePair.push_back(
    112         std::make_pair(Vector((*positer)[0], (*positer)[1], (*positer)[2]),
    113             steps));
    114   }
    115   // finally convert Vector pair to distance-like argument
    116   argument_t arg;
    117   arg.indices.first = DistancePair[0].second;
    118   arg.indices.second = DistancePair[1].second;
    119   arg.distance = DistancePair[0].first.distance(DistancePair[1].first);
    120   arg.globalid = index;
    121 
    122   return FunctionModel::arguments_t(1, arg);
    123 }
     96    filtered_positions.push_back(*positer);
     97  }
     98  return filtered_positions;
     99}
     100
     101Fragment::positions_t
     102Extractors::gatherDistanceOfTuples(
     103    const Fragment& fragment,
     104    const Fragment::charges_t elements
     105    ) {
     106  const Fragment::charges_t charges = fragment.getCharges();
     107  /// The main problem here is that we have to know how many same
     108  /// elements (but different atoms!) we are required to find. Hence,
     109  /// we first have to count same elements, then get different targets
     110  /// for each and then associated them in correct order back again.
     111
     112  // 1. we have to make elements unique with counts, hence convert to map
     113  elementcounts_t elementcounts;
     114  for (Fragment::charges_t::const_iterator elementiter = elements.begin();
     115      elementiter != elements.end(); ++elementiter) {
     116    // insert new element
     117    std::pair< elementcounts_t::iterator, bool> inserter =
     118        elementcounts.insert( std::make_pair( *elementiter, 1) );
     119    // if already present, just increase its count
     120    if (!inserter.second)
     121      ++(inserter.first->second);
     122  }
     123
     124  // 2. then for each element we need as many targets (chargeiters) as counts
     125  elementtargets_t elementtargets;
     126  for (elementcounts_t::const_iterator countiter = elementcounts.begin();
     127      countiter != elementcounts.end();
     128      ++countiter) {
     129    chargeiter_t chargeiter = charges.begin();
     130    const element_t &element = countiter->first;
     131    const count_t &count = countiter->second;
     132    for (count_t i = 0; i < count; ++i) {
     133      chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
     134      if (tempiter != charges.end()) {
     135        // try to insert new list
     136        std::pair< elementtargets_t::iterator, bool> inserter =
     137          elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
     138        // if already present, append to it
     139        if (!inserter.second) {
     140          inserter.first->second.push_back(tempiter);
     141        } else { // if created, increase vector's reserve to known size
     142          inserter.first->second.reserve(countiter->second);
     143        }
     144        // search from this element onwards then
     145        chargeiter = ++tempiter;
     146      } else {
     147        ELOG(1, "Could not find desired number of elements " << elements << " in fragment.");
     148        return Fragment::positions_t();
     149      }
     150    }
     151  }
     152
     153  // 3. we go again through elements and use one found target for each count
     154  // in that order
     155  elementcounts_t counts; // how many chargeiters of this element have been used
     156  chargeiters_t targets;
     157  targets.reserve(elements.size());
     158  for (Fragment::charges_t::const_iterator elementiter = elements.begin();
     159      elementiter != elements.end(); ++elementiter) {
     160    const element_t &element = *elementiter;
     161    count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
     162#ifndef NDEBUG
     163    {
     164      elementcounts_t::const_iterator testiter = elementcounts.find(element);
     165      ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
     166          "Extractors::gatherDistanceOfTuples() - we want to use more chargeiters for element "
     167          +toString(element)+" than we counted initially.");
     168    }
     169#endif
     170    elementtargets_t::iterator targetiter = elementtargets.find(element);
     171    ASSERT (targetiter != elementtargets.end(),
     172        "Extractors::gatherDistanceOfTuples() - not enough chargeiters for element "
     173        +toString(element)+".");
     174    chargeiters_t &chargeiters = targetiter->second;
     175    const chargeiter_t &chargeiter = chargeiters[count++];
     176    targets.push_back(chargeiter);
     177  }
     178#ifndef NDEBUG
     179  // check all for debugging
     180  for (chargeiters_t::const_iterator chargeiter = targets.begin();
     181      chargeiter != targets.end();
     182      ++chargeiter)
     183    ASSERT( *chargeiter != charges.end(),
     184        "Extractors::gatherDistanceOfTuples() - we have not found enough targets?!");
     185#endif
     186  // 4. convert position_t to Vector
     187  return Extractors::_detail::gatherPositionsFromCharges(
     188          fragment.getPositions(),
     189          charges,
     190          targets);
     191}
     192
     193FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
     194    const FunctionModel::arguments_t &args
     195    )
     196{
     197  FunctionModel::arguments_t returnargs(args);
     198  std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
     199  return returnargs;
     200}
     201
  • TabularUnified src/FunctionApproximation/Extractors.hpp

    r4a77be7 r301dbf  
    2323 */
    2424namespace Extractors {
     25  typedef Fragment::charges_t::const_iterator chargeiter_t;
     26  typedef std::vector<chargeiter_t> chargeiters_t;
     27
     28  typedef size_t count_t;
     29  typedef Fragment::charge_t element_t;
     30  typedef std::map< element_t, count_t> elementcounts_t;
     31  typedef std::map< element_t, chargeiters_t > elementtargets_t;
     32
    2533  /** Namespace for some internal helper functions.
    2634   *
     
    3745        const Fragment::positions_t &positions,
    3846        const size_t globalid);
     47
     48    /** Gather all positions from the same aligned vector of charges.
     49     *
     50     * Basically, we filter the positions indicated by the targets but
     51     * from a different vector that has the same layout.
     52     *
     53     * \param positions positions to search
     54     * \param charges charges to match with \targets
     55     * \param targets iterators on charges
     56     * \return filtered positions
     57     */
     58    Fragment::positions_t gatherPositionsFromCharges(
     59        const Fragment::positions_t &positions,
     60        const Fragment::charges_t &charges,
     61        const chargeiters_t targets
     62        );
    3963  }
    4064
     
    5377  }
    5478
    55   /** Gather first distance for the two matching charges.
     79  /** Gather all positions associated to the matching \a elements.
    5680   *
    5781   * \param fragment fragment with all nuclei positions
    58    * \param index index refers to the index within the global set of configurations
    59    * \param firstelement first element of pair
    60    * \param secondelement second element of pair, order is reflected in indices of return argument_t
    61    * \return vector of of argument_t containing all found distances
     82   * \param elements tuple of desired elements
     83   * \return vector of positions_t containing
    6284   */
    63   FunctionModel::arguments_t gatherFirstDistance(
     85  Fragment::positions_t gatherDistanceOfTuples(
    6486      const Fragment& fragment,
    65       const size_t index,
    66       const size_t firstelement,
    67       const size_t secondelement
     87      const Fragment::charges_t elements
     88      );
     89
     90  /** Reorder arguments by increasing distance.
     91   *
     92   * \param args arguments to reorder
     93   * \return reordered args
     94   */
     95  FunctionModel::arguments_t reorderArgumentsByIncreasingDistance(
     96      const FunctionModel::arguments_t &args
    6897      );
    6998
  • TabularUnified src/LevMartester.cpp

    r4a77be7 r301dbf  
    364364    // Afterwards we go through all of this type and gather the distance and the energy value
    365365    TrainingData MorseData(
    366         boost::bind(&Extractors::gatherFirstDistance, _1, _2, 6, 6) // gather first carbon pair
     366        boost::bind(&Extractors::_detail::gatherAllDistanceArguments,
     367            boost::bind(&Extractors::gatherDistanceOfTuples,
     368                _1, Fragment::charges_t(2,6.)
     369            ), _2 // gather first carbon pair
     370          )
    367371        );
    368372    MorseData(homologies.getHomologousGraphs(graph));
Note: See TracChangeset for help on using the changeset viewer.