source: src/FunctionApproximation/Extractors.cpp@ c211f7

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
Last change on this file since c211f7 was c211f7, checked in by Frederik Heber <heber@…>, 12 years ago

Refactored convertElementcountsToTargets() out of gatherDistanceOfTuples().

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * Extractors.cpp
26 *
27 * Created on: 15.10.2012
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "CodePatterns/MemDebug.hpp"
37
38#include <utility>
39#include <vector>
40#include <boost/assign.hpp>
41
42#include "CodePatterns/Assert.hpp"
43#include "CodePatterns/Log.hpp"
44
45#include "LinearAlgebra/Vector.hpp"
46
47#include "FunctionApproximation/Extractors.hpp"
48#include "FunctionApproximation/FunctionArgument.hpp"
49
50using namespace boost::assign;
51
52FunctionModel::arguments_t
53Extractors::_detail::gatherAllDistanceArguments(
54 const Fragment::positions_t &positions,
55 const size_t globalid)
56{
57 FunctionModel::arguments_t result;
58
59 // go through current configuration and gather all other distances
60 Fragment::positions_t::const_iterator firstpositer = positions.begin();
61 for (;firstpositer != positions.end(); ++firstpositer) {
62 Fragment::positions_t::const_iterator secondpositer = positions.begin();//firstpositer;
63 for (; secondpositer != positions.end(); ++secondpositer) {
64 if (firstpositer == secondpositer)
65 continue;
66 argument_t arg;
67 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
68 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
69 arg.distance = firsttemp.distance(secondtemp);
70 arg.indices = std::make_pair(
71 std::distance(
72 positions.begin(), firstpositer),
73 std::distance(
74 positions.begin(), secondpositer)
75 );
76 arg.globalid = globalid;
77 result.push_back(arg);
78 }
79 }
80
81 return result;
82}
83
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) {
93 Fragment::positions_t::const_iterator positer = positions.begin();
94 const size_t steps = std::distance(charges.begin(), *firstpairiter);
95 std::advance(positer, steps);
96 filtered_positions.push_back(*positer);
97 }
98 return filtered_positions;
99}
100
101Extractors::elementcounts_t
102Extractors::_detail::getElementCounts(
103 const Fragment::charges_t elements
104 )
105{
106 elementcounts_t elementcounts;
107 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
108 elementiter != elements.end(); ++elementiter) {
109 // insert new element
110 std::pair< elementcounts_t::iterator, bool> inserter =
111 elementcounts.insert( std::make_pair( *elementiter, 1) );
112 // if already present, just increase its count
113 if (!inserter.second)
114 ++(inserter.first->second);
115 }
116 return elementcounts;
117}
118
119Extractors::elementtargets_t
120Extractors::_detail::convertElementcountsToTargets(
121 const Fragment::charges_t &charges,
122 const elementcounts_t &elementcounts
123 )
124{
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 " << count << " in fragment.");
148 return Extractors::elementtargets_t();
149 }
150 }
151 }
152 return elementtargets;
153}
154
155Fragment::positions_t
156Extractors::gatherDistanceOfTuples(
157 const Fragment& fragment,
158 const Fragment::charges_t elements
159 ) {
160 const Fragment::charges_t charges = fragment.getCharges();
161 /// The main problem here is that we have to know how many same
162 /// elements (but different atoms!) we are required to find. Hence,
163 /// we first have to count same elements, then get different targets
164 /// for each and then associated them in correct order back again.
165
166 // 1. we have to make elements unique with counts, hence convert to map
167 elementcounts_t elementcounts =
168 Extractors::_detail::getElementCounts(elements);
169
170 // 2. then for each element we need as many targets (chargeiters) as counts
171 elementtargets_t elementtargets =
172 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
173
174 // 3. we go again through elements and use one found target for each count
175 // in that order
176 elementcounts_t counts; // how many chargeiters of this element have been used
177 chargeiters_t targets;
178 targets.reserve(elements.size());
179 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
180 elementiter != elements.end(); ++elementiter) {
181 const element_t &element = *elementiter;
182 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
183#ifndef NDEBUG
184 {
185 elementcounts_t::const_iterator testiter = elementcounts.find(element);
186 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
187 "Extractors::gatherDistanceOfTuples() - we want to use more chargeiters for element "
188 +toString(element)+" than we counted initially.");
189 }
190#endif
191 elementtargets_t::iterator targetiter = elementtargets.find(element);
192 ASSERT (targetiter != elementtargets.end(),
193 "Extractors::gatherDistanceOfTuples() - not enough chargeiters for element "
194 +toString(element)+".");
195 chargeiters_t &chargeiters = targetiter->second;
196 const chargeiter_t &chargeiter = chargeiters[count++];
197 targets.push_back(chargeiter);
198 }
199#ifndef NDEBUG
200 // check all for debugging
201 for (chargeiters_t::const_iterator chargeiter = targets.begin();
202 chargeiter != targets.end();
203 ++chargeiter)
204 ASSERT( *chargeiter != charges.end(),
205 "Extractors::gatherDistanceOfTuples() - we have not found enough targets?!");
206#endif
207 // 4. convert position_t to Vector
208 return Extractors::_detail::gatherPositionsFromCharges(
209 fragment.getPositions(),
210 charges,
211 targets);
212}
213
214FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
215 const FunctionModel::arguments_t &args
216 )
217{
218 FunctionModel::arguments_t returnargs(args);
219 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
220 return returnargs;
221}
222
Note: See TracBrowser for help on using the repository browser.