MINT2
Public Member Functions | Private Member Functions | Private Attributes | List of all members
HyperBinningMakerPhaseBinning Class Reference

#include <HyperBinningMakerPhaseBinning.h>

Inheritance diagram for HyperBinningMakerPhaseBinning:
HyperBinningMaker

Public Member Functions

 HyperBinningMakerPhaseBinning (const HyperCuboid &binningRange, HyperFunction *func)
 
virtual void makeBinning ()
 
void setNumBinPairs (int binpairs)
 
void setBinEdges (std::vector< double > binEdges)
 
virtual int gradientSplitAll ()
 
 ~HyperBinningMakerPhaseBinning ()
 
- Public Member Functions inherited from HyperBinningMaker
 HyperBinningMaker (const HyperCuboid &binningRange, const HyperPointSet &data)
 
 HyperBinningMaker (const HyperBinning &binning, const HyperPointSet &data)
 
void setBinningDimensions (std::vector< int > dims)
 
void addShadowHyperPointSet (const HyperPointSet &data)
 
void setSeed (int seed)
 
void useSnapToGrid (bool val)
 
void setGridMultiplier (HyperPoint &multipliers)
 
void setGridMultiplier (double multiplier)
 
void useEventWeights (bool val=true)
 
void setMinimumBinContent (double val)
 
void setShadowMinimumBinContent (double val)
 
void setMinimumEdgeLength (double val)
 
void setMinimumEdgeLength (HyperPoint val)
 
void setHyperFunction (HyperFunction *fnc)
 Set the HyperFunction - only used by some binning Algs. More...
 
void drawAfterEachIteration (TString path)
 
void updateFromExistingHyperBinning (const HyperBinning &binning)
 
void setNames (HyperName names)
 
int & getGlobalVolumeStatus (int volumeNumber)
 
int & getDimensionSpecificVolumeStatus (int volumeNumber, int dimension)
 
const int & getGlobalVolumeStatus (int volumeNumber) const
 
const int & getDimensionSpecificVolumeStatus (int volumeNumber, int dimension) const
 
int getNumContinueBins (int dimension=-1) const
 
int getNumBins () const
 
int getNumHyperVolumes () const
 
int split (int volumeNumber, int dimension, double splitPoint)
 
HyperCuboid splitBelowPoint (int dim, double splitPoint, const HyperCuboid &original, bool noSnapToGrid=false) const
 
HyperCuboid splitAbovePoint (int dim, double splitPoint, const HyperCuboid &original, bool noSnapToGrid=false) const
 
double getSumOfWeights (const HyperPointSet &hyperPointSet) const
 
double getWeight (const HyperPoint &hyperPoint) const
 
bool isValidBinningDimension (int dimension)
 
virtual bool passFunctionCriteria (HyperCuboid &cuboid1, HyperCuboid &cuboid2)
 
HyperPointSet filterHyperPointSet (const HyperPointSet &hyperPointSet, const HyperCuboid &hyperCuboid, bool print=false) const
 
void addBin (const HyperCuboid &hyperCuboid, const HyperPointSet &hyperPointSet, const HyperPointSet &shadowHyperPointSet, int status)
 
void setDimSpecStatusFromMinBinWidths (int volumeNumber)
 
void updateGlobalStatusFromDimSpecific (int volumeNumber)
 
bool snapToGrid (const HyperCuboid &cuboid, int dimension, double &splitCoord) const
 
virtual void startedAlgorithm ()
 
virtual void startedIteration ()
 
void drawCurrentState (TString path) const
 
virtual void finishedIteration ()
 
virtual void finishedAlgorithm ()
 
HyperBinningMemRes getHyperVolumeBinning () const
 
HyperHistogramgetHyperBinningHistogram () const
 
HyperHistogramgetShadowHyperBinningHistogram () const
 
HyperHistogramgetRatioHyperBinningHistogram () const
 
virtual ~HyperBinningMaker ()
 destructor More...
 
double countEventsBelowSplitPoint (int binNumber, int dimension, double splitPoint) const
 
double countEventsInHyperCuboid (const HyperPointSet &hyperPointSet, const HyperCuboid &hyperCuboid) const
 
double countShadowEventsBelowSplitPoint (int binNumber, int dimension, double splitPoint) const
 
double findSmartSplitPoint (int binNumber, int dimension, double dataFraction) const
 
int smartSplit (int binNumber, int dimension, double dataFraction)
 
int smartSplitAll (int dimension, double dataFraction)
 
int smartSplitAllRandomise (double dataFraction=0.5)
 
int smartMultiSplit (int binNumber, int dimension, int parts)
 
int smartMultiSplit (int binNumber, int dimension)
 
int smartMultiSplitAll (int dimension)
 
double findSmartSplitPointInt (int binNumber, int dimension, double dataFraction) const
 
int smartSplitInt (int binNumber, int dimension, double dataFraction)
 
int smartSplitAllInt (int dimension, double dataFraction)
 
int splitAll (int dimension, double splitPoint)
 
int splitAllRandomise (double splitPoint=0.5)
 
int likelihoodSplit (int binNumber)
 
int likelihoodSplitAll ()
 
int smartLikelihoodSplit (int binNumber)
 
int smartLikelihoodSplitAll ()
 
void getSplitToMinNeg2LLH (double &split, double &sig, int binNumber, int dimension, bool useConstraints=true)
 
void getDimWithLargestSplitSignificance (int &dim, double &split, int binNumber, bool useConstraints=true)
 
TH1D * scanSig (int binNumber, int dimension, int nbins, bool useConstraints=true)
 
double neg2LLH (int binNumber, int dimension, double splitPoint, bool useConstraints=true)
 
double nullNeg2LLH (int binNumber)
 

Private Member Functions

int splitByCoord (int volumeNumber, int dimension, HyperPoint &coord)
 
int getBinNumFromFunc (HyperPoint &point)
 
int getBinNumFromFuncVal (double phase)
 
double getLowBinBoundary (double phase)
 
double getHighBinBoundary (double phase)
 
double closestBinBoundary (double val)
 
HyperPoint getGrad (HyperPoint &point)
 
HyperPoint getGradPos (HyperPoint &point, double funcValAtPoint)
 
double getSecondDerivative (HyperPoint &point, HyperPoint &vector, double funcValAtPoint, double &deriv)
 
int splitDimFromGrad (int volumeNumber, HyperPoint gradient)
 
virtual int gradientSplit (int binNumber, int &dimension)
 
int systematicSplit (int volumeNumber, int dimension, double valAtCenter, HyperPoint gradient)
 
HyperPointSet getSplitCorners (int volumeNumber)
 
HyperPointSet getSplitFaces (int volumeNumber)
 
HyperPointSet getSplitEdges (int volumeNumber)
 
HyperPoint orderAndTestSplitPoints (HyperPointSet &points, HyperPoint &point, double valAtPoint, HyperPoint gradient)
 
int randomWalkSplit (int volumeNumber, int dimension)
 
void walkOrthogonal (HyperPoint &point, HyperCuboid &walkLimits)
 
void walk (HyperPoint &point, HyperCuboid &walkLimits)
 

Private Attributes

int _numBinPairs
 
CyclicPhaseBins _binEdges
 
int _maximumRandWalks
 
int _numWalkers
 
double _walkSizeFrac
 
int _numberOfSystematicSplits
 
int _numberOfGradientSplits
 

Additional Inherited Members

- Static Public Member Functions inherited from HyperBinningMaker
static void setOutputLevel (bool val)
 
- Protected Attributes inherited from HyperBinningMaker
std::vector< HyperCuboid_hyperCuboids
 
