source: src/FunctionApproximation/Extractors.cpp@ 93e908

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 93e908 was 691be4, checked in by Frederik Heber <heber@…>, 12 years ago

FunctionArgument now contains charges, too, and rewrote Extractors accordingly.

  • gatherDistancesFromFragment is now what we mostly want: Returns exactly the arguments in the way we specify.
  • PairPotential_AngleUnitTest now has gives additional types to potential's cstor.
  • Property mode set to 100644
File size: 11.4 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::gatherAllDistanceArguments(
54 const Fragment::positions_t& positions,
55 const Fragment::charges_t& charges,
56 const size_t globalid)
57{
58 FunctionModel::arguments_t result;
59
60 // go through current configuration and gather all other distances
61 Fragment::positions_t::const_iterator firstpositer = positions.begin();
62 for (;firstpositer != positions.end(); ++firstpositer) {
63 Fragment::positions_t::const_iterator secondpositer = positions.begin();//firstpositer;
64 for (; secondpositer != positions.end(); ++secondpositer) {
65 if (firstpositer == secondpositer)
66 continue;
67 argument_t arg;
68 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
69 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
70 arg.distance = firsttemp.distance(secondtemp);
71 arg.types = std::make_pair(
72 charges[ std::distance(positions.begin(), firstpositer) ],
73 charges[ std::distance(positions.begin(), secondpositer) ]
74 );
75 arg.indices = std::make_pair(
76 std::distance(
77 positions.begin(), firstpositer),
78 std::distance(
79 positions.begin(), secondpositer)
80 );
81 arg.globalid = globalid;
82 result.push_back(arg);
83 }
84 }
85
86 return result;
87}
88
89FunctionModel::arguments_t
90Extractors::gatherAllSymmetricDistanceArguments(
91 const Fragment::positions_t& positions,
92 const Fragment::charges_t& charges,
93 const size_t globalid)
94{
95 FunctionModel::arguments_t result;
96
97 // go through current configuration and gather all other distances
98 Fragment::positions_t::const_iterator firstpositer = positions.begin();
99 for (;firstpositer != positions.end(); ++firstpositer) {
100 Fragment::positions_t::const_iterator secondpositer = firstpositer;
101 for (; secondpositer != positions.end(); ++secondpositer) {
102 if (firstpositer == secondpositer)
103 continue;
104 argument_t arg;
105 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
106 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
107 arg.distance = firsttemp.distance(secondtemp);
108 arg.types = std::make_pair(
109 charges[ std::distance(positions.begin(), firstpositer) ],
110 charges[ std::distance(positions.begin(), secondpositer) ]
111 );
112 arg.indices = std::make_pair(
113 std::distance(
114 positions.begin(), firstpositer),
115 std::distance(
116 positions.begin(), secondpositer)
117 );
118 arg.globalid = globalid;
119 result.push_back(arg);
120 }
121 }
122
123 return result;
124}
125
126Fragment::positions_t Extractors::_detail::gatherPositionsFromTargets(
127 const Fragment::positions_t& positions,
128 const Fragment::charges_t& charges,
129 const chargeiters_t &targets
130 )
131{
132 Fragment::positions_t filtered_positions;
133 for (chargeiters_t::const_iterator firstpairiter = targets.begin();
134 firstpairiter != targets.end(); ++firstpairiter) {
135 Fragment::positions_t::const_iterator positer = positions.begin();
136 const size_t steps = std::distance(charges.begin(), *firstpairiter);
137 std::advance(positer, steps);
138 filtered_positions.push_back(*positer);
139 }
140 return filtered_positions;
141}
142
143FunctionModel::arguments_t Extractors::_detail::gatherDistancesFromTargets(
144 const Fragment::positions_t& positions,
145 const Fragment::charges_t& charges,
146 const chargeiters_t &targets,
147 const size_t globalid
148 )
149{
150 Fragment::positions_t filtered_positions;
151 Fragment::charges_t filtered_charges;
152 for (chargeiters_t::const_iterator firstpairiter = targets.begin();
153 firstpairiter != targets.end(); ++firstpairiter) {
154 Fragment::positions_t::const_iterator positer = positions.begin();
155 const size_t steps = std::distance(charges.begin(), *firstpairiter);
156 std::advance(positer, steps);
157 filtered_positions.push_back(*positer);
158 filtered_charges.push_back(**firstpairiter);
159 }
160 return Extractors::gatherAllSymmetricDistanceArguments(
161 filtered_positions,
162 filtered_charges,
163 globalid);
164}
165
166Extractors::elementcounts_t
167Extractors::_detail::getElementCounts(
168 const Fragment::charges_t elements
169 )
170{
171 elementcounts_t elementcounts;
172 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
173 elementiter != elements.end(); ++elementiter) {
174 // insert new element
175 std::pair< elementcounts_t::iterator, bool> inserter =
176 elementcounts.insert( std::make_pair( *elementiter, 1) );
177 // if already present, just increase its count
178 if (!inserter.second)
179 ++(inserter.first->second);
180 }
181 return elementcounts;
182}
183
184Extractors::elementtargets_t
185Extractors::_detail::convertElementcountsToTargets(
186 const Fragment::charges_t &charges,
187 const elementcounts_t &elementcounts
188 )
189{
190 elementtargets_t elementtargets;
191 for (elementcounts_t::const_iterator countiter = elementcounts.begin();
192 countiter != elementcounts.end();
193 ++countiter) {
194 chargeiter_t chargeiter = charges.begin();
195 const element_t &element = countiter->first;
196 const count_t &count = countiter->second;
197 for (count_t i = 0; i < count; ++i) {
198 chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
199 if (tempiter != charges.end()) {
200 // try to insert new list
201 std::pair< elementtargets_t::iterator, bool> inserter =
202 elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
203 // if already present, append to it
204 if (!inserter.second) {
205 inserter.first->second.push_back(tempiter);
206 } else { // if created, increase vector's reserve to known size
207 inserter.first->second.reserve(countiter->second);
208 }
209 // search from this element onwards then
210 chargeiter = ++tempiter;
211 } else {
212 ELOG(1, "Could not find desired number of elements " << count << " in fragment.");
213 return Extractors::elementtargets_t();
214 }
215 }
216 }
217 return elementtargets;
218}
219
220Extractors::chargeiters_t
221Extractors::_detail::realignElementtargets(
222 const elementtargets_t &elementtargets,
223 const Fragment::charges_t elements,
224 const elementcounts_t &elementcounts
225 )
226{
227 chargeiters_t targets;
228 elementcounts_t counts; // how many chargeiters of this element have been used
229 targets.reserve(elements.size());
230 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
231 elementiter != elements.end(); ++elementiter) {
232 const element_t &element = *elementiter;
233 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
234#ifndef NDEBUG
235 {
236 elementcounts_t::const_iterator testiter = elementcounts.find(element);
237 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
238 "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
239 +toString(element)+" than we counted initially.");
240 }
241#endif
242 elementtargets_t::const_iterator targetiter = elementtargets.find(element);
243 ASSERT (targetiter != elementtargets.end(),
244 "Extractors::_detail::realignElementTargets() - not enough chargeiters for element "
245 +toString(element)+".");
246 const chargeiters_t &chargeiters = targetiter->second;
247 const chargeiter_t &chargeiter = chargeiters[count++];
248 targets.push_back(chargeiter);
249 }
250 return targets;
251}
252
253Extractors::chargeiters_t
254Extractors::_detail::gatherTargetsFromFragment(
255 const Fragment::charges_t& charges,
256 const Fragment::charges_t elements
257 )
258{
259 /// The main problem here is that we have to know how many same
260 /// elements (but different atoms!) we are required to find. Hence,
261 /// we first have to count same elements, then get different targets
262 /// for each and then associated them in correct order back again.
263
264 // 1. we have to make elements unique with counts, hence convert to map
265 elementcounts_t elementcounts =
266 Extractors::_detail::getElementCounts(elements);
267
268 // 2. then for each element we need as many targets (chargeiters) as counts
269 elementtargets_t elementtargets =
270 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
271
272 // 3. we go again through elements and use one found target for each count
273 // in that order
274 chargeiters_t targets =
275 Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
276
277#ifndef NDEBUG
278 // check all for debugging
279 for (chargeiters_t::const_iterator chargeiter = targets.begin();
280 chargeiter != targets.end();
281 ++chargeiter)
282 ASSERT( *chargeiter != charges.end(),
283 "Extractors::gatherTargetsFromFragment() - we have not found enough targets?!");
284#endif
285
286 return targets;
287}
288
289Fragment::positions_t
290Extractors::gatherPositionsFromFragment(
291 const Fragment::positions_t positions,
292 const Fragment::charges_t charges,
293 const Fragment::charges_t& elements
294 )
295{
296 // 1.-3. gather correct charge positions
297 chargeiters_t targets =
298 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
299 // 4. convert position_t to Vector
300 return Extractors::_detail::gatherPositionsFromTargets(
301 positions,
302 charges,
303 targets);
304}
305
306FunctionModel::arguments_t
307Extractors::gatherDistancesFromFragment(
308 const Fragment::positions_t positions,
309 const Fragment::charges_t charges,
310 const Fragment::charges_t& elements,
311 const size_t globalid
312 )
313{
314 // 1.-3. gather correct charge positions
315 chargeiters_t targets =
316 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
317 // 4. convert position_t to Vector
318 return Extractors::_detail::gatherDistancesFromTargets(
319 positions,
320 charges,
321 targets,
322 globalid);
323}
324
325FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
326 const FunctionModel::arguments_t &args
327 )
328{
329 FunctionModel::arguments_t returnargs(args);
330 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
331 return returnargs;
332}
333
Note: See TracBrowser for help on using the repository browser.