source: src/FunctionApproximation/Extractors.cpp@ 63e786

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 63e786 was 63e786, checked in by Frederik Heber <heber@…>, 13 years ago

Refactored realignElementTargets() out of gatherDistancesOfTuples().

  • Property mode set to 100644
File size: 8.2 KB
RevLine 
[8aa597]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
[301dbf]42#include "CodePatterns/Assert.hpp"
[8aa597]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
[301dbf]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
[bc6705]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
[c211f7]119Extractors::elementtargets_t
120Extractors::_detail::convertElementcountsToTargets(
121 const Fragment::charges_t &charges,
122 const elementcounts_t &elementcounts
123 )
124{
[301dbf]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 {
[c211f7]147 ELOG(1, "Could not find desired number of elements " << count << " in fragment.");
148 return Extractors::elementtargets_t();
[301dbf]149 }
150 }
151 }
[c211f7]152 return elementtargets;
153}
154
[63e786]155Extractors::chargeiters_t
156Extractors::_detail::realignElementtargets(
157 const elementtargets_t &elementtargets,
158 const Fragment::charges_t elements,
159 const elementcounts_t &elementcounts
160 )
161{
162 chargeiters_t targets;
163 elementcounts_t counts; // how many chargeiters of this element have been used
164 targets.reserve(elements.size());
165 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
166 elementiter != elements.end(); ++elementiter) {
167 const element_t &element = *elementiter;
168 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
169#ifndef NDEBUG
170 {
171 elementcounts_t::const_iterator testiter = elementcounts.find(element);
172 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
173 "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
174 +toString(element)+" than we counted initially.");
175 }
176#endif
177 elementtargets_t::const_iterator targetiter = elementtargets.find(element);
178 ASSERT (targetiter != elementtargets.end(),
179 "Extractors::_detail::realignElementTargets() - not enough chargeiters for element "
180 +toString(element)+".");
181 const chargeiters_t &chargeiters = targetiter->second;
182 const chargeiter_t &chargeiter = chargeiters[count++];
183 targets.push_back(chargeiter);
184 }
185 return targets;
186}
187
[c211f7]188Fragment::positions_t
189Extractors::gatherDistanceOfTuples(
190 const Fragment& fragment,
191 const Fragment::charges_t elements
192 ) {
193 const Fragment::charges_t charges = fragment.getCharges();
194 /// The main problem here is that we have to know how many same
195 /// elements (but different atoms!) we are required to find. Hence,
196 /// we first have to count same elements, then get different targets
197 /// for each and then associated them in correct order back again.
198
199 // 1. we have to make elements unique with counts, hence convert to map
200 elementcounts_t elementcounts =
201 Extractors::_detail::getElementCounts(elements);
202
203 // 2. then for each element we need as many targets (chargeiters) as counts
204 elementtargets_t elementtargets =
205 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
[301dbf]206
207 // 3. we go again through elements and use one found target for each count
208 // in that order
[63e786]209 chargeiters_t targets =
210 Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
211
[301dbf]212#ifndef NDEBUG
213 // check all for debugging
214 for (chargeiters_t::const_iterator chargeiter = targets.begin();
215 chargeiter != targets.end();
216 ++chargeiter)
217 ASSERT( *chargeiter != charges.end(),
218 "Extractors::gatherDistanceOfTuples() - we have not found enough targets?!");
219#endif
220 // 4. convert position_t to Vector
221 return Extractors::_detail::gatherPositionsFromCharges(
222 fragment.getPositions(),
223 charges,
224 targets);
225}
226
227FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
228 const FunctionModel::arguments_t &args
229 )
230{
231 FunctionModel::arguments_t returnargs(args);
232 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
233 return returnargs;
[8aa597]234}
[301dbf]235
Note: See TracBrowser for help on using the repository browser.