source: src/FunctionApproximation/Extractors.cpp@ bc6705

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 Candidate_v1.7.0 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 bc6705 was bc6705, checked in by Frederik Heber <heber@…>, 13 years ago

Refactored getElementCounts out of gatherDistancesOfTuples().

  • Property mode set to 100644
File size: 7.5 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
119Fragment::positions_t
120Extractors::gatherDistanceOfTuples(
121 const Fragment& fragment,
122 const Fragment::charges_t elements
123 ) {
124 const Fragment::charges_t charges = fragment.getCharges();
125 /// The main problem here is that we have to know how many same
126 /// elements (but different atoms!) we are required to find. Hence,
127 /// we first have to count same elements, then get different targets
128 /// for each and then associated them in correct order back again.
129
130 // 1. we have to make elements unique with counts, hence convert to map
131 elementcounts_t elementcounts =
132 Extractors::_detail::getElementCounts(elements);
133
134 // 2. then for each element we need as many targets (chargeiters) as counts
135 elementtargets_t elementtargets;
136 for (elementcounts_t::const_iterator countiter = elementcounts.begin();
137 countiter != elementcounts.end();
138 ++countiter) {
139 chargeiter_t chargeiter = charges.begin();
140 const element_t &element = countiter->first;
141 const count_t &count = countiter->second;
142 for (count_t i = 0; i < count; ++i) {
143 chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
144 if (tempiter != charges.end()) {
145 // try to insert new list
146 std::pair< elementtargets_t::iterator, bool> inserter =
147 elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
148 // if already present, append to it
149 if (!inserter.second) {
150 inserter.first->second.push_back(tempiter);
151 } else { // if created, increase vector's reserve to known size
152 inserter.first->second.reserve(countiter->second);
153 }
154 // search from this element onwards then
155 chargeiter = ++tempiter;
156 } else {
157 ELOG(1, "Could not find desired number of elements " << elements << " in fragment.");
158 return Fragment::positions_t();
159 }
160 }
161 }
162
163 // 3. we go again through elements and use one found target for each count
164 // in that order
165 elementcounts_t counts; // how many chargeiters of this element have been used
166 chargeiters_t targets;
167 targets.reserve(elements.size());
168 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
169 elementiter != elements.end(); ++elementiter) {
170 const element_t &element = *elementiter;
171 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
172#ifndef NDEBUG
173 {
174 elementcounts_t::const_iterator testiter = elementcounts.find(element);
175 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
176 "Extractors::gatherDistanceOfTuples() - we want to use more chargeiters for element "
177 +toString(element)+" than we counted initially.");
178 }
179#endif
180 elementtargets_t::iterator targetiter = elementtargets.find(element);
181 ASSERT (targetiter != elementtargets.end(),
182 "Extractors::gatherDistanceOfTuples() - not enough chargeiters for element "
183 +toString(element)+".");
184 chargeiters_t &chargeiters = targetiter->second;
185 const chargeiter_t &chargeiter = chargeiters[count++];
186 targets.push_back(chargeiter);
187 }
188#ifndef NDEBUG
189 // check all for debugging
190 for (chargeiters_t::const_iterator chargeiter = targets.begin();
191 chargeiter != targets.end();
192 ++chargeiter)
193 ASSERT( *chargeiter != charges.end(),
194 "Extractors::gatherDistanceOfTuples() - we have not found enough targets?!");
195#endif
196 // 4. convert position_t to Vector
197 return Extractors::_detail::gatherPositionsFromCharges(
198 fragment.getPositions(),
199 charges,
200 targets);
201}
202
203FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
204 const FunctionModel::arguments_t &args
205 )
206{
207 FunctionModel::arguments_t returnargs(args);
208 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
209 return returnargs;
210}
211
Note: See TracBrowser for help on using the repository browser.