Belle II Software development
SinEqLine.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <tracking/trackingUtilities/numerics/Modulo.h>
11
12#include <tracking/trackingUtilities/geometry/Line2D.h>
13
14#include <tracking/trackingUtilities/numerics/EIncDec.h>
15
16#include <Math/Vector2D.h>
17
18#include <cmath>
19
20namespace Belle2 {
25
26 namespace TrackingUtilities {
27
37 class SinEqLine {
38
39 public:
42 m_slope(0.0),
43 m_intercept(0.0)
44 {}
45
46
48 explicit SinEqLine(const Line2D& line2D) :
49 m_slope(line2D.slope()),
50 m_intercept(line2D.intercept())
51 {}
52
54 SinEqLine(const double slope, const double intercept) :
55 m_slope(slope),
56 m_intercept(intercept)
57 {}
58
59
61 double map(const double x) const
62 { return sin(x) - getSlope() * x - getIntercept(); }
63
65 double gradient(const double x) const
66 { return cos(x) - getSlope(); }
67
69 static int getIHalfPeriod(const double x)
70 { return floor(x / M_PI); }
71
72 /* Computes the positive solution that has the smallest value of x.
73 The additional parameter serves as a criterion to abort the search if the solutions is further away than the specified half period.
74 */
75 double computeSmallestPositiveRoot(int maxIHalfPeriod = 5) const;
76
77
79 double computeRootLargerThanExtemumInHalfPeriod(int iHalfPeriod) const;
80
82 double computeRootForLargeSlope() const;
83
85 double computeRootInInterval(double lowerX, double upperX) const;
86
87 private:
89 double newtonX(const ROOT::Math::XYVector& pos) const;
90
92 static double secantX(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper);
93
95 static double middleX(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper);
96
98 static bool updateBounds(ROOT::Math::XYVector& lower, ROOT::Math::XYVector& upper, const ROOT::Math::XYVector& next);
99
101 static bool isBetween(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& next, const ROOT::Math::XYVector& upper)
102 { return lower.x() < next.x() and next.x() < upper.x(); }
103
105 static bool isConverged(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper)
106 {
107 return fabs(lower.y()) < 10e-7 or fabs(upper.y()) < 10e-7;
108 }
109
111 static double getConvergedBound(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper)
112 {
113 if (not std::isfinite(lower.y()) or not std::isfinite(upper.y())) {
114 return NAN;
115 }
116
117 if (fabs(lower.y()) <= fabs(upper.y())) {
118 return lower.x();
119 }
120
121 if (fabs(lower.y()) > fabs(upper.y())) {
122 return upper.x();
123 }
124
125 return NAN;
126 }
127
128 public:
130 static bool changesSign(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper)
131 { return (lower.y() > 0 and upper.y() < 0) or (lower.y() < 0 and upper.y() > 0); }
132
134 static EIncDec getEIncDec(const ROOT::Math::XYVector& lower, const ROOT::Math::XYVector& upper)
135 {
136 if (lower.y() < upper.y()) {
137 return EIncDec::c_Increasing;
138 } else if (lower.y() > upper.y()) {
139 return EIncDec::c_Decreasing;
140 } else if (lower.y() == upper.y()) {
141 return EIncDec::c_Constant;
142 } else {
143 return EIncDec::c_Invalid;
144 }
145 }
146
147 public:
149 double computeExtremumXInHalfPeriod(int iHalfPeriod) const;
150
152 static int getIPeriodFromIHalfPeriod(int iHalfPeriod)
153 { return isEven(iHalfPeriod) ? iHalfPeriod / 2 : (iHalfPeriod - 1) / 2; }
154
155 public:
157 bool hasLargeSlope() const
158 { return fabs(getSlope()) >= 1; }
159
161 double getSlope() const
162 { return m_slope; }
163
165 double getIntercept() const
166 { return m_intercept; }
167
168 private:
170 double m_slope;
171
174
175
176 };
177
178 }
180}
181
A two dimensional normal line.
Definition Line2D.h:39
double getIntercept() const
Getter for the intercept.
Definition SinEqLine.h:165
static double getConvergedBound(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Returns the better solution x from the bounds of the interval.
Definition SinEqLine.h:111
static bool updateBounds(ROOT::Math::XYVector &lower, ROOT::Math::XYVector &upper, const ROOT::Math::XYVector &next)
Replaces the lower or upper bound inplace if the next candidate position is valid and within the inte...
Definition SinEqLine.cc:149
static double secantX(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Fall back shrinking method to the secant algorithm.
Definition SinEqLine.cc:139
static double middleX(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Simple fall back shrinking method using trivial division of the interval.
Definition SinEqLine.cc:134
double computeExtremumXInHalfPeriod(int iHalfPeriod) const
Get the local extremum that is located in the half period indicated by the given index.
Definition SinEqLine.cc:185
double m_intercept
Memory for the intercept.
Definition SinEqLine.h:173
SinEqLine(const double slope, const double intercept)
Constructor taking the slope and intercept of the line that shall be superimposed with the sin curve.
Definition SinEqLine.h:54
bool hasLargeSlope() const
Indicates that the slope is so large such that the function has no local extrema.
Definition SinEqLine.h:157
static int getIHalfPeriod(const double x)
Returns the half period index in which the x position is located.
Definition SinEqLine.h:69
double computeRootInInterval(double lowerX, double upperX) const
Computes the solution in between the given x values. The x values are generally chosen consecutive lo...
Definition SinEqLine.cc:67
static EIncDec getEIncDec(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Determines if the function is increasing or decreasing in the interval.
Definition SinEqLine.h:134
double getSlope() const
Getter for the slope.
Definition SinEqLine.h:161
double computeSmallestPositiveRoot(int maxIHalfPeriod=5) const
Definition SinEqLine.cc:17
double computeRootForLargeSlope() const
Compute single solution in the case that fabs(slope) >= 1.
Definition SinEqLine.cc:50
static bool changesSign(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Checks if the function changes sign in the interval.
Definition SinEqLine.h:130
double computeRootLargerThanExtemumInHalfPeriod(int iHalfPeriod) const
Computes the solution that is addressed by the given half period index.
Definition SinEqLine.cc:38
static bool isBetween(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &next, const ROOT::Math::XYVector &upper)
Check is next position is within the interval given by lower and upper.
Definition SinEqLine.h:101
double m_slope
Memory for the slope.
Definition SinEqLine.h:170
SinEqLine()
Default constructor initializing slope and intercept to zero.
Definition SinEqLine.h:41
static int getIPeriodFromIHalfPeriod(int iHalfPeriod)
Helper function to translate the index of the half period to index of the containing period.
Definition SinEqLine.h:152
double gradient(const double x) const
Interpreting as the function f this method calculates the gradient as need in Newtons algorithms.
Definition SinEqLine.h:65
double map(const double x) const
Interpreting as the function f this method carries out the translation from x to y coordinates.
Definition SinEqLine.h:61
double newtonX(const ROOT::Math::XYVector &pos) const
Shrinking method of the newton algorithm return the next candidate root.
Definition SinEqLine.cc:144
SinEqLine(const Line2D &line2D)
Constructor taking the line that shall be superimposed with the sin curve.
Definition SinEqLine.h:48
static bool isConverged(const ROOT::Math::XYVector &lower, const ROOT::Math::XYVector &upper)
Check if the interval has shrunk close enough to the solution.
Definition SinEqLine.h:105
Abstract base class for different kinds of events.