source: src/FunctionApproximation/Extractors.cpp@ 6cfb355

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 v1.3.11
Last change on this file since 6cfb355 was 52e7da, checked in by Frederik Heber <heber@…>, 12 years ago

Angle training now also uses TrainingData.

  • Property mode set to 100644
File size: 9.3 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 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
84FunctionModel::arguments_t
85Extractors::gatherAllSymmetricDistanceArguments(
86 const Fragment::positions_t &positions,
87 const size_t globalid)
88{
89 FunctionModel::arguments_t result;
90
91 // go through current configuration and gather all other distances
92 Fragment::positions_t::const_iterator firstpositer = positions.begin();
93 for (;firstpositer != positions.end(); ++firstpositer) {
94 Fragment::positions_t::const_iterator secondpositer = firstpositer;
95 for (; secondpositer != positions.end(); ++secondpositer) {
96 if (firstpositer == secondpositer)
97 continue;
98 argument_t arg;
99 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
100 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
101 arg.distance = firsttemp.distance(secondtemp);
102 arg.indices = std::make_pair(
103 std::distance(
104 positions.begin(), firstpositer),
105 std::distance(
106 positions.begin(), secondpositer)
107 );
108 arg.globalid = globalid;
109 result.push_back(arg);
110 }
111 }
112
113 return result;
114}
115
116Fragment::positions_t Extractors::_detail::gatherPositionsFromCharges(
117 const Fragment::positions_t &positions,
118 const Fragment::charges_t &charges,
119 const chargeiters_t targets
120 )
121{
122 Fragment::positions_t filtered_positions;
123 for (chargeiters_t::const_iterator firstpairiter = targets.begin();
124 firstpairiter != targets.end(); ++firstpairiter) {
125 Fragment::positions_t::const_iterator positer = positions.begin();
126 const size_t steps = std::distance(charges.begin(), *firstpairiter);
127 std::advance(positer, steps);
128 filtered_positions.push_back(*positer);
129 }
130 return filtered_positions;
131}
132
133Extractors::elementcounts_t
134Extractors::_detail::getElementCounts(
135 const Fragment::charges_t elements
136 )
137{
138 elementcounts_t elementcounts;
139 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
140 elementiter != elements.end(); ++elementiter) {
141 // insert new element
142 std::pair< elementcounts_t::iterator, bool> inserter =
143 elementcounts.insert( std::make_pair( *elementiter, 1) );
144 // if already present, just increase its count
145 if (!inserter.second)
146 ++(inserter.first->second);
147 }
148 return elementcounts;
149}
150
151Extractors::elementtargets_t
152Extractors::_detail::convertElementcountsToTargets(
153 const Fragment::charges_t &charges,
154 const elementcounts_t &elementcounts
155 )
156{
157 elementtargets_t elementtargets;
158 for (elementcounts_t::const_iterator countiter = elementcounts.begin();
159 countiter != elementcounts.end();
160 ++countiter) {
161 chargeiter_t chargeiter = charges.begin();
162 const element_t &element = countiter->first;
163 const count_t &count = countiter->second;
164 for (count_t i = 0; i < count; ++i) {
165 chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
166 if (tempiter != charges.end()) {
167 // try to insert new list
168 std::pair< elementtargets_t::iterator, bool> inserter =
169 elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
170 // if already present, append to it
171 if (!inserter.second) {
172 inserter.first->second.push_back(tempiter);
173 } else { // if created, increase vector's reserve to known size
174 inserter.first->second.reserve(countiter->second);
175 }
176 // search from this element onwards then
177 chargeiter = ++tempiter;
178 } else {
179 ELOG(1, "Could not find desired number of elements " << count << " in fragment.");
180 return Extractors::elementtargets_t();
181 }
182 }
183 }
184 return elementtargets;
185}
186
187Extractors::chargeiters_t
188Extractors::_detail::realignElementtargets(
189 const elementtargets_t &elementtargets,
190 const Fragment::charges_t elements,
191 const elementcounts_t &elementcounts
192 )
193{
194 chargeiters_t targets;
195 elementcounts_t counts; // how many chargeiters of this element have been used
196 targets.reserve(elements.size());
197 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
198 elementiter != elements.end(); ++elementiter) {
199 const element_t &element = *elementiter;
200 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
201#ifndef NDEBUG
202 {
203 elementcounts_t::const_iterator testiter = elementcounts.find(element);
204 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
205 "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
206 +toString(element)+" than we counted initially.");
207 }
208#endif
209 elementtargets_t::const_iterator targetiter = elementtargets.find(element);
210 ASSERT (targetiter != elementtargets.end(),
211 "Extractors::_detail::realignElementTargets() - not enough chargeiters for element "
212 +toString(element)+".");
213 const chargeiters_t &chargeiters = targetiter->second;
214 const chargeiter_t &chargeiter = chargeiters[count++];
215 targets.push_back(chargeiter);
216 }
217 return targets;
218}
219
220Fragment::positions_t
221Extractors::gatherPositionOfTuples(
222 const Fragment& fragment,
223 const Fragment::charges_t elements
224 ) {
225 const Fragment::charges_t charges = fragment.getCharges();
226 /// The main problem here is that we have to know how many same
227 /// elements (but different atoms!) we are required to find. Hence,
228 /// we first have to count same elements, then get different targets
229 /// for each and then associated them in correct order back again.
230
231 // 1. we have to make elements unique with counts, hence convert to map
232 elementcounts_t elementcounts =
233 Extractors::_detail::getElementCounts(elements);
234
235 // 2. then for each element we need as many targets (chargeiters) as counts
236 elementtargets_t elementtargets =
237 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
238
239 // 3. we go again through elements and use one found target for each count
240 // in that order
241 chargeiters_t targets =
242 Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
243
244#ifndef NDEBUG
245 // check all for debugging
246 for (chargeiters_t::const_iterator chargeiter = targets.begin();
247 chargeiter != targets.end();
248 ++chargeiter)
249 ASSERT( *chargeiter != charges.end(),
250 "Extractors::gatherDistanceOfTuples() - we have not found enough targets?!");
251#endif
252 // 4. convert position_t to Vector
253 return Extractors::_detail::gatherPositionsFromCharges(
254 fragment.getPositions(),
255 charges,
256 targets);
257}
258
259FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
260 const FunctionModel::arguments_t &args
261 )
262{
263 FunctionModel::arguments_t returnargs(args);
264 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
265 return returnargs;
266}
267
Note: See TracBrowser for help on using the repository browser.