source: src/FunctionApproximation/Extractors.cpp@ e5ebaf

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

Added concatenateArguments to Extractors.

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