source: src/FunctionApproximation/Extractors.cpp@ 69fcba

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

FIX: Extractor's convertTargetsToArguments() did not set argument_t's indices correctly.

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