source: src/FunctionApproximation/Extractors.cpp@ 5f0c60

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

FIX: Removed doubly present inclusions from Extractors.

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