source: src/FunctionApproximation/TrainingData.cpp@ ff4fff9

CombiningParticlePotentialParsing
Last change on this file since ff4fff9 was e1fe7e, checked in by Frederik Heber <heber@…>, 11 years ago

FunctionModel now uses list_of_arguments to split sequence of subsets of distances.

  • this fixes ambiguities with the set of distances: Imagine the distances within a water molecule as OH (A) and HH (B). We then may have a sequence of argument_t as AABAAB. And with the current implementation of CompoundPotential::splitUpArgumentsByModels() we would always choose the latter (and more complex) model. Hence, we make two calls to TriplePotential_Angle, instead of calls twice to PairPotential_Harmonic for A, one to PairPotential_Harmonic for B, and once to TriplePotential_Angle for AAB.
  • now, we new list looks like A,A,B,AAB where each tuple of distances can be uniquely associated with a specific potential.
  • changed signatures of EmpiricalPotential::operator(), ::derivative(), ::parameter_derivative(). This involved changing all of the current specific potentials and CompoundPotential.
  • TrainingData must discern between the InputVector_t (just all distances) and the FilteredInputVector_t (tuples of subsets of distances).
  • FunctionApproximation now has list_of_arguments_t as parameter to evaluate() and evaluate_derivative().
  • DOCU: docu change in TrainingData.
  • Property mode set to 100644