std::vector< std::vector< int > > _linkedBins
 
std::vector< HyperPointSet_hyperPointSets
 
std::vector< HyperPointSet_shadowHyperPointSets
 
std::vector< int > _status
 
std::vector< std::vector< int > > _dimSpecificStatus
 
std::vector< int > _binningDimensions
 
bool _shadowAdded
 
bool _useEventWeights
 
double _minimumBinContent
 
double _shadowMinimumBinContent
 
HyperPoint _minimumEdgeLength
 
TRandom * _random
 
bool _drawAlgorithm
 
TString _drawAlgorithmDir
 
int _iterationNum
 
HyperName _names
 
HyperFunction_func
 
bool _snapToGrid
 
HyperPoint _gridMultiplier
 
- Static Protected Attributes inherited from HyperBinningMaker
static bool s_printBinning = true
 

Detailed Description

HyperPlot, Author: Sam Harnew, sam.h.nosp@m.arne.nosp@m.w@gma.nosp@m.il.c.nosp@m.om , Date: Dec 2015

This algorithm takes a HyperFunction which describes some kind of phase motion i.e. map from R^n -> [-pi, pi]. In the final HyperVolumeBinning, each HyperVolume gets assigned a bin number depending on the phase at that HyperVolume center. The range [ -pi, pi ] is split uniformly into a given number of bin pairs (so total bins = bin pairs x 2 ). The numbering of bins is like so...

[ -pi, pi ] -> [ -_numBinPairs, ..., -1, +1, ... , +_numBinPairs ]

The algorithm tries to split HyperVolumes such that the bin number does not change within the HyperVolumes limits.

Definition at line 38 of file HyperBinningMakerPhaseBinning.h.

Constructor & Destructor Documentation

◆ HyperBinningMakerPhaseBinning()

HyperBinningMakerPhaseBinning::HyperBinningMakerPhaseBinning ( const HyperCuboid binningRange,
HyperFunction func 
)

Constructor that initiates the base class HyperBinningMaker

Definition at line 9 of file HyperBinningMakerPhaseBinning.cpp.

9  :
10  HyperBinningMaker(binningRange, HyperPointSet( binningRange.getDimension() )),
11  _numBinPairs (0),
13  _numWalkers (5),
14  _walkSizeFrac (0.12),
17 {
18  setNumBinPairs(3);
19  setHyperFunction(func);
20  WELCOME_LOG << "Good day from the HyperBinningMakerPhaseBinning() Constructor"<<std::endl;
21 }
const int & getDimension() const
Definition: HyperCuboid.h:45
void setHyperFunction(HyperFunction *fnc)
Set the HyperFunction - only used by some binning Algs.
#define WELCOME_LOG

◆ ~HyperBinningMakerPhaseBinning()

HyperBinningMakerPhaseBinning::~HyperBinningMakerPhaseBinning ( )

Destructor

Definition at line 1021 of file HyperBinningMakerPhaseBinning.cpp.

1021  {
1022 
1023  INFO_LOG << "Number of gradient split attempts: " << _numberOfGradientSplits << std::endl;
1024  INFO_LOG << "Number of systematic split attempts: " << _numberOfSystematicSplits << std::endl;
1025 
1026 
1027  GOODBYE_LOG << "Goodbye from the HyperBinningMakerPhaseBinning() Constructor" <<std::endl;
1028 }
#define INFO_LOG
#define GOODBYE_LOG

Member Function Documentation

◆ closestBinBoundary()

double HyperBinningMakerPhaseBinning::closestBinBoundary ( double  val)
private

For a given phase, determine the closest bin boundary (as a phase)

Definition at line 183 of file HyperBinningMakerPhaseBinning.cpp.

183  {
184 
185  double low = getLowBinBoundary (val);
186  double high = getHighBinBoundary(val);
187 
188  double distLow = fabs(val - low );
189  double distHigh = fabs(val - high);
190 
191  if (distLow < distHigh) return low;
192 
193  return high;
194 
195 }

◆ getBinNumFromFunc()

int HyperBinningMakerPhaseBinning::getBinNumFromFunc ( HyperPoint point)
private

For a given HyperPoint, get the bin number

Definition at line 197 of file HyperBinningMakerPhaseBinning.cpp.

197  {
198 
199  return getBinNumFromFuncVal(_func->getVal(point));
200 
201 }
HyperFunction * _func
virtual double getVal(const HyperPoint &point) const =0

◆ getBinNumFromFuncVal()

int HyperBinningMakerPhaseBinning::getBinNumFromFuncVal ( double  phase)
private

For a given phase, get the bin number

Definition at line 163 of file HyperBinningMakerPhaseBinning.cpp.

163  {
164 
165  if (phase < -10.0) return -1;
166 
167  return _binEdges.getBinNumber(phase);
168 
169 }
int getBinNumber(double phase) const

◆ getGrad()

HyperPoint HyperBinningMakerPhaseBinning::getGrad ( HyperPoint point)
private

Evaluate the gradient at a given point. Step length is the minimium edge length. Function is evaluated at (x+h and x-h)

Definition at line 203 of file HyperBinningMakerPhaseBinning.cpp.

203  {
204 
205  int nBinningDims = _binningDimensions.size();
206  int nDims = _hyperCuboids.at(0).getDimension();
207 
208  HyperPoint grad(nDims, 0.0);
209 
210  for (int i = 0; i < nBinningDims; i++){
211  int dim = _binningDimensions.at(i);
212  double stepsize = _minimumEdgeLength.at(dim)*0.5;
213 
214  HyperPoint low (point);
215  HyperPoint high(point);
216  low .at(i) -= stepsize;
217  high.at(i) += stepsize;
218 
219  double valLow = _func->getVal(low );
220  double valHigh = _func->getVal(high);
221 
222  std::complex<double> compLow (cos(valLow ), sin(valLow ));
223  std::complex<double> compHigh(cos(valHigh), sin(valHigh));
224 
225  grad.at(i) = arg( compHigh*conj(compLow) )/(2.0*stepsize);
226  }
227  return grad;
228 }
HyperPoint _minimumEdgeLength
HyperFunction * _func
virtual double getVal(const HyperPoint &point) const =0
const double & at(int i) const
Definition: HyperPoint.cpp:433
std::vector< HyperCuboid > _hyperCuboids
std::vector< int > _binningDimensions

◆ getGradPos()

HyperPoint HyperBinningMakerPhaseBinning::getGradPos ( HyperPoint point,
double  funcValAtPoint 
)
private

Evaluate the gradient at a given point. Step length is the minimium edge length. Function is evaluated at (x+h) only

Definition at line 230 of file HyperBinningMakerPhaseBinning.cpp.

230  {
231 
232  int nBinningDims = _binningDimensions.size();
233  int nDims = _hyperCuboids.at(0).getDimension();
234 
235  HyperPoint grad(nDims, 0.0);
236 
237  for (int i = 0; i < nBinningDims; i++){
238  int dim = _binningDimensions.at(i);
239  double stepsize = _minimumEdgeLength.at(dim)*0.5;
240 
241  HyperPoint high(point);
242  high.at(i) += stepsize;
243 
244  double valHigh = _func->getVal(high);
245 
246  std::complex<double> compVal (cos(funcValAtPoint ), sin(funcValAtPoint ));
247  std::complex<double> compHigh(cos(valHigh), sin(valHigh));
248 
249  grad.at(i) = arg( compHigh*conj(compVal) )/(stepsize);
250  }
251 
252  return grad;
253 }
HyperPoint _minimumEdgeLength
HyperFunction * _func
virtual double getVal(const HyperPoint &point) const =0
const double & at(int i) const
Definition: HyperPoint.cpp:433
std::vector< HyperCuboid > _hyperCuboids
std::vector< int > _binningDimensions

