source: src/FunctionApproximation/Extractors.cpp@ f7ce2b

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

Changed Extractor's combineArguments() to neglect same arguments.

  • so far, we just add the two given argument vectors. Now, they are sorted and made unique.
  • Property mode set to 100644
File size: 21.2 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 of elements " << count << " in fragment.");
226 return Extractors::elementtargets_t();
227 }
228 }
229 }
230 return elementtargets;
231}
232
233Extractors::elementtargets_t
234Extractors::_detail::convertChargesToTargetMap(
235 const Fragment::charges_t& charges,
236 Fragment::charges_t elements
237 )
238{
239 // place each charge into a map
240 elementtargets_t completeelementtargets;
241 for (chargeiter_t chargeiter = charges.begin();
242 chargeiter != charges.end();
243 ++chargeiter) {
244 std::pair< elementtargets_t::iterator, bool> inserter =
245 completeelementtargets.insert( std::make_pair( *chargeiter, chargeiters_t(1, chargeiter)) );
246 // if already present, append to it
247 if (!inserter.second) {
248 inserter.first->second.push_back(chargeiter);
249 }
250 }
251 // pick out desired charges only
252 std::sort(elements.begin(), elements.end());
253 Fragment::charges_t::iterator eraseiter =
254 std::unique(elements.begin(), elements.end());
255 elements.erase(eraseiter, elements.end());
256 elementtargets_t elementtargets;
257 for(Fragment::charges_t::const_iterator iter = elements.begin();
258 iter != elements.end();
259 ++iter) {
260 elementtargets_t::const_iterator finditer = completeelementtargets.find(*iter);
261 ASSERT( finditer != completeelementtargets.end(),
262 "Extractors::_detail::convertChargesToTargetMap() - no element "+toString(*iter)+" present?");
263 std::pair< elementtargets_t::iterator, bool> inserter =
264 elementtargets.insert( std::make_pair( finditer->first, finditer->second) );
265 ASSERT( inserter.second,
266 "Extractors::_detail::convertChargesToTargetMap() - key twice?");
267 }
268 return elementtargets;
269}
270
271
272Extractors::chargeiters_t
273Extractors::_detail::realignElementtargets(
274 const elementtargets_t &elementtargets,
275 const Fragment::charges_t elements,
276 const elementcounts_t &elementcounts
277 )
278{
279 chargeiters_t targets;
280 elementcounts_t counts; // how many chargeiters of this element have been used
281 if (!elements.empty()) { // skip if no elements given
282 targets.reserve(elements.size());
283 for (Fragment::charges_t::const_iterator elementiter = elements.begin();
284 elementiter != elements.end(); ++elementiter) {
285 const element_t &element = *elementiter;
286 count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
287#ifndef NDEBUG
288 {
289 elementcounts_t::const_iterator testiter = elementcounts.find(element);
290 ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
291 "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
292 +toString(element)+" than we counted initially.");
293 }
294#endif
295 elementtargets_t::const_iterator targetiter = elementtargets.find(element);
296 if (targetiter != elementtargets.end()) {
297 const chargeiters_t &chargeiters = targetiter->second;
298 const chargeiter_t &chargeiter = chargeiters[count++];
299 targets.push_back(chargeiter);
300 }
301 }
302 }
303 return targets;
304}
305
306FunctionModel::arguments_t
307Extractors::gatherAllDistancesFromFragment(
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 /// The main problem here is that we have to know how many same
315 /// elements (but different atoms!) we are required to find. Hence,
316 /// we first have to count same elements, then get different targets
317 /// for each and then associated them in correct order back again.
318
319 // 1. we have to place each charge into a map as unique chargeiter, i.e. map
320 elementtargets_t elementtargets =
321 Extractors::_detail::convertChargesToTargetMap(
322 charges,
323 elements);
324
325 // 2. now we have to combine elementcounts out of elementtargets per desired element
326 // in a combinatorial fashion
327 targets_per_combination_t combinations =
328 Extractors::_detail::CombineChargesAndTargets(
329 elements,
330 elementtargets);
331
332 // 3. finally, convert chargeiters into argument list
333 FunctionModel::arguments_t args =
334 Extractors::_detail::convertTargetsToArguments(
335 positions,
336 charges,
337 combinations,
338 globalid);
339
340 return args;
341}
342
343Extractors::targets_per_combination_t
344Extractors::_detail::CombineChargesAndTargets(
345 const Fragment::charges_t& elements,
346 const elementtargets_t& elementtargets
347 )
348{
349 // recursively create all correct combinations of targets
350 targets_per_combination_t combinations;
351 chargeiters_t currenttargets;
352 boost::function<void (const chargeiters_t &currenttargets)> addFunction =
353 boost::bind(&targets_per_combination_t::push_back,
354 boost::ref(combinations),
355 _1);
356 pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
357
358 return combinations;
359}
360
361const Fragment::position_t& getPositionToChargeIter(
362 const Fragment::positions_t& positions,
363 const Fragment::charges_t& charges,
364 const Extractors::chargeiter_t &iter
365 )
366{
367 Fragment::positions_t::const_iterator positer = positions.begin();
368 std::advance(positer, std::distance(charges.begin(), iter));
369 const Fragment::position_t &position = *positer;
370 return position;
371}
372
373
374FunctionModel::arguments_t
375Extractors::_detail::convertTargetsToArguments(
376 const Fragment::positions_t& positions,
377 const Fragment::charges_t& charges,
378 const targets_per_combination_t combinations,
379 const size_t globalid
380 )
381{
382 FunctionModel::arguments_t args;
383 // create arguments from each combination. We cannot use
384 // gatherallSymmetricDistanceArguments() because it would not create the
385 // correct indices.
386 for (targets_per_combination_t::const_iterator iter = combinations.begin();
387 iter != combinations.end();
388 ++iter) {
389 for(chargeiters_t::const_iterator firstiter = iter->begin();
390 firstiter != iter->end();
391 ++firstiter) {
392 const Fragment::position_t &firstpos =
393 getPositionToChargeIter(positions, charges, *firstiter);
394 const Vector firsttemp(firstpos[0],firstpos[1],firstpos[2]);
395 for(chargeiters_t::const_iterator seconditer = firstiter;
396 seconditer != iter->end();
397 ++seconditer) {
398 if (firstiter == seconditer)
399 continue;
400 const Fragment::position_t &secondpos =
401 getPositionToChargeIter(positions, charges, *seconditer);
402 const Vector secondtemp(secondpos[0],secondpos[1],secondpos[2]);
403 argument_t arg;
404 arg.distance = firsttemp.distance(secondtemp);
405 arg.indices.first = std::distance(charges.begin(), *firstiter);
406 arg.indices.second = std::distance(charges.begin(), *seconditer);
407 arg.types.first = **firstiter;
408 arg.types.second = **seconditer;
409 args.push_back( arg );
410 }
411 }
412 }
413
414 return args;
415}
416
417void
418Extractors::_detail::pickLastElementAsTarget(
419 Fragment::charges_t elements,
420 elementtargets_t elementtargets,
421 chargeiters_t &currenttargets,
422 boost::function<void (const chargeiters_t &currenttargets)> &addFunction
423 )
424{
425 // get last element from charges
426 const Fragment::charge_t charge = elements.back();
427 elements.pop_back();
428 elementtargets_t::iterator iter = elementtargets.find(charge);
429 if (iter == elementtargets.end())
430 return;
431 bool NotEmpty = !iter->second.empty();
432 while (NotEmpty) {
433 // get last target from the vector of chargeiters
434 chargeiter_t target = iter->second.back();
435 iter->second.pop_back();
436 // remove this key if empty
437 if (iter->second.empty()) {
438 elementtargets.erase(iter);
439 NotEmpty = false;
440 }
441 currenttargets.push_back(target);
442 if (elements.empty()) {
443 // call add function
444 {
445 std::stringstream targetstream;
446 BOOST_FOREACH( chargeiter_t target, currenttargets ) {
447 targetstream << " " << *target;
448 }
449 LOG(3, "DEBUG: Adding set" << targetstream.str() << ".");
450 }
451 addFunction(currenttargets);
452 } else {
453 // if not, call us recursively
454 pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
455 }
456 // pop last in currenset again
457 currenttargets.pop_back();
458 }
459}
460
461Extractors::chargeiters_t
462Extractors::_detail::gatherTargetsFromFragment(
463 const Fragment::charges_t& charges,
464 const Fragment::charges_t elements
465 )
466{
467 /// The main problem here is that we have to know how many same
468 /// elements (but different atoms!) we are required to find. Hence,
469 /// we first have to count same elements, then get different targets
470 /// for each and then associated them in correct order back again.
471
472 // 1. we have to make elements unique with counts, hence convert to map
473 elementcounts_t elementcounts =
474 Extractors::_detail::getElementCounts(elements);
475
476 // 2. then for each element we need as many targets (chargeiters) as counts
477 elementtargets_t elementtargets =
478 Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
479
480 // 3. we go again through elements and use one found target for each count
481 // in that order
482 chargeiters_t targets =
483 Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
484
485#ifndef NDEBUG
486 // check all for debugging
487 for (chargeiters_t::const_iterator chargeiter = targets.begin();
488 chargeiter != targets.end();
489 ++chargeiter)
490 ASSERT( *chargeiter != charges.end(),
491 "Extractors::gatherTargetsFromFragment() - we have not found enough targets?!");
492#endif
493
494 return targets;
495}
496
497Fragment::positions_t
498Extractors::gatherPositionsFromFragment(
499 const Fragment::positions_t positions,
500 const Fragment::charges_t charges,
501 const Fragment::charges_t& elements
502 )
503{
504 // 1.-3. gather correct charge positions
505 chargeiters_t targets =
506 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
507 // 4. convert position_t to Vector
508 return Extractors::_detail::gatherPositionsFromTargets(
509 positions,
510 charges,
511 targets);
512}
513
514FunctionModel::arguments_t
515Extractors::gatherDistancesFromFragment(
516 const Fragment::positions_t positions,
517 const Fragment::charges_t charges,
518 const Fragment::charges_t& elements,
519 const size_t globalid
520 )
521{
522 // 1.-3. gather correct charge positions
523 chargeiters_t targets =
524 Extractors::_detail::gatherTargetsFromFragment(charges, elements);
525 // 4. convert position_t to Vector
526 return Extractors::_detail::gatherDistancesFromTargets(
527 positions,
528 charges,
529 targets,
530 globalid);
531}
532
533FunctionModel::arguments_t Extractors::reorderArgumentsByIncreasingDistance(
534 const FunctionModel::arguments_t &args
535 )
536{
537 FunctionModel::arguments_t returnargs(args);
538 std::sort(returnargs.begin(), returnargs.end(), argument_t::DistanceComparator);
539 return returnargs;
540}
541
542FunctionModel::arguments_t Extractors::reorderArgumentsByParticleTypes(
543 const FunctionModel::arguments_t &args,
544 const ParticleTypes_t &_types
545 )
546{
547 typedef std::list< argument_t > ListArguments_t;
548 ListArguments_t availableList(args.begin(), args.end());
549 FunctionModel::arguments_t returnargs;
550 returnargs.reserve(args.size());
551
552 // TODO: fill a lookup map such that we don't have O(M^3) scaling, if M is number
553 // of types (and we always must have M(M-1)/2 args) but O(M^2 log(M)). However, as
554 // M is very small (<=3), this is not necessary fruitful now.
555// typedef ParticleTypes_t firsttype;
556// typedef ParticleTypes_t secondtype;
557// typedef std::map< firsttype, std::map< secondtype, boost::ref(args) > > ArgsLookup_t;
558// ArgsLookup_t ArgsLookup;
559
560 // basically, we have two choose any two pairs out of types but only those
561 // where the first is less than the letter. Hence, we start the second
562 // iterator at the current position of the first one and skip the equal case.
563 for (ParticleTypes_t::const_iterator firstiter = _types.begin();
564 firstiter != _types.end();
565 ++firstiter) {
566 for (ParticleTypes_t::const_iterator seconditer = firstiter;
567 seconditer != _types.end();
568 ++seconditer) {
569 if (seconditer == firstiter)
570 continue;
571
572 // search the right one in _args (we might allow switching places of
573 // firstiter and seconditer, as distance is symmetric).
574 ListArguments_t::iterator iter = availableList.begin();
575 for (;iter != availableList.end(); ++iter) {
576 LOG(3, "DEBUG: Current args is " << *iter << ".");
577 if ((iter->types.first == *firstiter)
578 && (iter->types.second == *seconditer)) {
579 returnargs.push_back( *iter );
580 break;
581 }
582 else if ((iter->types.first == *seconditer)
583 && (iter->types.second == *firstiter)) {
584 argument_t flippedtypes(*iter);
585 std::swap( flippedtypes.indices.first, flippedtypes.indices.second );
586 std::swap( flippedtypes.types.first, flippedtypes.types.second );
587 returnargs.push_back( flippedtypes );
588 break;
589 }
590 }
591 ASSERT( iter != availableList.end(),
592 "Extractors::reorderArgumentsByParticleTypes() - could not find arguments to "
593 +toString(*firstiter)+","+toString(*seconditer)+".");
594 availableList.erase(iter);
595 }
596 }
597// LOG(2, "DEBUG: Final list of args is " << returnargs << ".");
598
599 return returnargs;
600}
601
602
603FunctionModel::arguments_t Extractors::combineArguments(
604 const FunctionModel::arguments_t &firstargs,
605 const FunctionModel::arguments_t &secondargs)
606{
607 FunctionModel::arguments_t args(firstargs);
608 args.insert(args.end(), secondargs.begin(), secondargs.end());
609// return args;
610 std::sort(args.begin(), args.end(),
611 boost::bind(&argument_t::operator<, _1, _2));
612 FunctionModel::arguments_t::iterator iter =
613 std::unique(args.begin(), args.end(),
614 boost::bind(&argument_t::operator==, _1, _2));
615 args.erase(iter, args.end());
616 return args;
617}
618
Note: See TracBrowser for help on using the repository browser.