Ignore:
Timestamp:
Nov 11, 2016, 2:25:36 PM (8 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

Converted filterArguments... into faster filter, renamed other to ..ByBindingModel.

  • there are now two filters: One filters by list of particles types and is meant for simple pair potentials. The other one filters (and reorders) by the binding model. This takes more computation time but is required for more complex potentials.
  • TESTFIX: This allows morse and harmonic pair potentials tests to pass again, removed XFAIL from the corresponding regression tests.
Location:
src/FunctionApproximation
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/FunctionApproximation/Extractors.cpp

    rf5dbea r1155ba  
    531531}
    532532
    533 FunctionModel::list_of_arguments_t Extractors::reorderArgumentsByParticleTypes(
    534     const FunctionModel::list_of_arguments_t &listargs,
     533FunctionModel::list_of_arguments_t Extractors::filterArgumentsByBindingModel(
     534    const FunctionModel::arguments_t &args,
    535535    const HomologyGraph &_graph,
    536536    const ParticleTypes_t &_types,
     
    539539{
    540540  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;
    669705          }
    670706        }
    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());
    758754    }
    759755  }
     
    769765    )
    770766{
     767  // list allows for quicker removal than vector
    771768  typedef std::list< argument_t > ListArguments_t;
    772769  ListArguments_t availableList(args.begin(), args.end());
    773770  LOG(2, "DEBUG: Initial list of args is " << args << ".");
    774 
    775771
    776772  // TODO: fill a lookup map such that we don't have O(M^3) scaling, if M is number
     
    779775//  typedef ParticleTypes_t firsttype;
    780776//  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;
    782778//  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."));
    783783
    784784  // basically, we have two choose any two pairs out of types but only those
    785785  // where the first is less than the latter. Hence, we start the second
    786786  // 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;
    789788  for (ParticleTypes_t::const_iterator firstiter = _types.begin();
    790789      firstiter != _types.end();
     
    804803        if ((iter->types.first == *firstiter)
    805804              && (iter->types.second == *seconditer)) {
    806           allargs.push_back( *iter );
     805          returnargs.push_back( FunctionModel::arguments_t(1, *iter) );
    807806          iter = availableList.erase(iter);
    808807          LOG(4, "DEBUG: Accepted argument.");
    809808        } else if ((iter->types.first == *seconditer)
    810809              && (iter->types.second == *firstiter)) {
    811           allargs.push_back( *iter );
     810          returnargs.push_back( FunctionModel::arguments_t(1, *iter) );
    812811          iter = availableList.erase(iter);
    813812          LOG(4, "DEBUG: Accepted (flipped) argument.");
     
    819818    }
    820819  }
    821   LOG(2, "DEBUG: Final list of args is " << allargs << ".");
    822 
    823   // first, we bring together tuples of distances that belong together
    824   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 list
    831 //  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 NDEBUG
    840 //    FunctionModel::arguments_t::const_iterator endoutiter =
    841 //#endif
    842 //        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 //  }
    847820
    848821  LOG(2, "DEBUG: We have generated " << returnargs.size() << " tuples of distances.");
  • src/FunctionApproximation/Extractors.hpp

    rf5dbea r1155ba  
    103103  }
    104104
    105   /** Reorder the arguments to bring adjacent ones together.
     105  /** Filter the arguments to select only these required by the model.
    106106   *
    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()
    111109   *
    112110   * \param listargs list of arguments to reorder each
     
    115113   * \return reordered args
    116114   */
    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,
    119117      const HomologyGraph &_graph,
    120118      const ParticleTypes_t &_types,
     
    122120      );
    123121
    124   /** Filter arguments according to types, allowing multiples.
     122  /** Filter and reorder the arguments to bring adjacent ones together.
    125123   *
    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.
    128128   *
    129    * \param args arguments to reorder
     129   * \param listargs list of arguments to filter and order appropriately
    130130   * \param _graph contains binding model of graph
    131131   * \param _types particle type vector
    132    * \return filtered list of args
     132   * \return reordered args
    133133   */
    134   FunctionModel::list_of_arguments_t filterArgumentsByParticleTypes(
     134  FunctionModel::list_of_arguments_t filterArgumentsByBindingModel(
    135135      const FunctionModel::arguments_t &args,
    136136      const HomologyGraph &_graph,
Note: See TracChangeset for help on using the changeset viewer.