File size: 7.4 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
7 *
8 *
9 * This file is part of MoleCuilder.
10 *
11 * MoleCuilder is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * MoleCuilder is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25/*
26 * TrainingData.cpp
27 *
28 * Created on: 15.10.2012
29 * Author: heber
30 */
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include "TrainingData.hpp"
40
41#include <algorithm>
42#include <boost/bind.hpp>
43#include <boost/foreach.hpp>
44#include <boost/lambda/lambda.hpp>
45#include <iostream>
46#include <sstream>
47
48#include "CodePatterns/Assert.hpp"
49#include "CodePatterns/Log.hpp"
50#include "CodePatterns/toString.hpp"
51
52#include "Fragmentation/Summation/SetValues/Fragment.hpp"
53#include "FunctionApproximation/FunctionArgument.hpp"
54#include "FunctionApproximation/FunctionModel.hpp"
55#include "FunctionApproximation/Extractors.hpp"
56
57void TrainingData::operator()(const range_t &range) {
58 for (HomologyContainer::const_iterator iter = range.first; iter != range.second; ++iter) {
59 const Fragment &fragment = iter->second.fragment;
60 // create internal list of arguments
61 FunctionModel::arguments_t all_args = Extractors::gatherAllSymmetricDistances(
62 fragment.getPositions(),
63 fragment.getCharges(),
64 DistanceVector.size()
65 );
66 DistanceVector.push_back( all_args );
67 const double &energy = iter->second.energy;
68 EnergyVector.push_back( FunctionModel::results_t(1, energy) );
69 // filter distances out of list of all arguments
70 FunctionModel::list_of_arguments_t args = filter(all_args);
71 LOG(3, "DEBUG: Filtered arguments are " << args << ".");
72 ArgumentVector.push_back( args );
73 }
74}
75
76const double TrainingData::getL2Error(const FunctionModel &model) const
77{
78 double L2sum = 0.;
79
80 FilteredInputVector_t::const_iterator initer = ArgumentVector.begin();
81 OutputVector_t::const_iterator outiter = EnergyVector.begin();
82 for (; initer != ArgumentVector.end(); ++initer, ++outiter) {
83 const FunctionModel::results_t result = model((*initer));
84 const double temp = fabs((*outiter)[0] - result[0]);
85 L2sum += temp*temp;
86 }
87 return L2sum;
88}
89
90const double TrainingData::getLMaxError(const FunctionModel &model) const
91{
92 double Lmax = 0.;
93// size_t maxindex = -1;
94 FilteredInputVector_t::const_iterator initer = ArgumentVector.begin();
95 OutputVector_t::const_iterator outiter = EnergyVector.begin();
96 for (; initer != ArgumentVector.end(); ++initer, ++outiter) {
97 const FunctionModel::results_t result = model((*initer));
98 const double temp = fabs((*outiter)[0] - result[0]);
99 if (temp > Lmax) {
100 Lmax = temp;
101// maxindex = std::distance(
102// const_cast<const FunctionApproximation::inputs_t &>(ArgumentVector).begin(),
103// initer
104// );
105 }
106 }
107 return Lmax;
108}
109
110const TrainingData::L2ErrorConfigurationIndexMap_t
111TrainingData::getWorstFragmentMap(
112 const FunctionModel &model,
113 const range_t &range) const
114{
115 L2ErrorConfigurationIndexMap_t WorseFragmentMap;
116 // fragments make it into the container in reversed order, hence count from top down
117 size_t index= std::distance(range.first, range.second)-1;
118 InputVector_t::const_iterator distanceiter = DistanceVector.begin();
119 FilteredInputVector_t::const_iterator initer = ArgumentVector.begin();
120 OutputVector_t::const_iterator outiter = EnergyVector.begin();
121 for (; initer != ArgumentVector.end(); ++initer, ++outiter, ++distanceiter) {
122 // calculate value from potential
123 const FunctionModel::list_of_arguments_t &args = *initer;
124 const FunctionModel::results_t result = model(args);
125 const double energy = (*outiter)[0];
126
127 // insert difference into map
128 const double error = fabs(energy - result[0]);
129 WorseFragmentMap.insert( std::make_pair( error, index-- ) );
130
131 {
132 // give only the distances in the debugging text
133 std::stringstream streamargs;
134 BOOST_FOREACH (argument_t arg, *distanceiter) {
135 streamargs << " " << arg.distance;
136 }
137 LOG(2, "DEBUG: frag.#" << index+1 << "'s error is |" << energy << " - " << result[0]
138 << "| = " << error << " for args " << streamargs.str() << ".");
139 }
140 }
141
142 return WorseFragmentMap;
143}
144
145const TrainingData::DistanceEnergyTable_t TrainingData::getDistanceEnergyTable() const
146{
147 TrainingData::DistanceEnergyTable_t table;
148
149 /// extract distance member variable from argument_t and first value from results_t
150 OutputVector_t::const_iterator ergiter = EnergyVector.begin();
151 for (InputVector_t::const_iterator iter = DistanceVector.begin();
152 iter != DistanceVector.end(); ++iter, ++ergiter) {
153 ASSERT( ergiter != EnergyVector.end(),
154 "TrainingData::getDistanceEnergyTable() - less output than input values.");
155 std::vector< double > values(iter->size(), 0.);
156 // transform all distances
157 const FunctionModel::arguments_t &args = *iter;
158 std::transform(
159 args.begin(), args.end(),
160 values.begin(),
161 boost::bind(&argument_t::distance, _1));
162
163 // get first energy value
164 values.push_back((*ergiter)[0]);
165
166 // push as table row
167 table.push_back(values);
168 }
169
170 return table;
171}
172
173const FunctionModel::results_t TrainingData::getTrainingOutputAverage() const
174{
175 if (EnergyVector.size() != 0) {
176 FunctionApproximation::outputs_t::const_iterator outiter = EnergyVector.begin();
177 FunctionModel::results_t result(*outiter);
178 for (++outiter; outiter != EnergyVector.end(); ++outiter)
179 for (size_t index = 0; index < (*outiter).size(); ++index)
180 result[index] += (*outiter)[index];
181 LOG(2, "DEBUG: Sum of EnergyVector is " << result << ".");
182 const double factor = 1./EnergyVector.size();
183 std::transform(result.begin(), result.end(), result.begin(),
184 boost::lambda::_1 * factor);
185 LOG(2, "DEBUG: Average EnergyVector is " << result << ".");
186 return result;
187 }
188 return FunctionModel::results_t();
189}
190
191std::ostream &operator<<(std::ostream &out, const TrainingData &data)
192{
193 const TrainingData::InputVector_t &DistanceVector = data.getAllArguments();
194 const TrainingData::OutputVector_t &EnergyVector = data.getTrainingOutputs();
195 out << "(" << DistanceVector.size()
196 << "," << EnergyVector.size() << ") data pairs: " << std::endl;
197 FunctionApproximation::inputs_t::const_iterator initer = DistanceVector.begin();
198 FunctionApproximation::outputs_t::const_iterator outiter = EnergyVector.begin();
199 for (; initer != DistanceVector.end(); ++initer, ++outiter) {
200 for (size_t index = 0; index < (*initer).size(); ++index)
201 out << "(" << (*initer)[index].indices.first << "," << (*initer)[index].indices.second
202 << ") " << (*initer)[index].distance;
203 out << " with energy ";
204 out << (*outiter);
205 out << std::endl;
206 }
207 return out;
208}
Note: See TracBrowser for help on using the repository browser.