source: src/FunctionApproximation/Extractors.cpp@ 172b6d

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 172b6d was 5aaa43, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: Fixed new copyright line since start of 2013 in CodeChecks test.

  • we must look for either Uni Bonn or myself.
  • added second copyright line since from 1st of Jan 2013 I am not employed by University of Bonn anymore, hence changes to the code are my own copyright.
  • Property mode set to 100644
File size: 21.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 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
7 *
8 *
9 * This file is part of MoleCuilder.
10 *
11 * MoleCuilder is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * MoleCuilder is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25/*
26 * Extractors.cpp
27 *
28 * Created on: 15.10.2012
29 * Author: heber
30 */
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include <sstream>
40#include <utility>
41#include <vector>
42#include <boost/assign.hpp>
43#include <boost/bind.hpp>
44#include <boost/foreach.hpp>
45
46#include "CodePatterns/Assert.hpp"
47#include "CodePatterns/Log.hpp"
48
49#include "LinearAlgebra/Vector.hpp"
50
51#include "FunctionApproximation/Extractors.hpp"
52#include "FunctionApproximation/FunctionArgument.hpp"
53
54using namespace boost::assign;
55
56#include "CodePatterns/Assert.hpp"
57#include "CodePatterns/Log.hpp"
58
59#include "LinearAlgebra/Vector.hpp"
60
61#include "FunctionApproximation/Extractors.hpp"
62#include "FunctionApproximation/FunctionArgument.hpp"
63
64using namespace boost::assign;
65
66FunctionModel::arguments_t
67Extractors::gatherAllDistanceArguments(
68 const Fragment::positions_t& positions,
69 const Fragment::charges_t& charges,
70 const size_t globalid)
71{
72 FunctionModel::arguments_t result;
73
74 // go through current configuration and gather all other distances
75 Fragment::positions_t::const_iterator firstpositer = positions.begin();
76 for (;firstpositer != positions.end(); ++firstpositer) {
77 Fragment::positions_t::const_iterator secondpositer = positions.begin();//firstpositer;
78 for (; secondpositer != positions.end(); ++secondpositer) {
79 if (firstpositer == secondpositer)
80 continue;
81 argument_t arg;
82 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
83 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
84 arg.distance = firsttemp.distance(secondtemp);
85 arg.types = std::make_pair(
86 charges[ std::distance(positions.begin(), firstpositer) ],
87 charges[ std::distance(positions.begin(), secondpositer) ]
88 );
89 arg.indices = std::make_pair(
90 std::distance(
91 positions.begin(), firstpositer),
92 std::distance(
93 positions.begin(), secondpositer)
94 );
95 arg.globalid = globalid;
96 result.push_back(arg);
97 }
98 }
99
100 return result;
101}
102
103FunctionModel::arguments_t
104Extractors::gatherAllSymmetricDistanceArguments(
105 const Fragment::positions_t& positions,
106 const Fragment::charges_t& charges,
107 const size_t globalid)
108{
109 FunctionModel::arguments_t result;
110
111 // go through current configuration and gather all other distances
112 Fragment::positions_t::const_iterator firstpositer = positions.begin();
113 for (;firstpositer != positions.end(); ++firstpositer) {
114 Fragment::positions_t::const_iterator secondpositer = firstpositer;
115 for (; secondpositer != positions.end(); ++secondpositer) {
116 if (firstpositer == secondpositer)
117 continue;
118 argument_t arg;
119 const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
120 const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
121 arg.distance = firsttemp.distance(secondtemp);
122 arg.types = std::make_pair(
123 charges[ std::distance(positions.begin(), firstpositer) ],
124 charges[ std::distance(positions.begin(), secondpositer) ]
125 );
126 arg.indices = std::make_pair(
127 std::distance(
128 positions.begin(), firstpositer),
129 std::distance(
130 positions.begin(), secondpositer)
131 );
132 arg.globalid = globalid;
133 result.push_back(arg);
134 }
135 }
136
137 return result;
138}
139
140Fragment::positions_t Extractors::_detail::gatherPositionsFromTargets(
141 const Fragment::positions_t& positions,
142 const Fragment::charges_t& charges,
143 const chargeiters_t &targets
144 )
145{
146 Fragment::positions_t filtered_positions;
147 for (chargeiters_t::const_iterator firstpairiter = targets.begin();
148 firstpairiter != targets.end(); ++firstpairiter) {
149 Fragment::positions_t::const_iterator positer = positions.begin();
150 const size_t steps = std::distance(charges.begin(), *firstpairiter);
151 std::advance(positer, steps);
152 filtered_positions.push_back(*positer);
153 }
154 return filtered_positions;
155}
156
157FunctionModel::arguments_t Extractors::_detail::gatherDistancesFromTargets(
158 const Fragment::positions_t& positions,
159 const Fragment::charges_t& charges,
160 const chargeiters_t &targets,
161 const size_t globalid
162 )
163{
164 Fragment::positions_t filtered_positions;
165 Fragment::charges_t filtered_charges;
166 for (chargeiters_t::const_iterator firstpairiter = targets.begin();
167 firstpairiter != targets.end(); ++firstpairiter) {
168 Fragment::positions_t::const_iterator positer = positions.begin();
169 const size_t steps = std::distance(charges.begin(), *firstpairiter);
170 std::advance(positer, steps);
171 filtered_positions.push_back(*positer);
172 filtered_charges.push_back(**firstpairiter);
173 }
174 return Extractors::gatherAllSymmetricDistanceArguments(
175 filtered_positions,
176 filtered_charges,
177 globalid);
178}
179
180Extractors::elementcounts_t
181Extractors::_detail::getElementCounts(
182 const Fragment::charges_t elements
183 )
184{
185 elementcounts_t elementcounts;
186 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
187 elementiter != elements.end(); ++elementiter) {
188 // insert new element
189 std::pair< elementcounts_t::iterator, bool> inserter =
190 elementcounts.insert( std::make_pair( *elementiter, 1) );
191 // if already present, just increase its count
192 if (!inserter.second)
193 ++(inserter.first->second);
194 }
195 return elementcounts;
196}
197
198Extractors::elementtargets_t
199Extractors::_detail::convertElementcountsToTargets(
200 const Fragment::charges_t &charges,
201 const elementcounts_t &elementcounts
202 )
203{
204 elementtargets_t elementtargets;
205 for (elementcounts_t::const_iterator countiter = elementcounts.begin();
206 countiter != elementcounts.end();
207 ++countiter) {
208 chargeiter_t chargeiter = charges.begin();
209 const element_t &element = countiter->first;
210 const count_t &count = countiter->second;
211 for (count_t i = 0; i < count; ++i) {
212 chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
213 if (tempiter != charges.end()) {
214 // try to insert new list
215 std::pair< elementtargets_t::iterator, bool> inserter =
216 elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
217 // if already present, append to it
218 if (!inserter.second) {
219 inserter.first->second.push_back(tempiter);
220 } else { // if created, increase vector's reserve to known size
221 inserter.first->second.reserve(countiter->second);
222 }
223 // search from this element onwards then
224 chargeiter = ++tempiter;
225 } else {
226 ELOG(1, "Could not find desired number " << count << " of element "
227 << element << " in fragment with " << charges << ".");
228 return Extractors::elementtargets_t();
229 }
230 }
231 }
232 return elementtargets;
233}
234
235Extractors::elementtargets_t
236Extractors::_detail::convertChargesToTargetMap(
237 const Fragment::charges_t& charges,
238 Fragment::charges_t elements
239 )
240{
241 // place each charge into a map
242 elementtargets_t completeelementtargets;
243 for (chargeiter_t chargeiter = charges.begin();
244 chargeiter != charges.end();
245 ++chargeiter) {
246 std::pair< elementtargets_t::iterator, bool> inserter =
247 completeelementtargets.insert( std::make_pair( *chargeiter, chargeiters_t(1, chargeiter)) );
248 // if already present, append to it
249 if (!inserter.second) {
250 inserter.first->second.push_back(chargeiter);
251 }
252 }
253 // pick out desired charges only
254 std::sort(elements.begin(), elements.end());
255 Fragment::charges_t::iterator eraseiter =
256 std::unique(elements.begin(), elements.end());
257 elements.erase(eraseiter, elements.end());
258 elementtargets_t elementtargets;
259 for(Fragment::charges_t::const_iterator iter = elements.begin();
260 iter != elements.end();
261 ++iter) {
262 elementtargets_t::const_iterator finditer = completeelementtargets.find(*iter);
263 ASSERT( finditer != completeelementtargets.end(),
264 "Extractors::_detail::convertChargesToTargetMap() - no element "+toString(*iter)+" present?");
265 std::pair< elementtargets_t::iterator, bool> inserter =
266 elementtargets.insert( std::make_pair( finditer->first, finditer->second) );
267 ASSERT( inserter.second,
268 "Extractors::_detail::convertChargesToTargetMap() - key twice?");
269 }
270 return elementtargets;
271}
272
273
274Extractors::chargeiters_t
275Extractors::_detail::realignElementtargets(
276 const elementtargets_t &elementtargets,
277 const Fragment::charges_t elements,
278 const elementcounts_t &elementcounts
279 )
280{
281 chargeiters_t targets;
282 elementcounts_t counts; // how many chargeiters of this element have been used
283 if (!elements.empty()) { // skip if no elements given
284 targets.reserve(elements.size());
285 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
286 elementiter != elements.end(); ++elementiter) {
287 const element_t &element = *elementiter;
288 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
289#ifndef NDEBUG
290 {
291 elementcounts_t::const_iterator testiter = elementcounts.find(element);
292 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
293 "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
294 +toString(element)+" than we counted initially.");
295 }
296#endif
297 elementtargets_t::const_iterator targetiter = elementtargets.find(element);
298 if (targetiter != elementtargets.end()) {
299 const chargeiters_t &chargeiters = targetiter->second;
300 const chargeiter_t &chargeiter = chargeiters[count++];
301 targets.push_back(chargeiter);
302 }
303 }
304 }
305 return targets;
306}
307
308FunctionModel::arguments_t
309Extractors::gatherAllDistancesFromFragment(
310 const Fragment::positions_t& positions,
311 const Fragment::charges_t& charges,
312 const Fragment::charges_t elements,
313 const size_t globalid
314 )
315{
316 /// The main problem here is that we have to know how many same
317 /// elements (but different atoms!) we are required to find. Hence,
318 /// we first have to count same elements, then get different targets
319 /// for each and then associated them in correct order back again.
320
321 // 1. we have to place each charge into a map as unique chargeiter, i.e. map
322 elementtargets_t elementtargets =
323 Extractors::_detail::convertChargesToTargetMap(
324 charges,
325 elements);
326
327 // 2. now we have to combine elementcounts out of elementtargets per desired element
328 // in a combinatorial fashion
329 targets_per_combination_t combinations =
330 Extractors::_detail::CombineChargesAndTargets(
331 elements,
332 elementtargets);
333
334 // 3. finally, convert chargeiters into argument list
335 FunctionModel::arguments_t args =
336 Extractors::_detail::convertTargetsToArguments(
337 positions,
338 charges,
339 combinations,
340 globalid);
341
342 return args;
343}
344
345Extractors::targets_per_combination_t
346Extractors::_detail::CombineChargesAndTargets(
347 const Fragment::charges_t& elements,
348 const elementtargets_t& elementtargets
349 )
350{
351 // recursively create all correct combinations of targets
352 targets_per_combination_t combinations;
353 chargeiters_t currenttargets;
354 boost::function<void (const chargeiters_t &currenttargets)> addFunction =
355 boost::bind(&targets_per_combination_t::push_back,
356 boost::ref(combinations),
357 _1);
358 pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
359
360 return combinations;
361}
362
363const Fragment::position_t& getPositionToChargeIter(
364 const Fragment::positions_t& positions,
365 const Fragment::charges_t& charges,
366 const Extractors::chargeiter_t &iter
367 )
368{
369 Fragment::positions_t::const_iterator positer = positions.begin();
370 std::advance(positer, std::distance(charges.begin(), iter));
371 const Fragment::position_t &position = *positer;
372 return position;
373}
374
375
376FunctionModel::arguments_t
377Extractors::_detail::convertTargetsToArguments(
378 const Fragment::positions_t& positions,
379 const Fragment::charges_t& charges,
380 const targets_per_combination_t combinations,
381 const size_t globalid
382 )
383{
384 FunctionModel::arguments_t args;
385 // create arguments from each combination. We cannot use
386 // gatherallSymmetricDistanceArguments() because it would not create the
387 // correct indices.
388 for (targets_per_combination_t::const_iterator iter = combinations.begin();
389 iter != combinations.end();
390 ++iter) {
391 for(chargeiters_t::const_iterator firstiter = iter->begin();
392 firstiter != iter->end();
393 ++firstiter) {
394 const Fragment::position_t &firstpos =
395 getPositionToChargeIter(positions, charges, *firstiter);
396 const Vector firsttemp(firstpos[0],firstpos[1],firstpos[2]);
397 for(chargeiters_t::const_iterator seconditer = firstiter;
398 seconditer != iter->end();
399 ++seconditer) {
400 if (firstiter == seconditer)
401 continue;
402 const Fragment::position_t &secondpos =
403 getPositionToChargeIter(positions, charges, *seconditer);
404 const Vector secondtemp(secondpos[0],secondpos[1],secondpos[2]);
405 argument_t arg;
406 arg.distance = firsttemp.distance(secondtemp);
407 arg.indices.first = std::distance(charges.begin(), *firstiter);
408 arg.indices.second = std::distance(charges.begin(), *seconditer);
409 arg.types.first = **firstiter;
410 arg.types.second = **seconditer;
411 args.push_back( arg );
412 }
413 }
414 }
415
416 return args;
417}
418
419void
420Extractors::_detail::pickLastElementAsTarget(
421 Fragment::charges_t elements,
422 elementtargets_t elementtargets,
423 chargeiters_t &currenttargets,
424 boost::function<void (const chargeiters_t &currenttargets)> &addFunction
425 )
426{
427 // get last element from charges
428 const Fragment::charge_t charge = elements.back();
429 elements.pop_back();
430 elementtargets_t::iterator iter = elementtargets.find(charge);
431 if (iter == elementtargets.end())
432 return;
433 bool NotEmpty = !iter->second.empty();
434 while (NotEmpty) {
435 // get last target from the vector of chargeiters
436 chargeiter_t target = iter->second.back();
437 iter->second.pop_back();
438 // remove this key if empty
439 if (iter->second.empty()) {
440 elementtargets.erase(iter);
441 NotEmpty = false;
442 }
443 currenttargets.push_back(target);
444 if (elements.empty()) {
445 // call add function
446 {
447 std::stringstream targetstream;
448 BOOST_FOREACH( chargeiter_t target, currenttargets ) {
449 targetstream << " " << *target;
450 }
451 LOG(3, "DEBUG: Adding set" << targetstream.str() << ".");
452 }
453 addFunction(currenttargets);
454 } else {
455 // if not, call us recursively
456 pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
457 }
458 // pop last in currenset again
459 currenttargets.pop_back();
460 }
461}
462
463Extractors::chargeiters_t
464Extractors::_detail::gatherTargetsFromFragment(
465 const Fragment::charges_t& charges,
466 const Fragment::charges_t elements
467 )
468{
469 /// The main problem here is that we have to know how many same
470 /// elements (but different atoms!) we are required to find. Hence,
471 /// we first have to count same elements, then get different targets
472 /// for each and then associated them in correct order back again.
473
474 // 1. we have to make elements unique with counts, hence convert to map
475 elementcounts_t elementcounts =
476 Extractors::_detail::getElementCounts(elements);
477
478 // 2. then for each element we need as many targets (chargeiters) as counts
479 elementtargets_t elementtargets =
480 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
481
482 // 3. we go again through elements and use one found target for each count
483 // in that order
484 chargeiters_t targets =
485 Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
486
487#ifndef NDEBUG
488 // check all for debugging
489 for (chargeiters_t::const_iterator chargeiter = targets.begin();
490 chargeiter != targets.end();
491 ++chargeiter)
492 ASSERT( *chargeiter != charges.end(),
493 "Extractors::gatherTargetsFromFragment() - we have not found enough targets?!");
494#endif
495
496 return targets;
497}
498
499Fragment::positions_t
500Extractors::gatherPositionsFromFragment(
501 const Fragment::positions_t positions,
502 const Fragment::charges_t charges,
503 const Fragment::charges_t& elements
504 )
505{
506 // 1.-3. gather correct charge positions
507 chargeiters_t targets =
508 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
509 // 4. convert position_t to Vector
510 return Extractors::_detail::gatherPositionsFromTargets(
511 positions,
512 charges,
513 targets);
514}
515
516FunctionModel::arguments_t
517Extractors::gatherDistancesFromFragment(
518 const Fragment::positions_t positions,
519 const Fragment::charges_t charges,
520 const Fragment::charges_t& elements,
521 const size_t globalid
522 )
523{
524 // 1.-3. gather correct charge positions
525 chargeiters_t targets =
526 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
527 // 4. convert position_t to Vector
528 return Extractors::_detail::gatherDistancesFromTargets(
529 positions,
530 charges,
531 targets,
532 globalid);
533}
534
535FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
536 const FunctionModel::arguments_t &args
537 )
538{
539 FunctionModel::arguments_t returnargs(args);
540 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
541 return returnargs;
542}
543
544FunctionModel::arguments_t Extractors::reorderArgumentsByParticleTypes(
545 const FunctionModel::arguments_t &args,
546 const ParticleTypes_t &_types
547 )
548{
549 typedef std::list< argument_t > ListArguments_t;
550 ListArguments_t availableList(args.begin(), args.end());
551 FunctionModel::arguments_t returnargs;
552 returnargs.reserve(args.size());
553
554 // TODO: fill a lookup map such that we don't have O(M^3) scaling, if M is number
555 // of types (and we always must have M(M-1)/2 args) but O(M^2 log(M)). However, as
556 // M is very small (<=3), this is not necessary fruitful now.
557// typedef ParticleTypes_t firsttype;
558// typedef ParticleTypes_t secondtype;
559// typedef std::map< firsttype, std::map< secondtype, boost::ref(args) > > ArgsLookup_t;
560// ArgsLookup_t ArgsLookup;
561
562 // basically, we have two choose any two pairs out of types but only those
563 // where the first is less than the letter. Hence, we start the second
564 // iterator at the current position of the first one and skip the equal case.
565 for (ParticleTypes_t::const_iterator firstiter = _types.begin();
566 firstiter != _types.end();
567 ++firstiter) {
568 for (ParticleTypes_t::const_iterator seconditer = firstiter;
569 seconditer != _types.end();
570 ++seconditer) {
571 if (seconditer == firstiter)
572 continue;
573
574 // search the right one in _args (we might allow switching places of
575 // firstiter and seconditer, as distance is symmetric).
576 ListArguments_t::iterator iter = availableList.begin();
577 for (;iter != availableList.end(); ++iter) {
578 LOG(3, "DEBUG: Current args is " << *iter << ".");
579 if ((iter->types.first == *firstiter)
580 && (iter->types.second == *seconditer)) {
581 returnargs.push_back( *iter );
582 break;
583 }
584 else if ((iter->types.first == *seconditer)
585 && (iter->types.second == *firstiter)) {
586 argument_t flippedtypes(*iter);
587 std::swap( flippedtypes.indices.first, flippedtypes.indices.second );
588 std::swap( flippedtypes.types.first, flippedtypes.types.second );
589 returnargs.push_back( flippedtypes );
590 break;
591 }
592 }
593 ASSERT( iter != availableList.end(),
594 "Extractors::reorderArgumentsByParticleTypes() - could not find arguments to "
595 +toString(*firstiter)+","+toString(*seconditer)+".");
596 availableList.erase(iter);
597 }
598 }
599// LOG(2, "DEBUG: Final list of args is " << returnargs << ".");
600
601 return returnargs;
602}
603
604
605FunctionModel::arguments_t Extractors::combineArguments(
606 const FunctionModel::arguments_t &firstargs,
607 const FunctionModel::arguments_t &secondargs)
608{
609 FunctionModel::arguments_t args(firstargs);
610 args.insert(args.end(), secondargs.begin(), secondargs.end());
611// return args;
612 std::sort(args.begin(), args.end(),
613 boost::bind(&argument_t::operator<, _1, _2));
614 FunctionModel::arguments_t::iterator iter =
615 std::unique(args.begin(), args.end(),
616 boost::bind(&argument_t::operator==, _1, _2));
617 args.erase(iter, args.end());
618 return args;
619}
620
Note: See TracBrowser for help on using the repository browser.