Ignore:
Timestamp:
Oct 2, 2016, 1:59:41 PM (9 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Fix_FitPotential_needs_atomicnumbers
Children:
6ffdf2
Parents:
8d5db8
git-author:
Frederik Heber <heber@…> (10/02/16 13:59:35)
git-committer:
Frederik Heber <heber@…> (10/02/16 13:59:41)
Message:

REFACTOR: Removed many unused functions from Extractor namespace.

  • TESTFIX: Extractor unit test now only checks on getAllSymmetricDistances().
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/FunctionApproximation/Extractors.cpp

    r8d5db8 ra13e21  
    5555
    5656using namespace boost::assign;
    57 
    58 FunctionModel::arguments_t
    59 Extractors::gatherAllDistanceArguments(
    60     const Fragment::positions_t& positions,
    61     const Fragment::charges_t& charges,
    62     const size_t globalid)
    63 {
    64   FunctionModel::arguments_t result;
    65 
    66   // go through current configuration and gather all other distances
    67   Fragment::positions_t::const_iterator firstpositer = positions.begin();
    68   for (;firstpositer != positions.end(); ++firstpositer) {
    69     Fragment::positions_t::const_iterator secondpositer = positions.begin();//firstpositer;
    70     for (; secondpositer != positions.end(); ++secondpositer) {
    71       if (firstpositer == secondpositer)
    72         continue;
    73       argument_t arg;
    74       const Vector firsttemp((*firstpositer)[0],(*firstpositer)[1],(*firstpositer)[2]);
    75       const Vector secondtemp((*secondpositer)[0],(*secondpositer)[1],(*secondpositer)[2]);
    76       arg.distance = firsttemp.distance(secondtemp);
    77       arg.types = std::make_pair(
    78           charges[ std::distance(positions.begin(), firstpositer) ],
    79           charges[ std::distance(positions.begin(), secondpositer) ]
    80           );
    81       arg.indices = std::make_pair(
    82           std::distance(
    83               positions.begin(), firstpositer),
    84           std::distance(
    85               positions.begin(), secondpositer)
    86           );
    87       arg.globalid = globalid;
    88       result.push_back(arg);
    89     }
    90   }
    91 
    92   return result;
    93 }
    9457
    9558FunctionModel::arguments_t
     
    13194}
    13295
    133 Fragment::positions_t Extractors::_detail::gatherPositionsFromTargets(
    134     const Fragment::positions_t& positions,
    135     const Fragment::charges_t& charges,
    136     const chargeiters_t &targets
    137     )
    138 {
    139   Fragment::positions_t filtered_positions;
    140   for (chargeiters_t::const_iterator firstpairiter = targets.begin();
    141       firstpairiter != targets.end(); ++firstpairiter) {
    142     Fragment::positions_t::const_iterator positer = positions.begin();
    143     const size_t steps = std::distance(charges.begin(), *firstpairiter);
    144     std::advance(positer, steps);
    145     filtered_positions.push_back(*positer);
    146   }
    147   return filtered_positions;
    148 }
    149 
    150 FunctionModel::arguments_t Extractors::_detail::gatherDistancesFromTargets(
    151     const Fragment::positions_t& positions,
    152     const Fragment::charges_t& charges,
    153     const chargeiters_t &targets,
    154     const size_t globalid
    155     )
    156 {
    157   Fragment::positions_t filtered_positions;
    158   Fragment::charges_t filtered_charges;
    159   for (chargeiters_t::const_iterator firstpairiter = targets.begin();
    160       firstpairiter != targets.end(); ++firstpairiter) {
    161     Fragment::positions_t::const_iterator positer = positions.begin();
    162     const size_t steps = std::distance(charges.begin(), *firstpairiter);
    163     std::advance(positer, steps);
    164     filtered_positions.push_back(*positer);
    165     filtered_charges.push_back(**firstpairiter);
    166   }
    167   return Extractors::gatherAllSymmetricDistanceArguments(
    168       filtered_positions,
    169       filtered_charges,
    170       globalid);
    171 }
    172 
    17396Extractors::elementcounts_t
    17497Extractors::_detail::getElementCounts(
     
    188111  return elementcounts;
    189112}
    190 
    191 Extractors::elementtargets_t
    192 Extractors::_detail::convertElementcountsToTargets(
    193     const Fragment::charges_t &charges,
    194     const elementcounts_t &elementcounts
    195     )
    196 {
    197   elementtargets_t elementtargets;
    198   for (elementcounts_t::const_iterator countiter = elementcounts.begin();
    199       countiter != elementcounts.end();
    200       ++countiter) {
    201     chargeiter_t chargeiter = charges.begin();
    202     const element_t &element = countiter->first;
    203     const count_t &count = countiter->second;
    204     for (count_t i = 0; i < count; ++i) {
    205       chargeiter_t tempiter = std::find(chargeiter, charges.end(), element);
    206       if (tempiter != charges.end()) {
    207         // try to insert new list
    208         std::pair< elementtargets_t::iterator, bool> inserter =
    209           elementtargets.insert( std::make_pair( countiter->first, chargeiters_t(1, tempiter)) );
    210         // if already present, append to it
    211         if (!inserter.second) {
    212           inserter.first->second.push_back(tempiter);
    213         } else { // if created, increase vector's reserve to known size
    214           inserter.first->second.reserve(countiter->second);
    215         }
    216         // search from this element onwards then
    217         chargeiter = ++tempiter;
    218       } else {
    219         ELOG(1, "Could not find desired number " << count << " of element "
    220             << element << " in fragment with " << charges << ".");
    221         return Extractors::elementtargets_t();
    222       }
    223     }
    224   }
    225   return elementtargets;
    226 }
    227 
    228 Extractors::elementtargets_t
    229 Extractors::_detail::convertChargesToTargetMap(
    230     const Fragment::charges_t& charges,
    231     Fragment::charges_t elements
    232     )
    233 {
    234   // place each charge into a map
    235   elementtargets_t completeelementtargets;
    236   for (chargeiter_t chargeiter = charges.begin();
    237       chargeiter != charges.end();
    238       ++chargeiter) {
    239     std::pair< elementtargets_t::iterator, bool> inserter =
    240         completeelementtargets.insert( std::make_pair( *chargeiter, chargeiters_t(1, chargeiter)) );
    241     // if already present, append to it
    242     if (!inserter.second) {
    243       inserter.first->second.push_back(chargeiter);
    244     }
    245   }
    246   // pick out desired charges only
    247   std::sort(elements.begin(), elements.end());
    248   Fragment::charges_t::iterator eraseiter =
    249       std::unique(elements.begin(), elements.end());
    250   elements.erase(eraseiter, elements.end());
    251   elementtargets_t elementtargets;
    252   for(Fragment::charges_t::const_iterator iter = elements.begin();
    253       iter != elements.end();
    254       ++iter) {
    255     elementtargets_t::const_iterator finditer = completeelementtargets.find(*iter);
    256     ASSERT( finditer != completeelementtargets.end(),
    257         "Extractors::_detail::convertChargesToTargetMap() - no element "+toString(*iter)+" present?");
    258     std::pair< elementtargets_t::iterator, bool> inserter =
    259         elementtargets.insert( std::make_pair( finditer->first, finditer->second) );
    260     ASSERT( inserter.second,
    261         "Extractors::_detail::convertChargesToTargetMap() - key twice?");
    262   }
    263   return elementtargets;
    264 }
    265 
    266 
    267 Extractors::chargeiters_t
    268 Extractors::_detail::realignElementtargets(
    269     const elementtargets_t &elementtargets,
    270     const Fragment::charges_t elements,
    271     const elementcounts_t &elementcounts
    272     )
    273 {
    274   chargeiters_t targets;
    275   elementcounts_t counts; // how many chargeiters of this element have been used
    276   if (!elements.empty()) {  // skip if no elements given
    277     targets.reserve(elements.size());
    278     for (Fragment::charges_t::const_iterator elementiter = elements.begin();
    279         elementiter != elements.end(); ++elementiter) {
    280       const element_t &element = *elementiter;
    281       count_t &count = counts[element]; // if not present, std::map creates instances with default of 0
    282 #ifndef NDEBUG
    283       {
    284         elementcounts_t::const_iterator testiter = elementcounts.find(element);
    285         ASSERT( (testiter != elementcounts.end()) && (count < testiter->second),
    286             "Extractors::_detail::realignElementTargets() - we want to use more chargeiters for element "
    287             +toString(element)+" than we counted initially.");
    288       }
    289 #endif
    290       elementtargets_t::const_iterator targetiter = elementtargets.find(element);
    291       if (targetiter != elementtargets.end()) {
    292         const chargeiters_t &chargeiters = targetiter->second;
    293         const chargeiter_t &chargeiter = chargeiters[count++];
    294         targets.push_back(chargeiter);
    295       }
    296     }
    297   }
    298   return targets;
    299 }
    300 
    301 FunctionModel::arguments_t
    302 Extractors::gatherAllDistancesFromFragment(
    303     const Fragment::positions_t& positions,
    304     const Fragment::charges_t& charges,
    305     const Fragment::charges_t elements,
    306     const size_t globalid
    307     )
    308 {
    309   /// The main problem here is that we have to know how many same
    310   /// elements (but different atoms!) we are required to find. Hence,
    311   /// we first have to count same elements, then get different targets
    312   /// for each and then associated them in correct order back again.
    313 
    314   // 0. if no elements given, we return empty arguments
    315   if (elements.empty())
    316     return FunctionModel::arguments_t();
    317 
    318   // 1. we have to place each charge into a map as unique chargeiter, i.e. map
    319   elementtargets_t elementtargets =
    320       Extractors::_detail::convertChargesToTargetMap(
    321           charges,
    322           elements);
    323 
    324   // 2. now we have to combine elementcounts out of elementtargets per desired element
    325   //    in a combinatorial fashion
    326   targets_per_combination_t combinations =
    327       Extractors::_detail::CombineChargesAndTargets(
    328           elements,
    329           elementtargets);
    330 
    331   // 3. finally, convert chargeiters into argument list
    332   FunctionModel::arguments_t args =
    333       Extractors::_detail::convertTargetsToArguments(
    334           positions,
    335           charges,
    336           combinations,
    337           globalid);
    338 
    339   return args;
    340 }
    341 
    342 Extractors::targets_per_combination_t
    343 Extractors::_detail::CombineChargesAndTargets(
    344     const Fragment::charges_t& elements,
    345     const elementtargets_t& elementtargets
    346     )
    347 {
    348   // recursively create all correct combinations of targets
    349   targets_per_combination_t combinations;
    350   chargeiters_t currenttargets;
    351   boost::function<void (const chargeiters_t &currenttargets)> addFunction =
    352       boost::bind(&targets_per_combination_t::push_back,
    353           boost::ref(combinations),
    354           _1);
    355   pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
    356 
    357   return combinations;
    358 }
    359 
    360 const Fragment::position_t& getPositionToChargeIter(
    361     const Fragment::positions_t& positions,
    362     const Fragment::charges_t& charges,
    363     const Extractors::chargeiter_t &iter
    364     )
    365 {
    366   Fragment::positions_t::const_iterator positer = positions.begin();
    367   std::advance(positer, std::distance(charges.begin(), iter));
    368   const Fragment::position_t &position = *positer;
    369   return position;
    370 }
    371 
    372 
    373 FunctionModel::arguments_t
    374 Extractors::_detail::convertTargetsToArguments(
    375     const Fragment::positions_t& positions,
    376     const Fragment::charges_t& charges,
    377     const targets_per_combination_t combinations,
    378     const size_t globalid
    379     )
    380 {
    381   FunctionModel::arguments_t args;
    382   // create arguments from each combination. We cannot use
    383   // gatherallSymmetricDistanceArguments() because it would not create the
    384   // correct indices.
    385   for (targets_per_combination_t::const_iterator iter = combinations.begin();
    386       iter != combinations.end();
    387       ++iter) {
    388     for(chargeiters_t::const_iterator firstiter = iter->begin();
    389         firstiter != iter->end();
    390         ++firstiter) {
    391       const Fragment::position_t &firstpos =
    392           getPositionToChargeIter(positions, charges, *firstiter);
    393       const Vector firsttemp(firstpos[0],firstpos[1],firstpos[2]);
    394       for(chargeiters_t::const_iterator seconditer = firstiter;
    395           seconditer != iter->end();
    396           ++seconditer) {
    397         if (firstiter == seconditer)
    398           continue;
    399         const Fragment::position_t &secondpos =
    400             getPositionToChargeIter(positions, charges, *seconditer);
    401         const Vector secondtemp(secondpos[0],secondpos[1],secondpos[2]);
    402         argument_t arg;
    403         arg.distance = firsttemp.distance(secondtemp);
    404         arg.indices.first = std::distance(charges.begin(), *firstiter);
    405         arg.indices.second = std::distance(charges.begin(), *seconditer);
    406         arg.types.first = **firstiter;
    407         arg.types.second = **seconditer;
    408         args.push_back( arg );
    409       }
    410     }
    411   }
    412 
    413   return args;
    414 }
    415 
    416 void
    417 Extractors::_detail::pickLastElementAsTarget(
    418     Fragment::charges_t elements,
    419     elementtargets_t elementtargets,
    420     chargeiters_t &currenttargets,
    421     boost::function<void (const chargeiters_t &currenttargets)> &addFunction
    422     )
    423 {
    424   // get last element from charges
    425   ASSERT( !elements.empty(),
    426       "Extractors::_detail::pickLastElementAsTarget() - no elements given to pick targets for.");
    427   const Fragment::charge_t charge = elements.back();
    428   elements.pop_back();
    429   elementtargets_t::iterator iter = elementtargets.find(charge);
    430   if (iter == elementtargets.end())
    431     return;
    432   bool NotEmpty = !iter->second.empty();
    433   while (NotEmpty) {
    434     // get last target from the vector of chargeiters
    435     chargeiter_t target = iter->second.back();
    436     iter->second.pop_back();
    437     // remove this key if empty
    438     if (iter->second.empty()) {
    439       elementtargets.erase(iter);
    440       NotEmpty = false;
    441     }
    442     currenttargets.push_back(target);
    443     if (elements.empty()) {
    444       // call add function
    445       {
    446         std::stringstream targetstream;
    447         BOOST_FOREACH( chargeiter_t target, currenttargets ) {
    448           targetstream << " " << *target;
    449         }
    450         LOG(3, "DEBUG: Adding set" << targetstream.str() << ".");
    451       }
    452       addFunction(currenttargets);
    453     } else {
    454       // if not, call us recursively
    455       pickLastElementAsTarget(elements, elementtargets, currenttargets, addFunction);
    456     }
    457     // pop last in currenset again
    458     currenttargets.pop_back();
    459   }
    460 }
    461 
    462 Extractors::chargeiters_t
    463 Extractors::_detail::gatherTargetsFromFragment(
    464     const Fragment::charges_t& charges,
    465     const Fragment::charges_t elements
    466     )
    467 {
    468   /// The main problem here is that we have to know how many same
    469   /// elements (but different atoms!) we are required to find. Hence,
    470   /// we first have to count same elements, then get different targets
    471   /// for each and then associated them in correct order back again.
    472 
    473   // 1. we have to make elements unique with counts, hence convert to map
    474   elementcounts_t elementcounts =
    475       Extractors::_detail::getElementCounts(elements);
    476 
    477   // 2. then for each element we need as many targets (chargeiters) as counts
    478   elementtargets_t elementtargets =
    479       Extractors::_detail::convertElementcountsToTargets(charges, elementcounts);
    480 
    481   // 3. we go again through elements and use one found target for each count
    482   // in that order
    483   chargeiters_t targets =
    484       Extractors::_detail::realignElementtargets(elementtargets, elements, elementcounts);
    485 
    486 #ifndef NDEBUG
    487   // check all for debugging
    488   for (chargeiters_t::const_iterator chargeiter = targets.begin();
    489       chargeiter != targets.end();
    490       ++chargeiter)
    491     ASSERT( *chargeiter != charges.end(),
    492         "Extractors::gatherTargetsFromFragment() - we have not found enough targets?!");
    493 #endif
    494 
    495   return targets;
    496 }
    497 
    498 Fragment::positions_t
    499 Extractors::gatherPositionsFromFragment(
    500     const Fragment::positions_t positions,
    501     const Fragment::charges_t charges,
    502     const Fragment::charges_t& elements
    503     )
    504 {
    505   // 1.-3. gather correct charge positions
    506   chargeiters_t targets =
    507       Extractors::_detail::gatherTargetsFromFragment(charges, elements);
    508   // 4. convert position_t to Vector
    509   return Extractors::_detail::gatherPositionsFromTargets(
    510           positions,
    511           charges,
    512           targets);
    513 }
    514 
    515 FunctionModel::arguments_t
    516 Extractors::gatherDistancesFromFragment(
    517     const Fragment::positions_t positions,
    518     const Fragment::charges_t charges,
    519     const Fragment::charges_t& elements,
    520     const size_t globalid
    521     )
    522 {
    523   // 1.-3. gather correct charge positions
    524   chargeiters_t targets =
    525       Extractors::_detail::gatherTargetsFromFragment(charges, elements);
    526   // 4. convert position_t to Vector
    527   return Extractors::_detail::gatherDistancesFromTargets(
    528           positions,
    529           charges,
    530           targets,
    531           globalid);
    532 }
    533 
    534 FunctionModel::list_of_arguments_t Extractors::reorderArgumentsByIncreasingDistance(
    535     const FunctionModel::list_of_arguments_t &listargs
    536     )
    537 {
    538   FunctionModel::list_of_arguments_t returnargs;
    539   for (FunctionModel::list_of_arguments_t::const_iterator iter = listargs.begin();
    540       iter != listargs.end(); ++iter) {
    541     const FunctionModel::arguments_t &args = *iter;
    542     FunctionModel::arguments_t sortedargs(args);
    543     std::sort(sortedargs.begin(), sortedargs.end(), argument_t::DistanceComparator);
    544     returnargs.push_back(sortedargs);
    545   }
    546   return returnargs;
    547 }
    548 
    549113
    550114struct ParticleTypesComparator {
Note: See TracChangeset for help on using the changeset viewer.