25#ifndef LSST_AFW_MATH_FUNCTIONLIBRARY_H
26#define LSST_AFW_MATH_FUNCTIONLIBRARY_H
50template <
typename ReturnT>
68 ReturnT
operator()(
double x)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
69 return static_cast<ReturnT
>(
x == _xo);
74 os <<
"IntegerDeltaFunction1 [" << _xo <<
"]: ";
75 os << Function1<ReturnT>::toString(
prefix);
96template <
typename ReturnT>
114 ReturnT
operator()(
double x,
double y)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
115 return static_cast<ReturnT
>((
x == _xo) && (
y == _yo));
120 os <<
"IntegerDeltaFunction2 [" << _xo <<
", " << _yo <<
"]: ";
121 os << Function2<ReturnT>::toString(
prefix);
144template <
typename ReturnT>
164 ReturnT
operator()(
double x)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
165 return static_cast<ReturnT
>((_multFac / this->
_params[0]) *
171 os <<
"GaussianFunction1 [" << _multFac <<
"]: ";
172 os << Function1<ReturnT>::toString(
prefix);
177 const double _multFac;
198template <
typename ReturnT>
225 ReturnT
operator()(
double x,
double y)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
226 if (_angle != this->
_params[2]) {
229 double pos1 = (_cosAngle *
x) + (_sinAngle *
y);
230 double pos2 = (-_sinAngle *
x) + (_cosAngle *
y);
231 return static_cast<ReturnT
>((_multFac / (this->
_params[0] * this->
_params[1])) *
233 ((pos2 * pos2) / (2.0 * this->_params[1] * this->_params[1]))));
238 os <<
"GaussianFunction2: ";
239 os << Function2<ReturnT>::toString(
prefix);
268 void _updateCache() const noexcept {
273 const double _multFac;
274 mutable double _angle;
275 mutable double _sinAngle;
276 mutable double _cosAngle;
282 _multFac(1.0 / (
lsst::
geom::TWOPI)),
302template <
typename ReturnT>
329 ReturnT
operator()(
double x,
double y)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
330 double radSq = (
x *
x) + (
y *
y);
332 double sigma2Sq = this->_params[1] * this->_params[1];
333 double b = this->_params[2];
334 return static_cast<ReturnT
>(
335 (_multFac / (sigma1Sq + (
b * sigma2Sq))) *
336 (
std::exp(-radSq / (2.0 * sigma1Sq)) + (
b *
std::exp(-radSq / (2.0 * sigma2Sq)))));
341 os <<
"DoubleGaussianFunction2 [" << _multFac <<
"]: ";
342 os << Function2<ReturnT>::toString(
prefix);
354 const double _multFac;
368template <
typename ReturnT>
388 if (params.
size() < 1) {
390 "PolynomialFunction1 called with empty vector");
406 ReturnT
operator()(
double x)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
409 for (
int ii =
order - 1; ii >= 0; --ii) {
410 retVal = (retVal *
x) + this->
_params[ii];
412 return static_cast<ReturnT
>(retVal);
422 os <<
"PolynomialFunction1 []: ";
423 os << Function1<ReturnT>::toString(
prefix);
446template <
typename ReturnT>
484 ReturnT
operator()(
double x,
double y)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
499 const int maxXCoeffInd = this->
_order;
504 int paramInd =
static_cast<int>(this->
_params.
size()) - 1;
508 for (
int xCoeffInd = 0; xCoeffInd <= maxXCoeffInd; ++xCoeffInd, --paramInd) {
509 _xCoeffs[xCoeffInd] = this->
_params[paramInd];
513 for (
int xCoeffInd = 0, endXCoeffInd = maxXCoeffInd; paramInd >= 0; --paramInd) {
514 _xCoeffs[xCoeffInd] = (_xCoeffs[xCoeffInd] *
y) + this->
_params[paramInd];
516 if (xCoeffInd >= endXCoeffInd) {
527 double retVal = _xCoeffs[maxXCoeffInd];
528 for (
int xCoeffInd = maxXCoeffInd - 1; xCoeffInd >= 0; --xCoeffInd) {
529 retVal = (retVal *
x) + _xCoeffs[xCoeffInd];
531 return static_cast<ReturnT
>(retVal);
542 os <<
"PolynomialFunction2 [" << this->
_order <<
"]: ";
543 os << Function2<ReturnT>::toString(
prefix);
555 mutable double _oldY;
579template <
typename ReturnT>
591 _initialize(minX, maxX);
605 if (params.
size() < 1) {
607 "Chebyshev1Function1 called with empty vector");
609 _initialize(minX, maxX);
625 double getMinX() const noexcept {
return _minX; };
630 double getMaxX() const noexcept {
return _maxX; };
640 double xPrime = (
x + _offset) * _scale;
644 int const order = _order;
647 }
else if (order == 1) {
652 for (
int i =
order - 2; i > 0; --i) {
653 double cshNext = (2 * xPrime * csh) + this->
_params[i] - cshPrev;
657 return (xPrime * csh) + this->
_params[0] - cshPrev;
662 os <<
"Chebyshev1Function1 [" << _minX <<
", " << _maxX <<
"]: ";
663 os << Function1<ReturnT>::toString(
prefix);
677 void _initialize(
double minX,
double maxX) {
680 _scale = 2.0 / (_maxX - _minX);
681 _offset = -(_minX + _maxX) * 0.5;
688 :
Function1<ReturnT>(1), _minX(0.0), _maxX(0.0), _scale(1.0), _offset(0.0), _order(0) {}
716template <
typename ReturnT>
730 _yCheby(this->
_order + 1),
731 _xCoeffs(this->
_order + 1) {
732 _initialize(xyRange);
749 _yCheby(this->
_order + 1),
750 _xCoeffs(this->
_order + 1) {
751 _initialize(xyRange);
779 if (truncOrder > this->
_order) {
781 os <<
"truncated order=" << truncOrder <<
" must be <= original order=" << this->
_order;
803 double const xPrime = (
x + _offsetX) * _scaleX;
804 double const yPrime = (
y + _offsetY) * _scaleY;
806 const int nParams =
static_cast<int>(this->
_params.
size());
807 const int order = this->
_order;
817 for (
int chebyInd = 2; chebyInd <=
order; chebyInd++) {
818 _yCheby[chebyInd] = (2 * yPrime * _yCheby[chebyInd - 1]) - _yCheby[chebyInd - 2];
821 for (
int coeffInd = 0; coeffInd <=
order; coeffInd++) {
822 _xCoeffs[coeffInd] = 0;
824 for (
int coeffInd = 0, endCoeffInd = 0, paramInd = 0; paramInd < nParams; paramInd++) {
825 _xCoeffs[coeffInd] += this->
_params[paramInd] * _yCheby[endCoeffInd];
829 coeffInd = endCoeffInd;
841 return _xCoeffs[0] + (_xCoeffs[1] * xPrime);
843 double cshPrev = _xCoeffs[
order];
844 double csh = (2 * xPrime * _xCoeffs[
order]) + _xCoeffs[
order - 1];
845 for (
int i =
order - 2; i > 0; --i) {
846 double cshNext = (2 * xPrime * csh) + _xCoeffs[i] - cshPrev;
850 return (xPrime * csh) + _xCoeffs[0] - cshPrev;
855 os <<
"Chebyshev1Function2 [";
857 os << Function2<ReturnT>::toString(
prefix);
869 mutable double _oldYPrime;
889 _scaleX = 2.0 / (_maxX - _minX);
890 _scaleY = 2.0 / (_maxY - _minY);
891 _offsetX = -(_minX + _maxX) * 0.5;
892 _offsetY = -(_minY + _maxY) * 0.5;
924template <
typename ReturnT>
931 double xOffset = 0.0)
932 :
Function1<ReturnT>(1), _invN(1.0 / static_cast<double>(n)) {
946 ReturnT
operator()(
double x)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
948 double xArg2 = xArg1 * _invN;
950 return static_cast<ReturnT
>(
std::sin(xArg1) *
std::sin(xArg2) / (xArg1 * xArg2));
952 return static_cast<ReturnT
>(1);
959 unsigned int getOrder() const noexcept {
return static_cast<unsigned int>(0.5 + (1.0 / _invN)); };
963 os <<
"LanczosFunction1 [" << this->
getOrder() <<
"]: ";
965 os << Function1<ReturnT>::toString(
prefix);
989template <
typename ReturnT>
996 double xOffset = 0.0,
997 double yOffset = 0.0)
998 :
Function2<ReturnT>(2), _invN(1.0 / static_cast<double>(n)) {
1014 ReturnT
operator()(
double x,
double y)
const noexcept(IS_NOTHROW_INIT<ReturnT>)
override {
1016 double xArg2 = xArg1 * _invN;
1022 double yArg2 = yArg1 * _invN;
1027 return static_cast<ReturnT
>(xFunc * yFunc);
1033 unsigned int getOrder() const noexcept {
return static_cast<unsigned int>(0.5 + (1.0 / _invN)); };
1037 os <<
"LanczosFunction2 [" << this->
getOrder() <<
"]: ";
1039 os << Function2<ReturnT>::toString(
prefix);
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
table::Key< double > angle
table::Key< double > ampl2
table::Key< double > sigma2
table::Key< double > sigma1
afw::table::Key< double > sigma
Base class for 2-dimensional polynomials of the form:
int _order
order of polynomial
static int nParametersFromOrder(int order)
Compute number of parameters from polynomial order.
1-dimensional weighted sum of Chebyshev polynomials of the first kind.
double getMinX() const noexcept
Get minimum allowed x.
Chebyshev1Function1(std::vector< double > params, double minX=-1, double maxX=1)
Construct a Chebyshev polynomial with specified parameters and range.
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
unsigned int getOrder() const noexcept
Get the polynomial order.
bool isLinearCombination() const noexcept override
Is the function a linear combination of its parameters?
Chebyshev1Function1(Chebyshev1Function1 const &)=default
Chebyshev1Function1(Chebyshev1Function1 &&)=default
Chebyshev1Function1 & operator=(Chebyshev1Function1 &&)=default
ReturnT operator()(double x) const override
Chebyshev1Function1(unsigned int order, double minX=-1, double maxX=1)
Construct a Chebyshev polynomial of specified order and range.
double getMaxX() const noexcept
Get maximum allowed x.
~Chebyshev1Function1() noexcept override=default
Chebyshev1Function1 & operator=(Chebyshev1Function1 const &)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
2-dimensional weighted sum of Chebyshev polynomials of the first kind.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
ReturnT operator()(double x, double y) const override
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
Chebyshev1Function2(unsigned int order, lsst::geom::Box2D const &xyRange=lsst::geom::Box2D(lsst::geom::Point2D(-1.0, -1.0), lsst::geom::Point2D(1.0, 1.0)))
Construct a Chebyshev polynomial of specified order and range.
Chebyshev1Function2(Chebyshev1Function2 const &)=default
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
~Chebyshev1Function2() noexcept override=default
lsst::geom::Box2D getXYRange() const noexcept
Get x,y range.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
virtual Chebyshev1Function2 truncate(int truncOrder) const
Return a truncated copy of lower (or equal) order.
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Chebyshev1Function2(Chebyshev1Function2 &&)=default
Chebyshev1Function2 & operator=(Chebyshev1Function2 const &)=default
Chebyshev1Function2 & operator=(Chebyshev1Function2 &&)=default
Chebyshev1Function2(std::vector< double > params, lsst::geom::Box2D const &xyRange=lsst::geom::Box2D(lsst::geom::Point2D(-1.0, -1.0), lsst::geom::Point2D(1.0, 1.0)))
Construct a Chebyshev polynomial with specified parameters and range.
double Guassian (sum of two Gaussians)
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
~DoubleGaussianFunction2() noexcept override=default
DoubleGaussianFunction2 & operator=(DoubleGaussianFunction2 const &)=default
DoubleGaussianFunction2(double sigma1, double sigma2=0, double ampl2=0)
Construct a Gaussian function with specified x and y sigma.
DoubleGaussianFunction2(DoubleGaussianFunction2 &&)=default
DoubleGaussianFunction2(DoubleGaussianFunction2 const &)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
DoubleGaussianFunction2()
DoubleGaussianFunction2 & operator=(DoubleGaussianFunction2 &&)=default
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
A Function taking one argument.
A Function taking two arguments.
std::vector< double > _params
unsigned int getNParameters() const noexcept
Return the number of function parameters.
~GaussianFunction1() noexcept override=default
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
GaussianFunction1 & operator=(GaussianFunction1 &&)=default
GaussianFunction1(GaussianFunction1 &&)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
GaussianFunction1(GaussianFunction1 const &)=default
GaussianFunction1 & operator=(GaussianFunction1 const &)=default
GaussianFunction1(double sigma)
Construct a Gaussian function with specified sigma.
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
GaussianFunction2(double sigma1, double sigma2, double angle=0.0)
Construct a 2-dimensional Gaussian function.
GaussianFunction2(GaussianFunction2 &&)=default
GaussianFunction2(GaussianFunction2 const &)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
~GaussianFunction2() noexcept override=default
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
GaussianFunction2 & operator=(GaussianFunction2 &&)=default
GaussianFunction2 & operator=(GaussianFunction2 const &)=default
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
1-dimensional integer delta function.
~IntegerDeltaFunction1() noexcept override=default
IntegerDeltaFunction1(IntegerDeltaFunction1 const &)=default
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
IntegerDeltaFunction1(double xo)
Construct an integer delta function with specified xo.
IntegerDeltaFunction1 & operator=(IntegerDeltaFunction1 &&)=default
IntegerDeltaFunction1(IntegerDeltaFunction1 &&)=default
std::string toString(std::string const &prefix="") const override
Return a string representation of the function.
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
IntegerDeltaFunction1 & operator=(IntegerDeltaFunction1 const &)=default
2-dimensional integer delta function.
IntegerDeltaFunction2 & operator=(IntegerDeltaFunction2 &&)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
IntegerDeltaFunction2(IntegerDeltaFunction2 const &)=default
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
IntegerDeltaFunction2 & operator=(IntegerDeltaFunction2 const &)=default
~IntegerDeltaFunction2() noexcept override=default
IntegerDeltaFunction2(double xo, double yo)
Construct an integer delta function with specified xo, yo.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
IntegerDeltaFunction2(IntegerDeltaFunction2 &&)=default
1-dimensional Lanczos function
LanczosFunction1(unsigned int n, double xOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
LanczosFunction1 & operator=(LanczosFunction1 &&)=default
~LanczosFunction1() noexcept override=default
LanczosFunction1 & operator=(LanczosFunction1 const &)=default
LanczosFunction1(LanczosFunction1 &&)=default
LanczosFunction1(LanczosFunction1 const &)=default
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
unsigned int getOrder() const noexcept
Get the order of the Lanczos function.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
2-dimensional separable Lanczos function
~LanczosFunction2() noexcept override=default
LanczosFunction2(LanczosFunction2 &&)=default
LanczosFunction2(LanczosFunction2 const &)=default
LanczosFunction2(unsigned int n, double xOffset=0.0, double yOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
LanczosFunction2 & operator=(LanczosFunction2 const &)=default
unsigned int getOrder() const noexcept
Get the order of Lanczos function.
LanczosFunction2 & operator=(LanczosFunction2 &&)=default
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
1-dimensional polynomial function.
unsigned int getOrder() const noexcept
Get the polynomial order.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
bool isLinearCombination() const noexcept override
Is the function a linear combination of its parameters?
PolynomialFunction1 & operator=(PolynomialFunction1 &&)=default
PolynomialFunction1(std::vector< double > params)
Construct a polynomial function with the specified parameters.
PolynomialFunction1 & operator=(PolynomialFunction1 const &)=default
PolynomialFunction1(PolynomialFunction1 &&)=default
PolynomialFunction1(unsigned int order)
Construct a polynomial function of the specified order.
PolynomialFunction1(PolynomialFunction1 const &)=default
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
~PolynomialFunction1() noexcept override=default
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
2-dimensional polynomial function with cross terms
PolynomialFunction2(std::vector< double > params)
Construct a polynomial function with specified parameters.
PolynomialFunction2 & operator=(PolynomialFunction2 const &)=default
PolynomialFunction2 & operator=(PolynomialFunction2 &&)=default
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
PolynomialFunction2(unsigned int order)
Construct a polynomial function of specified order.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
PolynomialFunction2(PolynomialFunction2 const &)=default
~PolynomialFunction2() noexcept override=default
std::vector< double > getDFuncDParameters(double x, double y) const override
Return the coefficients of the Function's parameters, evaluated at (x, y) I.e.
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
PolynomialFunction2(PolynomialFunction2 &&)=default
void write(afw::table::io::OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
An object passed to Persistable::write to allow it to persist itself.
A floating-point coordinate rectangle geometry.
double getMaxY() const noexcept
double getMaxX() const noexcept
double getMinY() const noexcept
double getMinX() const noexcept
Reports invalid arguments.
double constexpr PI
The ratio of a circle's circumference to diameter.