◆ getHighBinBoundary()

double HyperBinningMakerPhaseBinning::getHighBinBoundary ( double  phase)
private

For a given bin, get the upper phase boundary

Definition at line 177 of file HyperBinningMakerPhaseBinning.cpp.

177  {
178 
179  return _binEdges.getHighBinBoundary(phase);
180 
181 }
double getHighBinBoundary(int bin) const

◆ getLowBinBoundary()

double HyperBinningMakerPhaseBinning::getLowBinBoundary ( double  phase)
private

For a given bin, get the lower phase boundary

Definition at line 171 of file HyperBinningMakerPhaseBinning.cpp.

171  {
172 
173  return _binEdges.getLowBinBoundary(phase);
174 
175 }
double getLowBinBoundary(int bin) const

◆ getSecondDerivative()

double HyperBinningMakerPhaseBinning::getSecondDerivative ( HyperPoint point,
HyperPoint vector,
double  funcValAtPoint,
double &  deriv 
)
private

Evaluate the second and first derivative in a given direction at a given point

Definition at line 255 of file HyperBinningMakerPhaseBinning.cpp.

255  {
256 
257  bool centeral = true;
258 
259  HyperPoint normVector = vector/vector.norm();
260 
261  double stepLength = fabs(_minimumEdgeLength.dotProduct(normVector)*0.5);
262  //double stepLength = vector.norm()*0.25;
263 
264  if (centeral){
265  HyperPoint low = point - normVector*stepLength;
266  HyperPoint high = point + normVector*stepLength;
267 
268  double val = funcValAtPoint;
269  double lowVal = _func->getVal(low );
270  double highVal = _func->getVal(high );
271 
272  double h = (high - low).norm()*0.5;
273 
274  firstDeriv = (highVal - lowVal)/(2.0*h);
275  double secondDeriv = (lowVal + highVal - 2.0*val)/(h*h);
276  return secondDeriv;
277  }
278 
279  HyperPoint high1 = point + normVector*stepLength;
280  HyperPoint high2 = point + normVector*stepLength*2.0;
281 
282  double val = _func->getVal(point );
283  double high1Val = _func->getVal(high1 );
284  double high2Val = _func->getVal(high2 );
285 
286  double h = (high1 - high2).norm();
287 
288  double secondDeriv = (val + high2Val - 2.0*high1Val)/(h*h);
289  return secondDeriv;
290 
291 
292 }
HyperPoint _minimumEdgeLength
double dotProduct(const HyperPoint &other) const
Definition: HyperPoint.cpp:147
HyperFunction * _func
virtual double getVal(const HyperPoint &point) const =0
double norm() const
Definition: HyperPoint.cpp:131

◆ getSplitCorners()

HyperPointSet HyperBinningMakerPhaseBinning::getSplitCorners ( int  volumeNumber)
private

Get a list of all the corners of the volume number given

Definition at line 328 of file HyperBinningMakerPhaseBinning.cpp.

328  {
329 
330  //Get the cuboid we are trying to split
331  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
332 
333  //Figure out what dimesions we need
334  int dimensions = _hyperCuboids.at(0).getDimension();
335 
336  std::vector<int> binningDimensions;
337  for (int i = 0; i < dimensions; i++){
338  if ( chosenHyperCuboid.getWidth(i) < 2.0*_minimumEdgeLength.at(i) ) continue;
339  if ( isValidBinningDimension(i) == false ) continue;
340  binningDimensions.push_back(i);
341  }
342 
343  int nSplittingDims = binningDimensions.size();
344 
345  //Get the center of the bin and get the function / bin value
346  HyperPoint point = chosenHyperCuboid.getCenter();
347 
348  //Project the cuboid into the splitting dimensions
349  HyperCuboid projectedCuboid = chosenHyperCuboid.project(binningDimensions);
350 
351  VERBOSE_LOG << "Geting vector of all my verticies" << std::endl;
352 
353  //Get the verticies of the projected cuboid
354  HyperPointSet projectedVerticies = projectedCuboid.getVertices();
355 
356  //Turn the `projected verticies` into `verticies` that use the coordinates
357  //of the bin centre for all dimensions that are not in binningDimensions
358 
359  HyperPointSet verticies(dimensions);
360 
361  for (unsigned i = 0; i < projectedVerticies.size(); i++){
362  HyperPoint vertex(point);
363 
364  for (int j = 0; j < nSplittingDims; j++){
365  vertex.at( binningDimensions.at(j) ) = projectedVerticies.at(i).at(j);
366  }
367 
368  //move the verticies a very small amount towards the bin centre.
369  //can cause issues if the verticies are on the limit of the
370  //kinematically allowed region
371 
372  for (int j = 0; j < nSplittingDims; j++){
373 
374  int thisDim = binningDimensions.at(j);
375 
376  double addOrSubtract = 0.0;
377  double pointVal = point .at( thisDim );
378  double vertVal = vertex.at( thisDim );
379  if ( vertVal > pointVal ) { addOrSubtract = -1.00; }
380  else { addOrSubtract = +1.00; }
381 
382  //if (dimension != thisDim ) {
383  // addOrSubtract *= 0.99;
384  //}
385 
386  vertex.at( thisDim ) += addOrSubtract*_minimumEdgeLength.at( thisDim );
387  }
388 
389  verticies.push_back(vertex);
390  }
391 
392  return verticies;
393 }
HyperPointSet getVertices() const
HyperPoint _minimumEdgeLength
bool isValidBinningDimension(int dimension)
#define VERBOSE_LOG
const HyperPoint & at(int i) const
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
HyperPoint getWidth() const
const double & at(int i) const
Definition: HyperPoint.cpp:433
unsigned int size() const
std::vector< HyperCuboid > _hyperCuboids
HyperCuboid project(std::vector< int > dims) const

◆ getSplitEdges()

HyperPointSet HyperBinningMakerPhaseBinning::getSplitEdges ( int  volumeNumber)
private

Get a list of all the edge centers of the volume number given

Definition at line 444 of file HyperBinningMakerPhaseBinning.cpp.

