Ignore:
Timestamp:
Feb 24, 2013, 12:58:06 PM (12 years ago)
Author:
Frederik Heber <heber@…>
Branches:
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
Children:
8ea8c8
Parents:
94f567
git-author:
Frederik Heber <heber@…> (10/15/12 14:19:37)
git-committer:
Frederik Heber <heber@…> (02/24/13 12:58:06)
Message:

Added PairPotential_Angle training to LevMartester.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/LevMartester.cpp

    r94f567 r9340ee  
    3939#include "CodePatterns/MemDebug.hpp"
    4040
     41#include <boost/assign.hpp>
    4142#include <boost/filesystem.hpp>
    4243#include <boost/program_options.hpp>
     
    6364#include "Helpers/defs.hpp"
    6465#include "Potentials/Specifics/PairPotential_Morse.hpp"
     66#include "Potentials/Specifics/PairPotential_Angle.hpp"
    6567#include "Potentials/Specifics/SaturationPotential.hpp"
    6668
    6769namespace po = boost::program_options;
     70
     71using namespace boost::assign;
     72
     73HomologyGraph getFirstGraphWithThreeCarbons(const HomologyContainer &homologies)
     74{
     75  FragmentNode SaturatedCarbon(6,4); // carbon has atomic number 6 and should have 4 bonds for C3H8
     76  FragmentNode DanglingCarbon(6,3); // carbon has atomic number 6 and should have 3 pure bonds for C3H8
     77  for (HomologyContainer::container_t::const_iterator iter =
     78      homologies.begin(); iter != homologies.end(); ++iter) {
     79    if ((iter->first.hasNode(SaturatedCarbon,2)) && (iter->first.hasNode(DanglingCarbon,1)))
     80      return iter->first;
     81  }
     82  return HomologyGraph();
     83}
    6884
    6985HomologyGraph getFirstGraphWithTwoCarbons(const HomologyContainer &homologies)
     
    203219}
    204220
     221double
     222function_angle(
     223    const double &r_ij,
     224    const double &r_ik,
     225    const double &r_jk
     226  )
     227{
     228//  Info info(__func__);
     229  const double angle = pow(r_ij,2.) + pow(r_ik,2.) - pow(r_jk,2.);
     230  const double divisor = 2.* r_ij * r_ik;
     231
     232//  LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
     233  if (divisor == 0.)
     234    return 0.;
     235  else
     236    return angle/divisor;
     237}
    205238
    206239int main(int argc, char **argv)
     
    251284    LOG(1, "INFO: graph " << iter->first << " has Fragment "
    252285        << iter->second.first << " and associated energy " << iter->second.second << ".");
     286  }
     287
     288  /******************** Angle TRAINING ********************/
     289  {
     290    // then we ought to pick the right HomologyGraph ...
     291    const HomologyGraph graph = getFirstGraphWithThreeCarbons(homologies);
     292    LOG(1, "First representative graph containing three saturated carbons is " << graph << ".");
     293
     294    // Afterwards we go through all of this type and gather the distance and the energy value
     295    typedef std::pair<
     296        FunctionApproximation::inputs_t,
     297        FunctionApproximation::outputs_t> InputOutputVector_t;
     298    InputOutputVector_t DistanceEnergyVector;
     299    std::pair<HomologyContainer::const_iterator, HomologyContainer::const_iterator> range =
     300        homologies.getHomologousGraphs(graph);
     301    for (HomologyContainer::const_iterator fragiter = range.first; fragiter != range.second; ++fragiter) {
     302      // get distance out of Fragment
     303      const double &energy = fragiter->second.second;
     304      const Fragment &fragment = fragiter->second.first;
     305      const Fragment::charges_t charges = fragment.getCharges();
     306      const Fragment::positions_t positions = fragment.getPositions();
     307      std::vector< std::pair<Vector, size_t> > DistanceVectors;
     308      for (Fragment::charges_t::const_iterator chargeiter = charges.begin();
     309          chargeiter != charges.end(); ++chargeiter) {
     310        if (*chargeiter == 6) {
     311          Fragment::positions_t::const_iterator positer = positions.begin();
     312          const size_t steps = std::distance(charges.begin(), chargeiter);
     313          std::advance(positer, steps);
     314          DistanceVectors.push_back(
     315              std::make_pair(Vector((*positer)[0], (*positer)[1], (*positer)[2]),
     316                  steps));
     317        }
     318      }
     319      if (DistanceVectors.size() == (size_t)3) {
     320        FunctionModel::arguments_t args(3);
     321        // we require specific ordering of the carbons: ij, ik, jk
     322        typedef std::vector< std::pair<size_t, size_t> > indices_t;
     323        indices_t indices;
     324        indices += std::make_pair(0,1), std::make_pair(0,2), std::make_pair(1,2);
     325        // create the three arguments
     326        for (indices_t::const_iterator iter = indices.begin(); iter != indices.end(); ++iter) {
     327          const size_t &firstindex = iter->first;
     328          const size_t &secondindex = iter->second;
     329          argument_t &arg = args[(size_t)std::distance(const_cast<const indices_t&>(indices).begin(), iter)];
     330          arg.indices.first = DistanceVectors[firstindex].second;
     331          arg.indices.second = DistanceVectors[secondindex].second;
     332          arg.distance = DistanceVectors[firstindex].first.distance(DistanceVectors[secondindex].first);
     333          arg.globalid = DistanceEnergyVector.first.size();
     334        }
     335        // make largest distance last to create correct angle
     336        // (this would normally depend on the order of the nodes in the subgraph)
     337        std::list<argument_t> sorted_args;
     338        double greatestdistance = 0.;
     339        for(FunctionModel::arguments_t::const_iterator iter = args.begin(); iter != args.end(); ++iter)
     340          greatestdistance = std::max(greatestdistance, iter->distance);
     341        for(FunctionModel::arguments_t::const_iterator iter = args.begin(); iter != args.end(); ++iter)
     342          if (iter->distance == greatestdistance)
     343            sorted_args.push_back(*iter);
     344          else
     345            sorted_args.push_front(*iter);
     346        // and add the training pair
     347        DistanceEnergyVector.first.push_back( FunctionModel::arguments_t(sorted_args.begin(), sorted_args.end()) );
     348        DistanceEnergyVector.second.push_back( FunctionModel::results_t(1,energy) );
     349      } else {
     350        ELOG(2, "main() - found not exactly three carbon atoms in fragment "
     351            << fragment << ".");
     352      }
     353    }
     354    // print training data for debugging
     355    {
     356      LOG(1, "INFO: I gathered the following (" << DistanceEnergyVector.first.size()
     357          << "," << DistanceEnergyVector.second.size() << ") data pairs: ");
     358      FunctionApproximation::inputs_t::const_iterator initer = DistanceEnergyVector.first.begin();
     359      FunctionApproximation::outputs_t::const_iterator outiter = DistanceEnergyVector.second.begin();
     360      for (; initer != DistanceEnergyVector.first.end(); ++initer, ++outiter) {
     361        std::stringstream stream;
     362        const double cos_angle = function_angle((*initer)[0].distance,(*initer)[1].distance,(*initer)[2].distance);
     363        for (size_t index = 0; index < (*initer).size(); ++index)
     364           stream << " (" << (*initer)[index].indices.first << "," << (*initer)[index].indices.second
     365              << ") " << (*initer)[index].distance;
     366        stream << " with energy " << *outiter << " and cos(angle) " << cos_angle;
     367        LOG(1, "INFO:" << stream.str());
     368      }
     369    }
     370    // NOTICE that distance are in bohrradi as they come from MPQC!
     371
     372    // now perform the function approximation by optimizing the model function
     373    FunctionModel::parameters_t params(PairPotential_Angle::MAXPARAMS, 0.);
     374    params[PairPotential_Angle::energy_offset] =  -1.;
     375    params[PairPotential_Angle::spring_constant] =  1.;
     376    params[PairPotential_Angle::equilibrium_distance] =  0.2;
     377    PairPotential_Angle angle;
     378    LOG(0, "INFO: Initial parameters are " << params << ".");
     379    angle.setParameters(params);
     380    FunctionModel &model = angle;
     381    FunctionApproximation approximator(
     382        DistanceEnergyVector.first.begin()->size(),
     383        DistanceEnergyVector.second.begin()->size(),
     384        model);
     385    approximator.setTrainingData(DistanceEnergyVector.first,DistanceEnergyVector.second);
     386    if (model.isBoxConstraint() && approximator.checkParameterDerivatives())
     387      approximator(FunctionApproximation::ParameterDerivative);
     388    else
     389      ELOG(0, "We require parameter derivatives for a box constraint minimization.");
     390    params = model.getParameters();
     391
     392    LOG(0, "RESULT: Best parameters are " << params << ".");
    253393  }
    254394
Note: See TracChangeset for help on using the changeset viewer.