12 _maximumRandWalks(30),
15 _numberOfSystematicSplits(0),
16 _numberOfGradientSplits (0)
20 WELCOME_LOG <<
"Good day from the HyperBinningMakerPhaseBinning() Constructor"<<std::endl;
28 if (splitDim >= dimension) splitDim = 0;
38 INFO_LOG <<
"--------------------------------------------------" <<std::endl;
39 INFO_LOG <<
"Trying to split all bins" << std::endl;
47 if (unchanged >= dimension)
break;
60 VERBOSE_LOG <<
"HyperBinningMakerPhaseBinning::gradientSplitAll( )" << std::endl;
67 int splittableDone = 0;
69 for (
int i = 0; i < initialSize; i++){
72 loadingbar.
update(splittableDone);
102 double direction =
_random->Gaus(0.0, 1.0);
103 point.
at(walkDim) += walkSize*direction;
106 if ( walkLimits.
inVolume(point) == false ){
107 point.
at(walkDim) -= walkSize*direction;
108 walk( point, walkLimits);
119 walkWidth.
at(i) = 0.0;
122 walkWidth.
at(i) = walkWidth.
at(i)*
_random->Gaus(0.0, 1.0);
126 point = point + walkWidth;
129 if ( walkLimits.
inVolume(point) == false ){
130 point = point - walkWidth;
131 walk( point, walkLimits);
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);
148 std::vector<double> binEdges;
151 binEdges.push_back( - TMath::Pi() + (TMath::Pi()/
double(
_numBinPairs))*i );
165 if (phase < -10.0)
return -1;
188 double distLow = fabs(val - low );
189 double distHigh = fabs(val - high);
191 if (distLow < distHigh)
return low;
210 for (
int i = 0; i < nBinningDims; i++){
216 low .
at(i) -= stepsize;
217 high.
at(i) += stepsize;
222 std::complex<double> compLow (cos(valLow ), sin(valLow ));
223 std::complex<double> compHigh(cos(valHigh), sin(valHigh));
225 grad.
at(i) = arg( compHigh*conj(compLow) )/(2.0*stepsize);
237 for (
int i = 0; i < nBinningDims; i++){
242 high.
at(i) += stepsize;
246 std::complex<double> compVal (cos(funcValAtPoint ), sin(funcValAtPoint ));
247 std::complex<double> compHigh(cos(valHigh), sin(valHigh));
249 grad.
at(i) = arg( compHigh*conj(compVal) )/(stepsize);
257 bool centeral =
true;
265 HyperPoint low = point - normVector*stepLength;
266 HyperPoint high = point + normVector*stepLength;
268 double val = funcValAtPoint;
272 double h = (high - low).norm()*0.5;
274 firstDeriv = (highVal - lowVal)/(2.0*h);
275 double secondDeriv = (lowVal + highVal - 2.0*val)/(h*h);
279 HyperPoint high1 = point + normVector*stepLength;
280 HyperPoint high2 = point + normVector*stepLength*2.0;
286 double h = (high1 - high2).norm();
288 double secondDeriv = (val + high2Val - 2.0*high1Val)/(h*h);
297 double minGrad = gradient.
norm()*0.25;
300 double maxGrad = -1.0;
301 int dimWithMaxGrad = -1;
307 double gradInThisDim = fabs( gradient.
at(i) ) + minGrad;
312 if ( gradInThisDim > maxGrad ) {
313 maxGrad = gradInThisDim;
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;
325 return dimWithMaxGrad;
336 std::vector<int> binningDimensions;
337 for (
int i = 0; i < dimensions; i++){
340 binningDimensions.push_back(i);
343 int nSplittingDims = binningDimensions.size();
351 VERBOSE_LOG <<
"Geting vector of all my verticies" << std::endl;
361 for (
unsigned i = 0; i < projectedVerticies.
size(); i++){
364 for (
int j = 0; j < nSplittingDims; j++){
365 vertex.
at( binningDimensions.at(j) ) = projectedVerticies.
at(i).
at(j);
372 for (
int j = 0; j < nSplittingDims; j++){
374 int thisDim = binningDimensions.at(j);
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; }
404 std::vector<int> binningDimensions;
405 for (
int i = 0; i < dimensions; i++){
408 binningDimensions.push_back(i);
411 int nSplittingDims = binningDimensions.size();
420 VERBOSE_LOG <<
"Geting vector of all my faces" << std::endl;
426 for (
int i = 0; i < nSplittingDims; i++){
428 int thisDim = binningDimensions.at(i);
453 std::vector<int> binningDimensions;
454 for (
int i = 0; i < dimensions; i++){
457 binningDimensions.push_back(i);
460 int nSplittingDims = binningDimensions.size();
462 if (nSplittingDims == 0){
463 ERROR_LOG <<
"There should always be at least 1 splittable dimension!" << std::endl;
472 VERBOSE_LOG <<
"Geting vector of all my edges" << std::endl;
473 VERBOSE_LOG <<
"There are " << nSplittingDims <<
" split dimensions" << std::endl;
478 VERBOSE_LOG <<
"There are " << projectedVerticies.
size() <<
" verticies" << std::endl;
485 for (
unsigned i = 0; i < projectedVerticies.
size(); i++){
488 for (
int j = 0; j < nSplittingDims; j++){
489 vertex.
at( binningDimensions.at(j) ) = projectedVerticies.
at(i).
at(j);
496 for (
int j = 0; j < nSplittingDims; j++){
498 int thisDim = binningDimensions.at(j);
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; }
517 VERBOSE_LOG <<
"About to return my verticies" << std::endl;
536 std::vector<double> functionEstimateFom;
537 std::vector<double> functionEstimate;
538 std::vector<int> index;
543 VERBOSE_LOG <<
"Sorting points to speed my life up" << std::endl;
545 for (
unsigned i = 0; i < points.
size(); i++){
549 double estimate = valAtPoint + gradient.
dotProduct(points.
at(i) - point);
551 if ( estimate >= lowBoundary && estimate <= highBoundary ){
552 double fom1 = lowBoundary - estimate;
553 double fom2 = estimate - highBoundary;
555 if (fom1 > fom2) {fom = fom1;}
558 if (estimate < lowBoundary){
559 fom = lowBoundary - estimate;
561 if (estimate > highBoundary){
562 fom = estimate - highBoundary;
565 functionEstimate .push_back(estimate);
566 functionEstimateFom.push_back(fom );
571 TMath::Sort( (
int)points.
size(), &(functionEstimateFom.at(0)), &(index.at(0)) );
583 double uncertaintySum = 0.0;
584 int uncertainiesAdded = 0;
586 for (
unsigned i = 0; i < points.
size(); i++){
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;
593 if (uncertainiesAdded >= 2){
594 estimateUncert = uncertaintySum/double(uncertainiesAdded - 1.0);
599 if ( fom < -estimateUncert*5.0 ) {
606 std::complex<double> cEst(cos(estimate), sin(estimate));
607 std::complex<double> cValHere(cos(valHere) , sin(valHere ));
609 double diff = arg( cEst*conj(cValHere) );
611 uncertaintySum += fabs(diff);
626 ERROR_LOG <<
"This should be zero" << std::endl;
650 pointsToTest.addHyperPointSet(corners);
651 pointsToTest.addHyperPointSet(faces );
652 pointsToTest.addHyperPointSet(edges );
654 VERBOSE_LOG <<
"Got a big list of " << pointsToTest.size() <<
" to test " << std::endl;
669 std::complex<double> cValAtPoint (cos(valAtPoint) , sin(valAtPoint ));
670 std::complex<double> cValAtCenter(cos(valAtCenter) , sin(valAtCenter));
672 double dy = arg( cValAtCenter*conj(cValAtPoint) );
674 double binEdge = 0.0;
682 double scale = fabs( (binEdge - valAtCenter)/dy );
688 HyperPoint splitPoint = centerPoint + ( point - centerPoint )*scale;
689 return splitByCoord(volumeNumber, dimension, splitPoint );
703 VERBOSE_LOG <<
"Calling gradientSplit(" << volumeNumber <<
", " << dimension <<
")" << std::endl;
744 HyperPoint splitLimitsWidth = highPoint - lowPoint;
745 VERBOSE_LOG <<
"I have a nice set of split limits" << std::endl;
755 for (
int i = 0; i < nDims; i++){
756 gradientTrans.
at(i) *= (splitLimitsWidth.
at(i)*2.0);
761 double rateOfInc = gradientTrans.
norm2();
765 double scale = (closestBound - valCenter)/rateOfInc;
774 for (
int i = 0; i < nDims; i++){
775 splitVector.
at(i) *= (splitLimitsWidth.
at(i)*2.0);
782 double firstDeriv = 0.0;
788 double a = secondDeriv/2.0;
789 double b = firstDeriv;
790 double c = valCenter - closestBound;
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);
797 double quadraticSol = quadraticSol1;
798 if ( fabs(quadraticSol1) > fabs(quadraticSol2) ){
799 quadraticSol = quadraticSol2;
805 if (quadraticSol != quadraticSol){
810 HyperPoint refinedSplitVector = (splitVector * quadraticSol ) / splitVector.
norm();
814 HyperPoint splitPoint = splitVector + binCenter;
815 HyperPoint refinedSplitPoint = refinedSplitVector + binCenter;
819 HyperPoint refinedSplitPointExtended = refinedSplitVector*1.05 + binCenter;
826 bool crossCheck1 =
false;
827 bool crossCheck2 =
false;
828 bool crossCheck4 =
false;
830 if (crossCheck1 ==
true){
832 double predictedVal = valCenter + gradient.
dotProduct( splitPoint - binCenter );
833 std::cout << predictedVal <<
", " << closestBound << std::endl;
837 if (crossCheck2 ==
true){
839 double directionVal = splitVector.
dotProduct(refinedSplitPoint - binCenter);
841 if (directionVal < 0.0) directionVal = -1.0;
842 else directionVal = 1.0;
844 double predictedVal = 0.5*secondDeriv*(refinedSplitPoint - binCenter).norm2() + directionVal*firstDeriv*(refinedSplitPoint - binCenter).norm() + valCenter;
846 std::cout << predictedVal <<
", " << closestBound << std::endl;
850 if (crossCheck4 ==
true){
852 std::cout << gradient.
dotProduct( splitVector )/splitVector.
norm() <<
", " << firstDeriv << std::endl;
859 if (splitLimits.
inVolume(refinedSplitPointExtended) ==
false) {
864 double valNew =
_func->
getVal(refinedSplitPointExtended);
869 bool crossCheck3 =
false;
871 if (crossCheck3 ==
true){
874 double valRealRef =
_func->
getVal(refinedSplitPoint);
875 double valExtrap = closestBound;
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));
883 std::cout << valCenter <<
" -> (" << valReal <<
" ?= " << valExtrap <<
" ) -> " << diff / fabs(valCenter-valExtrap) << std::endl;
884 std::cout << diff <<
" -> " << diffRef << std::endl;
890 if ( binNew == binNumber ) {
896 return splitByCoord(volumeNumber, dimension, refinedSplitPointExtended );
902 VERBOSE_LOG <<
"Calling gradientSplit(" << volumeNumber <<
", " << dimension <<
")" << std::endl;
940 lowPoint .
at(dimension) += minBinWidth*0.5;
941 highPoint.
at(dimension) -= minBinWidth*0.5;
943 VERBOSE_LOG <<
"Walk width in split dim = " << highPoint.
at(dimension) - lowPoint.
at(dimension) << std::endl;
966 VERBOSE_LOG <<
"-- walker " << j <<
" fancies exploring this space" << std::endl;
968 walk( points.
at(j), walkLimits );
971 VERBOSE_LOG <<
" has fnc val = " << val << std::endl;
973 if ( fabs(val - valCenter) > 0.5 ) {
1027 GOODBYE_LOG <<
"Goodbye from the HyperBinningMakerPhaseBinning() Constructor" <<std::endl;
virtual int gradientSplit(int binNumber, int &dimension)
HyperPointSet getVertices() const
int getNumContinueBins(int dimension=-1) const
HyperPoint _minimumEdgeLength
HyperPoint getGrad(HyperPoint &point)
static bool s_printBinning
double dotProduct(const HyperPoint &other) const
int splitByCoord(int volumeNumber, int dimension, HyperPoint &coord)
void setWeight(int i, double w)
int getBinNumFromFunc(HyperPoint &point)
double getHighBinBoundary(int bin) const
bool isValidBinningDimension(int dimension)
virtual int gradientSplitAll()
HyperPointSet getEdgeCenters() const
int _numberOfSystematicSplits
double getHighBinBoundary(double phase)
HyperPointSet getSplitFaces(int volumeNumber)
virtual void makeBinning()
HyperPointSet getSplitEdges(int volumeNumber)
int systematicSplit(int volumeNumber, int dimension, double valAtCenter, HyperPoint gradient)
virtual void finishedIteration()
HyperPoint orderAndTestSplitPoints(HyperPointSet &points, HyperPoint &point, double valAtPoint, HyperPoint gradient)
const HyperPoint & at(int i) const
int _numberOfGradientSplits
HyperPoint getCenter() const
double closestBinBoundary(double val)
const HyperPoint & getHighCorner() const
void updateGlobalStatusFromDimSpecific(int volumeNumber)
void walkOrthogonal(HyperPoint &point, HyperCuboid &walkLimits)
HyperPoint getWidth() const
virtual double getVal(const HyperPoint &point) const =0
double getSecondDerivative(HyperPoint &point, HyperPoint &vector, double funcValAtPoint, double &deriv)
const double & at(int i) const
int splitDimFromGrad(int volumeNumber, HyperPoint gradient)
void setHyperFunction(HyperFunction *fnc)
Set the HyperFunction - only used by some binning Algs.
const HyperPoint & getLowCorner() const
unsigned int size() const
int & getGlobalVolumeStatus(int volumeNumber)
double getLowBinBoundary(int bin) const
void walk(HyperPoint &point, HyperCuboid &walkLimits)
int randomWalkSplit(int volumeNumber, int dimension)
void setBinEdges(std::vector< double > binEdges)
int & getDimensionSpecificVolumeStatus(int volumeNumber, int dimension)
double getWeight(int i=0) const
CyclicPhaseBins _binEdges
int getBinNumber(double phase) const
HyperPoint getGradPos(HyperPoint &point, double funcValAtPoint)
std::vector< HyperCuboid > _hyperCuboids
HyperPointSet getSplitCorners(int volumeNumber)
std::vector< int > _binningDimensions
~HyperBinningMakerPhaseBinning()
void setNumBinPairs(int binpairs)
double getLowBinBoundary(double phase)
HyperBinningMakerPhaseBinning(const HyperCuboid &binningRange, HyperFunction *func)
HyperCuboid project(std::vector< int > dims) const
int getBinNumFromFuncVal(double phase)
int split(int volumeNumber, int dimension, double splitPoint)
void push_back(const HyperPoint &point)
bool inVolume(const HyperPoint &coords) const