444  {
445 
446 
447  //Get the cuboid we are trying to split
448  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
449 
450  //Figure out what dimesions we need
451  int dimensions = _hyperCuboids.at(0).getDimension();
452 
453  std::vector<int> binningDimensions;
454  for (int i = 0; i < dimensions; i++){
455  if ( chosenHyperCuboid.getWidth(i) < 2.0*_minimumEdgeLength.at(i) ) continue;
456  if ( isValidBinningDimension(i) == false ) continue;
457  binningDimensions.push_back(i);
458  }
459 
460  int nSplittingDims = binningDimensions.size();
461 
462  if (nSplittingDims == 0){
463  ERROR_LOG << "There should always be at least 1 splittable dimension!" << std::endl;
464  }
465 
466  //Get the center of the bin and get the function / bin value
467  HyperPoint point = chosenHyperCuboid.getCenter();
468 
469  //Project the cuboid into the splitting dimensions
470  HyperCuboid projectedCuboid = chosenHyperCuboid.project(binningDimensions);
471 
472  VERBOSE_LOG << "Geting vector of all my edges" << std::endl;
473  VERBOSE_LOG << "There are " << nSplittingDims << " split dimensions" << std::endl;
474 
475  //Get the verticies of the projected cuboid
476  HyperPointSet projectedVerticies = projectedCuboid.getEdgeCenters();
477 
478  VERBOSE_LOG << "There are " << projectedVerticies.size() << " verticies" << std::endl;
479 
480  //Turn the `projected verticies` into `verticies` that use the coordinates
481  //of the bin centre for all dimensions that are not in binningDimensions
482 
483  HyperPointSet verticies(dimensions);
484 
485  for (unsigned i = 0; i < projectedVerticies.size(); i++){
486  HyperPoint vertex(point);
487 
488  for (int j = 0; j < nSplittingDims; j++){
489  vertex.at( binningDimensions.at(j) ) = projectedVerticies.at(i).at(j);
490  }
491 
492  //move the verticies a very small amount towards the bin centre.
493  //can cause issues if the verticies are on the limit of the
494  //kinematically allowed region
495 
496  for (int j = 0; j < nSplittingDims; j++){
497 
498  int thisDim = binningDimensions.at(j);
499 
500  double addOrSubtract = 0.0;
501  double pointVal = point .at( thisDim );
502  double vertVal = vertex.at( thisDim );
503  if ( vertVal == pointVal ) { addOrSubtract = 0.00; }
504  else if ( vertVal > pointVal ) { addOrSubtract = -1.00; }
505  else { addOrSubtract = +1.00; }
506 
507  //if (dimension != thisDim ) {
508  // addOrSubtract *= 0.99;
509  //}
510 
511  vertex.at( thisDim ) += addOrSubtract*_minimumEdgeLength.at( thisDim );
512  }
513 
514  verticies.push_back(vertex);
515  }
516 
517  VERBOSE_LOG << "About to return my verticies" << std::endl;
518 
519 
520  return verticies;
521 
522 }
HyperPoint _minimumEdgeLength
#define ERROR_LOG
bool isValidBinningDimension(int dimension)
HyperPointSet getEdgeCenters() const
#define VERBOSE_LOG
const HyperPoint & at(int i) const
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
HyperPoint getWidth() const
const double & at(int i) const
Definition: HyperPoint.cpp:433
unsigned int size() const
std::vector< HyperCuboid > _hyperCuboids
HyperCuboid project(std::vector< int > dims) const

◆ getSplitFaces()

HyperPointSet HyperBinningMakerPhaseBinning::getSplitFaces ( int  volumeNumber)
private

Get a list of all the face centers of the volume number given

Definition at line 395 of file HyperBinningMakerPhaseBinning.cpp.

395  {
396 
397 
398  //Get the cuboid we are trying to split
399  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
400 
401  //Figure out what dimesions we need
402  int dimensions = _hyperCuboids.at(0).getDimension();
403 
404  std::vector<int> binningDimensions;
405  for (int i = 0; i < dimensions; i++){
406  if ( chosenHyperCuboid.getWidth(i) < 2.0*_minimumEdgeLength.at(i) ) continue;
407  if ( isValidBinningDimension(i) == false ) continue;
408  binningDimensions.push_back(i);
409  }
410 
411  int nSplittingDims = binningDimensions.size();
412 
413 
414  //Get the center of the bin and get the function / bin value
415  HyperPoint point = chosenHyperCuboid.getCenter();
416 
417  //Project the cuboid into the splitting dimensions
418  HyperCuboid projectedCuboid = chosenHyperCuboid.project(binningDimensions);
419 
420  VERBOSE_LOG << "Geting vector of all my faces" << std::endl;
421 
422 
423 
424  HyperPointSet verticies(dimensions);
425 
426  for (int i = 0; i < nSplittingDims; i++){
427 
428  int thisDim = binningDimensions.at(i);
429  HyperPoint faceA(point);
430  HyperPoint faceB(point);
431 
432  faceA.at(thisDim) = faceA.at(thisDim) - 0.5*chosenHyperCuboid.getWidth(thisDim) + _minimumEdgeLength.at(thisDim);
433  faceB.at(thisDim) = faceB.at(thisDim) + 0.5*chosenHyperCuboid.getWidth(thisDim) - _minimumEdgeLength.at(thisDim);
434 
435  verticies.push_back(faceA);
436  verticies.push_back(faceB);
437 
438  }
439 
440  return verticies;
441 
442 }
HyperPoint _minimumEdgeLength
bool isValidBinningDimension(int dimension)
#define VERBOSE_LOG
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
HyperPoint getWidth() const
const double & at(int i) const
Definition: HyperPoint.cpp:433
std::vector< HyperCuboid > _hyperCuboids
HyperCuboid project(std::vector< int > dims) const

◆ gradientSplit()

int HyperBinningMakerPhaseBinning::gradientSplit ( int  binNumber,
int &  dimension 
)
privatevirtual

The default split method. It uses the gradient of the function to predict where the boundary wetween two bin numbers is. If it fails, it will call the systematic split instead

Definition at line 699 of file HyperBinningMakerPhaseBinning.cpp.

