source: src/FunctionApproximation/Extractors.cpp@ 57f14c

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

FIX: Extractors::_detail::convertElementcountsToTargets() complains openly when element has not been found.

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