Changeset 1155ba for src/FunctionApproximation
- Timestamp:
- Nov 11, 2016, 2:25:36 PM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, 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_ChronosMutex, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids_IntegrationTest, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, ThirdParty_MPQC_rebuilt_buildsystem, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes, stable
- Children:
- f45a91
- Parents:
- f5dbea
- git-author:
- Frederik Heber <heber@…> (10/08/16 07:56:22)
- git-committer:
- Frederik Heber <heber@…> (11/11/16 14:25:36)
- Location:
- src/FunctionApproximation
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/FunctionApproximation/Extractors.cpp
rf5dbea r1155ba 531 531 } 532 532 533 FunctionModel::list_of_arguments_t Extractors:: reorderArgumentsByParticleTypes(534 const FunctionModel:: list_of_arguments_t &listargs,533 FunctionModel::list_of_arguments_t Extractors::filterArgumentsByBindingModel( 534 const FunctionModel::arguments_t &args, 535 535 const HomologyGraph &_graph, 536 536 const ParticleTypes_t &_types, … … 539 539 { 540 540 FunctionModel::list_of_arguments_t returnargs; 541 for (FunctionModel::list_of_arguments_t::const_iterator listiter = listargs.begin(); 542 listiter != listargs.end(); ++listiter) { 543 const FunctionModel::arguments_t &args = *listiter; 544 545 // deal with the case when there are no distances (ConstantPotential) 546 if (_bindingmodel.getNodes().size() < 2) { 547 LOG(3, "DEBUG: Potential requires only one or no particle types, needs no distances."); 548 continue; 549 } 550 if (_bindingmodel.getGraph().getEdges().empty()) { 551 LOG(3, "DEBUG: Potential represents non-bonded interactions, gets all distances."); 552 // TODO: Here we need to constrain to all distances matching the types? 553 returnargs.push_back(args); 554 continue; 555 } 556 557 /// 0. place all nodes in a lookup map for their type 558 type_index_lookup_t type_index_lookup; 559 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 560 iter != args.end(); ++iter) { 561 if (type_index_lookup.left.find(iter->indices.first) == type_index_lookup.left.end()) 562 type_index_lookup.left.insert( std::make_pair(iter->indices.first, iter->types.first) ); 563 else { 564 ASSERT(type_index_lookup.left.at(iter->indices.first) == iter->types.first, 565 "Extractors::reorderArgumentsByParticleTypes() - entry " +toString(iter->indices.first)+ 566 " is already present with different type "+toString(iter->types.first) 567 +" than "+toString(type_index_lookup.left.at(iter->indices.first))); 568 } 569 if (type_index_lookup.left.find(iter->indices.second) == type_index_lookup.left.end()) 570 type_index_lookup.left.insert( std::make_pair(iter->indices.second, iter->types.second) ); 571 else { 572 ASSERT(type_index_lookup.left.at(iter->indices.second) == iter->types.second, 573 "Extractors::reorderArgumentsByParticleTypes() - entry " +toString(iter->indices.second)+ 574 " is already present with different type "+toString(iter->types.second) 575 +" than "+toString(type_index_lookup.left.at(iter->indices.second))); 576 } 577 } 578 if (DoLog(3)) { 579 std::stringstream output; 580 for (type_index_lookup_t::left_const_iterator indexiter = type_index_lookup.left.begin(); 581 indexiter != type_index_lookup.left.end(); ++indexiter) { 582 output << " [" << indexiter->first << "," << indexiter->second << "]"; 583 } 584 LOG(3, "DEBUG: index to type map:" << output.str()); 585 } 586 if (DoLog(3)) { 587 std::stringstream output; 588 for (type_index_lookup_t::right_const_iterator typeiter = type_index_lookup.right.begin(); 589 typeiter != type_index_lookup.right.end(); ++typeiter) { 590 output << " [" << typeiter->first << "," << typeiter->second << "]"; 591 } 592 LOG(3, "DEBUG: type to index map " << output.str()); 593 } 594 595 /// 1. construct boost::graph from arguments_t (iter) 596 const size_t N = type_index_lookup.left.size(); 597 UndirectedGraph fragmentgraph(N); 598 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 599 iter != args.end(); ++iter) { 600 if (iter->bonded) 601 boost::add_edge(iter->indices.first, iter->indices.second, fragmentgraph); 602 } 603 index_map_t index_map = boost::get(boost::vertex_index, fragmentgraph); 604 LOG(2, "DEBUG: We have " << boost::num_vertices(fragmentgraph) << " nodes in the fragment graph."); 605 606 /// 2. grab first node of the binding model (gives a type) 607 const BindingModel::vector_nodes_t::const_iterator firstiter = _bindingmodel.getNodes().begin(); 608 const FragmentNode &firstnode = *firstiter; 609 const Extractors::ParticleType_t &firsttype = firstnode.getAtomicNumber(); 610 611 /// 3. grab all candidate nodes contained in arguments_t 612 std::pair< 613 type_index_lookup_t::right_const_iterator, 614 type_index_lookup_t::right_const_iterator> range = type_index_lookup.right.equal_range(firsttype); 615 616 /// 4. go over all candidate nodes (gives index) 617 const size_t nodes_in_bindingmodel = _bindingmodel.getNodes().size(); 618 LOG(2, "DEBUG: There are " << nodes_in_bindingmodel << " nodes in the binding model."); 619 set_of_nodes_t set_of_nodes; 620 for (type_index_lookup_t::right_const_iterator rangeiter = range.first; 621 rangeiter != range.second; ++rangeiter) { 622 const size_t &rootindex = rangeiter->second; 623 LOG(2, "DEBUG: Current root index is " << rootindex); 624 625 /// 5a. from node in graph (with this index) perform BFS till n-1 (#nodes in binding model) 626 std::vector<size_t> distances(boost::num_vertices(fragmentgraph)); 627 boost::breadth_first_search( 628 fragmentgraph, 629 boost::vertex(rootindex, fragmentgraph), 630 boost::visitor(record_distance(&distances[0]))); 631 LOG(3, "DEBUG: BFS discovered the following distances " << distances); 632 633 /// 5b. and store all node in map with distance to root as key 634 nodes_per_level_t nodes_per_level; 635 for (size_t i=0;i<distances.size();++i) { 636 nodes_per_level.insert( std::make_pair(level_t(distances[i]), node_t(i)) ); 637 } 638 LOG(3, "DEBUG: Nodes per level are " << nodes_per_level); 639 640 /// 6. construct all possible induced connected subgraphs with this map (see fragmentation) 641 nodes_t nodes; 642 // rootindex is always contained 643 nodes.insert( rootindex ); 644 level_t level = 0; 645 646 generateAllInducedConnectedSubgraphs( 647 nodes_in_bindingmodel-1, level, nodes, set_of_nodes, nodes_per_level, fragmentgraph, distances, index_map); 648 LOG(2, "DEBUG: We have found " << set_of_nodes.size() << " unique induced, connected subgraphs."); 649 } 650 651 /// 8. go through each induced, connected subgraph 652 for (set_of_nodes_t::const_iterator nodesiter = set_of_nodes.begin(); 653 nodesiter != set_of_nodes.end(); ++nodesiter) { 654 /// 9. convert its nodes into a HomologyGraph using the subgraph and arguments_t (types for index) 655 const nodes_t &nodes = *nodesiter; 656 const HomologyGraph nodes_graph = 657 createHomologyGraphFromNodes(nodes, type_index_lookup, fragmentgraph, index_map); 658 659 /// 10. compare each converted HomologyGraph with _bindingmodel: Accept or Reject 660 if (nodes_graph == _bindingmodel.getGraph()) { 661 LOG(2, "ACCEPT: " << nodes_graph << " is identical to " << _bindingmodel.getGraph()); 662 /// 11. for each accepted keyset, pick _all_ symmetric distances from arguments_t 663 FunctionModel::arguments_t argumentbunch; 664 argumentbunch.reserve(args.size()); 665 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 666 iter != args.end(); ++iter) { 667 if ((nodes.count(iter->indices.first) != 0) && (nodes.count(iter->indices.second) != 0)) { 668 argumentbunch.push_back(*iter); 541 542 // deal with the case when there are no distances (ConstantPotential) 543 if (_bindingmodel.getNodes().size() < 2) { 544 LOG(3, "DEBUG: Potential requires only one or no particle types, needs no distances."); 545 return returnargs; 546 } 547 if (_bindingmodel.getGraph().getEdges().empty()) { 548 LOG(3, "DEBUG: Potential represents non-bonded interactions, gets all distances."); 549 // TODO: Here we need to constrain to all distances matching the types? 550 returnargs.push_back(args); 551 return returnargs; 552 } 553 554 /// 0. place all nodes in a lookup map for their type 555 type_index_lookup_t type_index_lookup; 556 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 557 iter != args.end(); ++iter) { 558 if (type_index_lookup.left.find(iter->indices.first) == type_index_lookup.left.end()) 559 type_index_lookup.left.insert( std::make_pair(iter->indices.first, iter->types.first) ); 560 else { 561 ASSERT(type_index_lookup.left.at(iter->indices.first) == iter->types.first, 562 "Extractors::reorderArgumentsByParticleTypes() - entry " +toString(iter->indices.first)+ 563 " is already present with different type "+toString(iter->types.first) 564 +" than "+toString(type_index_lookup.left.at(iter->indices.first))); 565 } 566 if (type_index_lookup.left.find(iter->indices.second) == type_index_lookup.left.end()) 567 type_index_lookup.left.insert( std::make_pair(iter->indices.second, iter->types.second) ); 568 else { 569 ASSERT(type_index_lookup.left.at(iter->indices.second) == iter->types.second, 570 "Extractors::reorderArgumentsByParticleTypes() - entry " +toString(iter->indices.second)+ 571 " is already present with different type "+toString(iter->types.second) 572 +" than "+toString(type_index_lookup.left.at(iter->indices.second))); 573 } 574 } 575 if (DoLog(3)) { 576 std::stringstream output; 577 for (type_index_lookup_t::left_const_iterator indexiter = type_index_lookup.left.begin(); 578 indexiter != type_index_lookup.left.end(); ++indexiter) { 579 output << " [" << indexiter->first << "," << indexiter->second << "]"; 580 } 581 LOG(3, "DEBUG: index to type map:" << output.str()); 582 } 583 if (DoLog(3)) { 584 std::stringstream output; 585 for (type_index_lookup_t::right_const_iterator typeiter = type_index_lookup.right.begin(); 586 typeiter != type_index_lookup.right.end(); ++typeiter) { 587 output << " [" << typeiter->first << "," << typeiter->second << "]"; 588 } 589 LOG(3, "DEBUG: type to index map " << output.str()); 590 } 591 592 /// 1. construct boost::graph from arguments_t (iter) 593 const size_t N = type_index_lookup.left.size(); 594 UndirectedGraph fragmentgraph(N); 595 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 596 iter != args.end(); ++iter) { 597 if (iter->bonded) 598 boost::add_edge(iter->indices.first, iter->indices.second, fragmentgraph); 599 } 600 index_map_t index_map = boost::get(boost::vertex_index, fragmentgraph); 601 LOG(2, "DEBUG: We have " << boost::num_vertices(fragmentgraph) << " nodes in the fragment graph."); 602 603 /// 2. grab first node of the binding model (gives a type) 604 const BindingModel::vector_nodes_t::const_iterator firstiter = _bindingmodel.getNodes().begin(); 605 const FragmentNode &firstnode = *firstiter; 606 const Extractors::ParticleType_t &firsttype = firstnode.getAtomicNumber(); 607 608 /// 3. grab all candidate nodes contained in arguments_t 609 std::pair< 610 type_index_lookup_t::right_const_iterator, 611 type_index_lookup_t::right_const_iterator> range = type_index_lookup.right.equal_range(firsttype); 612 613 /// 4. go over all candidate nodes (gives index) 614 const size_t nodes_in_bindingmodel = _bindingmodel.getNodes().size(); 615 LOG(2, "DEBUG: There are " << nodes_in_bindingmodel << " nodes in the binding model."); 616 set_of_nodes_t set_of_nodes; 617 for (type_index_lookup_t::right_const_iterator rangeiter = range.first; 618 rangeiter != range.second; ++rangeiter) { 619 const size_t &rootindex = rangeiter->second; 620 LOG(2, "DEBUG: Current root index is " << rootindex); 621 622 /// 5a. from node in graph (with this index) perform BFS till n-1 (#nodes in binding model) 623 std::vector<size_t> distances(boost::num_vertices(fragmentgraph)); 624 boost::breadth_first_search( 625 fragmentgraph, 626 boost::vertex(rootindex, fragmentgraph), 627 boost::visitor(record_distance(&distances[0]))); 628 LOG(3, "DEBUG: BFS discovered the following distances " << distances); 629 630 /// 5b. and store all node in map with distance to root as key 631 nodes_per_level_t nodes_per_level; 632 for (size_t i=0;i<distances.size();++i) { 633 nodes_per_level.insert( std::make_pair(level_t(distances[i]), node_t(i)) ); 634 } 635 LOG(3, "DEBUG: Nodes per level are " << nodes_per_level); 636 637 /// 6. construct all possible induced connected subgraphs with this map (see fragmentation) 638 nodes_t nodes; 639 // rootindex is always contained 640 nodes.insert( rootindex ); 641 level_t level = 0; 642 643 generateAllInducedConnectedSubgraphs( 644 nodes_in_bindingmodel-1, level, nodes, set_of_nodes, nodes_per_level, fragmentgraph, distances, index_map); 645 LOG(2, "DEBUG: We have found " << set_of_nodes.size() << " unique induced, connected subgraphs."); 646 } 647 648 /// 8. go through each induced, connected subgraph 649 for (set_of_nodes_t::const_iterator nodesiter = set_of_nodes.begin(); 650 nodesiter != set_of_nodes.end(); ++nodesiter) { 651 /// 9. convert its nodes into a HomologyGraph using the subgraph and arguments_t (types for index) 652 const nodes_t &nodes = *nodesiter; 653 const HomologyGraph nodes_graph = 654 createHomologyGraphFromNodes(nodes, type_index_lookup, fragmentgraph, index_map); 655 656 /// 10. compare each converted HomologyGraph with _bindingmodel: Accept or Reject 657 if (nodes_graph == _bindingmodel.getGraph()) { 658 LOG(2, "ACCEPT: " << nodes_graph << " is identical to " << _bindingmodel.getGraph()); 659 /// 11. for each accepted keyset, pick _all_ symmetric distances from arguments_t 660 FunctionModel::arguments_t argumentbunch; 661 argumentbunch.reserve(args.size()); 662 for(FunctionModel::arguments_t::const_iterator iter = args.begin(); 663 iter != args.end(); ++iter) { 664 if ((nodes.count(iter->indices.first) != 0) && (nodes.count(iter->indices.second) != 0)) { 665 argumentbunch.push_back(*iter); 666 } 667 } 668 const size_t num_symmetric_distances = nodes.size()*(nodes.size()-1)/2; 669 ASSERT( argumentbunch.size() == num_symmetric_distances, 670 "Extractors::reorderArgumentsByParticleTypes() - only "+toString(argumentbunch.size())+ 671 " found instead of "+toString(num_symmetric_distances)); 672 LOG(3, "DEBUG: Final bunch of arguments is " << argumentbunch << "."); 673 674 /** 675 * We still need to bring the arguments in the correct order for the potential. 676 * 677 * The potential gives the desired order via the nodes in the HomologyGraph! Their 678 * sequence matches with the user-defined particle types and because of the properties 679 * of the homology graph (FragmentNode stores type and number of edges) it also 680 * matches with the desired bonding graph. 681 */ 682 683 /// So, we need to extract from the argumentbunch the information contained in each 684 /// FragmentNode, namely its type and the number of connected edges 685 node_FragmentNode_map_t node_FragmentNode_map = fillNodeFragmentMap(argumentbunch); 686 687 /// Then, we step through the nodes of the bindingmodel ... 688 /// ... and find a suitable mapping from indices in the arguments to 689 /// the index in the order of the HomologyGraph's nodes 690 const BindingModel::vector_nodes_t bindingmodel_nodes = _bindingmodel.getNodes(); 691 argindex_to_nodeindex_t argindex_to_nodeindex; 692 size_t nodeindex = 0; 693 for (BindingModel::vector_nodes_t::const_iterator nodeiter = bindingmodel_nodes.begin(); 694 nodeiter != bindingmodel_nodes.end(); ++nodeiter) { 695 const FragmentNode &node = *nodeiter; 696 LOG(3, "DEBUG: Binding model's node #" << node << "."); 697 /// ... and pick for each the first (and unique) from these stored nodes. 698 node_FragmentNode_map_t::iterator mapiter = node_FragmentNode_map.begin(); 699 for (;mapiter != node_FragmentNode_map.end(); ++mapiter) { 700 if ((mapiter->second.first == node.getAtomicNumber()) 701 && (mapiter->second.second == node.getConnectedEdges())) { 702 LOG(3, "DEBUG: #" << mapiter->first << " with type " << mapiter->second.first 703 << " and " << mapiter->second.second << " connected edges matches."); 704 break; 669 705 } 670 706 } 671 const size_t num_symmetric_distances = nodes.size()*(nodes.size()-1)/2; 672 ASSERT( argumentbunch.size() == num_symmetric_distances, 673 "Extractors::reorderArgumentsByParticleTypes() - only "+toString(argumentbunch.size())+ 674 " found instead of "+toString(num_symmetric_distances)); 675 LOG(3, "DEBUG: Final bunch of arguments is " << argumentbunch << "."); 676 677 /** 678 * We still need to bring the arguments in the correct order for the potential. 679 * 680 * The potential gives the desired order via the nodes in the HomologyGraph! Their 681 * sequence matches with the user-defined particle types and because of the properties 682 * of the homology graph (FragmentNode stores type and number of edges) it also 683 * matches with the desired bonding graph. 684 */ 685 686 /// So, we need to extract from the argumentbunch the information contained in each 687 /// FragmentNode, namely its type and the number of connected edges 688 node_FragmentNode_map_t node_FragmentNode_map = fillNodeFragmentMap(argumentbunch); 689 690 /// Then, we step through the nodes of the bindingmodel ... 691 /// ... and find a suitable mapping from indices in the arguments to 692 /// the index in the order of the HomologyGraph's nodes 693 const BindingModel::vector_nodes_t bindingmodel_nodes = _bindingmodel.getNodes(); 694 argindex_to_nodeindex_t argindex_to_nodeindex; 695 size_t nodeindex = 0; 696 for (BindingModel::vector_nodes_t::const_iterator nodeiter = bindingmodel_nodes.begin(); 697 nodeiter != bindingmodel_nodes.end(); ++nodeiter) { 698 const FragmentNode &node = *nodeiter; 699 LOG(3, "DEBUG: Binding model's node #" << node << "."); 700 /// ... and pick for each the first (and unique) from these stored nodes. 701 node_FragmentNode_map_t::iterator mapiter = node_FragmentNode_map.begin(); 702 for (;mapiter != node_FragmentNode_map.end(); ++mapiter) { 703 if ((mapiter->second.first == node.getAtomicNumber()) 704 && (mapiter->second.second == node.getConnectedEdges())) { 705 LOG(3, "DEBUG: #" << mapiter->first << " with type " << mapiter->second.first 706 << " and " << mapiter->second.second << " connected edges matches."); 707 break; 708 } 709 } 710 ASSERT( mapiter != node_FragmentNode_map.end(), 711 "Extractors::reorderArgumentsByParticleTypes() - could not find a suitable node for #"+ 712 toString(mapiter->first)+" with type "+toString(mapiter->second.first)+" and "+ 713 toString(mapiter->second.second)+" connected edges"); 714 std::pair<argindex_to_nodeindex_t::iterator, bool> inserter = 715 argindex_to_nodeindex.insert( std::make_pair(mapiter->first, nodeindex++) ); 716 ASSERT( inserter.second, 717 "Extractors::reorderArgumentsByParticleTypes() - node #"+toString(mapiter->first)+ 718 " is already present?"); 719 // remove to ensure uniqueness of choice 720 node_FragmentNode_map.erase(mapiter); 721 } 722 LOG(4, "DEBUG: argument's indices to node index map is " << argindex_to_nodeindex); 723 // i.e. this is not the arg's index in argumentbunch, but the index of the position 724 // contained in the argument_t 725 726 /// Finally, we only need to bring the arguments in the typical order: 727 /// 01 02 03 04 ... 0n, 12 13 14 ... 1n, 23 24 25 ... 2n, ..., (n-1)n 728 /// These ordering we store in a map for each argument's indices 729 const size_t num_args = argindex_to_nodeindex.size(); 730 argument_placement_map_t argument_placement_map = fillArgumentsPlacementMap(num_args); 731 LOG(4, "DEBUG: Placement map is " << argument_placement_map); 732 ASSERT( argument_placement_map.size() == argumentbunch.size(), 733 "Extractors::reorderArgumentsByParticleTypes() - placement map has size "+ 734 toString(argument_placement_map.size())+" and we expected "+toString(argumentbunch.size())); 735 736 // and finally resort the arguments with the constructed placement map 737 FunctionModel::arguments_t sortedargs(argumentbunch.size()); 738 for (FunctionModel::arguments_t::const_iterator argiter = argumentbunch.begin(); 739 argiter != argumentbunch.end(); ++argiter) { 740 const argument_t &arg = *argiter; 741 const argument_t::indices_t translatedIndices = 742 translateIndices(argindex_to_nodeindex, arg.indices); 743 const argument_placement_map_t::const_iterator indexiter = 744 argument_placement_map.find( translatedIndices ); 745 ASSERT( indexiter != argument_placement_map.end(), 746 "Extractors::reorderArgumentsByParticleTypes() - could not find place for edge "+ 747 toString(arg.indices)); 748 sortedargs[indexiter->second] = arg; 749 LOG(3, "DEBUG: Placed argument " << arg << " at #" << indexiter->second 750 << " as translated indices are " << translatedIndices); 751 } 752 LOG(2, "DEBUG: Sorted arguments are " << sortedargs << "."); 753 754 returnargs.push_back(sortedargs); 755 } else { 756 LOG(2, "REJECT: " << nodes_graph << " is not identical to " << _bindingmodel.getGraph()); 757 } 707 ASSERT( mapiter != node_FragmentNode_map.end(), 708 "Extractors::reorderArgumentsByParticleTypes() - could not find a suitable node for #"+ 709 toString(mapiter->first)+" with type "+toString(mapiter->second.first)+" and "+ 710 toString(mapiter->second.second)+" connected edges"); 711 std::pair<argindex_to_nodeindex_t::iterator, bool> inserter = 712 argindex_to_nodeindex.insert( std::make_pair(mapiter->first, nodeindex++) ); 713 ASSERT( inserter.second, 714 "Extractors::reorderArgumentsByParticleTypes() - node #"+toString(mapiter->first)+ 715 " is already present?"); 716 // remove to ensure uniqueness of choice 717 node_FragmentNode_map.erase(mapiter); 718 } 719 LOG(4, "DEBUG: argument's indices to node index map is " << argindex_to_nodeindex); 720 // i.e. this is not the arg's index in argumentbunch, but the index of the position 721 // contained in the argument_t 722 723 /// Finally, we only need to bring the arguments in the typical order: 724 /// 01 02 03 04 ... 0n, 12 13 14 ... 1n, 23 24 25 ... 2n, ..., (n-1)n 725 /// These ordering we store in a map for each argument's indices 726 const size_t num_args = argindex_to_nodeindex.size(); 727 argument_placement_map_t argument_placement_map = fillArgumentsPlacementMap(num_args); 728 LOG(4, "DEBUG: Placement map is " << argument_placement_map); 729 ASSERT( argument_placement_map.size() == argumentbunch.size(), 730 "Extractors::reorderArgumentsByParticleTypes() - placement map has size "+ 731 toString(argument_placement_map.size())+" and we expected "+toString(argumentbunch.size())); 732 733 // and finally resort the arguments with the constructed placement map 734 FunctionModel::arguments_t sortedargs(argumentbunch.size()); 735 for (FunctionModel::arguments_t::const_iterator argiter = argumentbunch.begin(); 736 argiter != argumentbunch.end(); ++argiter) { 737 const argument_t &arg = *argiter; 738 const argument_t::indices_t translatedIndices = 739 translateIndices(argindex_to_nodeindex, arg.indices); 740 const argument_placement_map_t::const_iterator indexiter = 741 argument_placement_map.find( translatedIndices ); 742 ASSERT( indexiter != argument_placement_map.end(), 743 "Extractors::reorderArgumentsByParticleTypes() - could not find place for edge "+ 744 toString(arg.indices)); 745 sortedargs[indexiter->second] = arg; 746 LOG(3, "DEBUG: Placed argument " << arg << " at #" << indexiter->second 747 << " as translated indices are " << translatedIndices); 748 } 749 LOG(2, "DEBUG: Sorted arguments are " << sortedargs << "."); 750 751 returnargs.push_back(sortedargs); 752 } else { 753 LOG(2, "REJECT: " << nodes_graph << " is not identical to " << _bindingmodel.getGraph()); 758 754 } 759 755 } … … 769 765 ) 770 766 { 767 // list allows for quicker removal than vector 771 768 typedef std::list< argument_t > ListArguments_t; 772 769 ListArguments_t availableList(args.begin(), args.end()); 773 770 LOG(2, "DEBUG: Initial list of args is " << args << "."); 774 775 771 776 772 // TODO: fill a lookup map such that we don't have O(M^3) scaling, if M is number … … 779 775 // typedef ParticleTypes_t firsttype; 780 776 // typedef ParticleTypes_t secondtype; 781 // typedef std::map< firsttype, std::map< secondtype, boost::ref(args)> > ArgsLookup_t;777 // typedef std::map< firsttype, std::map< secondtype, FunctionModel::arguments_t > > ArgsLookup_t; 782 778 // ArgsLookup_t ArgsLookup; 779 780 ASSERT( _types.size() <= 2, 781 "Extractors::filterArgumentsByParticleTypes() - this only filters and does not reorder." 782 +std::string(" Hence, it is not useful for multiple arguments per model.")); 783 783 784 784 // basically, we have two choose any two pairs out of types but only those 785 785 // where the first is less than the latter. Hence, we start the second 786 786 // iterator at the current position of the first one and skip the equal case. 787 FunctionModel::arguments_t allargs; 788 allargs.reserve(args.size()); 787 FunctionModel::list_of_arguments_t returnargs; 789 788 for (ParticleTypes_t::const_iterator firstiter = _types.begin(); 790 789 firstiter != _types.end(); … … 804 803 if ((iter->types.first == *firstiter) 805 804 && (iter->types.second == *seconditer)) { 806 allargs.push_back( *iter);805 returnargs.push_back( FunctionModel::arguments_t(1, *iter) ); 807 806 iter = availableList.erase(iter); 808 807 LOG(4, "DEBUG: Accepted argument."); 809 808 } else if ((iter->types.first == *seconditer) 810 809 && (iter->types.second == *firstiter)) { 811 allargs.push_back( *iter);810 returnargs.push_back( FunctionModel::arguments_t(1, *iter) ); 812 811 iter = availableList.erase(iter); 813 812 LOG(4, "DEBUG: Accepted (flipped) argument."); … … 819 818 } 820 819 } 821 LOG(2, "DEBUG: Final list of args is " << allargs << ".");822 823 // first, we bring together tuples of distances that belong together824 FunctionModel::list_of_arguments_t singlelist_allargs;825 singlelist_allargs.push_back(allargs);826 FunctionModel::list_of_arguments_t returnargs =827 reorderArgumentsByParticleTypes(singlelist_allargs, _graph, _types, _bindingmodel);828 // ASSERT( sortedargs.size() == (size_t)1,829 // "Extractors::filterArgumentsByParticleTypes() - reordering did not generate a single list.");830 // // then we split up the tuples of arguments and place each into single list831 // FunctionModel::list_of_arguments_t returnargs;832 // FunctionModel::arguments_t::const_iterator argiter = sortedargs.begin()->begin();833 // const size_t num_types = _types.size();834 // const size_t args_per_tuple = num_types * (num_types-1) / 2;835 // while (argiter != sortedargs.begin()->end()) {836 // FunctionModel::arguments_t currenttuple(args_per_tuple);837 // const FunctionModel::arguments_t::const_iterator startiter = argiter;838 // std::advance(argiter, args_per_tuple);839 //#ifndef NDEBUG840 // FunctionModel::arguments_t::const_iterator endoutiter =841 //#endif842 // std::copy(startiter, argiter, currenttuple.begin());843 // ASSERT( endoutiter == currenttuple.end(),844 // "Extractors::filterArgumentsByParticleTypes() - currenttuple not initialized to right size.");845 // returnargs.push_back(currenttuple);846 // }847 820 848 821 LOG(2, "DEBUG: We have generated " << returnargs.size() << " tuples of distances."); -
src/FunctionApproximation/Extractors.hpp
rf5dbea r1155ba 103 103 } 104 104 105 /** Reorder the arguments to bring adjacent ones together.105 /** Filter the arguments to select only these required by the model. 106 106 * 107 * After filtering via particle types arguments related via same indices 108 * must not necessarily be contained in the same bunch. This reordering 109 * is done here, preserving the alignment given in 110 * \sa filterArgumentsByParticleTypes() 107 * \warning this is meant as a faster way of getting the arguments for simple 108 * pair potentials. In any other case, one should use filterArgumentsByBindingModel() 111 109 * 112 110 * \param listargs list of arguments to reorder each … … 115 113 * \return reordered args 116 114 */ 117 FunctionModel::list_of_arguments_t reorderArgumentsByParticleTypes(118 const FunctionModel:: list_of_arguments_t &eachargs,115 FunctionModel::list_of_arguments_t filterArgumentsByParticleTypes( 116 const FunctionModel::arguments_t &args, 119 117 const HomologyGraph &_graph, 120 118 const ParticleTypes_t &_types, … … 122 120 ); 123 121 124 /** Filter a rguments according to types, allowing multiples.122 /** Filter and reorder the arguments to bring adjacent ones together. 125 123 * 126 * If particle types is (0,1,2) and three arguments, each with a pair of types, 127 * are given, then the alignment will be: (0,1), (0,2), and (1,2). 124 * We need to find all matching subgraphs (given by \a _bindingmodel) in the 125 * given homology graph (given by \a _graph) of the fragment molecule. 126 * This means filtering down to the desired particle types and then find 127 * all possible matching subgraphs in each of argument lists, \a eachargs. 128 128 * 129 * \param args arguments to reorder129 * \param listargs list of arguments to filter and order appropriately 130 130 * \param _graph contains binding model of graph 131 131 * \param _types particle type vector 132 * \return filtered list ofargs132 * \return reordered args 133 133 */ 134 FunctionModel::list_of_arguments_t filterArgumentsBy ParticleTypes(134 FunctionModel::list_of_arguments_t filterArgumentsByBindingModel( 135 135 const FunctionModel::arguments_t &args, 136 136 const HomologyGraph &_graph,
Note:
See TracChangeset
for help on using the changeset viewer.