699  {
700 
702 
703  VERBOSE_LOG <<"Calling gradientSplit(" << volumeNumber << ", " << dimension << ")" << std::endl;
704 
705  //first get the Hypercube that we want to split
706 
707  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
708 
709 
710  //Get the center of the bin. Ideally we want
711  //to find a split point as colse as possible to this
712  HyperPoint binCenter = chosenHyperCuboid.getCenter();
713 
714  //Evaluate the function at the bin center and find the
715  //'bin number' from this. Also find out which bin boundary
716  //is closest to us.
717 
718  double valCenter = _func->getVal(binCenter);
719  int binNumber = getBinNumFromFuncVal(valCenter);
720  double closestBound = closestBinBoundary(valCenter);
721 
722  //Gradient given in the same coordinates as the binning
723  HyperPoint gradient = getGradPos(binCenter, valCenter);
724 
725  dimension = splitDimFromGrad(volumeNumber, gradient);
726 
727  //if (fabs(gradient.at(dimension))*10.0 < gradient.norm()){
728  // return randomWalkSplit(volumeNumber, dimension);
729  //}
730 
731  //When we are splitting the bin, there is no point in splitting in a
732  //region that will result in bins that are too narrow. Therefore define the "splitLimits"
733 
734  HyperPoint lowPoint = chosenHyperCuboid.getLowCorner ();
735  HyperPoint highPoint = chosenHyperCuboid.getHighCorner();
736 
737  lowPoint = lowPoint + _minimumEdgeLength*0.499;
738  highPoint = highPoint - _minimumEdgeLength*0.499;
739 
740  lowPoint .at(dimension) += _minimumEdgeLength.at(dimension)*0.5;
741  highPoint.at(dimension) -= _minimumEdgeLength.at(dimension)*0.5;
742 
743  HyperCuboid splitLimits(lowPoint, highPoint);
744  HyperPoint splitLimitsWidth = highPoint - lowPoint;
745  VERBOSE_LOG << "I have a nice set of split limits" << std::endl;
746 
747 
748  //tranform gradient to a coordinate system where the bin
749  //is limited by [-1, 1] in all dims
750 
751  HyperPoint gradientTrans = gradient;
752 
753  int nDims = _hyperCuboids.at(0).getDimension();
754 
755  for (int i = 0; i < nDims; i++){
756  gradientTrans.at(i) *= (splitLimitsWidth.at(i)*2.0);
757  }
758 
759  //if I move along in space by 'gradient' the change in the function will be
760 
761  double rateOfInc = gradientTrans.norm2();
762 
763  //We need the function to change by the distance to the nearest boundary:
764 
765  double scale = (closestBound - valCenter)/rateOfInc;
766 
767  HyperPoint splitVector = gradientTrans*scale;
768 
769  //Now we need to transform the SplitVector back to
770  //the real coordinate system.
771  //The fact that we multiply by the same thing again
772  //I found counter-intuative, but I think it's correct.
773 
774  for (int i = 0; i < nDims; i++){
775  splitVector.at(i) *= (splitLimitsWidth.at(i)*2.0);
776  }
777 
778  //Now we have a direction to look along, we can find the
779  //second derivate in this direction to improve the estimate
780 
781  //double firstDeriv = gradientOrig.dotProduct(splitVector)/splitVector.norm();
782  double firstDeriv = 0.0;
783  double secondDeriv = getSecondDerivative(binCenter, splitVector, valCenter, firstDeriv);
784 
785  // f(x) = f(x0) + f'(x0) (x-x0) + f''(x0) (x-x0)^2 / 2
786  //solve the quadratic eqn
787 
788  double a = secondDeriv/2.0;
789  double b = firstDeriv;
790  double c = valCenter - closestBound;
791 
792  double quadraticSol1 = (-b + sqrt(b*b - 4.0*a*c))/(2.0*a);
793  double quadraticSol2 = (-b - sqrt(b*b - 4.0*a*c))/(2.0*a);
794 
795  //choose the solution that is closest to the bin center
796 
797  double quadraticSol = quadraticSol1;
798  if ( fabs(quadraticSol1) > fabs(quadraticSol2) ){
799  quadraticSol = quadraticSol2;
800  }
801 
802  //If the solution to the quadratic is NaN, just go with the
803  //more simple cornerSplit function.
804 
805  if (quadraticSol != quadraticSol){
806  return systematicSplit(volumeNumber, dimension, valCenter, gradient);
807  }
808 
809  //Get a refined split vector using improved first deriv and second deriv
810  HyperPoint refinedSplitVector = (splitVector * quadraticSol ) / splitVector.norm();
811 
812  //Use the split vectors to get split points
813 
814  HyperPoint splitPoint = splitVector + binCenter;
815  HyperPoint refinedSplitPoint = refinedSplitVector + binCenter;
816 
817  //Want to add a small amount extra to make sure we cross a bin boundary.
818 
819  HyperPoint refinedSplitPointExtended = refinedSplitVector*1.05 + binCenter;
820 
821  //As a cross check, can make a function in the original coordinate
822  //system that models the function using f(x0) and grad(x0). We then
823  //evaluate this at the split point that was determined. Hopefully
824  //this returns the nearest bin boundary!!! (It does)
825 
826  bool crossCheck1 = false;
827  bool crossCheck2 = false;
828  bool crossCheck4 = false;
829 
830  if (crossCheck1 == true){
831 
832  double predictedVal = valCenter + gradient.dotProduct( splitPoint - binCenter );
833  std::cout << predictedVal << ", " << closestBound << std::endl;
834 
835  }
836 
837  if (crossCheck2 == true){
838 
839  double directionVal = splitVector.dotProduct(refinedSplitPoint - binCenter);
840 
841  if (directionVal < 0.0) directionVal = -1.0;
842  else directionVal = 1.0;
843 
844  double predictedVal = 0.5*secondDeriv*(refinedSplitPoint - binCenter).norm2() + directionVal*firstDeriv*(refinedSplitPoint - binCenter).norm() + valCenter;
845 
846  std::cout << predictedVal << ", " << closestBound << std::endl;
847 
848  }
849 
850  if (crossCheck4 == true){
851 
852  std::cout << gradient.dotProduct( splitVector )/splitVector.norm() << ", " << firstDeriv << std::endl;
853  }
854 
855 
856  //See if the predicted split point is within the bin limits, if not
857  //return try a less sophisticated method.
858 
859  if (splitLimits.inVolume(refinedSplitPointExtended) == false) {
860  return systematicSplit(volumeNumber, dimension, valCenter, gradient);
861  }
862 
863  //See what the function and the bin number is at the new point
864  double valNew = _func->getVal(refinedSplitPointExtended);
865  int binNew = getBinNumFromFuncVal(valNew);
866 
867  //As a cross check we can see how the extrapolation agrees with the real value.
868 
869  bool crossCheck3 = false;
870 
871  if (crossCheck3 == true){
872 
873  double valReal = _func->getVal( splitPoint);
874  double valRealRef = _func->getVal(refinedSplitPoint);
875  double valExtrap = closestBound;
876 
877  std::complex<double> cValReal (cos(valReal) , sin(valReal) );
878  std::complex<double> cValRealRef(cos(valRealRef), sin(valRealRef) );
879  std::complex<double> cValExtrap (cos(valExtrap) , sin(valExtrap));
880  double diff = arg(cValReal *conj(cValExtrap));
881  double diffRef = arg(cValRealRef*conj(cValExtrap));
882 
883  std::cout << valCenter << " -> (" << valReal << " ?= " << valExtrap << " ) -> " << diff / fabs(valCenter-valExtrap) << std::endl;
884  std::cout << diff << " -> " << diffRef << std::endl;
885 
886  }
887 
888  //If we end up in the same bin, try a less sophisticated approach
889 
890  if ( binNew == binNumber ) {
891  return systematicSplit(volumeNumber, dimension, valCenter, gradient);
892  }
893 
894  //Finally, if everything else goes OK, split bin at the chosen split point
895 
896  return splitByCoord(volumeNumber, dimension, refinedSplitPointExtended );
897 
898 }
HyperPoint _minimumEdgeLength
double dotProduct(const HyperPoint &other) const
Definition: HyperPoint.cpp:147
int splitByCoord(int volumeNumber, int dimension, HyperPoint &coord)
#define VERBOSE_LOG
int systematicSplit(int volumeNumber, int dimension, double valAtCenter, HyperPoint gradient)
HyperFunction * _func
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
virtual double getVal(const HyperPoint &point) const =0
double getSecondDerivative(HyperPoint &point, HyperPoint &vector, double funcValAtPoint, double &deriv)
const double & at(int i) const
Definition: HyperPoint.cpp:433
int splitDimFromGrad(int volumeNumber, HyperPoint gradient)
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
double norm2() const
Definition: HyperPoint.cpp:139
HyperPoint getGradPos(HyperPoint &point, double funcValAtPoint)
std::vector< HyperCuboid > _hyperCuboids
double norm() const
Definition: HyperPoint.cpp:131

◆ gradientSplitAll()

int HyperBinningMakerPhaseBinning::gradientSplitAll ( )
virtual

Definition at line 58 of file HyperBinningMakerPhaseBinning.cpp.

58  {
59 
60  VERBOSE_LOG << "HyperBinningMakerPhaseBinning::gradientSplitAll( )" << std::endl;
61 
62  int initialSize = _hyperCuboids.size();
63  int nSplits = 0;
64 
65  int splittable = getNumContinueBins();
66  LoadingBar loadingbar(splittable);
67  int splittableDone = 0;
68 
69  for (int i = 0; i < initialSize; i++){
71 
72  loadingbar.update(splittableDone);
73  splittableDone++;
74 
75  int dimension = -1;
76  int split = gradientSplit( i, dimension );
77 
78  nSplits += split;
79 
80  if (split == 0){
83  }
84 
85  }
86  }
87 
88  return nSplits;
89 }
virtual int gradientSplit(int binNumber, int &dimension)
int getNumContinueBins(int dimension=-1) const
#define VERBOSE_LOG
void updateGlobalStatusFromDimSpecific(int volumeNumber)
int & getGlobalVolumeStatus(int volumeNumber)
int & getDimensionSpecificVolumeStatus(int volumeNumber, int dimension)
std::vector< HyperCuboid > _hyperCuboids
int split(int volumeNumber, int dimension, double splitPoint)

