25 #ifndef LSST_AFW_MATH_FUNCTIONLIBRARY_H 
   26 #define LSST_AFW_MATH_FUNCTIONLIBRARY_H 
   51 template <
typename ReturnT>
 
   69     ReturnT 
operator()(
double x) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
   70         return static_cast<ReturnT
>(
x == _xo);
 
   75         os << 
"IntegerDeltaFunction1 [" << _xo << 
"]: ";
 
   76         os << Function1<ReturnT>::toString(
prefix);
 
   98 template <
typename ReturnT>
 
  116     ReturnT 
operator()(
double x, 
double y) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  117         return static_cast<ReturnT
>((
x == _xo) && (
y == _yo));
 
  122         os << 
"IntegerDeltaFunction2 [" << _xo << 
", " << _yo << 
"]: ";
 
  123         os << Function2<ReturnT>::toString(
prefix);
 
  146 template <
typename ReturnT>
 
  166     ReturnT 
operator()(
double x) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  167         return static_cast<ReturnT
>((_multFac / this->
_params[0]) *
 
  173         os << 
"GaussianFunction1 [" << _multFac << 
"]: ";
 
  174         os << Function1<ReturnT>::toString(
prefix);
 
  179     const double _multFac;  
 
  200 template <
typename ReturnT>
 
  227     ReturnT 
operator()(
double x, 
double y) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  228         if (_angle != this->
_params[2]) {
 
  231         double pos1 = (_cosAngle * 
x) + (_sinAngle * 
y);
 
  232         double pos2 = (-_sinAngle * 
x) + (_cosAngle * 
y);
 
  233         return static_cast<ReturnT
>((_multFac / (this->
_params[0] * this->
_params[1])) *
 
  235                                              ((pos2 * pos2) / (2.0 * this->_params[1] * this->_params[1]))));
 
  240         os << 
"GaussianFunction2: ";
 
  241         os << Function2<ReturnT>::toString(
prefix);
 
  270     void _updateCache() const noexcept {
 
  275     const double _multFac;     
 
  276     mutable double _angle;     
 
  277     mutable double _sinAngle;  
 
  278     mutable double _cosAngle;  
 
  304 template <
typename ReturnT>
 
  331     ReturnT 
operator()(
double x, 
double y) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  332         double radSq = (
x * 
x) + (
y * 
y);
 
  334         double sigma2Sq = this->_params[1] * this->_params[1];
 
  335         double b = this->_params[2];
 
  336         return static_cast<ReturnT
>(
 
  337                 (_multFac / (sigma1Sq + (
b * sigma2Sq))) *
 
  338                 (
std::exp(-radSq / (2.0 * sigma1Sq)) + (
b * 
std::exp(-radSq / (2.0 * sigma2Sq)))));
 
  343         os << 
"DoubleGaussianFunction2 [" << _multFac << 
"]: ";
 
  344         os << Function2<ReturnT>::toString(
prefix);
 
  356     const double _multFac;  
 
  370 template <
typename ReturnT>
 
  390         if (params.
size() < 1) {
 
  392                               "PolynomialFunction1 called with empty vector");
 
  408     ReturnT 
operator()(
double x) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  411         for (
int ii = 
order - 1; ii >= 0; --ii) {
 
  412             retVal = (retVal * 
x) + this->
_params[ii];
 
  414         return static_cast<ReturnT
>(retVal);
 
  424         os << 
"PolynomialFunction1 []: ";
 
  425         os << Function1<ReturnT>::toString(
prefix);
 
  448 template <
typename ReturnT>
 
  486     ReturnT 
operator()(
double x, 
double y) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  501         const int maxXCoeffInd = this->
_order;
 
  506             int paramInd = 
static_cast<int>(this->
_params.
size()) - 1;
 
  510             for (
int xCoeffInd = 0; xCoeffInd <= maxXCoeffInd; ++xCoeffInd, --paramInd) {
 
  511                 _xCoeffs[xCoeffInd] = this->
_params[paramInd];
 
  515             for (
int xCoeffInd = 0, endXCoeffInd = maxXCoeffInd; paramInd >= 0; --paramInd) {
 
  516                 _xCoeffs[xCoeffInd] = (_xCoeffs[xCoeffInd] * 
y) + this->
_params[paramInd];
 
  518                 if (xCoeffInd >= endXCoeffInd) {
 
  529         double retVal = _xCoeffs[maxXCoeffInd];
 
  530         for (
int xCoeffInd = maxXCoeffInd - 1; xCoeffInd >= 0; --xCoeffInd) {
 
  531             retVal = (retVal * 
x) + _xCoeffs[xCoeffInd];
 
  533         return static_cast<ReturnT
>(retVal);
 
  544         os << 
"PolynomialFunction2 [" << this->
_order << 
"]: ";
 
  545         os << Function2<ReturnT>::toString(
prefix);
 
  557     mutable double _oldY;                  
 
  581 template <
typename ReturnT>
 
  593         _initialize(minX, maxX);
 
  607         if (params.
size() < 1) {
 
  609                               "Chebyshev1Function1 called with empty vector");
 
  611         _initialize(minX, maxX);
 
  627     double getMinX() const noexcept { 
return _minX; };
 
  632     double getMaxX() const noexcept { 
return _maxX; };
 
  642         double xPrime = (
x + _offset) * _scale;
 
  646         int const order = _order;
 
  649         } 
else if (order == 1) {
 
  654         for (
int i = 
order - 2; i > 0; --i) {
 
  655             double cshNext = (2 * xPrime * csh) + this->
_params[i] - cshPrev;
 
  659         return (xPrime * csh) + this->
_params[0] - cshPrev;
 
  664         os << 
"Chebyshev1Function1 [" << _minX << 
", " << _maxX << 
"]: ";
 
  665         os << Function1<ReturnT>::toString(
prefix);
 
  679     void _initialize(
double minX, 
double maxX) {
 
  682         _scale = 2.0 / (_maxX - _minX);
 
  683         _offset = -(_minX + _maxX) * 0.5;
 
  690             : 
Function1<ReturnT>(1), _minX(0.0), _maxX(0.0), _scale(1.0), _offset(0.0), _order(0) {}
 
  718 template <
typename ReturnT>
 
  732               _yCheby(this->
_order + 1),
 
  733               _xCoeffs(this->
_order + 1) {
 
  734         _initialize(xyRange);
 
  751               _yCheby(this->
_order + 1),
 
  752               _xCoeffs(this->
_order + 1) {
 
  753         _initialize(xyRange);
 
  781         if (truncOrder > this->
_order) {
 
  783             os << 
"truncated order=" << truncOrder << 
" must be <= original order=" << this->
_order;
 
  805         double const xPrime = (
x + _offsetX) * _scaleX;
 
  806         double const yPrime = (
y + _offsetY) * _scaleY;
 
  808         const int nParams = 
static_cast<int>(this->
_params.
size());
 
  809         const int order = this->
_order;
 
  819             for (
int chebyInd = 2; chebyInd <= 
order; chebyInd++) {
 
  820                 _yCheby[chebyInd] = (2 * yPrime * _yCheby[chebyInd - 1]) - _yCheby[chebyInd - 2];
 
  823             for (
int coeffInd = 0; coeffInd <= 
order; coeffInd++) {
 
  824                 _xCoeffs[coeffInd] = 0;
 
  826             for (
int coeffInd = 0, endCoeffInd = 0, paramInd = 0; paramInd < nParams; paramInd++) {
 
  827                 _xCoeffs[coeffInd] += this->
_params[paramInd] * _yCheby[endCoeffInd];
 
  831                     coeffInd = endCoeffInd;
 
  843             return _xCoeffs[0] + (_xCoeffs[1] * xPrime);
 
  845         double cshPrev = _xCoeffs[
order];
 
  846         double csh = (2 * xPrime * _xCoeffs[
order]) + _xCoeffs[
order - 1];
 
  847         for (
int i = 
order - 2; i > 0; --i) {
 
  848             double cshNext = (2 * xPrime * csh) + _xCoeffs[i] - cshPrev;
 
  852         return (xPrime * csh) + _xCoeffs[0] - cshPrev;
 
  857         os << 
"Chebyshev1Function2 [";
 
  859         os << Function2<ReturnT>::toString(
prefix);
 
  871     mutable double _oldYPrime;
 
  891         _scaleX = 2.0 / (_maxX - _minX);
 
  892         _scaleY = 2.0 / (_maxY - _minY);
 
  893         _offsetX = -(_minX + _maxX) * 0.5;
 
  894         _offsetY = -(_minY + _maxY) * 0.5;
 
  926 template <
typename ReturnT>
 
  933                               double xOffset = 0.0)  
 
  934             : 
Function1<ReturnT>(1), _invN(1.0 / static_cast<double>(n)) {
 
  948     ReturnT 
operator()(
double x) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
  950         double xArg2 = xArg1 * _invN;
 
  952             return static_cast<ReturnT
>(
std::sin(xArg1) * 
std::sin(xArg2) / (xArg1 * xArg2));
 
  954             return static_cast<ReturnT
>(1);
 
  961     unsigned int getOrder() const noexcept { 
return static_cast<unsigned int>(0.5 + (1.0 / _invN)); };
 
  965         os << 
"LanczosFunction1 [" << this->
getOrder() << 
"]: ";
 
  967         os << Function1<ReturnT>::toString(
prefix);
 
  991 template <
typename ReturnT>
 
  998                               double xOffset = 0.0,  
 
  999                               double yOffset = 0.0)  
 
 1000             : 
Function2<ReturnT>(2), _invN(1.0 / static_cast<double>(n)) {
 
 1016     ReturnT 
operator()(
double x, 
double y) 
const noexcept(IS_NOTHROW_INIT<ReturnT>)
 override {
 
 1018         double xArg2 = xArg1 * _invN;
 
 1024         double yArg2 = yArg1 * _invN;
 
 1029         return static_cast<ReturnT
>(xFunc * yFunc);
 
 1035     unsigned int getOrder() const noexcept { 
return static_cast<unsigned int>(0.5 + (1.0 / _invN)); };
 
 1039         os << 
"LanczosFunction2 [" << this->
getOrder() << 
"]: ";
 
 1041         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.
 
Chebyshev1Function1 & operator=(Chebyshev1Function1 const &)=default
 
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
 
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
 
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
Chebyshev1Function1 & operator=(Chebyshev1Function1 &&)=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.
 
Chebyshev1Function2 & operator=(Chebyshev1Function2 const &)=default
 
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.
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
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
 
~Chebyshev1Function2() noexcept override=default
 
lsst::geom::Box2D getXYRange() const noexcept
Get x,y range.
 
Chebyshev1Function2 & operator=(Chebyshev1Function2 &&)=default
 
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(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(double sigma1, double sigma2=0, double ampl2=0)
Construct a Gaussian function with specified x and y sigma.
 
DoubleGaussianFunction2 & operator=(DoubleGaussianFunction2 const &)=default
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
DoubleGaussianFunction2(DoubleGaussianFunction2 &&)=default
 
DoubleGaussianFunction2(DoubleGaussianFunction2 const &)=default
 
std::string toString(std::string const &prefix) const override
Return a string representation of the 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 & operator=(DoubleGaussianFunction2 &&)=default
 
DoubleGaussianFunction2()
 
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
 
GaussianFunction1(GaussianFunction1 &&)=default
 
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
 
GaussianFunction1 & operator=(GaussianFunction1 &&)=default
 
GaussianFunction1(GaussianFunction1 const &)=default
 
GaussianFunction1(double sigma)
Construct a Gaussian function with specified sigma.
 
GaussianFunction1 & operator=(GaussianFunction1 const &)=default
 
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
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 const &)=default
 
GaussianFunction2 & operator=(GaussianFunction2 &&)=default
 
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
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 & operator=(IntegerDeltaFunction1 const &)=default
 
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.
 
2-dimensional integer delta function.
 
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
 
IntegerDeltaFunction2(IntegerDeltaFunction2 const &)=default
 
IntegerDeltaFunction2 & operator=(IntegerDeltaFunction2 const &)=default
 
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
 
~IntegerDeltaFunction2() noexcept override=default
 
IntegerDeltaFunction2(double xo, double yo)
Construct an integer delta function with specified xo, yo.
 
IntegerDeltaFunction2 & operator=(IntegerDeltaFunction2 &&)=default
 
IntegerDeltaFunction2(IntegerDeltaFunction2 &&)=default
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
1-dimensional Lanczos function
 
LanczosFunction1(unsigned int n, double xOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
 
~LanczosFunction1() noexcept override=default
 
LanczosFunction1 & operator=(LanczosFunction1 &&)=default
 
LanczosFunction1(LanczosFunction1 &&)=default
 
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
LanczosFunction1(LanczosFunction1 const &)=default
 
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
 
LanczosFunction1 & operator=(LanczosFunction1 const &)=default
 
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
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
~LanczosFunction2() noexcept override=default
 
LanczosFunction2 & operator=(LanczosFunction2 &&)=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
 
unsigned int getOrder() const noexcept
Get the order of Lanczos function.
 
LanczosFunction2 & operator=(LanczosFunction2 const &)=default
 
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
 
1-dimensional polynomial function.
 
unsigned int getOrder() const noexcept
Get the polynomial order.
 
PolynomialFunction1 & operator=(PolynomialFunction1 &&)=default
 
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
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(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
 
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(unsigned int order)
Construct a polynomial function of specified order.
 
PolynomialFunction2 & operator=(PolynomialFunction2 &&)=default
 
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
 
PolynomialFunction2(PolynomialFunction2 const &)=default
 
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
 
~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.
 
constexpr double PI
The ratio of a circle's circumference to diameter.
 
A base class for image defects.