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 {
409 int const order =
static_cast<int>(this->
_params.
size()) - 1;
410 double retVal = this->
_params[order];
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) {
652 double cshPrev = this->
_params[order];
653 double csh = (2 * xPrime * this->
_params[order]) + this->
_params[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;
786 int truncNParams = this->nParametersFromOrder(truncOrder);
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 [";
858 os << this->_order <<
", " << this->getXYRange() <<
"]";
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);
1056 #endif // #ifndef LSST_AFW_MATH_FUNCTIONLIBRARY_H double getMinY() const noexcept
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
2-dimensional weighted sum of Chebyshev polynomials of the first kind.
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 override
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
unsigned int getNParameters() const noexcept
Return the number of function parameters.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
PolynomialFunction1(unsigned int order)
Construct a polynomial function of the specified order.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
PolynomialFunction2(unsigned int order)
Construct a polynomial function of specified order.
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
1-dimensional Lanczos function
double Guassian (sum of two Gaussians)
double getMaxX() const noexcept
Get maximum allowed x.
unsigned int getOrder() const noexcept
Get the order of the Lanczos function.
A floating-point coordinate rectangle geometry.
An object passed to Persistable::write to allow it to persist itself.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
GaussianFunction1(double sigma)
Construct a Gaussian function with specified sigma.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
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.
double getMinX() const noexcept
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
2-dimensional polynomial function with cross terms
PolynomialFunction1(std::vector< double > params)
Construct a polynomial function with the specified parameters.
1-dimensional weighted sum of Chebyshev polynomials of the first kind.
double getMaxX() const noexcept
Chebyshev1Function1(unsigned int order, double minX=-1, double maxX=1)
Construct a Chebyshev polynomial of specified order and range.
2-dimensional integer delta function.
virtual Chebyshev1Function2 truncate(int truncOrder) const
Return a truncated copy of lower (or equal) order.
IntegerDeltaFunction1(double xo)
Construct an integer delta function with specified xo.
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.
table::Key< double > angle
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
bool isLinearCombination() const noexcept override
Is the function a linear combination of its parameters?
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
table::Key< double > sigma2
LanczosFunction2(unsigned int n, double xOffset=0.0, double yOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
IntegerDeltaFunction1 & operator=(IntegerDeltaFunction1 const &)=default
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
2-dimensional separable Lanczos function
A Function taking two arguments.
bool isLinearCombination() const noexcept override
Is the function a linear combination of its parameters?
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
ReturnT operator()(double x) const override
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
Base class for 2-dimensional polynomials of the form:
afw::table::Key< double > sigma
double getMaxY() const noexcept
std::vector< double > _params
A base class for image defects.
IntegerDeltaFunction2(double xo, double yo)
Construct an integer delta function with specified xo, yo.
1-dimensional integer delta function.
unsigned int getOrder() const noexcept
Get the order of Lanczos function.
DoubleGaussianFunction2()
A Function taking one argument.
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
PolynomialFunction2(std::vector< double > params)
Construct a polynomial function with specified parameters.
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.
ReturnT operator()(double x, double y) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
ReturnT operator()(double x) 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.
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
DoubleGaussianFunction2(double sigma1, double sigma2=0, double ampl2=0)
Construct a Gaussian function with specified x and y sigma.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
table::Key< double > ampl2
lsst::geom::Box2D getXYRange() const noexcept
Get x,y range.
std::string toString(std::string const &prefix) const override
Return a string representation of the function.
unsigned int getOrder() const noexcept
Get the polynomial order.
~IntegerDeltaFunction1() noexcept override=default
ReturnT operator()(double x) const noexcept(IS_NOTHROW_INIT< ReturnT >) override
std::string toString(std::string const &prefix) const override
Return a string representation of the 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.
Reports invalid arguments.
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.
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
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.
GaussianFunction2(double sigma1, double sigma2, double angle=0.0)
Construct a 2-dimensional Gaussian function.
bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
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.
double constexpr PI
The ratio of a circle's circumference to diameter.
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.
table::Key< double > sigma1
1-dimensional polynomial function.
LanczosFunction1(unsigned int n, double xOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.