◆ makeBinning()

void HyperBinningMakerPhaseBinning::makeBinning ( )
virtual

run the algorithm

Implements HyperBinningMaker.

Definition at line 23 of file HyperBinningMakerPhaseBinning.cpp.

23  {
24 
25  int dimension = _binningDimensions.size();
26 
27  int splitDim = 0;
28  if (splitDim >= dimension) splitDim = 0;
29 
30  int nBins = 0;
31  int unchanged = 0;
32 
33 
34  while ( 1==1 ){
36 
37  if (s_printBinning == true) {
38  INFO_LOG << "--------------------------------------------------" <<std::endl;
39  INFO_LOG << "Trying to split all bins" << std::endl;
40  INFO_LOG << "There are " << getNumContinueBins() << " splittable bins" << std::endl;
41  }
42 
44 
45  if (nBins == getNumBins()) unchanged++;
46  else unchanged = 0;
47  if (unchanged >= dimension) break;
48  nBins = getNumBins();
49  if (s_printBinning == true) INFO_LOG << "There is now a total of " << nBins << " bins" << std::endl;
50 
51  }
52 
53  if (s_printBinning == true) INFO_LOG << "Mint binning algorithm complete " <<std::endl;
54 
55 }
int getNumContinueBins(int dimension=-1) const
#define INFO_LOG
static bool s_printBinning
virtual void finishedIteration()
std::vector< int > _binningDimensions

◆ orderAndTestSplitPoints()

HyperPoint HyperBinningMakerPhaseBinning::orderAndTestSplitPoints ( HyperPointSet points,
HyperPoint point,
double  valAtPoint,
HyperPoint  gradient 
)
private

See systematicSplit for a full description.

Definition at line 526 of file HyperBinningMakerPhaseBinning.cpp.

526  {
527 
528  int bin = getBinNumFromFuncVal(valAtPoint);
529 
530  //To speed things up, we want to order the corners by
531  //the most likely to split. Can use gradient to see
532 
533  //The FOM is essentially just the distance to the nearest bin edge.
534  //It's negative if we are still inside the bin.
535 
536  std::vector<double> functionEstimateFom;
537  std::vector<double> functionEstimate;
538  std::vector<int> index;
539 
540  double lowBoundary = getLowBinBoundary (valAtPoint);
541  double highBoundary = getHighBinBoundary(valAtPoint);
542 
543  VERBOSE_LOG << "Sorting points to speed my life up" << std::endl;
544 
545  for (unsigned i = 0; i < points.size(); i++){
546 
547  index.push_back(i);
548 
549  double estimate = valAtPoint + gradient.dotProduct(points.at(i) - point);
550  double fom = 0.0;
551  if ( estimate >= lowBoundary && estimate <= highBoundary ){
552  double fom1 = lowBoundary - estimate;
553  double fom2 = estimate - highBoundary;
554 
555  if (fom1 > fom2) {fom = fom1;}
556  else {fom = fom2;}
557  }
558  if (estimate < lowBoundary){
559  fom = lowBoundary - estimate;
560  }
561  if (estimate > highBoundary){
562  fom = estimate - highBoundary;
563  }
564 
565  functionEstimate .push_back(estimate);
566  functionEstimateFom.push_back(fom );
567 
568  }
569 
570 
571  TMath::Sort( (int)points.size(), &(functionEstimateFom.at(0)), &(index.at(0)) );
572  //for (unsigned i = 0; i < points.size(); i++){
573  // std::cout << functionEstimateFom.at( index.at(i) ) << std::endl;
574  //}
575 
576  //Evaluate the function for each vertex and see if the bin number changes.
577  //If so, choose a split point that is somewhere between the vetex and the
578  //bin center.
579 
580  //Each time we evaluate the function at a corner, we can see how good
581  //our predictions are, and set an error.
582 
583  double uncertaintySum = 0.0;
584  int uncertainiesAdded = 0;
585 
586  for (unsigned i = 0; i < points.size(); i++){
587 
588  double vtxNum = index.at(i);
589  double estimate = functionEstimate .at(vtxNum);
590  double fom = functionEstimateFom.at(vtxNum);
591  double estimateUncert = TMath::Pi()*2.0;
592 
593  if (uncertainiesAdded >= 2){
594  estimateUncert = uncertaintySum/double(uncertainiesAdded - 1.0);
595  }
596 
597  // i.e. if our estimate indicates that this bin is
598  // more than 3.5 sigma from a bin boundary, we give up.
599  if ( fom < -estimateUncert*5.0 ) {
600  //std::cout << "Breaking loop at " << i << "; fom est = " << fom << " ± " << estimateUncert << std::endl;
601  break;
602  }
603  double valHere = _func->getVal(points.at(vtxNum));
604  int binHere = getBinNumFromFuncVal(valHere);
605 
606  std::complex<double> cEst(cos(estimate), sin(estimate));
607  std::complex<double> cValHere(cos(valHere) , sin(valHere ));
608 
609  double diff = arg( cEst*conj(cValHere) );
610 
611  uncertaintySum += fabs(diff);
612  uncertainiesAdded++;
613 
614  //std::cout << i << " "<< estimate << " : [ " << lowBoundary << ", " << highBoundary << "] "<< valHere << std::endl;
615 
616  if (binHere != bin){
617  HyperPoint returnPoint(points.at(vtxNum));
618  returnPoint.setWeight(0, valHere);
619  return returnPoint;
620  }
621 
622  }
623 
624  HyperPoint returnPoint(0);
625  if (returnPoint.getDimension() !=0 ){
626  ERROR_LOG << "This should be zero" << std::endl;
627  }
628 
629  return returnPoint;
630 
631 }
double dotProduct(const HyperPoint &other) const
Definition: HyperPoint.cpp:147
void setWeight(int i, double w)
Definition: Weights.cpp:52
#define ERROR_LOG
#define VERBOSE_LOG
const HyperPoint & at(int i) const
HyperFunction * _func
virtual double getVal(const HyperPoint &point) const =0
unsigned int size() const

◆ randomWalkSplit()

int HyperBinningMakerPhaseBinning::randomWalkSplit ( int  volumeNumber,
int  dimension 
)
private

Do random walk within the HyperVolume to search for a point where the bin number changes. Not really used anymore.

Definition at line 900 of file HyperBinningMakerPhaseBinning.cpp.

