Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8309052
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
106 KB
Subscribers
None
View Options
diff --git a/DipoleShower/Base/DipoleSplittingGenerator.cc b/DipoleShower/Base/DipoleSplittingGenerator.cc
--- a/DipoleShower/Base/DipoleSplittingGenerator.cc
+++ b/DipoleShower/Base/DipoleSplittingGenerator.cc
@@ -1,610 +1,611 @@
// -*- C++ -*-
//
// DipoleSplittingGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleSplittingGenerator class.
//
#include <config.h>
#include "DipoleSplittingGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/DipoleShower/DipoleShowerHandler.h"
using namespace Herwig;
DipoleSplittingGenerator::DipoleSplittingGenerator()
: HandlerBase(),
theExponentialGenerator(0), prepared(false), presampling(false),
theDoCompensate(false) {
if ( ShowerHandler::currentHandler() )
setGenerator(ShowerHandler::currentHandler()->generator());
}
DipoleSplittingGenerator::~DipoleSplittingGenerator() {
if ( theExponentialGenerator ) {
delete theExponentialGenerator;
theExponentialGenerator = 0;
}
}
IBPtr DipoleSplittingGenerator::clone() const {
return new_ptr(*this);
}
IBPtr DipoleSplittingGenerator::fullclone() const {
return new_ptr(*this);
}
void DipoleSplittingGenerator::wrap(Ptr<DipoleSplittingGenerator>::ptr other) {
assert(!prepared);
theOtherGenerator = other;
}
void DipoleSplittingGenerator::resetVariations() {
for ( map<string,double>::iterator w = currentWeights.begin();
w != currentWeights.end(); ++w )
w->second = 1.;
}
void DipoleSplittingGenerator::prepare(const DipoleSplittingInfo& sp) {
generatedSplitting = sp;
generatedSplitting.splittingKinematics(splittingKernel()->splittingKinematics());
generatedSplitting.splittingParameters().resize(splittingKernel()->nDimAdditional());
if ( wrapping() ) {
generatedSplitting.emitterData(theSplittingKernel->emitter(generatedSplitting.index()));
generatedSplitting.spectatorData(theSplittingKernel->spectator(generatedSplitting.index()));
generatedSplitting.emissionData(theSplittingKernel->emission(generatedSplitting.index()));
parameters.resize(theOtherGenerator->nDim());
prepared = true;
return;
}
generatedSplitting.emitterData(splittingKernel()->emitter(generatedSplitting.index()));
generatedSplitting.spectatorData(splittingKernel()->spectator(generatedSplitting.index()));
generatedSplitting.emissionData(splittingKernel()->emission(generatedSplitting.index()));
presampledSplitting = generatedSplitting;
prepared = true;
parameters.resize(nDim());
theExponentialGenerator =
new exsample::exponential_generator<DipoleSplittingGenerator,UseRandom>();
theExponentialGenerator->sampling_parameters().maxtry = maxtry();
theExponentialGenerator->sampling_parameters().presampling_points = presamplingPoints();
theExponentialGenerator->sampling_parameters().freeze_grid = freezeGrid();
+ theExponentialGenerator->detuning(detuning());
theExponentialGenerator->docompensate(theDoCompensate);
theExponentialGenerator->function(this);
theExponentialGenerator->initialize();
}
void DipoleSplittingGenerator::fixParameters(const DipoleSplittingInfo& sp,
Energy optHardPt) {
assert(generator());
assert(!presampling);
assert(prepared);
assert(sp.index() == generatedSplitting.index());
generatedSplitting.scale(sp.scale());
parameters[3] = sp.scale()/generator()->maximumCMEnergy();
generatedSplitting.hardPt(sp.hardPt());
parameters[0] = splittingKinematics()->ptToRandom(optHardPt == ZERO ?
generatedSplitting.hardPt() :
min(generatedSplitting.hardPt(),optHardPt),
sp.scale(),
sp.emitterX(), sp.spectatorX(),
generatedSplitting.index(),
*splittingKernel());
size_t shift = 4;
if ( generatedSplitting.index().emitterPDF().pdf() &&
generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.emitterX(sp.emitterX());
generatedSplitting.spectatorX(sp.spectatorX());
parameters[4] = sp.emitterX();
parameters[5] = sp.spectatorX();
shift += 2;
}
if ( generatedSplitting.index().emitterPDF().pdf() &&
!generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.emitterX(sp.emitterX());
parameters[4] = sp.emitterX();
++shift;
}
if ( !generatedSplitting.index().emitterPDF().pdf() &&
generatedSplitting.index().spectatorPDF().pdf() ) {
generatedSplitting.spectatorX(sp.spectatorX());
parameters[4] = sp.spectatorX();
++shift;
}
if ( splittingReweight() ) {
parameters[shift] = splittingReweight()->evaluate(sp);
++shift;
}
if ( splittingKernel()->nDimAdditional() )
copy(sp.lastSplittingParameters().begin(),sp.lastSplittingParameters().end(),parameters.begin()+shift);
if ( sp.emitter() )
generatedSplitting.emitter(sp.emitter());
if ( sp.spectator() )
generatedSplitting.spectator(sp.spectator());
}
int DipoleSplittingGenerator::nDim() const {
assert(!wrapping());
assert(prepared);
int ret = 4; // 0 pt, 1 z, 2 phi, 3 scale, 4/5 xs + parameters
if ( generatedSplitting.index().emitterPDF().pdf() ) {
++ret;
}
if ( generatedSplitting.index().spectatorPDF().pdf() ) {
++ret;
}
if ( splittingReweight() )
++ret;
ret += splittingKernel()->nDimAdditional();
return ret;
}
const vector<bool>& DipoleSplittingGenerator::sampleFlags() {
assert(!wrapping());
if ( !theFlags.empty() )
return theFlags;
theFlags.resize(nDim(),false);
theFlags[0] = true; theFlags[1] = true; theFlags[2] = true; // 0 pt, 1 z, 2 phi
return theFlags;
}
const pair<vector<double>,vector<double> >& DipoleSplittingGenerator::support() {
assert(!wrapping());
if ( !theSupport.first.empty() )
return theSupport;
vector<double> lower(nDim(),0.);
vector<double> upper(nDim(),1.);
pair<double,double> kSupport =
generatedSplitting.splittingKinematics()->kappaSupport(generatedSplitting);
pair<double,double> xSupport =
generatedSplitting.splittingKinematics()->xiSupport(generatedSplitting);
lower[0] = kSupport.first;
lower[1] = xSupport.first;
upper[0] = kSupport.second;
upper[1] = xSupport.second;
if ( splittingReweight() ) {
pair<double,double> bounds = splittingReweight()->reweightBounds(generatedSplitting.index());
int pos = 4;
if ( generatedSplitting.index().emitterPDF().pdf() ) {
++pos;
}
if ( generatedSplitting.index().spectatorPDF().pdf() ) {
++pos;
}
lower[pos] = bounds.first;
upper[pos] = bounds.second;
}
theSupport.first = lower;
theSupport.second = upper;
return theSupport;
}
void DipoleSplittingGenerator::startPresampling() {
assert(!wrapping());
splittingKernel()->startPresampling(generatedSplitting.index());
presampling = true;
}
void DipoleSplittingGenerator::stopPresampling() {
assert(!wrapping());
splittingKernel()->stopPresampling(generatedSplitting.index());
presampling = false;
}
bool DipoleSplittingGenerator::haveOverestimate() const {
assert(!wrapping());
assert(prepared);
return
generatedSplitting.splittingKinematics()->haveOverestimate() &&
splittingKernel()->haveOverestimate(generatedSplitting);
}
bool DipoleSplittingGenerator::overestimate(const vector<double>& point) {
assert(!wrapping());
assert(prepared);
assert(!presampling);
assert(haveOverestimate());
if ( ! generatedSplitting.splittingKinematics()->generateSplitting(point[0],point[1],point[2],
generatedSplitting,
*splittingKernel()) )
return 0.;
generatedSplitting.splittingKinematics()->prepareSplitting(generatedSplitting);
return
( generatedSplitting.splittingKinematics()->jacobianOverestimate() *
splittingKernel()->overestimate(generatedSplitting) *
(splittingReweight() ? splittingReweight()->evaluate(generatedSplitting) : 1.) );
}
double DipoleSplittingGenerator::invertOverestimateIntegral(double value) const {
assert(!wrapping());
assert(prepared);
assert(!presampling);
assert(haveOverestimate());
return
splittingKernel()->invertOverestimateIntegral(generatedSplitting,value);
}
double DipoleSplittingGenerator::evaluate(const vector<double>& point) {
assert(!wrapping());
assert(prepared);
assert(generator());
DipoleSplittingInfo& split =
( !presampling ? generatedSplitting : presampledSplitting );
split.continuesEvolving();
size_t shift = 4;
if ( presampling ) {
split.scale(point[3] * generator()->maximumCMEnergy());
if ( split.index().emitterPDF().pdf() &&
split.index().spectatorPDF().pdf() ) {
split.emitterX(point[4]);
split.spectatorX(point[5]);
shift += 2;
}
if ( split.index().emitterPDF().pdf() &&
!split.index().spectatorPDF().pdf() ) {
split.emitterX(point[4]);
++shift;
}
if ( !split.index().emitterPDF().pdf() &&
split.index().spectatorPDF().pdf() ) {
split.spectatorX(point[4]);
++shift;
}
if ( splittingReweight() )
++shift;
if ( splittingKernel()->nDimAdditional() )
copy(point.begin()+shift,point.end(),split.splittingParameters().begin());
split.hardPt(split.splittingKinematics()->ptMax(split.scale(),
split.emitterX(),
split.spectatorX(),
split.index(),
*splittingKernel()));
}
if ( ! split.splittingKinematics()->generateSplitting(point[0],point[1],point[2],split,*splittingKernel()) ) {
split.lastValue(0.);
return 0.;
}
split.splittingKinematics()->prepareSplitting(split);
if ( split.stoppedEvolving() ) {
split.lastValue(0.);
return 0.;
}
if ( !presampling )
splittingKernel()->clearAlphaPDFCache();
double kernel = splittingKernel()->evaluate(split);
if ( splittingReweight() ) {
if ( !presampling )
kernel *= splittingReweight()->evaluate(split);
else
kernel *= point[shift-1];
}
double jac = split.splittingKinematics()->jacobian();
// multiply in the profile scales when relevant
assert(ShowerHandler::currentHandler());
if ( ShowerHandler::currentHandler()->firstInteraction() &&
ShowerHandler::currentHandler()->profileScales() &&
!presampling ) {
Energy hard = ShowerHandler::currentHandler()->hardScale();
if ( hard > ZERO )
kernel *= ShowerHandler::currentHandler()->profileScales()->hardScaleProfile(hard,split.lastPt());
}
split.lastValue( abs(jac) * kernel );
if ( isnan(split.lastValue()) || isinf(split.lastValue()) ) {
generator()->log() << "DipoleSplittingGenerator:evaluate(): problematic splitting kernel encountered for "
<< splittingKernel()->name() << "\n" << flush;
split.lastValue(0.0);
}
if ( kernel < 0. )
return 0.;
return split.lastValue();
}
void DipoleSplittingGenerator::doGenerate(map<string,double>& variations,
Energy optCutoff) {
assert(!wrapping());
double res = 0.;
Energy startPt = generatedSplitting.hardPt();
double optKappaCutoff = 0.0;
if ( optCutoff > splittingKinematics()->IRCutoff() ) {
optKappaCutoff = splittingKinematics()->ptToRandom(optCutoff,
generatedSplitting.scale(),
generatedSplitting.emitterX(),
generatedSplitting.spectatorX(),
generatedSplitting.index(),
*splittingKernel());
}
resetVariations();
while (true) {
try {
if ( optKappaCutoff == 0.0 ) {
res = theExponentialGenerator->generate();
} else {
res = theExponentialGenerator->generate(optKappaCutoff);
}
} catch (exsample::exponential_regenerate&) {
resetVariations();
generatedSplitting.hardPt(startPt);
continue;
} catch (exsample::hit_and_miss_maxtry&) {
throw DipoleShowerHandler::RedoShower();
} catch (exsample::selection_maxtry&) {
throw DipoleShowerHandler::RedoShower();
}
break;
}
for ( map<string,double>::const_iterator w = currentWeights.begin();
w != currentWeights.end(); ++w ) {
map<string,double>::iterator v = variations.find(w->first);
if ( v != variations.end() )
v->second *= w->second;
else
variations[w->first] = w->second;
}
if ( res == 0. ) {
generatedSplitting.lastPt(0.0*GeV);
generatedSplitting.didStopEvolving();
} else {
generatedSplitting.continuesEvolving();
if ( theMCCheck )
theMCCheck->book(generatedSplitting.emitterX(),
generatedSplitting.spectatorX(),
generatedSplitting.scale(),
startPt,
generatedSplitting.lastPt(),
generatedSplitting.lastZ(),
1.);
}
}
Energy DipoleSplittingGenerator::generate(const DipoleSplittingInfo& split,
map<string,double>& variations,
Energy optHardPt,
Energy optCutoff) {
fixParameters(split,optHardPt);
if ( wrapping() ) {
return theOtherGenerator->generateWrapped(generatedSplitting,variations,optHardPt,optCutoff);
}
doGenerate(variations,optCutoff);
return generatedSplitting.lastPt();
}
Energy DipoleSplittingGenerator::generateWrapped(DipoleSplittingInfo& split,
map<string,double>& variations,
Energy optHardPt,
Energy optCutoff) {
assert(!wrapping());
DipoleSplittingInfo backup = generatedSplitting;
generatedSplitting = split;
fixParameters(split,optHardPt);
try {
doGenerate(variations,optCutoff);
} catch (...) {
split = generatedSplitting;
generatedSplitting = backup;
throw;
}
Energy pt = generatedSplitting.lastPt();
split = generatedSplitting;
generatedSplitting = backup;
return pt;
}
void DipoleSplittingGenerator::completeSplitting(DipoleSplittingInfo& sp) const {
pair<bool,bool> conf = sp.configuration();
sp = generatedSplitting;
sp.configuration(conf);
}
Ptr<DipoleSplittingKernel>::tptr DipoleSplittingGenerator::splittingKernel() const {
if ( wrapping() )
return theOtherGenerator->splittingKernel();
return theSplittingKernel;
}
Ptr<DipoleSplittingReweight>::tptr DipoleSplittingGenerator::splittingReweight() const {
if ( wrapping() )
return theOtherGenerator->splittingReweight();
return theSplittingReweight;
}
Ptr<DipoleSplittingKinematics>::tptr DipoleSplittingGenerator::splittingKinematics() const {
if ( wrapping() )
return theOtherGenerator->splittingKinematics();
return theSplittingKernel->splittingKinematics();
}
void DipoleSplittingGenerator::splittingKernel(Ptr<DipoleSplittingKernel>::tptr sp) {
theSplittingKernel = sp;
if ( theSplittingKernel->mcCheck() )
theMCCheck = theSplittingKernel->mcCheck();
}
void DipoleSplittingGenerator::splittingReweight(Ptr<DipoleSplittingReweight>::tptr sp) {
theSplittingReweight = sp;
}
void DipoleSplittingGenerator::debugGenerator(ostream& os) const {
os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
os << " generating splittings using\n"
<< " splittingKernel = " << splittingKernel()->name()
<< " splittingKinematics = " << generatedSplitting.splittingKinematics()->name() << "\n"
<< " to sample splittings of type:\n";
os << generatedSplitting;
os << "--------------------------------------------------------------------------------\n";
}
void DipoleSplittingGenerator::debugLastEvent(ostream& os) const {
os << "--- DipoleSplittingGenerator ---------------------------------------------------\n";
os << " last generated event:\n";
os << generatedSplitting;
os << "--------------------------------------------------------------------------------\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleSplittingGenerator::persistentOutput(PersistentOStream & os) const {
os << theOtherGenerator << theSplittingKernel << theSplittingReweight << theMCCheck << theDoCompensate;
}
void DipoleSplittingGenerator::persistentInput(PersistentIStream & is, int) {
is >> theOtherGenerator >> theSplittingKernel >> theSplittingReweight >> theMCCheck >> theDoCompensate;
}
ClassDescription<DipoleSplittingGenerator> DipoleSplittingGenerator::initDipoleSplittingGenerator;
// Definition of the static class description member.
void DipoleSplittingGenerator::Init() {
static ClassDocumentation<DipoleSplittingGenerator> documentation
("DipoleSplittingGenerator is used by the dipole shower "
"to sample splittings from a given dipole splitting kernel.");
static Reference<DipoleSplittingGenerator,DipoleSplittingKernel> interfaceSplittingKernel
("SplittingKernel",
"Set the splitting kernel to sample from.",
&DipoleSplittingGenerator::theSplittingKernel, false, false, true, false, false);
static Reference<DipoleSplittingGenerator,DipoleSplittingReweight> interfaceSplittingReweight
("SplittingReweight",
"Set the splitting reweight.",
&DipoleSplittingGenerator::theSplittingReweight, false, false, true, true, false);
static Reference<DipoleSplittingGenerator,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingGenerator::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
}
diff --git a/DipoleShower/Base/DipoleSplittingGenerator.h b/DipoleShower/Base/DipoleSplittingGenerator.h
--- a/DipoleShower/Base/DipoleSplittingGenerator.h
+++ b/DipoleShower/Base/DipoleSplittingGenerator.h
@@ -1,476 +1,481 @@
// -*- C++ -*-
//
// DipoleSplittingGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleSplittingGenerator_H
#define HERWIG_DipoleSplittingGenerator_H
//
// This is the declaration of the DipoleSplittingGenerator class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "Herwig/DipoleShower/Kernels/DipoleSplittingKernel.h"
#include "DipoleSplittingReweight.h"
#include "Herwig/DipoleShower/Utility/DipoleMCCheck.h"
#include "Herwig/Sampling/exsample/exponential_generator.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingGenerator is used by the dipole shower
* to sample splittings from a given dipole splitting kernel.
*
* @see \ref DipoleSplittingGeneratorInterfaces "The interfaces"
* defined for DipoleSplittingGenerator.
*/
class DipoleSplittingGenerator: public HandlerBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleSplittingGenerator();
/**
* The destructor.
*/
virtual ~DipoleSplittingGenerator();
//@}
public:
/**
* Return the dipole splitting kernel.
*/
Ptr<DipoleSplittingKernel>::tptr splittingKernel() const;
/**
* Return the dipole splitting reweight.
*/
Ptr<DipoleSplittingReweight>::tptr splittingReweight() const;
/**
* Return the dipole splitting kinematics.
*/
Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const;
/**
* Set the dipole splitting kernel.
*/
void splittingKernel(Ptr<DipoleSplittingKernel>::tptr sp);
/**
* Set the dipole splitting reweight.
*/
void splittingReweight(Ptr<DipoleSplittingReweight>::tptr sp);
/**
* Make a wrapper around another generator.
*/
void wrap(Ptr<DipoleSplittingGenerator>::ptr other);
/**
* Return true, if this is actually a wrapper around
* another splitting generator.
*/
bool wrapping() const { return theOtherGenerator; }
public:
/**
* Reset the current variations to one
*/
void resetVariations();
/**
* Prepare to fill the given splitting.
*/
void prepare(const DipoleSplittingInfo&);
/**
* Fix parameters from the fiven DipoleSplittingInfo
* and generate the next splitting. Return the
* pt selected for the next splitting.
*/
Energy generate(const DipoleSplittingInfo&,
map<string,double>& variations,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Fix parameters from the fiven DipoleSplittingInfo
* and generate the next splitting. Return the
* pt selected for the next splitting when called
* from a wrapping generator.
*/
Energy generateWrapped(DipoleSplittingInfo&,
map<string,double>& variations,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Complete the given splitting.
*/
void completeSplitting(DipoleSplittingInfo&) const;
/**
* Return the last generated splitting
*/
const DipoleSplittingInfo& lastSplitting() const { return generatedSplitting; }
public:
/**
* Print debug information on the splitting
* handled.
*/
void debugGenerator(ostream&) const;
/**
* Print debug information on the last
* generated event.
*/
void debugLastEvent(ostream&) const;
protected:
/**
* Update parameters given a splitting.
*/
void fixParameters(const DipoleSplittingInfo&,
Energy optHardPt = ZERO);
/**
* With the parameters previuosly supplied
* through fixParameters generate the next
* splitting.
*/
void doGenerate(map<string,double>& variations,
Energy optCutoff = ZERO);
public:
/**
* Return the number of random numbers
* needed to sample this kernel.
*/
int nDim() const;
/**
* Flag, which variables are free variables.
*/
const vector<bool>& sampleFlags();
/**
* Return the support of the splitting kernel.
* The lower bound on the first variable is
* assumed to correspond to the cutoff on the
* evolution variable.
*/
const pair<vector<double>,vector<double> >& support();
/**
* Return the parameter point associated to the splitting
* previously supplied through fixParameters.
*/
const vector<double>& parameterPoint() const { return parameters; }
/**
* Indicate that presampling of this kernel
* will be performed in the next calls to
* evaluate until stopPresampling() is called.
*/
void startPresampling();
/**
* Indicate that presampling of this kernel
* is done until startPresampling() is called.
*/
void stopPresampling();
/**
* Return the number of points to presample this
* splitting generator.
*/
unsigned long presamplingPoints() const { return splittingKernel()->presamplingPoints(); }
/**
* Return the maximum number of trials
* to generate a splitting.
*/
unsigned long maxtry() const { return splittingKernel()->maxtry(); }
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long freezeGrid() const { return splittingKernel()->freezeGrid(); }
/**
+ * Return the detuning factor applied to the sampling overestimate kernel
+ */
+ double detuning() const { return splittingKernel()->detuning(); }
+
+ /**
* Return true, if this splitting generator
* is able to deliver an overestimate to the sampled
* kernel.
*/
bool haveOverestimate() const;
/**
* Return an overestimate to the sampled kernel.
*/
bool overestimate(const vector<double>&);
/**
* Invert the integral over the overestimate to equal
* the given value.
*/
double invertOverestimateIntegral(double) const;
/**
* Evalute the splitting kernel.
*/
double evaluate(const vector<double>&);
/**
* Indicate that a veto with the given kernel value and overestimate has occured.
*/
void veto(const vector<double>&, double p, double r) {
splittingKernel()->veto(generatedSplitting, p, r, currentWeights);
}
/**
* Indicate that an accept with the given kernel value and overestimate has occured.
*/
void accept(const vector<double>&, double p, double r) {
splittingKernel()->accept(generatedSplitting, p, r, currentWeights);
}
/**
* True, if sampler should apply compensation
*/
void doCompensate(bool yes = true) { theDoCompensate = yes; }
public:
/**@name Wrap to the exsample2 interface until this is finally cleaned up. */
//@{
inline const vector<bool>& variable_flags () {
return sampleFlags();
}
inline size_t evolution_variable () const { return 0; }
inline double evolution_cutoff () { return support().first[0]; }
inline const vector<double>& parameter_point () const {
return parameterPoint();
}
inline void start_presampling () {
startPresampling();
}
inline void stop_presampling () {
stopPresampling();
}
inline size_t dimension () const {
return nDim();
}
inline unsigned long presampling_points () const {
return presamplingPoints();
}
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* Pointer to another generator to wrap around.
*/
Ptr<DipoleSplittingGenerator>::ptr theOtherGenerator;
/**
* The dipole splitting kernel to sample
* splitting from.
*/
Ptr<DipoleSplittingKernel>::ptr theSplittingKernel;
/**
* The dipole splitting reweight.
*/
Ptr<DipoleSplittingReweight>::ptr theSplittingReweight;
/**
* Pointer to the exponential generator
*/
exsample::exponential_generator<DipoleSplittingGenerator,UseRandom>*
theExponentialGenerator;
/**
* The dipole splitting to be completed.
*/
DipoleSplittingInfo generatedSplitting;
/**
* A backup of the dipole splitting to be
* completed, if this generator is presampled.
*/
DipoleSplittingInfo presampledSplitting;
/**
* True, if prepared to sample splittings
* of a given kind.
*/
bool prepared;
/**
* Wether or not the kernel is currently
* being presampled.
*/
bool presampling;
/**
* The parameter point.
*/
vector<double> parameters;
/**
* The sampling flags
*/
vector<bool> theFlags;
/**
* The support.
*/
pair<vector<double>,vector<double> > theSupport;
/**
* Pointer to a check histogram object
*/
Ptr<DipoleMCCheck>::ptr theMCCheck;
/**
* True, if sampler should apply compensation
*/
bool theDoCompensate;
/**
* The currently used weight map
*/
map<string,double> currentWeights;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<DipoleSplittingGenerator> initDipoleSplittingGenerator;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleSplittingGenerator & operator=(const DipoleSplittingGenerator &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleSplittingGenerator. */
template <>
struct BaseClassTrait<Herwig::DipoleSplittingGenerator,1> {
/** Typedef of the first base class of DipoleSplittingGenerator. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleSplittingGenerator class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleSplittingGenerator>
: public ClassTraitsBase<Herwig::DipoleSplittingGenerator> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleSplittingGenerator"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleSplittingGenerator is implemented. It may also include several, space-separated,
* libraries if the class DipoleSplittingGenerator depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_DipoleSplittingGenerator_H */
diff --git a/DipoleShower/Kernels/DipoleSplittingKernel.cc b/DipoleShower/Kernels/DipoleSplittingKernel.cc
--- a/DipoleShower/Kernels/DipoleSplittingKernel.cc
+++ b/DipoleShower/Kernels/DipoleSplittingKernel.cc
@@ -1,362 +1,369 @@
// -*- C++ -*-
//
// DipoleSplittingKernel.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleSplittingKernel class.
//
#include "DipoleSplittingKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/ShowerHandler.h"
using namespace Herwig;
DipoleSplittingKernel::DipoleSplittingKernel()
: HandlerBase(), theScreeningScale(0.0*GeV),
thePresamplingPoints(2000), theMaxtry(100000),
theFreezeGrid(500000),
+ theDetuning(1.0),
theStrictLargeN(false),
theFactorizationScaleFactor(1.0),
theRenormalizationScaleFactor(1.0),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
theVirtualitySplittingScale(false),
presampling(false) {}
DipoleSplittingKernel::~DipoleSplittingKernel() {}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleSplittingKernel::persistentOutput(PersistentOStream & os) const {
os << theAlphaS << ounit(theScreeningScale,GeV) << theSplittingKinematics << thePDFRatio
- << thePresamplingPoints << theMaxtry << theFreezeGrid
+ << thePresamplingPoints << theMaxtry << theFreezeGrid << theDetuning
<< theFlavour << theMCCheck << theStrictLargeN
<< theFactorizationScaleFactor
<< theRenormalizationScaleFactor
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theVirtualitySplittingScale;
}
void DipoleSplittingKernel::persistentInput(PersistentIStream & is, int) {
is >> theAlphaS >> iunit(theScreeningScale,GeV) >> theSplittingKinematics >> thePDFRatio
- >> thePresamplingPoints >> theMaxtry >> theFreezeGrid
+ >> thePresamplingPoints >> theMaxtry >> theFreezeGrid >> theDetuning
>> theFlavour >> theMCCheck >> theStrictLargeN
>> theFactorizationScaleFactor
>> theRenormalizationScaleFactor
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theVirtualitySplittingScale;
}
double DipoleSplittingKernel::alphaPDF(const DipoleSplittingInfo& split,
Energy optScale,
double rScaleFactor,
double fScaleFactor) const {
Energy pt = optScale == ZERO ? split.lastPt() : optScale;
Energy2 scale = ZERO;
if ( !virtualitySplittingScale() ) {
scale = sqr(pt) + sqr(theScreeningScale);
} else {
scale = sqr(splittingKinematics()->QFromPt(pt,split)) + sqr(theScreeningScale);
}
Energy2 rScale = sqr(theRenormalizationScaleFactor*rScaleFactor)*scale;
rScale = rScale > sqr(renormalizationScaleFreeze()) ? rScale : sqr(renormalizationScaleFreeze());
Energy2 fScale = sqr(theFactorizationScaleFactor*fScaleFactor)*scale;
fScale = fScale > sqr(factorizationScaleFreeze()) ? fScale : sqr(factorizationScaleFreeze());
double alphas = 1.0;
double pdf = 1.0;
// check if we are potentially reweighting and cache evaluations
bool evaluatePDF = true;
bool evaluateAlphaS = true;
bool variations =
!ShowerHandler::currentHandler()->showerVariations().empty() &&
!presampling;
if ( variations ) {
/*
cerr << "--------------------------------------------------------------------------------\n"
<< flush;
cerr << "variations ... central scale/GeV = "
<< sqrt(scale/GeV2) << " r = "
<< rScaleFactor << " f = " << fScaleFactor << "\n"
<< flush;
*/
map<double,double>::const_iterator pit = thePDFCache.find(fScaleFactor);
evaluatePDF = (pit == thePDFCache.end());
if ( !evaluatePDF ) {
//cerr << "PDF is cached: ";
pdf = pit->second;
//cerr << pdf << "\n" << flush;
}
map<double,double>::const_iterator ait = theAlphaSCache.find(rScaleFactor);
evaluateAlphaS = (ait == theAlphaSCache.end());
if ( !evaluateAlphaS ) {
//cerr << "alphas is cached: ";
alphas = ait->second;
//cerr << alphas << "\n" << flush;
}
}
if ( evaluateAlphaS )
alphas = alphaS()->value(rScale);
if ( evaluatePDF ) {
if ( split.index().initialStateEmitter() ) {
assert(pdfRatio());
pdf *=
split.lastEmitterZ() *
(*pdfRatio())(split.index().emitterPDF(), fScale,
split.index().emitterData(),split.emitterData(),
split.emitterX(),split.lastEmitterZ());
}
if ( split.index().initialStateSpectator() ) {
assert(pdfRatio());
pdf *=
split.lastSpectatorZ() *
(*pdfRatio())(split.index().spectatorPDF(), fScale,
split.index().spectatorData(),split.spectatorData(),
split.spectatorX(),split.lastSpectatorZ());
}
}
if ( evaluatePDF && variations ) {
//cerr << "caching PDF = " << pdf << "\n" << flush;
thePDFCache[fScaleFactor] = pdf;
}
if ( evaluateAlphaS && variations ) {
//cerr << "caching alphas = " << alphas << "\n" << flush;
theAlphaSCache[rScaleFactor] = alphas;
}
double ret = alphas*pdf / (2.*Constants::pi);
if ( ret < 0. )
ret = 0.;
return ret;
}
void DipoleSplittingKernel::accept(const DipoleSplittingInfo& split,
double, double,
map<string,double>& weights) const {
if ( ShowerHandler::currentHandler()->showerVariations().empty() )
return;
double reference = alphaPDF(split);
assert(reference > 0.);
for ( map<string,ShowerHandler::ShowerVariation>::const_iterator var =
ShowerHandler::currentHandler()->showerVariations().begin();
var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) {
if ( ( ShowerHandler::currentHandler()->firstInteraction() && var->second.firstInteraction ) ||
( !ShowerHandler::currentHandler()->firstInteraction() && var->second.secondaryInteractions ) ) {
/*
cerr << "reweighting in accept for: "
<< var->first
<< " using "
<< var->second.renormalizationScaleFactor << " "
<< var->second.factorizationScaleFactor << " "
<< var->second.firstInteraction << " "
<< var->second.secondaryInteractions << "\n" << flush;
*/
double varied = alphaPDF(split,ZERO,
var->second.renormalizationScaleFactor,
var->second.factorizationScaleFactor);
if ( varied != reference ) {
map<string,double>::iterator wi = weights.find(var->first);
if ( wi != weights.end() )
wi->second *= varied/reference;
else
weights[var->first] = varied/reference;
}
}
}
}
void DipoleSplittingKernel::veto(const DipoleSplittingInfo& split,
double p, double r,
map<string,double>& weights) const {
if ( ShowerHandler::currentHandler()->showerVariations().empty() )
return;
double reference = alphaPDF(split);
// this is dangerous, but we have no other choice currently -- need to
// carefully check for the effects; the assumption is that if the central
// one ius zero, then so will be the variations.
if ( reference == 0.0 )
return;
for ( map<string,ShowerHandler::ShowerVariation>::const_iterator var =
ShowerHandler::currentHandler()->showerVariations().begin();
var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) {
if ( ( ShowerHandler::currentHandler()->firstInteraction() && var->second.firstInteraction ) ||
( !ShowerHandler::currentHandler()->firstInteraction() && var->second.secondaryInteractions ) ) {
/*
cerr << "reweighting in veto for: "
<< var->first
<< " using "
<< var->second.renormalizationScaleFactor << " "
<< var->second.factorizationScaleFactor << " "
<< var->second.firstInteraction << " "
<< var->second.secondaryInteractions << "\n" << flush;
*/
double varied = alphaPDF(split,ZERO,
var->second.renormalizationScaleFactor,
var->second.factorizationScaleFactor);
if ( varied != reference ) {
map<string,double>::iterator wi = weights.find(var->first);
if ( wi != weights.end() )
wi->second *= (r - varied*p/reference) / (r-p);
else
weights[var->first] = (r - varied*p/reference) / (r-p);
}
}
}
}
AbstractClassDescription<DipoleSplittingKernel> DipoleSplittingKernel::initDipoleSplittingKernel;
// Definition of the static class description member.
void DipoleSplittingKernel::Init() {
static ClassDocumentation<DipoleSplittingKernel> documentation
("DipoleSplittingKernel is the base class for all kernels "
"used within the dipole shower.");
static Reference<DipoleSplittingKernel,AlphaSBase> interfaceAlphaS
("AlphaS",
"The strong coupling to be used by this splitting kernel.",
&DipoleSplittingKernel::theAlphaS, false, false, true, true, false);
static Parameter<DipoleSplittingKernel,Energy> interfaceScreeningScale
("ScreeningScale",
"A colour screening scale",
&DipoleSplittingKernel::theScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Reference<DipoleSplittingKernel,DipoleSplittingKinematics> interfaceSplittingKinematics
("SplittingKinematics",
"The splitting kinematics to be used by this splitting kernel.",
&DipoleSplittingKernel::theSplittingKinematics, false, false, true, false, false);
static Reference<DipoleSplittingKernel,PDFRatio> interfacePDFRatio
("PDFRatio",
"Set the optional PDF ratio object to evaluate this kernel",
&DipoleSplittingKernel::thePDFRatio, false, false, true, true, false);
static Parameter<DipoleSplittingKernel,unsigned long> interfacePresamplingPoints
("PresamplingPoints",
"The number of points used to presample this kernel.",
&DipoleSplittingKernel::thePresamplingPoints, 2000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,unsigned long> interfaceMaxtry
("Maxtry",
"The maximum number of attempts to generate a splitting.",
&DipoleSplittingKernel::theMaxtry, 10000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,unsigned long> interfaceFreezeGrid
("FreezeGrid",
"",
&DipoleSplittingKernel::theFreezeGrid, 500000, 1, 0,
false, false, Interface::lowerlim);
static Reference<DipoleSplittingKernel,ParticleData> interfaceFlavour
("Flavour",
"Set the flavour to be produced if ambiguous.",
&DipoleSplittingKernel::theFlavour, false, false, true, true, false);
static Reference<DipoleSplittingKernel,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingKernel::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
static Switch<DipoleSplittingKernel,bool> interfaceStrictLargeN
("StrictLargeN",
"Work in a strict large-N limit.",
&DipoleSplittingKernel::theStrictLargeN, false, false, false);
static SwitchOption interfaceStrictLargeNOn
(interfaceStrictLargeN,
"On",
"Replace C_F -> C_A/2 where present",
true);
static SwitchOption interfaceStrictLargeNOff
(interfaceStrictLargeN,
"Off",
"Keep C_F=4/3",
false);
interfaceStrictLargeN.rank(-2);
static Parameter<DipoleSplittingKernel,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&DipoleSplittingKernel::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
interfaceFactorizationScaleFactor.rank(-2);
static Parameter<DipoleSplittingKernel,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&DipoleSplittingKernel::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
interfaceRenormalizationScaleFactor.rank(-2);
static Parameter<DipoleSplittingKernel,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&DipoleSplittingKernel::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&DipoleSplittingKernel::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<DipoleSplittingKernel,bool> interfaceVirtualitySplittingScale
("VirtualitySplittingScale",
"Use the virtuality as the splitting scale.",
&DipoleSplittingKernel::theVirtualitySplittingScale, false, false, false);
static SwitchOption interfaceVirtualitySplittingScaleYes
(interfaceVirtualitySplittingScale,
"Yes",
"Use vrituality.",
true);
static SwitchOption interfaceVirtualitySplittingScaleNo
(interfaceVirtualitySplittingScale,
"No",
"Use transverse momentum.",
false);
+ static Parameter<DipoleSplittingKernel,double> interfaceDetuning
+ ("Detuning",
+ "A value to detune the overestimate kernel.",
+ &DipoleSplittingKernel::theDetuning, 1.0, 1.0, 0,
+ false, false, Interface::lowerlim);
+
}
diff --git a/DipoleShower/Kernels/DipoleSplittingKernel.h b/DipoleShower/Kernels/DipoleSplittingKernel.h
--- a/DipoleShower/Kernels/DipoleSplittingKernel.h
+++ b/DipoleShower/Kernels/DipoleSplittingKernel.h
@@ -1,480 +1,495 @@
// -*- C++ -*-
//
// DipoleSplittingKernel.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleSplittingKernel_H
#define HERWIG_DipoleSplittingKernel_H
//
// This is the declaration of the DipoleSplittingKernel class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/StandardModel/AlphaSBase.h"
#include "ThePEG/PDF/PDF.h"
#include "Herwig/DipoleShower/Utility/PDFRatio.h"
#include "Herwig/DipoleShower/Base/DipoleSplittingInfo.h"
#include "Herwig/DipoleShower/Kinematics/DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingKernel is the base class for all kernels
* used within the dipole shower.
*
* @see \ref DipoleSplittingKernelInterfaces "The interfaces"
* defined for DipoleSplittingKernel.
*/
class DipoleSplittingKernel: public HandlerBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleSplittingKernel();
/**
* The destructor.
*/
virtual ~DipoleSplittingKernel();
//@}
public:
/**
* Return the alpha_s to be used
*/
Ptr<AlphaSBase>::tptr alphaS() const { return theAlphaS; }
/**
* Set the alpha_s to be used
*/
void alphaS(Ptr<AlphaSBase>::tptr ap) { theAlphaS = ap; }
/**
* Return the splitting kinematics object
*/
Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const { return theSplittingKinematics; }
/**
* Return the mc check object
*/
Ptr<DipoleMCCheck>::ptr mcCheck() const { return theMCCheck; }
/**
* Set the splitting kinematics object
*/
void splittingKinematics(Ptr<DipoleSplittingKinematics>::tptr sp) { theSplittingKinematics = sp; }
/**
* Return the PDFRatio object
*/
Ptr<PDFRatio>::tptr pdfRatio() const { return thePDFRatio; }
/**
* Set the PDFRatio object
*/
void pdfRatio(Ptr<PDFRatio>::tptr sp) { thePDFRatio = sp; }
/**
* Return the number of additional parameter
* random variables needed to evaluate this kernel
* except the momentum fractions of incoming partons.
* These will be accessible through the
* lastSplittingParameters() container of the splitting
* info object.
*/
virtual int nDimAdditional() const { return 0; }
/**
* Set the freezing value for the renormalization scale
*/
void renormalizationScaleFreeze(Energy s) { theRenormalizationScaleFreeze = s; }
/**
* Set the freezing value for the factorization scale
*/
void factorizationScaleFreeze(Energy s) { theFactorizationScaleFreeze = s; }
/**
* Get the freezing value for the renormalization scale
*/
Energy renormalizationScaleFreeze() const { return theRenormalizationScaleFreeze; }
/**
* Get the freezing value for the factorization scale
*/
Energy factorizationScaleFreeze() const { return theFactorizationScaleFreeze; }
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const = 0;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const = 0;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const = 0;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const = 0;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const = 0;
/**
* Return the flavour produced, if this cannot
* be determined from the dipole.
*/
PDPtr flavour() const { return theFlavour; }
/**
* Return true, if this splitting kernel is supposed to work in a
* strict large-N limit, i.e. replacing C_F by C_A/2
*/
bool strictLargeN() const { return theStrictLargeN; }
public:
/**
* Inform this splitting kernel, that it is being
* presampled until a call to stopPresampling
*/
virtual void startPresampling(const DipoleIndex&) {
presampling = true;
}
/**
* Inform this splitting kernel, that it is not being
* presampled until a call to startPresampling
*/
virtual void stopPresampling(const DipoleIndex&) {
presampling = false;
}
/**
* Return the number of points to presample this
* splitting generator.
*/
unsigned long presamplingPoints() const { return thePresamplingPoints; }
/**
* Return the maximum number of trials
* to generate a splitting.
*/
unsigned long maxtry() const { return theMaxtry; }
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long freezeGrid() const { return theFreezeGrid; }
/**
* Set the number of accepted points after which the grid should
* be frozen
*/
void freezeGrid(unsigned long n) { theFreezeGrid = n; }
/**
+ * Set a detuning factor to be applied to the sampling overestimate kernel
+ */
+ void detuning(double d) { theDetuning = d; }
+
+ /**
+ * Return the detuning factor applied to the sampling overestimate kernel
+ */
+ double detuning() const { return theDetuning; }
+
+ /**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const = 0;
/**
* Clear the alphaPDF cache
*/
void clearAlphaPDFCache() const {
theAlphaSCache.clear();
thePDFCache.clear();
}
/**
* Update the variations vector at the given splitting using the indicated
* kernel and overestimate values.
*/
virtual void accept(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
/**
* Update the variations vector at the given splitting using the indicated
* kernel and overestimate values.
*/
virtual void veto(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
/**
* Return true, if this kernel is capable of
* delivering an overestimate to the kernel, and
* of inverting the integral over the overestimate
* w.r.t. the phasepsace provided by the given
* DipoleSplittingInfo object.
*/
virtual bool haveOverestimate(const DipoleSplittingInfo&) const { return false; }
/**
* Return the overestimate to this splitting kernel
* for the given dipole splitting.
*/
virtual double overestimate(const DipoleSplittingInfo&) const { return -1.; }
/**
* Invert the integral over the overestimate
* w.r.t. the phasepsace provided by the given
* DipoleSplittingInfo object to equal
* the given value.
*/
virtual double invertOverestimateIntegral(const DipoleSplittingInfo&, double) const { return -1.; }
public:
/**
* Get the factorization scale factor
*/
double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
/**
* Set the factorization scale factor
*/
void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
/**
* Get the renormalization scale factor
*/
double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
/**
* Set the renormalization scale factor
*/
void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
protected:
/**
* Return the common factor of (alphas/2pi)*(pdf ratio)
*/
double alphaPDF(const DipoleSplittingInfo&,
Energy optScale = ZERO,
double rScaleFactor = 1.0,
double fScaleFactor = 1.0) const;
/**
* Return true, if the virtuality of the splitting should be used as the
* argument of alphas rather than the pt
*/
bool virtualitySplittingScale() const { return theVirtualitySplittingScale; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The alpha_s to be used.
*/
Ptr<AlphaSBase>::ptr theAlphaS;
/**
* An optional 'colour screening' scale
* for alternative intrinsic pt generation.
*/
Energy theScreeningScale;
/**
* The splitting kinematics to be used.
*/
Ptr<DipoleSplittingKinematics>::ptr theSplittingKinematics;
/**
* An optional PDF ratio object to be used
* when evaluating this kernel.
*/
Ptr<PDFRatio>::ptr thePDFRatio;
/**
* The number of points to presample this
* splitting generator.
*/
unsigned long thePresamplingPoints;
/**
* The maximum number of trials
* to generate a splitting.
*/
unsigned long theMaxtry;
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long theFreezeGrid;
/**
+ * The detuning factor applied to the sampling overestimate kernel
+ */
+ double theDetuning;
+
+ /**
* The flavour produced, if this cannot
* be determined from the dipole.
*/
PDPtr theFlavour;
/**
* Pointer to a check histogram object
*/
Ptr<DipoleMCCheck>::ptr theMCCheck;
/**
* True, if this splitting kernel is supposed to work in a
* strict large-N limit, i.e. replacing C_F by C_A/2
*/
bool theStrictLargeN;
/**
* The factorization scale factor.
*/
double theFactorizationScaleFactor;
/**
* The renormalization scale factor.
*/
double theRenormalizationScaleFactor;
/**
* A freezing value for the renormalization scale
*/
Energy theRenormalizationScaleFreeze;
/**
* A freezing value for the factorization scale
*/
Energy theFactorizationScaleFreeze;
/**
* True, if the virtuality of the splitting should be used as the
* argument of alphas rather than the pt
*/
bool theVirtualitySplittingScale;
/**
* Cache for alphas evaluations
*/
mutable map<double,double> theAlphaSCache;
/**
* Cache for PDF evaluations
*/
mutable map<double,double> thePDFCache;
/**
* True, if we are presampling
*/
bool presampling;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class with persistent data.
*/
static AbstractClassDescription<DipoleSplittingKernel> initDipoleSplittingKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleSplittingKernel & operator=(const DipoleSplittingKernel &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleSplittingKernel. */
template <>
struct BaseClassTrait<Herwig::DipoleSplittingKernel,1> {
/** Typedef of the first base class of DipoleSplittingKernel. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleSplittingKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleSplittingKernel>
: public ClassTraitsBase<Herwig::DipoleSplittingKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleSplittingKernel"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleSplittingKernel is implemented. It may also include several, space-separated,
* libraries if the class DipoleSplittingKernel depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_DipoleSplittingKernel_H */
diff --git a/Sampling/exsample/cell.h b/Sampling/exsample/cell.h
--- a/Sampling/exsample/cell.h
+++ b/Sampling/exsample/cell.h
@@ -1,304 +1,306 @@
// -*- C++ -*-
//
// cell.h is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
//
// Copyright (C) 2008-2011 Simon Platzer -- simon.plaetzer@desy.de
//
// ExSample is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
#ifndef EXSAMPLE_cell_h_included
#define EXSAMPLE_cell_h_included
#include "utility.h"
#include "adaption_info.h"
#include "statistics.h"
namespace exsample {
/// \brief Information contained in a leaf cell
class cell_info {
public:
/// the default constructor
cell_info();
/// construct from boundaries and adaption info
cell_info(const std::vector<double>& ll,
const std::vector<double>& ur,
const adaption_info& ainfo);
/// construct from boundaries, flags for variables to be sampled,
/// and adaption info
cell_info(const std::vector<double>& ll,
const std::vector<double>& ur,
const std::vector<bool>& sampled_variables,
const adaption_info& ainfo);
public:
/// generate a flat trial point in this cell
template<class Random>
void select(Random&,
std::vector<double>&);
/// generate a flat trial point in this cell
/// only for the variables falgged as true
template<class Random>
void select(Random&,
std::vector<double>&,
const std::vector<bool>&);
/// indicate a function value for the given point
void selected(const std::vector<double>&,
double,
const adaption_info&);
/// indicate that a point has been
/// accepted in this cell
void accept() { ++accepted_; }
/// reject a previously accepted event
void reject() { --accepted_; }
public:
/// return true, if below efficiency threshold
bool bad(const adaption_info& ainfo) const {
return ((static_cast<double>(accepted_)/static_cast<double>(attempted_)) <
ainfo.efficiency_threshold);
}
/// suggest a split and indicate wether it is worth
/// to be performed
std::pair<std::size_t,double> get_split(const adaption_info&,
bool&) const;
/// explore this cell performing a flat sampling,
/// updating the given statistics object and pre-filling
/// the efficiency histogram by a trial unweighting
template<class Random, class Function, class SlaveStatistics>
void explore(Random&, const adaption_info&, Function*, statistics*,
- SlaveStatistics& opt);
+ SlaveStatistics& opt, double detuning = 1.0);
/// explore this cell in a more refined way, which
/// is however not suited for already calculating integrals
/// and stuff
template<class Random, class Function>
- void explore(Random&, const adaption_info&, Function*);
+ void explore(Random&, const adaption_info&, Function*,
+ double detuning = 1.0);
public:
/// get the current overestimate
double overestimate() const { return overestimate_; }
/// return the position of the last maximum
const std::vector<double>& last_max_position() const { return last_max_position_; }
/// set the current overestimate and maximum position
void overestimate(double v, const std::vector<double>& pos) {
overestimate_ = v;
last_max_position_ = pos;
}
/// get the volume
double volume() const { return volume_; }
/// get the lower left corner
const std::vector<double>& lower_left() const { return lower_left_; }
/// get the upper right corner
const std::vector<double>& upper_right() const { return upper_right_; }
/// get the number of attempted events
unsigned long attempted() const { return attempted_; }
/// get the number of accepted events
unsigned long accepted() const { return accepted_; }
public:
/// return the number of missing events
/// for the given parameter bin id
int parametric_missing(const bit_container<parameter_hash_bits>& id) const;
/// set the number of missing events
/// for the given parameter bin id
void parametric_missing(const bit_container<parameter_hash_bits>& id, int n);
/// increase to the number of missing events
/// for the given parameter bin id
void increase_parametric_missing(const bit_container<parameter_hash_bits>& id);
/// decrease to the number of missing events
/// for the given parameter bin id
void decrease_parametric_missing(const bit_container<parameter_hash_bits>& id);
/// return true, if the cell is compensating in
/// at least one parameter bin
bool parametric_compensating() const {
return !parametric_missing_map_.empty();
}
/// return true, if the cell contains the
/// indicated parameter point
bool contains_parameter(const std::vector<double>& point,
const std::vector<bool>& sampled) const;
public:
/// put to ostream
template<class OStream>
void put(OStream& os) const;
/// get from istream
template<class IStream>
void get(IStream& is);
private:
/// the value of the overestimate in this cell
double overestimate_;
/// the volume of this cell
double volume_;
/// the lower left corner of this cell
std::vector<double> lower_left_;
/// the upper right corner of this cell
std::vector<double> upper_right_;
/// midpoint of this cell
std::vector<double> mid_point_;
/// the position of the last encountered
/// maximum in this cell
std::vector<double> last_max_position_;
/// left-right statistics of average weight
std::vector<std::pair<double,double> > avg_weight_;
/// the number of attempts in this cell
unsigned long attempted_;
/// the number of accepted events in this cell
unsigned long accepted_;
/// an optional map of parameter bin ids
/// to the number of missing events
std::map<bit_container<parameter_hash_bits>,int> parametric_missing_map_;
};
/// \brief the general cell class
class cell {
public:
/// default constructor
cell();
/// construct from boundaries and adaption info
cell(const std::vector<double>& ll,
const std::vector<double>& ur,
const adaption_info& ainfo);
/// construct from boundaries, flags for variables to be sampled,
/// and adaption info
cell(const std::vector<double>& ll,
const std::vector<double>& ur,
const std::vector<bool>& sampled_variables,
const adaption_info& ainfo);
/// copy constructor
cell(const cell& x);
/// assignment
cell& operator=(const cell& x);
public:
/// split this cell, exploring the
/// child not containing the current overestimate
template<class Random, class Function>
std::pair<cell,cell> split(std::pair<std::size_t,double> split_d,
Random& rnd_gen,
Function* f,
const adaption_info& ainfo,
const std::vector<bool>& sampled =
- std::vector<bool>());
+ std::vector<bool>(),
+ double detuning = 1.0);
public:
/// return the split dimension
std::size_t split_dimension() const { return split_dimension_; }
/// return the split value
double split_point() const { return split_point_; }
/// return the integral
double integral() const { return integral_; }
/// access the integral
double& integral() { return integral_; }
/// set the integral
void integral(double v) { integral_ = v; }
/// access the number of missing events
int& missing_events() { return missing_events_; }
/// return the number of missing events
int missing_events() const { return missing_events_; }
/// set the number of missing events
void missing_events(int n) { missing_events_ = n; }
/// access the cell_info object
cell_info& info() { assert(cell_info_); return *cell_info_; }
/// return the cell_info object
const cell_info& info() const { assert(cell_info_); return *cell_info_; }
public:
/// put to ostream
template<class OStream>
void put(OStream& os) const;
/// get from istream
template<class IStream>
void get(IStream& is);
private:
/// the dimension along this cell
/// was split
std::size_t split_dimension_;
/// the value, where this cell was split
double split_point_;
/// the integral of the absolute value
/// of the overestimate over all the
/// children cells
double integral_;
/// the number of missing events in this cell
int missing_events_;
/// a pointer to the cell info object,
/// if this is a leaf cell
boost::scoped_ptr<cell_info> cell_info_;
};
}
#include "cell.icc"
#endif // EXSAMPLE_cell_h_included
diff --git a/Sampling/exsample/cell.icc b/Sampling/exsample/cell.icc
--- a/Sampling/exsample/cell.icc
+++ b/Sampling/exsample/cell.icc
@@ -1,487 +1,490 @@
// -*- C++ -*-
//
// cell.icc is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
//
// Copyright (C) 2008-2011 Simon Platzer -- simon.plaetzer@desy.de
//
// ExSample is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
namespace exsample {
template<class Random>
void cell_info::select (Random& rnd_gen,
std::vector<double>& p) {
std::transform(lower_left_.begin(),lower_left_.end(),
upper_right_.begin(),p.begin(),
rnd_gen);
++attempted_;
}
template<class Random>
void cell_info::select (Random& rnd_gen,
std::vector<double>& p,
const std::vector<bool>& sample) {
conditional_transform(lower_left_.begin(),lower_left_.end(),
upper_right_.begin(),sample.begin(),
p.begin(),rnd_gen);
++attempted_;
}
template<class Random, class Function, class SlaveStatistics>
void cell_info::explore(Random& rnd_gen,
const adaption_info& ainfo,
Function* function, statistics* stats,
- SlaveStatistics& opt) {
+ SlaveStatistics& opt,
+ double detuning) {
function->start_presampling();
unsigned long n_sampled = 0;
std::vector<double> ll = lower_left_;
std::vector<double> ur = upper_right_;
double val = 0.;
std::vector<double> pos (ll.size());
std::vector< std::pair<double,std::vector<double> > > vals;
unsigned long ivalnonzero = 0;
while (n_sampled < ainfo.presampling_points) {
std::transform(ll.begin(),ll.end(),
ur.begin(),pos.begin(),
rnd_gen);
- val = function->evaluate(pos);
+ val = function->evaluate(pos) * detuning;
vals.push_back( std::pair<double,std::vector<double> > (val,pos) );
if ( val != 0 ) ivalnonzero++;
++n_sampled;
}
while ( ivalnonzero > 0 ) {
double avg = 0;
double err = 0;
double maxval = 0;
std::vector<double> maxpos (ll.size());
unsigned long imax;
for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
val = std::abs(vals[ival].first);
if ( val == 0 ) continue;
avg += val;
err += sqr(val);
if ( val > maxval ) {
maxval = val;
maxpos = vals[ival].second;
imax = ival;
}
}
avg /= ivalnonzero;
err /= ivalnonzero;
err = sqrt(err-sqr(avg));
if ( maxval <= avg+sqrt(ivalnonzero/2.)*err ) {
overestimate_ = maxval;
last_max_position_ = maxpos;
break;
}
vals.erase(vals.begin()+imax);
ivalnonzero--;
}
for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
val = vals[ival].first;
stats->presampled(val);
opt.select(val);
selected(pos,std::abs(val),ainfo);
}
function->stop_presampling();
}
template<class Random, class Function>
void cell_info::explore (Random& rnd_gen,
- const adaption_info& ainfo, Function* function) {
+ const adaption_info& ainfo, Function* function,
+ double detuning) {
function->start_presampling();
unsigned long n_sampled = 0;
std::vector<double> ll = lower_left_;
std::vector<double> ur = upper_right_;
double val = 0.;
std::vector<double> pos (ll.size());
std::vector< std::pair<double,std::vector<double> > > vals;
while (n_sampled < ainfo.presampling_points) {
std::transform(ll.begin(),ll.end(),
ur.begin(),pos.begin(),
rnd_gen);
- val = function->evaluate(pos);
+ val = function->evaluate(pos) * detuning;
if ( std::abs(val) > 0 )
vals.push_back( std::pair<double,std::vector<double> > (std::abs(val),pos) );
++n_sampled;
}
while ( vals.size() > 0 ) {
double avg = 0;
double err = 0;
double maxval = 0;
std::vector<double> maxpos (ll.size());
unsigned long imax;
for ( unsigned long ival=0; ival < vals.size(); ival++ ) {
double thisval = vals[ival].first;
avg += thisval;
err += sqr(thisval);
if ( thisval > maxval ) {
maxval = thisval;
maxpos = vals[ival].second;
imax = ival;
}
}
avg /= vals.size();
err /= vals.size();
err = sqrt(err-sqr(avg));
if ( maxval <= avg+sqrt(vals.size()/2.)*err ) {
overestimate_ = maxval;
last_max_position_ = maxpos;
break;
}
vals.erase(vals.begin()+imax);
}
function->stop_presampling();
}
template<class OStream>
void cell_info::put (OStream& os) const {
os << overestimate_;
ostream_traits<OStream>::separator(os);
os << volume_;
ostream_traits<OStream>::separator(os);
os << lower_left_.size();
ostream_traits<OStream>::separator(os);
for (std::size_t k = 0; k < lower_left_.size(); ++k) {
os << lower_left_[k];
ostream_traits<OStream>::separator(os);
}
for (std::size_t k = 0; k < upper_right_.size(); ++k) {
os << upper_right_[k];
ostream_traits<OStream>::separator(os);
}
for (std::size_t k = 0; k < mid_point_.size(); ++k) {
os << mid_point_[k];
ostream_traits<OStream>::separator(os);
}
for (std::size_t k = 0; k < last_max_position_.size(); ++k) {
os << last_max_position_[k];
ostream_traits<OStream>::separator(os);
}
for (std::size_t k = 0; k < avg_weight_.size(); ++k) {
os << avg_weight_[k].first;
ostream_traits<OStream>::separator(os);
os << avg_weight_[k].second;
ostream_traits<OStream>::separator(os);
}
os << attempted_;
ostream_traits<OStream>::separator(os);
os << accepted_;
ostream_traits<OStream>::separator(os);
os << parametric_missing_map_.size();
ostream_traits<OStream>::separator(os);
for ( std::map<bit_container<parameter_hash_bits>,int>::const_iterator p =
parametric_missing_map_.begin(); p != parametric_missing_map_.end(); ++p ) {
p->first.put(os);
os << p->second;
ostream_traits<OStream>::separator(os);
}
}
template<class IStream>
void cell_info::get (IStream& is) {
std::size_t dim;
is >> overestimate_ >> volume_ >> dim;
lower_left_.resize(dim);
for (std::size_t k = 0; k < lower_left_.size(); ++k) {
is >> lower_left_[k];
}
upper_right_.resize(dim);
for (std::size_t k = 0; k < upper_right_.size(); ++k) {
is >> upper_right_[k];
}
mid_point_.resize(dim);
for (std::size_t k = 0; k < mid_point_.size(); ++k) {
is >> mid_point_[k];
}
last_max_position_.resize(dim);
for (std::size_t k = 0; k < last_max_position_.size(); ++k) {
is >> last_max_position_[k];
}
avg_weight_.resize(dim);
for (std::size_t k = 0; k < avg_weight_.size(); ++k) {
is >> avg_weight_[k].first >> avg_weight_[k].second;
}
is >> attempted_ >> accepted_ >> dim;
for ( size_t k = 0; k < dim; ++k ) {
bit_container<parameter_hash_bits> in;
in.get(is);
is >> parametric_missing_map_[in];
}
}
template<class Random, class Function>
std::pair<cell,cell >
cell::split (std::pair<std::size_t,double> split_d,
Random& rnd_gen,
Function* function,
const adaption_info& ainfo,
- const std::vector<bool>& sampled) {
+ const std::vector<bool>& sampled,
+ double detuning) {
assert(!missing_events() && !info().parametric_compensating());
split_dimension_ = split_d.first;
split_point_ = split_d.second;
std::vector<double> lower_left1 = info().lower_left();
std::vector<double> upper_right1 = info().upper_right();
std::vector<double> lower_left2 = info().lower_left();
std::vector<double> upper_right2 = info().upper_right();
upper_right1[split_dimension_] = split_point_;
lower_left2[split_dimension_] = split_point_;
std::pair<cell,cell> children;
if (sampled.empty())
children = std::pair<cell,cell>(cell(lower_left1,upper_right1,ainfo),
cell(lower_left2,upper_right2,ainfo));
else
children = std::pair<cell,cell> (cell(lower_left1,upper_right1,sampled,ainfo),
cell(lower_left2,upper_right2,sampled,ainfo));
if (info().last_max_position()[split_dimension_] <= split_point_) {
children.first.info().overestimate(info().overestimate(),info().last_max_position());
- children.second.info().explore(rnd_gen,ainfo,function);
+ children.second.info().explore(rnd_gen,ainfo,function,detuning);
} else {
children.second.info().overestimate(info().overestimate(),info().last_max_position());
- children.first.info().explore(rnd_gen,ainfo,function);
+ children.first.info().explore(rnd_gen,ainfo,function,detuning);
}
cell_info_.reset(0);
children.first.integral(children.first.info().volume() * children.first.info().overestimate());
children.second.integral(children.second.info().volume() * children.second.info().overestimate());
return children;
}
template<class OStream>
void cell::put (OStream& os) const {
os << split_dimension_;
ostream_traits<OStream>::separator(os);
os << split_point_;
ostream_traits<OStream>::separator(os);
os << integral_;
ostream_traits<OStream>::separator(os);
os << missing_events_;
ostream_traits<OStream>::separator(os);
if (cell_info_) {
os << "has_cell_info";
ostream_traits<OStream>::separator(os);
cell_info_->put(os);
} else {
os << "has_no_cell_info";
ostream_traits<OStream>::separator(os);
}
}
template<class IStream>
void cell::get (IStream& is) {
std::string info_tag;
is >> split_dimension_ >> split_point_
>> integral_ >> missing_events_
>> info_tag;
if (info_tag == "has_cell_info") {
cell_info_.reset(new cell_info());
cell_info_->get(is);
}
}
inline cell_info::cell_info()
: overestimate_(0.), volume_(0.),
lower_left_(), upper_right_(), mid_point_(),
last_max_position_(), avg_weight_(),
attempted_(0), accepted_(0) {}
inline cell_info::cell_info(const std::vector<double>& ll,
const std::vector<double>& ur,
const adaption_info& ainfo)
: overestimate_(0.), volume_(),
lower_left_(ll), upper_right_(ur), mid_point_(),
last_max_position_(),
avg_weight_(std::vector<std::pair<double,double> >
(ainfo.dimension,std::make_pair(0.,0.))),
attempted_(0), accepted_(0) {
std::vector<double> delta;
std::transform(ur.begin(),ur.end(),
ll.begin(),std::back_inserter(delta),
std::minus<double>());
volume_ =
std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
std::transform(ur.begin(),ur.end(),
ll.begin(),std::back_inserter(mid_point_),
std::plus<double>());
for (std::size_t k = 0; k < ainfo.dimension; ++k)
mid_point_[k] /= 2.;
}
inline cell_info::cell_info(const std::vector<double>& ll,
const std::vector<double>& ur,
const std::vector<bool>& sampled_variables,
const adaption_info& ainfo)
: overestimate_(0.), volume_(),
lower_left_(ll), upper_right_(ur), mid_point_(),
last_max_position_(),
avg_weight_(std::vector<std::pair<double,double> >
(ainfo.dimension,std::make_pair(0.,0.))),
attempted_(0), accepted_(0) {
std::vector<double> delta;
conditional_transform(ur.begin(),ur.end(),
ll.begin(),sampled_variables.begin(),
std::back_inserter(delta),
std::minus<double>());
volume_ =
std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
std::transform(ur.begin(),ur.end(),
ll.begin(),std::back_inserter(mid_point_),
std::plus<double>());
for (std::size_t k = 0; k < ainfo.dimension; ++k)
mid_point_[k] /= 2.;
}
inline int cell_info::parametric_missing(const bit_container<parameter_hash_bits>& id) const {
std::map<bit_container<parameter_hash_bits>,int>::const_iterator mit
= parametric_missing_map_.find(id);
if (mit == parametric_missing_map_.end())
return 0;
return mit->second;
}
inline void cell_info::parametric_missing(const bit_container<parameter_hash_bits>& id, int n) {
if (n == 0) {
std::map<bit_container<parameter_hash_bits>,int>::iterator mit
= parametric_missing_map_.find(id);
if (mit != parametric_missing_map_.end())
parametric_missing_map_.erase(mit);
return;
}
parametric_missing_map_[id] = n;
}
inline void cell_info::increase_parametric_missing(const bit_container<parameter_hash_bits>& id) {
std::map<bit_container<parameter_hash_bits>,int>::iterator mit
= parametric_missing_map_.find(id);
if (mit != parametric_missing_map_.end()) {
mit->second += 1;
if (mit->second == 0) parametric_missing_map_.erase(mit);
} else parametric_missing_map_[id] = 1;
}
inline void cell_info::decrease_parametric_missing(const bit_container<parameter_hash_bits>& id) {
std::map<bit_container<parameter_hash_bits>,int>::iterator mit
= parametric_missing_map_.find(id);
if (mit != parametric_missing_map_.end()) {
mit->second -= 1;
if (mit->second == 0) parametric_missing_map_.erase(mit);
} else assert(false);
}
inline void cell_info::selected(const std::vector<double>& p,
double weight,
const adaption_info& ainfo) {
for (std::size_t k = 0; k < p.size(); ++k) {
if (ainfo.adapt[k]) {
if (p[k] < mid_point_[k])
avg_weight_[k].first += weight;
else
avg_weight_[k].second += weight;
}
}
}
inline std::pair<std::size_t,double> cell_info::get_split (const adaption_info& ainfo,
bool& worth) const {
std::size_t split_d = 0;
double gain = 0.;
for (std::size_t k = 0; k < ainfo.dimension; ++k) {
double xgain = 0.;
double left = avg_weight_[k].first;
double right = avg_weight_[k].second;
if (left+right > 0.) {
xgain = std::abs(left-right)/(left+right);
}
if (xgain > gain) {
gain = xgain;
split_d = k;
}
}
worth = (gain >= ainfo.gain_threshold);
return std::make_pair(split_d,mid_point_[split_d]);
}
inline bool cell_info::contains_parameter (const std::vector<double>& point,
const std::vector<bool>& sampled) const {
std::vector<double>::const_iterator p = point.begin();
std::vector<double>::const_iterator l = lower_left_.begin();
std::vector<double>::const_iterator u = upper_right_.begin();
std::vector<bool>::const_iterator f = sampled.begin();
for (; p < point.end(); ++p, ++f, ++l, ++u)
if (!(*f)) {
if (((*l) > (*p)) ||
((*u) < (*p)))
return false;
}
return true;
}
inline cell::cell()
: split_dimension_(0), split_point_(0.),
integral_(0.), missing_events_(0),
cell_info_(0) {}
inline cell::cell(const std::vector<double>& ll,
const std::vector<double>& ur,
const adaption_info& ainfo)
: split_dimension_(0), split_point_(0.),
integral_(0.), missing_events_(0),
cell_info_(new cell_info(ll,ur,ainfo)) {}
inline cell::cell(const std::vector<double>& ll,
const std::vector<double>& ur,
const std::vector<bool>& sampled_variables,
const adaption_info& ainfo)
: split_dimension_(0), split_point_(0.),
integral_(0.), missing_events_(0),
cell_info_(new cell_info(ll,ur,sampled_variables,ainfo)) {}
inline cell::cell(const cell& x)
: split_dimension_(x.split_dimension_),
split_point_(x.split_point_),
integral_(x.integral_),
missing_events_(x.missing_events_),
cell_info_(0) {
if (x.cell_info_)
cell_info_.reset(new cell_info(*x.cell_info_));
}
inline cell& cell::operator=(const cell& x) {
if (this == &x)
return *this;
split_dimension_ = x.split_dimension_;
split_point_ = x.split_point_;
integral_ = x.integral_;
missing_events_ = x.missing_events_;
if (x.cell_info_)
cell_info_.reset(new cell_info(*x.cell_info_));
return *this;
}
}
diff --git a/Sampling/exsample/exponential_generator.h b/Sampling/exsample/exponential_generator.h
--- a/Sampling/exsample/exponential_generator.h
+++ b/Sampling/exsample/exponential_generator.h
@@ -1,243 +1,249 @@
// -*- C++ -*-
//
// exponential_generator.h is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
//
// Copyright (C) 2008-2011 Simon Platzer -- simon.plaetzer@desy.de
//
// ExSample is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
#ifndef EXSAMPLE_exponential_generator_h_included
#define EXSAMPLE_exponential_generator_h_included
#include "cell.h"
#include "selectors.h"
#include "statistics.h"
#include "linear_interpolator.h"
#include "binary_tree.h"
namespace exsample {
/// \brief Exception thrown, if the exponential_generator has just changed its
/// state. The attempt of generating an event should be repeated.
struct exponential_regenerate{};
/// \brief The generator for sudakov-type distributions.
template<class Function, class Random>
class exponential_generator {
public:
/// default constructor
exponential_generator()
: function_(0), check_events_(0), adaption_info_(), root_cell_(),
rnd_gen_(), did_split_(false), initialized_(false),
evolution_variable_(0), evolution_cutoff_(0.),
sample_variables_(), sample_other_variables_(),
parameter_splits_(),
last_cell_(), last_point_(), last_value_(0.),
last_parameter_bin_(), exponents_(),
last_exponent_integrand_(),
last_exponent_(), compensating_(false),
integral_accessor_(), missing_accessor_(),
parametric_selector_(), exponent_selector_(),
parametric_sampler_(), attempts_(0), accepts_(0),
- splits_(0), docompensate_(false) {}
+ splits_(0), docompensate_(false), detuning_(1.0) {}
public:
/// initialize this generator
void initialize();
/// finalize this generator
void finalize() {}
/// generate an event, returning
/// the sign of the weight or zero
/// for an event below the evolution cutoff
double generate();
/// generate an event, returning
/// the sign of the weight or zero
/// for an event below the evolution cutoff
double generate(double cutoff) {
double oldcut = evolution_cutoff_;
evolution_cutoff_ = cutoff;
double w = 0.0;
try {
w = generate();
} catch(...) {
evolution_cutoff_ = oldcut;
throw;
}
evolution_cutoff_ = oldcut;
return w;
}
/// return the last sampled phase space point
const std::vector<double>& last_point() const { return last_point_; }
/// return the last evaluated function
double last_value() const { return last_value_; }
/// indicate that the last generated point has been rejected
void reject() {
last_cell_->info().reject();
}
public:
/// return true, if this generator has been initialized
bool initialized() const { return initialized_; }
/// return true, if at least one split has been performed
bool did_split() const { return did_split_; }
/// access the function
Function& function() { return *function_; }
/// set the function
void function(Function * f) { function_ = f; }
/// access the adaption_info object
adaption_info& sampling_parameters() { return adaption_info_; }
/// indicate, if compensation should be applied
void docompensate(bool yes = true) { docompensate_ = yes; }
+ /// set the detuning parameter
+ void detuning(double val) { detuning_ = val; }
+
public:
/// put to ostream
template<class OStream>
void put(OStream& os) const;
/// get from istream
template<class IStream>
void get(IStream& is);
private:
/// check for and possibly split
/// the last selected cell
bool split();
/// get the projection of the density integrating over every
/// variable to be sampled, except the evolution variable for the
/// indicated parameter point. the k'th entry in
/// last_exponent_integrand_ is the value in the evolution
/// variable bin from evolution_splits_[k] to
/// evolution_splits_[k+1]
void get_exponent();
/// compensate
void compensate();
/// get all parameter points to build
/// all possible sub tree hashes
std::set<std::vector<double> > parameter_points();
/// get all parameter points to build
/// all possible sub tree hashes
void recursive_parameter_points(std::set<std::vector<double> >&,
std::vector<double>&,
size_t);
/// function to be sampled
Function * function_;
/// the number of events after which
/// a cell is checked for splits
unsigned long check_events_;
/// the adaption info object
adaption_info adaption_info_;
/// the root cell
binary_tree<cell> root_cell_;
/// the random number generator to be used
rnd_generator<Random> rnd_gen_;
/// wether a split has already been performed
bool did_split_;
/// wether this generator has been initialized
bool initialized_;
/// the position of the evolution variable
std::size_t evolution_variable_;
/// the cutoff on the evolution variable
double evolution_cutoff_;
/// flags of variables to be sampled
/// including the evolution variable
std::vector<bool> sample_variables_;
/// flags of variables to be sampled
/// excluding the evolution variable
std::vector<bool> sample_other_variables_;
/// the splits in any parameter done so far
/// (including the evolution variable)
std::map<std::size_t,std::vector<double> > parameter_splits_;
/// the last selected cell
binary_tree<cell>::iterator last_cell_;
/// the last sampled phasespace point
std::vector<double> last_point_;
/// the last function value
double last_value_;
/// the last parameter bin id
bit_container<parameter_hash_bits> last_parameter_bin_;
/// map parameter bin ids to exponent interpolations
std::map<bit_container<parameter_hash_bits>,linear_interpolator > exponents_;
/// the last exponent integrand
std::vector<double> last_exponent_integrand_;
/// the last exponent
std::map<bit_container<parameter_hash_bits>,linear_interpolator >::iterator last_exponent_;
/// wether or not we are compensating
bool compensating_;
/// the integral accessor to be used
integral_accessor integral_accessor_;
/// the missing events accessor to be used
parametric_missing_accessor missing_accessor_;
/// the parametric selector to be used
parametric_selector parametric_selector_;
/// the parametric selector to be used for parameter bins
parametric_selector exponent_selector_;
/// the parametric sampler to be used
parametric_sampling_selector<rnd_generator<Random> > parametric_sampler_;
/// the number of trials in the veto loo so far
unsigned long attempts_;
/// the number of accepted events so far
unsigned long accepts_;
/// number of splits done
unsigned long splits_;
/// true, if compensation should be applied
bool docompensate_;
+ /// a detuning factor to be applied to the overestimate
+ double detuning_;
+
};
}
#include "exponential_generator.icc"
#endif // EXSAMPLE_exponential_generator_h_included
diff --git a/Sampling/exsample/exponential_generator.icc b/Sampling/exsample/exponential_generator.icc
--- a/Sampling/exsample/exponential_generator.icc
+++ b/Sampling/exsample/exponential_generator.icc
@@ -1,385 +1,386 @@
// -*- C++ -*-
//
// exponential_generator.icc is part of ExSample -- A Library for Sampling Sudakov-Type Distributions
//
// Copyright (C) 2008-2011 Simon Platzer -- simon.plaetzer@desy.de
//
// ExSample is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
namespace exsample {
template<class Function, class Random>
void exponential_generator<Function,Random>::initialize() {
adaption_info_.dimension = function_->dimension();
adaption_info_.lower_left = function_->support().first;
adaption_info_.upper_right = function_->support().second;
if (adaption_info_.adapt.empty())
adaption_info_.adapt = std::vector<bool>(adaption_info_.dimension,true);
evolution_variable_ = function_->evolution_variable();
evolution_cutoff_ = function_->evolution_cutoff();
sample_variables_ = function_->variable_flags();
sample_other_variables_ = sample_variables_;
sample_other_variables_[evolution_variable_] = false;
last_point_.resize(adaption_info_.dimension);
parametric_selector_ = parametric_selector(&last_point_,sample_other_variables_);
exponent_selector_ = parametric_selector(&last_point_,sample_variables_);
missing_accessor_ = parametric_missing_accessor(&last_parameter_bin_);
parametric_sampler_ = parametric_sampling_selector<rnd_generator<Random> >
(&last_point_,&last_parameter_bin_,sample_other_variables_,rnd_gen_);
if (initialized_) return;
splits_ = 0;
for ( std::size_t k = 0; k < adaption_info_.dimension; ++k ) {
if ( sample_other_variables_[k] )
continue;
parameter_splits_[k].push_back(adaption_info_.lower_left[k]);
parameter_splits_[k].push_back(adaption_info_.upper_right[k]);
}
root_cell_ =
binary_tree<cell>(cell(adaption_info_.lower_left,
adaption_info_.upper_right,
sample_other_variables_,
adaption_info_));
- root_cell_.value().info().explore(rnd_gen_,adaption_info_,function_);
+ root_cell_.value().info().explore(rnd_gen_,adaption_info_,function_,detuning_);
root_cell_.value().integral(root_cell_.value().info().volume() * root_cell_.value().info().overestimate());
last_exponent_integrand_.resize(1);
check_events_ = adaption_info_.presampling_points;
initialized_ = true;
}
template<class Function, class Random>
bool exponential_generator<Function,Random>::split () {
if (adaption_info_.freeze_grid <= accepts_)
return false;
if (compensating_)
return false;
if (!(*last_cell_).info().bad(adaption_info_)) return false;
bool dosplit = false;
std::pair<std::size_t,double> sp =
(*last_cell_).info().get_split(adaption_info_,dosplit);
if (!dosplit) return false;
if (!adaption_info_.adapt[sp.first]) return false;
if (splits_ == parameter_hash_bits/2)
return false;
++splits_;
- last_cell_.node().split((*last_cell_).split(sp,rnd_gen_,function_,adaption_info_,sample_other_variables_));
+ last_cell_.node().split((*last_cell_).split(sp,rnd_gen_,function_,adaption_info_,
+ sample_other_variables_,detuning_));
if ( !sample_other_variables_[sp.first] ) {
if ( std::find(parameter_splits_[sp.first].begin(),parameter_splits_[sp.first].end(),sp.second)
== parameter_splits_[sp.first].end() ) {
parameter_splits_[sp.first].push_back(sp.second);
std::sort(parameter_splits_[sp.first].begin(),parameter_splits_[sp.first].end());
if ( sp.first == evolution_variable_ ) {
last_exponent_integrand_.push_back(0.);
}
}
}
did_split_ = true;
last_point_ = function_->parameter_point();
root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
exponents_.clear();
get_exponent();
return true;
}
template<class Function, class Random>
void exponential_generator<Function,Random>::get_exponent () {
last_parameter_bin_.reset();
root_cell_.subtree_hash (exponent_selector_,last_parameter_bin_);
last_exponent_ = exponents_.find(last_parameter_bin_);
if (last_exponent_ != exponents_.end())
return;
exponents_[last_parameter_bin_] = linear_interpolator();
last_exponent_ = exponents_.find(last_parameter_bin_);
double old_evo = last_point_[evolution_variable_];
std::vector<double>::iterator exp_it = last_exponent_integrand_.begin();
for (std::vector<double>::iterator esp = parameter_splits_[evolution_variable_].begin();
esp < boost::prior(parameter_splits_[evolution_variable_].end()); ++esp, ++exp_it) {
last_point_[evolution_variable_] = (*esp + *boost::next(esp))/2.;
*exp_it = root_cell_.accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
}
exp_it = boost::prior(last_exponent_integrand_.end());
double total = 0.;
for (std::vector<double>::iterator esp = boost::prior(parameter_splits_[evolution_variable_].end());
esp > parameter_splits_[evolution_variable_].begin(); --esp, --exp_it) {
last_exponent_->second.set_interpolation(*esp,total);
total += (*exp_it) * ((*esp) - (*boost::prior(esp)));
}
last_exponent_->second.set_interpolation(parameter_splits_[evolution_variable_].front(),total);
last_point_[evolution_variable_] = old_evo;
}
template<class Function, class Random>
std::set<std::vector<double> >
exponential_generator<Function,Random>::parameter_points() {
std::set<std::vector<double> > res;
std::vector<double> pt(adaption_info_.dimension,0.);
recursive_parameter_points(res,pt,0);
return res;
}
template<class Function, class Random>
void exponential_generator<Function,Random>::
recursive_parameter_points(std::set<std::vector<double> >& res,
std::vector<double>& pt,
size_t current) {
if ( current == adaption_info_.dimension ) {
res.insert(pt);
return;
}
if ( sample_variables_[current] ) {
recursive_parameter_points(res,pt,current+1);
return;
}
for ( std::vector<double>::const_iterator sp =
parameter_splits_[current].begin();
sp != boost::prior(parameter_splits_[current].end()); ++sp ) {
pt[current] = (*sp + *boost::next(sp))/2.;
recursive_parameter_points(res,pt,current+1);
}
}
template<class Function, class Random>
void exponential_generator<Function,Random>::compensate() {
if (!did_split_ || !docompensate_) {
assert(did_split_ || last_cell_ == root_cell_.begin());
exponents_.clear();
last_cell_->info().overestimate(last_value_,last_point_);
last_cell_->integral(last_cell_->info().volume() * last_cell_->info().overestimate());
last_point_ = function_->parameter_point();
get_exponent();
return;
}
std::vector<double> themaxpoint = last_point_;
std::set<std::vector<double> > id_points
= parameter_points();
for ( std::set<std::vector<double> >::const_iterator id =
id_points.begin(); id != id_points.end(); ++id ) {
last_point_ = *id;
get_exponent();
}
std::map<bit_container<parameter_hash_bits>,linear_interpolator >
old_exponents = exponents_;
double old_oe = last_cell_->info().overestimate();
last_cell_->info().overestimate(last_value_,themaxpoint);
last_cell_->integral(last_cell_->info().volume() * last_cell_->info().overestimate());
exponents_.clear();
for ( std::set<std::vector<double> >::const_iterator id =
id_points.begin(); id != id_points.end(); ++id ) {
last_point_ = *id;
get_exponent();
std::map<bit_container<parameter_hash_bits>,linear_interpolator >::iterator
old_exp = old_exponents.find(last_parameter_bin_);
std::map<bit_container<parameter_hash_bits>,linear_interpolator >::iterator
new_exp = exponents_.find(last_parameter_bin_);
assert(old_exp != old_exponents.end() && new_exp != exponents_.end());
double old_norm = 1. - std::exp(-(old_exp->second)(adaption_info_.lower_left[evolution_variable_]));
double new_norm = 1. - std::exp(-(new_exp->second)(adaption_info_.lower_left[evolution_variable_]));
for (binary_tree<cell>::iterator it = root_cell_.begin();
it != root_cell_.end(); ++it) {
if ( !it->info().contains_parameter(last_point_,sample_variables_) )
continue;
double old_int = 0.;
double new_int = 0.;
for ( std::vector<double>::const_iterator sp = parameter_splits_[evolution_variable_].begin();
sp != boost::prior(parameter_splits_[evolution_variable_].end()); ++sp ) {
if ( *sp >= it->info().lower_left()[evolution_variable_] &&
*sp < it->info().upper_right()[evolution_variable_] ) {
double xl = *sp;
double xxl = *boost::next(sp);
double old_al =
(old_exp->second.interpolation()[xxl] - old_exp->second.interpolation()[xl]) /
(xxl-xl);
double old_bl =
(xxl * old_exp->second.interpolation()[xl] -
xl * old_exp->second.interpolation()[xxl]) /
(xxl-xl);
double new_al =
(new_exp->second.interpolation()[xxl] - new_exp->second.interpolation()[xl]) /
(xxl-xl);
double new_bl =
(xxl * new_exp->second.interpolation()[xl] -
xl * new_exp->second.interpolation()[xxl]) /
(xxl-xl);
if ( std::abs(old_al) > std::numeric_limits<double>::epsilon() ) {
old_int += (exp(-(old_al*xl+old_bl)) - exp(-(old_al*xxl+old_bl)))/old_al;
} else {
old_int += (xxl-xl)*exp(-old_bl);
}
if ( std::abs(new_al) > std::numeric_limits<double>::epsilon() ) {
new_int += (exp(-(new_al*xl+new_bl)) - exp(-(new_al*xxl+new_bl)))/new_al;
} else {
new_int += (xxl-xl)*exp(-new_bl);
}
}
}
double scaling;
if (it != last_cell_) {
if (old_int > std::numeric_limits<double>::epsilon() &&
new_int > std::numeric_limits<double>::epsilon())
scaling = ((old_norm * new_int) /
(new_norm * old_int)) - 1.;
else
scaling = 0.;
} else {
if (old_int > std::numeric_limits<double>::epsilon() &&
new_int > std::numeric_limits<double>::epsilon())
scaling = ((last_value_ * old_norm * new_int) /
(old_oe * new_norm * old_int)) - 1.;
else
scaling = 0.;
}
it->info().parametric_missing(last_parameter_bin_,
it->info().parametric_missing(last_parameter_bin_) +
static_cast<int>(round(scaling * it->info().attempted())));
if (it->info().parametric_missing(last_parameter_bin_) != 0) {
compensating_ = true;
}
}
}
last_point_ = function_->parameter_point();
}
template<class Function, class Random>
double exponential_generator<Function,Random>::generate () {
if (compensating_) {
compensating_ = false;
for (binary_tree<cell>::iterator it = root_cell_.begin();
it != root_cell_.end(); ++it)
if (it->info().parametric_compensating()) {
compensating_ = true;
break;
}
parametric_sampler_.compensate(compensating_);
}
last_point_ = function_->parameter_point();
if (last_point_[evolution_variable_] < evolution_cutoff_) {
return 0.;
}
unsigned long n_hit_miss = 0;
unsigned long n_select = 0;
double minus_log_r;
root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
get_exponent();
while (true) {
n_select = 0;
minus_log_r = -std::log(rnd_gen_()) + last_exponent_->second(last_point_[evolution_variable_]);
if (!last_exponent_->second.invertible(minus_log_r)) {
return 0.;
}
try {
last_point_[evolution_variable_] = last_exponent_->second.unique_inverse(minus_log_r);
} catch (constant_interpolation& c) {
last_point_[evolution_variable_] = rnd_gen_(c.range.first,c.range.second);
}
assert(!std::isnan(last_point_[evolution_variable_]) &&
!std::isinf(last_point_[evolution_variable_]));
if (last_point_[evolution_variable_] < evolution_cutoff_) {
return 0.;
}
++attempts_;
if (compensating_) {
root_cell_.tree_accumulate(missing_accessor_,std::plus<int>());
}
if (parameter_splits_[evolution_variable_].size() > 2)
root_cell_.tree_accumulate(parametric_selector_,integral_accessor_,std::plus<double>());
if (did_split_)
while ((last_cell_ = root_cell_.select(parametric_sampler_)) == root_cell_.end()) {
root_cell_.tree_accumulate(missing_accessor_,std::plus<int>());
if(++n_select > adaption_info_.maxtry)
throw selection_maxtry();
}
else
last_cell_ = root_cell_.begin();
last_cell_->info().select(rnd_gen_,last_point_,sample_other_variables_);
last_value_ = function_->evaluate(last_point_);
assert(last_value_ >= 0.);
last_cell_->info().selected(last_point_,last_value_,adaption_info_);
if (last_value_ > last_cell_->info().overestimate()) {
if ( std::abs(last_value_)/last_cell_->info().overestimate() > 2. ) {
last_value_ =
last_cell_->info().overestimate()*
(1.+exp(2.*(2.-std::abs(last_value_)/last_cell_->info().overestimate())));
}
compensate();
throw exponential_regenerate();
}
if (last_cell_->info().attempted() % check_events_ == 0) {
if (split()) {
throw exponential_regenerate();
}
}
if (last_value_/last_cell_->info().overestimate() > rnd_gen_()) {
function_->accept(last_point_,last_value_,last_cell_->info().overestimate());
break;
}
if ( last_value_ != 0.0 ) {
function_->veto(last_point_,last_value_,last_cell_->info().overestimate());
}
if(++n_hit_miss > adaption_info_.maxtry)
throw hit_and_miss_maxtry();
}
if (last_value_ == 0.)
return 0.;
++accepts_;
++check_events_;
last_cell_->info().accept();
return 1.;
}
template<class Function, class Random>
template<class OStream>
void exponential_generator<Function,Random>::put (OStream& os) const {
os << check_events_; ostream_traits<OStream>::separator(os);
adaption_info_.put(os);
root_cell_.put(os);
os << did_split_; ostream_traits<OStream>::separator(os);
os << initialized_; ostream_traits<OStream>::separator(os);
os << evolution_variable_; ostream_traits<OStream>::separator(os);
os << evolution_cutoff_; ostream_traits<OStream>::separator(os);
os << sample_variables_; ostream_traits<OStream>::separator(os);
os << sample_other_variables_; ostream_traits<OStream>::separator(os);
os << parameter_splits_; ostream_traits<OStream>::separator(os);
// last_cell_ is selected new so we ignore it here
os << last_point_; ostream_traits<OStream>::separator(os);
os << last_value_; ostream_traits<OStream>::separator(os);
last_parameter_bin_.put(os);
os << exponents_.size(); ostream_traits<OStream>::separator(os);
for ( std::map<bit_container<parameter_hash_bits>,linear_interpolator >::const_iterator
ex = exponents_.begin(); ex != exponents_.end() ; ++ex ) {
ex->first.put(os);
ex->second.put(os);
}
os << last_exponent_integrand_; ostream_traits<OStream>::separator(os);
os << compensating_; ostream_traits<OStream>::separator(os);
os << attempts_; ostream_traits<OStream>::separator(os);
os << accepts_; ostream_traits<OStream>::separator(os);
os << splits_; ostream_traits<OStream>::separator(os);
os << docompensate_; ostream_traits<OStream>::separator(os);
}
template<class Function, class Random>
template<class IStream>
void exponential_generator<Function,Random>::get (IStream& is) {
is >> check_events_;
adaption_info_.get(is);
root_cell_.get(is);
is >> did_split_ >> initialized_ >> evolution_variable_
>> evolution_cutoff_ >> sample_variables_ >> sample_other_variables_
>> parameter_splits_;
// last_cell_ is selected new so we ignore it here
is >> last_point_ >> last_value_;
last_parameter_bin_.get(is);
size_t dim; is >> dim;
for ( size_t k = 0; k < dim ; ++k ) {
bit_container<parameter_hash_bits> key;
key.get(is);
exponents_[key].get(is);
}
is >> last_exponent_integrand_;
last_exponent_ = exponents_.find(last_parameter_bin_);
is >> compensating_ >> attempts_ >> accepts_ >> splits_ >> docompensate_;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 2:06 PM (11 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023063
Default Alt Text
(106 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment