Newer
Older
// Standard header files go here
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <sstream>
#include <vector>
#include <list>
#include <algorithm> // for std::sort
#include <utility> // For std::pair
#include <cassert>
// Includes check for correct Boost version(s)
#include <common/GGlobalDefines.hpp>
//#include "GGlobalDefines.hpp"
// Boost header files go here
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/cast.hpp>
#ifndef GOmegaPiIndividual_HPP_
#define GOmegaPiIndividual_HPP_
// For Microsoft-compatible compilers
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
// Geneva header files go here
#include <hap/GRandomT.hpp>
#include <common/GCommonEnums.hpp>
#include <common/GExceptions.hpp>
#include <geneva/GConstrainedDoubleObject.hpp>
#include <geneva/GConstrainedDoubleObjectCollection.hpp>
#include <geneva/GDoubleGaussAdaptor.hpp>
#include <geneva/GObjectExpectationChecksT.hpp>
#include <geneva/GParameterObjectCollection.hpp>
#include <geneva/GParameterSet.hpp>
#ifdef GENEVATESTING
#include <common/GUnitTestFrameworkT.hpp>
#endif /* GENEVATESTING */
#include "PwaUtils/AbsStates.hh"
#include "PwaUtils/DataUtils.hh"
#include "Examples/MATpbarpToOmegaPi/OmegaPiData.hh"
#include "Examples/MATpbarpToOmegaPi/OmegaPiEventList.hh"
#include "Examples/MATpbarpToOmegaPi/pbarpToOmegaPi0States.hh"
#include "Examples/MATpbarpToOmegaPi/OmegaPiLh.hh"
namespace Gem
{
namespace Geneva
{
/************************************************************************************************/
/**
* This individual searches for the minimum of a parabola of a given dimension,
* It is part of a complete example that lets users adapt their optimization
* problems more easily to the Geneva conventions.
*/
class GOmegaPiIndividual :public GParameterSet
{
///////////////////////////////////////////////////////////////////////
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int) {
using boost::serialization::make_nvp;
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(GParameterSet);
ar & BOOST_SERIALIZATION_NVP(_omegaPiLhPtr);
}
///////////////////////////////////////////////////////////////////////
public:
/********************************************************************************************/
/**
* A simple constructor that initializes this object with a collection of bounded
* double variables.
*
* @param dim The amount of variables
* @param min The lower boundary of the variables
* @param max The upper boundary of the variables
*/
GOmegaPiIndividual(boost::shared_ptr<pbarpToOmegaPi0States> theStates)
// Set up a GConstrainedDoubleObjectCollection
boost::shared_ptr<GConstrainedDoubleObjectCollection> gbdc_ptr(new GConstrainedDoubleObjectCollection());
// Create a suitable adaptor (sigma=0.1, sigma-adaption=0.5, min sigma=0, max sigma=0,5)
boost::shared_ptr<GDoubleGaussAdaptor> gdga_ptr(new GDoubleGaussAdaptor(0.1, 0.5, 0., 0.5));
gdga_ptr->setAdaptionThreshold(1); // Adaption parameters are modified after each adaption
gdga_ptr->setAdaptionProbability(0.05); // The likelihood for a parameter to be adapted
// Add a GConstrainedDoubleObject object to the collection
// gbdc_ptr->push_back(gbd_ptr);
// gpoc_ptr->push_back(gbd_ptr);
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaSinglet=_barpToOmegaPi0States->jpclsSinglet();
setFitParamVal(JPCLSOmegaSinglet, gbdc_ptr);
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet0=_barpToOmegaPi0States->jpclsTriplet0();
setFitParamVal(JPCLSOmegaTriplet0, gbdc_ptr);
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet1=_barpToOmegaPi0States->jpclsTriplet1();
setFitParamVal(JPCLSOmegaTriplet1, gbdc_ptr);
for(std::size_t i=0; i<gbdc_ptr->size(); i++) {
// Register the adaptor with GConstrainedDoubleObject objects
gbdc_ptr->at(i)->addAdaptor(gdga_ptr);
}
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Add the collection to this object
this->push_back(gbdc_ptr);
}
/********************************************************************************************/
/**
* A standard copy constructor
*
* @param cp A copy of another GOmegaPiIndividual
*/
GOmegaPiIndividual(const GOmegaPiIndividual& cp)
: GParameterSet(cp)
,_omegaPiLhPtr( new OmegaPiLh(cp.omegaPiLhPtr()) )
{
_barpToOmegaPi0States=_omegaPiLhPtr->omegaPi0States();
}
/********************************************************************************************/
/**
* The standard destructor
*/
virtual ~GOmegaPiIndividual()
{
}
/********************************************************************************************/
boost::shared_ptr<OmegaPiLh> omegaPiLhPtr() const {return _omegaPiLhPtr;}
/**
* A standard assignment operator
*
* @param cp A copy of another GOmegaPiIndividual object
* @return A constant reference to this object
*/
const GOmegaPiIndividual& operator=(const GOmegaPiIndividual& cp){
GOmegaPiIndividual::load_(&cp);
return *this;
}
/*******************************************************************************************/
/**
* Checks for equality with another GOmegaPiIndividual object.
*
* NOTE: THIS FUNCTION IS OPTIONAL AND IS MAINLY USED IN CONJUNCTION WITH UNIT TESTS.
* You do not need it if you do not intend to perform unit tests.
*
* @param cp A constant reference to another GOmegaPiIndividual object
* @return A boolean indicating whether both objects are equal
*/
bool operator==(const GOmegaPiIndividual& cp) const {
using namespace Gem::Common;
// Means: The expectation of equality was fulfilled, if no error text was emitted (which converts to "true")
return !checkRelationshipWith(cp, CE_EQUALITY, 0.,"GOmegaPiIndividual::operator==","cp", CE_SILENT);
}
/*******************************************************************************************/
/**
* Checks for inequality with another GOmegaPiIndividual object.
*
* NOTE: THIS FUNCTION IS OPTIONAL AND IS MAINLY USED IN CONJUNCTION WITH UNIT TESTS.
* You do not need it if you do not intend to perform unit tests.
*
* @param cp A constant reference to another GOmegaPiIndividual object
* @return A boolean indicating whether both objects are inequal
*/
bool operator!=(const GOmegaPiIndividual& cp) const {
using namespace Gem::Common;
// Means: The expectation of inequality was fulfilled, if no error text was emitted (which converts to "true")
return !checkRelationshipWith(cp, CE_INEQUALITY, 0.,"GOmegaPiIndividual::operator!=","cp", CE_SILENT);
}
bool getFitParams(OmegaPiData::fitParamVal& fitParmVal)
{
std::vector<double> theParms;
// Extract the GDoubleCollection object. In a realistic scenario, you might want
// to add error checks here upon first invocation.
boost::shared_ptr<GConstrainedDoubleObjectCollection> vC = at<GConstrainedDoubleObjectCollection>(0);
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
std::vector< boost::shared_ptr<const JPCLS> >::const_iterator itJPCLS;
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaSinglet=_barpToOmegaPi0States->jpclsSinglet();
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet0=_barpToOmegaPi0States->jpclsTriplet0();
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet1=_barpToOmegaPi0States->jpclsTriplet1();
std::vector<double> par;
for(std::size_t i=0; i<vC->size(); i++){
double value = vC->at(i)->value();
par.push_back(value);
}
if (par.size()!= JPCLSOmegaSinglet.size()*2+JPCLSOmegaTriplet0.size()*2+JPCLSOmegaTriplet1.size()*2-3){
std::cout << "size of parameters wrong!!! par.size()=" << par.size() << "\tJPCLSOmegaSinglet.size()+JPCLSOmegaTriplet0.size()+JPCLSOmegaTriplet1.size()-3=" << JPCLSOmegaSinglet.size()*2+JPCLSOmegaTriplet0.size()*2+JPCLSOmegaTriplet1.size()*2-3 << std::endl;
assert(0);
}
int counter=0;
for ( itJPCLS=JPCLSOmegaSinglet.begin(); itJPCLS!=JPCLSOmegaSinglet.end(); ++itJPCLS){
//now fill the fitParameterMap
double mag=par[counter];
counter++;
double phi=0.;
if (counter>1){ phi=par[counter];
counter++;
}
std::pair <double,double> tmpParameter=make_pair(mag,phi);
fitParmVal.omegaProdSinglet[(*itJPCLS)]=tmpParameter;
}
for ( itJPCLS=JPCLSOmegaTriplet0.begin(); itJPCLS!=JPCLSOmegaTriplet0.end(); ++itJPCLS){
//now fill the fitParameterMap
double mag=par[counter];
counter++;
double phi=0.;
if (counter>JPCLSOmegaSinglet.size()*2){ phi=par[counter];
counter++;
}
std::pair <double,double> tmpParameter=make_pair(mag,phi);
fitParmVal.omegaProdTriplet0[(*itJPCLS)]=tmpParameter;
}
for ( itJPCLS=JPCLSOmegaTriplet1.begin(); itJPCLS!=JPCLSOmegaTriplet1.end(); ++itJPCLS){
//now fill the fitParameterMap
double mag=par[counter];
counter++;
double phi=0.;
if (counter>JPCLSOmegaSinglet.size()*2+JPCLSOmegaTriplet0.size()*2-1){ phi=par[counter];
counter++;
}
std::pair <double,double> tmpParameter=make_pair(mag,phi);
fitParmVal.omegaProdTriplet1[(*itJPCLS)]=tmpParameter;
}
return true;
}
void printFitParams(OmegaPiData::fitParamVal& fitParmVal)
{
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaSinglet=_barpToOmegaPi0States->jpclsSinglet();
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet0=_barpToOmegaPi0States->jpclsTriplet0();
std::vector< boost::shared_ptr<const JPCLS> > JPCLSOmegaTriplet1=_barpToOmegaPi0States->jpclsTriplet1();
std::vector< boost::shared_ptr<const JPCLS> >::const_iterator itJPCLS;
std::cout << "***fit parameter singlet states*** " <<std::endl;
for ( itJPCLS=JPCLSOmegaSinglet.begin(); itJPCLS!=JPCLSOmegaSinglet.end(); ++itJPCLS){
std::cout << (*itJPCLS)->name()<< "\t";
std::pair<double, double> tmpParam=fitParmVal.omegaProdSinglet[(*itJPCLS)];
std::cout <<"\t mag:" << tmpParam.first <<"\t phi:" << tmpParam.second << std::endl;
}
std::cout << "***fit parameter triplet m=0 states*** " <<std::endl;
for ( itJPCLS=JPCLSOmegaTriplet0.begin(); itJPCLS!=JPCLSOmegaTriplet0.end(); ++itJPCLS){
std::cout<< (*itJPCLS)->name()<< "\t";
std::pair<double, double> tmpParam=fitParmVal.omegaProdTriplet0[(*itJPCLS)];
std::cout <<"\t mag:" << tmpParam.first <<"\t phi:" << tmpParam.second << std::endl;
}
std::cout << "***fit parameter triplet m=1 states*** " <<std::endl;
for ( itJPCLS=JPCLSOmegaTriplet1.begin(); itJPCLS!=JPCLSOmegaTriplet1.end(); ++itJPCLS){
std::cout<< (*itJPCLS)->name()<< "\t";
std::pair<double, double> tmpParam=fitParmVal.omegaProdTriplet1[(*itJPCLS)];
std::cout <<"\t mag:" << tmpParam.first <<"\t phi:" << tmpParam.second << std::endl;
}
std::cout << std::endl;
return;
}
boost::shared_ptr<OmegaPiLh> getOmegaPiLhPtr() {return _omegaPiLhPtr;}
/*******************************************************************************************/
/**
* Checks whether a given expectation for the relationship between this object and another object
* is fulfilled.
*
* NOTE: THIS FUNCTION IS OPTIONAL AND IS MAINLY USED IN CONJUNCTION WITH UNIT TESTS.
* You do not need it if you do not intend to perform unit tests.
*
* @param cp A constant reference to another object, camouflaged as a GObject
* @param e The expected outcome of the comparison
* @param limit The maximum deviation for floating point values (important for similarity checks)
* @param caller An identifier for the calling entity
* @param y_name An identifier for the object that should be compared to this one
* @param withMessages Whether or not information should be emitted in case of deviations from the expected outcome
* @return A boost::optional<std::string> object that holds a descriptive string if expectations were not met
*/
boost::optional<std::string> checkRelationshipWith(const GObject& cp,
const Gem::Common::expectation& e,
const double& limit,
const std::string& caller,
const std::string& y_name,
const bool& withMessages) const
{
using namespace Gem::Common;
// Check that we are not accidently assigning this object to itself
selfAssignmentCheck<GOmegaPiIndividual>(&cp);
// Use this call instead when local data needs to be loaded:
// const GOmegaPiIndividual *p_load = GObject::conversion_cast<GOmegaPiIndividual>(&cp);
// Will hold possible deviations from the expectation, including explanations
std::vector<boost::optional<std::string> > deviations;
// Check our parent class'es data ...
deviations.push_back(GParameterSet::checkRelationshipWith(cp, e, limit, "GOmegaPiIndividual", y_name, withMessages));
// Check local data like this:
// deviations.push_back(checkExpectation(withMessages, "GOmegaPiIndividual", val_, p_load->val_, "val_", "p_load->val_", e , limit));
return evaluateDiscrepancies("GOmegaPiIndividual", caller, deviations, e);
}
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
#ifdef GENEVATESTING
/*******************************************************************************************/
/**
* Applies modifications to this object. This is needed for testing purposes
*
* @return A boolean which indicates whether modifications were made
*/
virtual bool modify_GUnitTests() {
bool result;
// Call the parent class'es function
if(GParameterSet::modify_GUnitTests()) result = true;
// Check that this individual actually contains data to be modified
if(this->size() != 0) {
adapt(); // Perform modifications
result = true;
}
return result;
}
/*******************************************************************************************/
/**
* Performs self tests that are expected to succeed. This is needed for testing purposes
*/
virtual void specificTestsNoFailureExpected_GUnitTests() {
const boost::uint32_t NITERATIONS=100;
// Call the parent class'es function
GParameterSet::specificTestsNoFailureExpected_GUnitTests();
// Create an individual
boost::shared_ptr<Gem::Geneva::GStartIndividual> p
= boost::shared_ptr<Gem::Geneva::GStartIndividual>(new GStartIndividual(1000, -10, 10));
// Adapt a number of times and check that there were changes
double oldfitness = p->fitness();
for(boost::uint32_t i=0; i<NITERATIONS; i++) {
p->adapt();
double newfitness = p->fitness();
BOOST_CHECK_MESSAGE(newfitness != oldfitness, "Rare failures are normal for this test / " << i << "/" << NITERATIONS);
oldfitness = newfitness;
}
}
/*******************************************************************************************/
/**
* Performs self tests that are expected to fail. This is needed for testing purposes
*/
virtual void specificTestsFailuresExpected_GUnitTests() {
// Call the parent class'es function
GParameterSet::specificTestsFailuresExpected_GUnitTests();
}
#endif /* GENEVATESTING */
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
protected:
/********************************************************************************************/
/**
* Loads the data of another GOmegaPiIndividual, camouflaged as a GObject.
*
* @param cp A copy of another GOmegaPiIndividual, camouflaged as a GObject
*/
virtual void load_(const GObject* cp)
{
// Check that we are not accidently assigning this object to itself
selfAssignmentCheck<GOmegaPiIndividual>(cp);
// Use this call instead when local data needs to be loaded:
// const GOmegaPiIndividual *p_load = GObject::conversion_cast<GOmegaPiIndividual>(cp);
// Load our parent's data
GParameterSet::load_(cp);
// Load local data here like this:
// myVar = p_load->myVar;
}
/********************************************************************************************/
/**
* Creates a deep clone of this object
*
* @return A deep clone of this object, camouflaged as a GObject
*/
virtual GObject* clone_() const {
return new GOmegaPiIndividual(*this);
}
/********************************************************************************************/
/**
* The actual fitness calculation takes place here.
*
* @return The value of this object
*/
virtual double fitnessCalculation(){
double result = 0.;
OmegaPiData::fitParamVal theFitParmValTmp;
assert(getFitParams(theFitParmValTmp));
result=_omegaPiLhPtr->calcLogLh(theFitParmValTmp);
return result;
}
private:
/********************************************************************************************/
/**
* The default constructor. Intentionally private and empty, as it is only needed for
* serialization purposes.
*/
boost::shared_ptr<OmegaPiLh> _omegaPiLhPtr;
boost::shared_ptr<pbarpToOmegaPi0States> _barpToOmegaPi0States;
GOmegaPiIndividual() :GParameterSet()
{
_barpToOmegaPi0States = pbarpToOmegaPi0States::getStates();
}
void setFitParamVal(std::vector< boost::shared_ptr<const JPCLS> > theJPCLSs, boost::shared_ptr<GConstrainedDoubleObjectCollection> theGbdc_ptr){
std::vector< boost::shared_ptr<const JPCLS> >::const_iterator itJPCLS;
int counter=0;
for ( itJPCLS=theJPCLSs.begin(); itJPCLS!=theJPCLSs.end(); ++itJPCLS){
//now fill the fitParameterMap
boost::shared_ptr<GConstrainedDoubleObject> gbd_ptr(new GConstrainedDoubleObject(0., 1.) ); //JPCLS magnitude
theGbdc_ptr->push_back(gbd_ptr);
if (counter>0){
boost::shared_ptr<GConstrainedDoubleObject> gbd_ptr(new GConstrainedDoubleObject(-M_PI, M_PI) ); //JPCLS phi
theGbdc_ptr->push_back(gbd_ptr);
}
counter++;
}
}
/********************************************************************************************/
// You can add other variables here. Do not forget to serialize them if necessary
// int myVar;
};
/*************************************************************************************************/
} /* namespace Geneva */
} /* namespace Gem */
// Needed for serialization purposes
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(Gem::Geneva::GOmegaPiIndividual)
// Needed for testing purposes
/*************************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************/
/**
* As the Gem::Geneva::Gem::Geneva::GOmegaPiIndividual has a private default constructor, we need to provide a
* specialization of the factory function that creates GStartProjectIndividual objects
*/
//template <>
//boost::shared_ptr<Gem::Geneva::GOmegaPiIndividual> TFactory_GUnitTests<Gem::Geneva::GOmegaPiIndividual>() {
// return boost::shared_ptr<Gem::Geneva::GOmegaPiIndividual>(new Gem::Geneva::GOmegaPiIndividual(1000,-10.,10.));
//}
/*************************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************/
#endif /* GSTARTINDIVIDUAL_HPP_ */