900  {
901 
902  VERBOSE_LOG <<"Calling gradientSplit(" << volumeNumber << ", " << dimension << ")" << std::endl;
903 
904  //first get the Hypercube that we want to split
905 
906  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
907 
908  HyperPoint lowPoint = chosenHyperCuboid.getLowCorner ();
909  HyperPoint highPoint = chosenHyperCuboid.getHighCorner();
910 
911 
912  //get the minumum bin width in the dimension we're splitting in
913  double minBinWidth = _minimumEdgeLength.at(dimension);
914 
915  //if the volume we're splitting is narrower than minBinWidth*2 we bail now
916  //if ( binWidth < minBinWidth*2.0 ) return 0;
917 
918 
919 
920  //When we do the random walk, there is no point in walking to regions that will
921  //result in bins that are too narrow. Therefore define the "walkLimits"
922 
923 
924  HyperPoint binCenter = chosenHyperCuboid.getCenter();
925 
926  lowPoint = lowPoint + _minimumEdgeLength*0.499;
927  highPoint = highPoint - _minimumEdgeLength*0.499;
928 
929  //for ( int i = 0; i < lowPoint.getDimension(); i++ ){
930  // if ( highPoint.at(i) - lowPoint.at(i) < 2.0*_minimumEdgeLength.at(i) ){
931  // lowPoint .at(i) = binCenter.at(i) - 0.01*_minimumEdgeLength.at(i);
932  // highPoint.at(i) = binCenter.at(i) + 0.01*_minimumEdgeLength.at(i);
933  // }
934  // else{
935  // lowPoint .at(i) += _minimumEdgeLength.at(i);
936  // highPoint.at(i) -= _minimumEdgeLength.at(i);
937  // }
938  //}
939 
940  lowPoint .at(dimension) += minBinWidth*0.5;
941  highPoint.at(dimension) -= minBinWidth*0.5;
942 
943  VERBOSE_LOG <<"Walk width in split dim = " << highPoint.at(dimension) - lowPoint.at(dimension) << std::endl;
944 
945  //INFO_LOG << "I bet this happens first" << std::endl;
946  HyperCuboid walkLimits(lowPoint, highPoint);
947 
948 
949  //Random walk starting point
950  HyperPoint point = chosenHyperCuboid.getCenter();
951  //point.at(2) = 0.3;
952  //point.at(3) = -0.2;
953  //point.at(4) = 2.0;
954 
955  HyperPointSet points(_numWalkers, point);
956 
957  double valCenter = getBinNumFromFunc(point);
958 
959 
960  for ( int i = 0; i < _maximumRandWalks; i++ ){
961 
962  VERBOSE_LOG <<"Random walk " << i << " of " << _maximumRandWalks << std::endl;
963 
964 
965  for (int j = 0; j < _numWalkers; j++){
966  VERBOSE_LOG <<"-- walker " << j << " fancies exploring this space" << std::endl;
967 
968  walk( points.at(j), walkLimits );
969  VERBOSE_LOG <<"-- walker " << j;
970  double val = getBinNumFromFunc( points.at(j) );
971  VERBOSE_LOG << " has fnc val = " << val << std::endl;
972 
973  if ( fabs(val - valCenter) > 0.5 ) {
974 
975  return splitByCoord(volumeNumber, dimension, points.at(j) );
976 
977  }
978 
979  }
980 
981  //make two pointx which are a short distance either size of the split
982 
983  //HyperPoint point1(point);
984  //HyperPoint point2(point);
985  //point1.at(dimension) += walkSize*0.5;
986  //point2.at(dimension) -= walkSize*0.5;
987  //
988  //if ( walkLimits.inVolume(point1) == false ){
989  // point1.at(dimension) -= walkSize*0.5;
990  // point1.at(dimension) += minBinWidth*0.5;
991  //}
992  //
993  //if ( walkLimits.inVolume(point2) == false ){
994  // point2.at(dimension) += walkSize*0.5;
995  // point2.at(dimension) -= minBinWidth*0.5;
996  //}
997 
998  //Evaluate the function for each point
999  //double val1 = _func->getVal(point1);
1000  //double val2 = _func->getVal(point2);
1001 
1002  //double val = _func->getVal(point);
1003 
1004 
1005  //If the function values are sufficiently different - SPLIT!!
1006  //if ( fabs(val1 - val2) > 0.5 ) {
1007  //if ( fabs(val - valCenter) > 0.5 ) {
1008 
1009  // splitByCoord();
1010 
1011  //}
1012 
1013  }
1014 
1015  return 0;
1016 
1017 }
HyperPoint _minimumEdgeLength
int splitByCoord(int volumeNumber, int dimension, HyperPoint &coord)
#define VERBOSE_LOG
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
const double & at(int i) const
Definition: HyperPoint.cpp:433
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
void walk(HyperPoint &point, HyperCuboid &walkLimits)
std::vector< HyperCuboid > _hyperCuboids

◆ setBinEdges()

void HyperBinningMakerPhaseBinning::setBinEdges ( std::vector< double >  binEdges)

set the bin edges - the highest bin edge is the lowest + pi, so only nBinPair edges need to be passed

Definition at line 157 of file HyperBinningMakerPhaseBinning.cpp.

◆ setNumBinPairs()

void HyperBinningMakerPhaseBinning::setNumBinPairs ( int  binpairs)

set the number of bin pairs (see class description of details)

Definition at line 146 of file HyperBinningMakerPhaseBinning.cpp.

146  {
147  _numBinPairs = binpairs;
148  std::vector<double> binEdges;
149 
150  for (int i = 0; i < 2*_numBinPairs; i++){
151  binEdges.push_back( - TMath::Pi() + (TMath::Pi()/double(_numBinPairs))*i );
152  }
153 
154  _binEdges = CyclicPhaseBins(binEdges);
155 }

◆ splitByCoord()

int HyperBinningMakerPhaseBinning::splitByCoord ( int  volumeNumber,
int  dimension,
HyperPoint coord 
)
private

Split a HyperVolume in a given dimension at a given coord

Definition at line 136 of file HyperBinningMakerPhaseBinning.cpp.

136  {
137 
138  double low = _hyperCuboids.at(volumeNumber).getLowCorner ().at(dimension);
139  double high = _hyperCuboids.at(volumeNumber).getHighCorner().at(dimension);
140  double splitPoint = (point.at(dimension) - low)/(high-low);
141  return split(volumeNumber, dimension, splitPoint);
142 
143 }
std::vector< HyperCuboid > _hyperCuboids
int split(int volumeNumber, int dimension, double splitPoint)

◆ splitDimFromGrad()

int HyperBinningMakerPhaseBinning::splitDimFromGrad ( int  volumeNumber,
HyperPoint  gradient 
)
private

Use the graident at the center of the given volume number to decide what dimension to split in.

Definition at line 295 of file HyperBinningMakerPhaseBinning.cpp.

295  {
296 
297  double minGrad = gradient.norm()*0.25;
298 
299 
300  double maxGrad = -1.0;
301  int dimWithMaxGrad = -1;
302 
303  for (int i = 0; i < gradient.getDimension(); i++){
304 
305  if ( getDimensionSpecificVolumeStatus(volumeNumber, i) == VolumeStatus::DONE ) continue;
306 
307  double gradInThisDim = fabs( gradient.at(i) ) + minGrad;
308 
309  gradInThisDim *= _hyperCuboids.at(volumeNumber).getWidth(i);
310  gradInThisDim /= _minimumEdgeLength.at(i);
311 
312  if ( gradInThisDim > maxGrad ) {
313  maxGrad = gradInThisDim;
314  dimWithMaxGrad = i;
315  }
316 
317  }
318 
319  if (dimWithMaxGrad == -1){
320  ERROR_LOG << "Something has gone horribly wrong - if no dimensions can be split, I shouldn't be arriving here" << std::endl;
321  }
322 
323  //std::cout << gradient << " " << dimWithMaxGrad <<std::endl;
324 
325  return dimWithMaxGrad;
326 }
HyperPoint _minimumEdgeLength
#define ERROR_LOG
const double & at(int i) const
Definition: HyperPoint.cpp:433
int & getDimensionSpecificVolumeStatus(int volumeNumber, int dimension)
std::vector< HyperCuboid > _hyperCuboids
int getDimension() const
Definition: HyperPoint.h:99
double norm() const
Definition: HyperPoint.cpp:131

◆ systematicSplit()

int HyperBinningMakerPhaseBinning::systematicSplit ( int  volumeNumber,
int  dimension,
double  valAtCenter,
HyperPoint  gradient 
)
private

