Math
Nonlinear solver
-
template<class F, class T = double>
class Solve A class that solves a provided function for a zero.
The first template argument, F, is the type of the function. Typically you would simple function object that defines the operator() method and use that for F.
The second template argument (optional: default = double) is the type of the arguments to the function.
The solving process is in two parts:
First the solution needs to be bracketed.
This can be done in several ways:
a) If you know the appropriate range, you can set it in the constructor:
Solve<MyFunc> solver(func, x_min, x_max);
b) If you don’t know the range, you can set an initial guess range and let Solve expand the range until it finds a range that brackets the solution:
Solve<MyFunc> solver(func, x_min, x_max); solver.bracket()
c) If you know one end of the range, but not the other you can expand only one side of the range from the initial guess:
Solve<MyFunc> solver(func, 0, r_max); solver.bracketUpper()
(There is also a corresponding bracketLower() method.)
d) Sometimes there is a fundamental limit past which you want to make sure that the range doesn’t go. e.g. For values that must be positive, you might want to make sure the range doesn’t extend past 0.
For this case, there are the following two functions
solver.bracketUpperWithLimit(upper_limit) solver.bracketLowerWithLimit(lower_limit)
Finally, note that there is nothing in the code that enforces x_min < x_max. If the two limits bracket the code in reverse order, that’s ok.
The next step is to solve for the root within this range. There are currently two algorithms for doing that: Bisect and Brent. You can tell Solve which one to use with:
solver.setMethod(Bisect) solver.setMethod(Brent)
(In fact, the former is unnecessary, since Bisect is the default.)
Then the method root() will solve for the root in that range.
Typical usage:
struct MyFunc { double operator()(double x) { return [...] } }; MyFunc func; Solve<MyFunc> solver(func, xmin, xmax); solver.bracket(); // If necessary solver.setMethod(Brent); // If desired double result = solver.root()
Public Functions
-
inline Solve(const F &func_, T lb_, T ub_)
Constructor taking the function to solve, and the range (if known).
-
inline void setMaxSteps(int m)
Set the maximum number of steps for the solving algorithm to use.
-
inline void setMethod(Method m_)
Set which method to use: Bisect or Brent.
-
inline void setXTolerance(T tol)
Set the tolerance to define when the root is close enough to 0. (abs(x) < tol)
-
inline void evaluateBounds() const
Make sure the current bounds have corresponding flower, fupper.
-
inline void bracket()
Hunt for bracket, geometrically expanding range.
This version assumes that the root is to the side of the end point that is closer to 0. This will be true if the function is monotonic.
-
inline void bracketUpper()
Hunt for bracket, geometrically expanding range.
This one only expands to the right for when you know that the lower bound is definitely to the left of the root, but the upper bound might not bracket it.
-
inline void bracketLower()
Hunt for bracket, geometrically expanding range.
The opposite of bracketUpper — only expand to the left.
-
inline void bracketUpperWithLimit(T upper_limit)
Hunt for upper bracket, with an upper limit to how far it can go.
Other mathematical functions
-
void galsim::math::sincos(double theta, double &sint, double &cost)
-
double galsim::math::gamma_p(double a, double x)
-
double galsim::math::sinc(double x)
-
double galsim::math::Si(double x)
-
double galsim::math::Ci(double x)
Horner’s method for polynomial evaluation
-
void galsim::math::Horner(const double *x, const int nx, const double *coef, const int nc, double *result)
-
void galsim::math::Horner2D(const double *x, const double *y, const int nx, const double *coef, const int ncx, const int ncy, double *result, double *temp)
C++ Integration Functions
-
template<class T>
struct IntRegion A type that encapsulates everything known about the integral in a region.
The constructor of IntRegion takes the minimum and maximum values for the region, along with an optional ostream for outputing diagnostic information.
After the integration is done, the IntRegion will also hold the estimate of the integral’s value over the region, along with an estimate of the error.
Public Functions
-
inline IntRegion(const T a, const T b, std::ostream *dbgout_ = 0, std::map<T, T> *fxmap_ = 0)
Constructor taking the bounds of the region and (optionally) an ostream for outputing diagnostic information.
Note that normally a < b. However, a > b is also valid. If a > b, then the integral will be from right to left, which is just the negative of the integral from b to a.
- Parameters:
a – The left end of the region
b – The right end of the region
dbgout_ – An optional ostream for diagnostic info
fxmap_ – Known results
-
inline void subDivide(std::vector<IntRegion<T>> &children)
Subdivide a region according to the current split points or biset.
If there are no split points set yet, then this will bisect the region. However, you may also set split points using addSplit(x). This is worth doing if you know about any discontinuities, zeros or poles in the function you are integrating.
-
inline void bisect()
Set a split point at the bisection.
-
inline void findZeroCrossings()
Search for zero crossings based on values stored in fxmap.
-
inline void addSplit(const T x)
Add a split point to the current list to be used by the next subDivide call.
This is worth doing if you know about any discontinuities, zeros or poles in the function you are integrating.
-
inline size_t getNSplit() const
Get the number of split points currently set.
-
inline void useFXMap()
Setup an fxmap for this region.
-
inline IntRegion(const T a, const T b, std::ostream *dbgout_ = 0, std::map<T, T> *fxmap_ = 0)
-
template<class UF>
inline double galsim::integ::int1d(const UF &func, double min, double max, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 1-dimensional integral using simple min/max values for the region.
- Parameters:
func – The function to be integrated (may be a function object)
min – The lower bound of the integration
max – The upper bound of the integration
relerr – The target relative error
abserr – The target absolute error
-
template<class UF>
inline double galsim::integ::int1d(const UF &func, IntRegion<double> ®, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 1-dimensional integral using an IntRegion.
- Parameters:
func – The function to be integrated(may be a function object)
reg – The region of the integration
relerr – The target relative error
abserr – The target absolute error
-
template<class BF>
inline double galsim::integ::int2d(const BF &func, double xmin, double xmax, double ymin, double ymax, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 2-dimensional integral using simple min/max values for borh regions (i.e. the integral is over a square)
-
template<class BF, class YREG>
inline double galsim::integ::int2d(const BF &func, IntRegion<double> ®, const YREG &yreg, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 2-dimensional integral.
- Parameters:
func – The function to be integrated (may be a function object)
reg – The region of the inner integral
yreg – yreg(x) is the region of the outer integral at x
relerr – The target relative error
abserr – The target absolute error
-
template<class BF>
inline double galsim::integ::int2d(const BF &func, IntRegion<double> ®, IntRegion<double> &yreg, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 3-dimensional integral using constant IntRegions for both regions (i.e. the integral is over a square)
-
template<class TF>
inline double galsim::integ::int3d(const TF &func, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 3-dimensional integral using simple min/max values for all regions (i.e. the integral is over a cube)
-
template<class TF, class YREG, class ZREG>
inline double galsim::integ::int3d(const TF &func, IntRegion<double> ®, const YREG &yreg, const ZREG &zreg, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 3-dimensional integral.
- Parameters:
func – The function to be integrated (may be a function object)
reg – The region of the inner integral
yreg – yreg(x) is the region of the middle integral at x
zreg – zreg(x)(y) is the region of the outer integral at x,y
relerr – The target relative error
abserr – The target absolute error
-
template<class TF>
inline double galsim::integ::int3d(const TF &func, IntRegion<double> ®, IntRegion<double> &yreg, IntRegion<double> &zreg, const double relerr = DEFRELERR, const double abserr = DEFABSERR) Perform a 3-dimensional integral using constant IntRegions for all regions (i.e. the integral is over a cube)
-
double galsim::math::hankel_trunc(const std::function<double(double)> f, double k, double nu, double maxr, double relerr = 1.e-6, double abserr = 1.e-12, int nzeros = 10)
-
double galsim::math::hankel_inf(const std::function<double(double)> f, double k, double nu, double relerr = 1.e-6, double abserr = 1.e-12, int nzeros = 10)
Misc Utilities
-
int galsim::SetOMPThreads(int num_threads)
-
int galsim::GetOMPThreads()