This function looks at the function value at specific points within the HyperVolume. It uses the corners of the HyperVolume, a point in the middle of each face (NPlane), and a point in the middle of each edge. If the bin number changes at any of these points, it will result in the bin being split. To speed things up it uses the gradient at the HyperVolume center to order the points, on which are most liekly to result in a successful split. While looping through the points it estimates the uncertainty of the function estimate (from the graient). If the estimate indicates that the function is more than 5 sigma from a bin split, it will skip that point (and all remaining points since they are ordered)

Definition at line 633 of file HyperBinningMakerPhaseBinning.cpp.

633  {
634 
636 
637  //int binNumAtCenter = getBinNumFromFuncVal(valAtCenter);
638 
639  HyperCuboid& chosenHyperCuboid = _hyperCuboids.at(volumeNumber);
640  HyperPoint centerPoint = chosenHyperCuboid.getCenter();
641 
642 
643 
644  HyperPointSet pointsToTest( _hyperCuboids.at(0).getDimension() );
645 
646  HyperPointSet corners = getSplitCorners(volumeNumber);
647  HyperPointSet faces = getSplitFaces (volumeNumber);
648  HyperPointSet edges = getSplitEdges (volumeNumber);
649 
650  pointsToTest.addHyperPointSet(corners);
651  pointsToTest.addHyperPointSet(faces );
652  pointsToTest.addHyperPointSet(edges );
653 
654  VERBOSE_LOG << "Got a big list of " << pointsToTest.size() << " to test " << std::endl;
655 
656  //pointsToTest.print();
657 
658  //for (int i = 0; i < corners.size(); i++){
659  // pointsToTest.push_back( (corners.at(i) + centerPoint)*0.5 );
660  //}
661 
662 
663  HyperPoint point = orderAndTestSplitPoints(pointsToTest, centerPoint, valAtCenter, gradient);
664 
665  if ( point.getDimension() == 0 ) return 0;
666 
667  double valAtPoint = point.getWeight();
668 
669  std::complex<double> cValAtPoint (cos(valAtPoint) , sin(valAtPoint ));
670  std::complex<double> cValAtCenter(cos(valAtCenter) , sin(valAtCenter));
671 
672  double dy = arg( cValAtCenter*conj(cValAtPoint) );
673 
674  double binEdge = 0.0;
675  if (dy > 0.0){
676  binEdge = getLowBinBoundary(valAtCenter);
677  }
678  else{
679  binEdge = getHighBinBoundary(valAtCenter);
680  }
681 
682  double scale = fabs( (binEdge - valAtCenter)/dy );
683  if (scale > 1.00){
684  //ERROR_LOG << "THIS HAS TO BE LESS THAN 1.0 - It's " << scale << std::endl;
685  scale = 1.0;
686  }
687 
688  HyperPoint splitPoint = centerPoint + ( point - centerPoint )*scale;
689  return splitByCoord(volumeNumber, dimension, splitPoint );
690 
691 
692 }
int splitByCoord(int volumeNumber, int dimension, HyperPoint &coord)
#define VERBOSE_LOG
HyperPointSet getSplitFaces(int volumeNumber)
HyperPointSet getSplitEdges(int volumeNumber)
HyperPoint orderAndTestSplitPoints(HyperPointSet &points, HyperPoint &point, double valAtPoint, HyperPoint gradient)
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
double getWeight(int i=0) const
Definition: Weights.cpp:40
std::vector< HyperCuboid > _hyperCuboids
HyperPointSet getSplitCorners(int volumeNumber)
int getDimension() const
Definition: HyperPoint.h:99

◆ walk()

void HyperBinningMakerPhaseBinning::walk ( HyperPoint point,
HyperCuboid walkLimits 
)
private

Do a random walk in a random dimension (within the walk limits)

Definition at line 113 of file HyperBinningMakerPhaseBinning.cpp.

113  {
114 
115  HyperPoint walkWidth = (walkLimits.getHighCorner() - walkLimits.getLowCorner())*_walkSizeFrac;
116 
117  for (int i = 0; i < point.getDimension(); i++){
118  if ( isValidBinningDimension(i) == false ) {
119  walkWidth.at(i) = 0.0;
120  }
121  else{
122  walkWidth.at(i) = walkWidth.at(i)*_random->Gaus(0.0, 1.0);
123  }
124  }
125 
126  point = point + walkWidth;
127 
128  //If this walk went out of the walk limits, move back, and try again.
129  if ( walkLimits.inVolume(point) == false ){
130  point = point - walkWidth;
131  walk( point, walkLimits);
132  }
133 
134 }
bool isValidBinningDimension(int dimension)
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
const double & at(int i) const
Definition: HyperPoint.cpp:433
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
void walk(HyperPoint &point, HyperCuboid &walkLimits)
int getDimension() const
Definition: HyperPoint.h:99
bool inVolume(const HyperPoint &coords) const

◆ walkOrthogonal()

void HyperBinningMakerPhaseBinning::walkOrthogonal ( HyperPoint point,
HyperCuboid walkLimits 
)
private

Do a random walk in one dimension (within the walk limits)

Definition at line 92 of file HyperBinningMakerPhaseBinning.cpp.

92  {
93 
94  //randomly select what direction we're going to walk in
95  int walkDimNum = floor(_random->Uniform(0.0, _binningDimensions.size()));
96  int walkDim = _binningDimensions.at(walkDimNum);
97 
98  double walkSize = _walkSizeFrac*( walkLimits.getHighCorner().at(walkDim) - walkLimits.getLowCorner().at(walkDim) );
99  //if (walkSize < _minimumEdgeLength.at(walkDim)) walkSize = _minimumEdgeLength.at(walkDim);
100 
101  //randomly move along this axis
102  double direction = _random->Gaus(0.0, 1.0);
103  point.at(walkDim) += walkSize*direction;
104 
105  //If this walk went out of the walk limits, move back, and try again.
106  if ( walkLimits.inVolume(point) == false ){
107  point.at(walkDim) -= walkSize*direction;
108  walk( point, walkLimits);
109  }
110 
111 }
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
const double & at(int i) const
Definition: HyperPoint.cpp:433
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
void walk(HyperPoint &point, HyperCuboid &walkLimits)
std::vector< int > _binningDimensions
bool inVolume(const HyperPoint &coords) const

Member Data Documentation

◆ _binEdges

CyclicPhaseBins HyperBinningMakerPhaseBinning::_binEdges
private

Definition at line 43 of file HyperBinningMakerPhaseBinning.h.

◆ _maximumRandWalks

int HyperBinningMakerPhaseBinning::_maximumRandWalks
private

Definition at line 45 of file HyperBinningMakerPhaseBinning.h.

◆ _numberOfGradientSplits

int HyperBinningMakerPhaseBinning::_numberOfGradientSplits
private

Definition at line 50 of file HyperBinningMakerPhaseBinning.h.

◆ _numberOfSystematicSplits

int HyperBinningMakerPhaseBinning::_numberOfSystematicSplits
private

Definition at line 49 of file HyperBinningMakerPhaseBinning.h.

◆ _numBinPairs

int HyperBinningMakerPhaseBinning::_numBinPairs
private

Definition at line 42 of file HyperBinningMakerPhaseBinning.h.

◆ _numWalkers

int HyperBinningMakerPhaseBinning::_numWalkers
private

Definition at line 46 of file HyperBinningMakerPhaseBinning.h.

◆ _walkSizeFrac

double HyperBinningMakerPhaseBinning::_walkSizeFrac
private

Definition at line 47 of file HyperBinningMakerPhaseBinning.h.


The documentation for this class was generated from the following files: