LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
FunctionLibrary.h
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 #ifndef LSST_AFW_MATH_FUNCTIONLIBRARY_H
26 #define LSST_AFW_MATH_FUNCTIONLIBRARY_H
27 
36 #include <algorithm>
37 #include <cmath>
38 
39 #include "lsst/afw/geom.h"
40 #include "lsst/afw/math/Function.h"
41 #include "lsst/afw/geom/Angle.h"
42 
43 namespace lsst {
44 namespace afw {
45 namespace math {
46 
47 #ifndef SWIG
48 using boost::serialization::make_nvp;
49 #endif
50 
61  template<typename ReturnT>
62  class IntegerDeltaFunction1: public Function1<ReturnT> {
63  public:
65 
70  double xo)
71  :
72  Function1<ReturnT>(0),
73  _xo(xo)
74  {}
75 
76  virtual ~IntegerDeltaFunction1() {};
77 
78  virtual Function1Ptr clone() const {
80  }
81 
82  virtual ReturnT operator() (double x, double y) const {
83  return static_cast<ReturnT>(x == _xo);
84  }
85 
86  virtual std::string toString(std::string const& prefix="") const {
87  std::ostringstream os;
88  os << "IntegerDeltaFunction1 [" << _xo << "]: ";
89  os << Function1<ReturnT>::toString(prefix);
90  return os.str();
91  };
92 
93  private:
94  double _xo;
95 
96  protected:
97  /* Default constructor: intended only for serialization */
98  explicit IntegerDeltaFunction1() : Function1<ReturnT>(0), _xo(0.0) {}
99 
100  private:
102  template <class Archive>
103  void serialize(Archive& ar, unsigned int const version) {
104  ar & make_nvp("fn1", boost::serialization::base_object<Function1<ReturnT> >(*this));
105  ar & make_nvp("xo", this->_xo);
106  }
107  };
108 
119  template<typename ReturnT>
120  class IntegerDeltaFunction2: public Function2<ReturnT> {
121  public:
123 
128  double xo,
129  double yo)
130  :
131  Function2<ReturnT>(0),
132  _xo(xo),
133  _yo(yo)
134  {}
135 
137 
138  virtual Function2Ptr clone() const {
140  }
141 
142  virtual ReturnT operator() (double x, double y) const {
143  return static_cast<ReturnT>((x == _xo) && (y == _yo));
144  }
145 
146  virtual std::string toString(std::string const& prefix) const {
147  std::ostringstream os;
148  os << "IntegerDeltaFunction2 [" << _xo << ", " << _yo << "]: ";
149  os << Function2<ReturnT>::toString(prefix);
150  return os.str();
151  }
152 
153  private:
154  double _xo;
155  double _yo;
156 
157  protected:
158  /* Default constructor: intended only for serialization */
159  explicit IntegerDeltaFunction2() : Function2<ReturnT>(0), _xo(0.0), _yo(0.0) {}
160 
161  private:
163  template <class Archive>
164  void serialize(Archive& ar, unsigned int const version) {
165  ar & make_nvp("fn2", boost::serialization::base_object<Function2<ReturnT> >(*this));
166  ar & make_nvp("xo", this->_xo);
167  ar & make_nvp("yo", this->_yo);
168  }
169  };
170 
181  template<typename ReturnT>
182  class GaussianFunction1: public Function1<ReturnT> {
183  public:
185 
190  double sigma)
191  :
192  Function1<ReturnT>(1),
193  _multFac(1.0 / std::sqrt(lsst::afw::geom::TWOPI))
194  {
195  this->_params[0] = sigma;
196  }
197  virtual ~GaussianFunction1() {}
198 
199  virtual Function1Ptr clone() const {
200  return Function1Ptr(new GaussianFunction1(this->_params[0]));
201  }
202 
203  virtual ReturnT operator() (double x) const {
204  return static_cast<ReturnT> (
205  (_multFac / this->_params[0]) *
206  std::exp(- (x * x) / (2.0 * this->_params[0] * this->_params[0])));
207  }
208 
209  virtual std::string toString(std::string const& prefix) const {
210  std::ostringstream os;
211  os << "GaussianFunction1 [" << _multFac << "]: ";
212  os << Function1<ReturnT>::toString(prefix);
213  return os.str();
214  }
215 
216  private:
217  const double _multFac;
218 
219  protected:
220  /* Default constructor: intended only for serialization */
221  explicit GaussianFunction1() : Function1<ReturnT>(1), _multFac(1.0 / std::sqrt(lsst::afw::geom::TWOPI)) {}
222 
223  private:
225  template <class Archive>
226  void serialize(Archive& ar, unsigned int const version) {
227  ar & make_nvp("fn1", boost::serialization::base_object<Function1<ReturnT> >(*this));
228  }
229  };
230 
245  template<typename ReturnT>
246  class GaussianFunction2: public Function2<ReturnT> {
247  public:
249 
254  double sigma1,
255  double sigma2,
256  double angle = 0.0)
257  :
258  Function2<ReturnT>(3),
259  _multFac(1.0 / (lsst::afw::geom::TWOPI))
260  {
261  this->_params[0] = sigma1;
262  this->_params[1] = sigma2;
263  this->_params[2] = angle;
264  _updateCache();
265  }
266 
267  virtual ~GaussianFunction2() {}
268 
269  virtual Function2Ptr clone() const {
270  return Function2Ptr(new GaussianFunction2(this->_params[0], this->_params[1], this->_params[2]));
271  }
272 
273  virtual ReturnT operator() (double x, double y) const {
274  if (_angle != this->_params[2]) {
275  _updateCache();
276  }
277  double pos1 = ( _cosAngle * x) + (_sinAngle * y);
278  double pos2 = (-_sinAngle * x) + (_cosAngle * y);
279  return static_cast<ReturnT> (
280  (_multFac / (this->_params[0] * this->_params[1])) *
281  std::exp(- ((pos1 * pos1) / (2.0 * this->_params[0] * this->_params[0]))
282  - ((pos2 * pos2) / (2.0 * this->_params[1] * this->_params[1]))));
283  }
284 
285  virtual std::string toString(std::string const& prefix) const {
286  std::ostringstream os;
287  os << "GaussianFunction2: ";
288  os << Function2<ReturnT>::toString(prefix);
289  return os.str();
290  }
291 
292  virtual bool isPersistable() const { return true; }
293 
294  protected:
295 
296  virtual std::string getPersistenceName() const;
297 
298  virtual void write(afw::table::io::OutputArchiveHandle & handle) const;
299 
300  private:
318  void _updateCache() const {
319  _angle = this->_params[2];
320  _sinAngle = std::sin(_angle);
321  _cosAngle = std::cos(_angle);
322  }
323  const double _multFac;
324  mutable double _angle;
325  mutable double _sinAngle;
326  mutable double _cosAngle;
327 
328  protected:
329  /* Default constructor: intended only for serialization */
330  explicit GaussianFunction2() : Function2<ReturnT>(3), _multFac(1.0 / (lsst::afw::geom::TWOPI)), _angle(0.0),
331  _sinAngle(0.0), _cosAngle(1.0) {}
332 
333  private:
335  template <class Archive>
336  void serialize(Archive& ar, unsigned int const version) {
337  ar & make_nvp("fn2", boost::serialization::base_object<Function2<ReturnT> >(*this));
338  ar & make_nvp("angle", this->_angle);
339  ar & make_nvp("sinAngle", this->_sinAngle);
340  ar & make_nvp("cosAngle", this->_cosAngle);
341  }
342  };
343 
358  template<typename ReturnT>
359  class DoubleGaussianFunction2: public Function2<ReturnT> {
360  public:
362 
367  double sigma1,
368  double sigma2 = 0,
369  double ampl2 = 0)
370  :
371  Function2<ReturnT>(3),
372  _multFac(1.0 / (lsst::afw::geom::TWOPI))
373  {
374  this->_params[0] = sigma1;
375  this->_params[1] = sigma2;
376  this->_params[2] = ampl2;
377  }
378 
380 
381  virtual Function2Ptr clone() const {
382  return Function2Ptr(
383  new DoubleGaussianFunction2(this->_params[0], this->_params[1], this->_params[2]));
384  }
385 
386  virtual ReturnT operator() (double x, double y) const {
387  double radSq = (x * x) + (y * y);
388  double sigma1Sq = this->_params[0] * this->_params[0];
389  double sigma2Sq = this->_params[1] * this->_params[1];
390  double b = this->_params[2];
391  return static_cast<ReturnT> (
392  (_multFac / (sigma1Sq + (b * sigma2Sq))) *
393  (std::exp(-radSq / (2.0 * sigma1Sq))
394  + (b * std::exp(-radSq / (2.0 * sigma2Sq)))));
395  }
396 
397  virtual std::string toString(std::string const& prefix) const {
398  std::ostringstream os;
399  os << "DoubleGaussianFunction2 [" << _multFac << "]: ";
400  os << Function2<ReturnT>::toString(prefix);
401  return os.str();
402  }
403 
404  virtual bool isPersistable() const { return true; }
405 
406  protected:
407 
408  virtual std::string getPersistenceName() const;
409 
410  virtual void write(afw::table::io::OutputArchiveHandle & handle) const;
411 
412  private:
413  const double _multFac;
414 
415  protected:
416  /* Default constructor: intended only for serialization */
417  explicit DoubleGaussianFunction2() : Function2<ReturnT>(3), _multFac(1.0 / (lsst::afw::geom::TWOPI)) {}
418 
419  private:
421  template <class Archive>
422  void serialize(Archive& ar, unsigned int const version) {
423  ar & make_nvp("fn2", boost::serialization::base_object<Function2<ReturnT> >(*this));
424  }
425  };
426 
434  template<typename ReturnT>
435  class PolynomialFunction1: public Function1<ReturnT> {
436  public:
438 
445  unsigned int order)
446  :
447  Function1<ReturnT>(order+1) {
448  }
449 
458  std::vector<double> params)
459  :
460  Function1<ReturnT>(params)
461  {
462  if (params.size() < 1) {
463  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
464  "PolynomialFunction1 called with empty vector");
465  }
466  }
467 
468  virtual ~PolynomialFunction1() {}
469 
470  virtual Function1Ptr clone() const {
471  return Function1Ptr(new PolynomialFunction1(this->_params));
472  }
473 
474  virtual bool isLinearCombination() const { return true; };
475 
476  virtual ReturnT operator() (double x) const {
477  int const order = static_cast<int>(this->_params.size()) - 1;
478  double retVal = this->_params[order];
479  for (int ii = order-1; ii >= 0; --ii) {
480  retVal = (retVal * x) + this->_params[ii];
481  }
482  return static_cast<ReturnT>(retVal);
483  }
484 
488  unsigned int getOrder() const { return this->getNParameters() - 1; };
489 
490  virtual std::string toString(std::string const& prefix) const {
491  std::ostringstream os;
492  os << "PolynomialFunction1 []: ";
493  os << Function1<ReturnT>::toString(prefix);
494  return os.str();
495  }
496 
497  protected:
498  /* Default constructor: intended only for serialization */
499  explicit PolynomialFunction1() : Function1<ReturnT>(1) {}
500 
501  private:
503  template <class Archive>
504  void serialize(Archive& ar, unsigned int const version) {
505  ar & make_nvp("fn1", boost::serialization::base_object<Function1<ReturnT> >(*this));
506  }
507  };
508 
523  template<typename ReturnT>
525  public:
527 
536  unsigned int order)
537  :
538  BasePolynomialFunction2<ReturnT>(order),
539  _oldY(0),
540  _xCoeffs(this->_order + 1)
541  {}
542 
554  std::vector<double> params)
555  :
557  BasePolynomialFunction2<ReturnT>(params),
558  _oldY(0),
559  _xCoeffs(this->_order + 1)
560  {}
561 
562  virtual ~PolynomialFunction2() {}
563 
564  virtual Function2Ptr clone() const {
565  return Function2Ptr(new PolynomialFunction2(this->_params));
566  }
567 
568  virtual ReturnT operator() (double x, double y) const {
569  /* Solve as follows:
570  - f(x,y) = Cx0 + Cx1 x + Cx2 x^2 + Cx3 x^3 + ...
571  where:
572  Cx0 = P0 + P2 y + P5 y^2 + P9 y^3 + ...
573  Cx1 = P1 + P4 y + P8 y2 + ...
574  Cx2 = P3 + P7 y + ...
575  Cx3 = P6 + ...
576  ...
577 
578  Compute Cx0, Cx1...Cxn by solving 1-d polynomials in y in the usual way.
579  These values are cached and only recomputed for new values of Y or if the parameters change.
580 
581  Then compute f(x,y) by solving the 1-d polynomial in x in the usual way.
582  */
583  const int maxXCoeffInd = this->_order;
584 
585  if ((y != _oldY) || !this->_isCacheValid) {
586  // update _xCoeffs cache
587  // note: paramInd is decremented in both of the following loops
588  int paramInd = static_cast<int>(this->_params.size()) - 1;
589 
590  // initialize _xCoeffs to coeffs for pure y^n; e.g. for 3rd order:
591  // _xCoeffs[0] = _params[9], _xCoeffs[1] = _params[8], ... _xCoeffs[3] = _params[6]
592  for (int xCoeffInd = 0; xCoeffInd <= maxXCoeffInd; ++xCoeffInd, --paramInd) {
593  _xCoeffs[xCoeffInd] = this->_params[paramInd];
594  }
595 
596  // finish computing _xCoeffs
597  for (int xCoeffInd = 0, endXCoeffInd = maxXCoeffInd; paramInd >= 0; --paramInd) {
598  _xCoeffs[xCoeffInd] = (_xCoeffs[xCoeffInd] * y) + this->_params[paramInd];
599  ++xCoeffInd;
600  if (xCoeffInd >= endXCoeffInd) {
601  xCoeffInd = 0;
602  --endXCoeffInd;
603  }
604  }
605 
606  _oldY = y;
607  this->_isCacheValid = true;
608  }
609 
610  // use _xCoeffs to compute result
611  double retVal = _xCoeffs[maxXCoeffInd];
612  for (int xCoeffInd = maxXCoeffInd - 1; xCoeffInd >= 0; --xCoeffInd) {
613  retVal = (retVal * x) + _xCoeffs[xCoeffInd];
614  }
615  return static_cast<ReturnT>(retVal);
616  }
617 
618  virtual std::vector<double> getDFuncDParameters(double x, double y) const;
619 
620  virtual std::string toString(std::string const& prefix) const {
621  std::ostringstream os;
622  os << "PolynomialFunction2 [" << this->_order << "]: ";
623  os << Function2<ReturnT>::toString(prefix);
624  return os.str();
625  }
626 
627  virtual bool isPersistable() const { return true; }
628 
629  protected:
630 
631  virtual std::string getPersistenceName() const;
632 
633  virtual void write(afw::table::io::OutputArchiveHandle & handle) const;
634 
635  private:
636  mutable double _oldY;
637  mutable std::vector<double> _xCoeffs;
638 
639  protected:
640  /* Default constructor: intended only for serialization */
641  explicit PolynomialFunction2() : BasePolynomialFunction2<ReturnT>(), _oldY(0), _xCoeffs(0) {}
642 
643  private:
645  template <class Archive>
646  void serialize(Archive& ar, unsigned int const version) {
647  ar & make_nvp("fn2", boost::serialization::base_object<BasePolynomialFunction2<ReturnT> >(*this));
648  ar & make_nvp("yCoeffs", this->_xCoeffs); // sets size of _xCoeffs; name is historical
649  }
650  };
651 
668  template<typename ReturnT>
669  class Chebyshev1Function1: public Function1<ReturnT> {
670  public:
672 
679  unsigned int order,
680  double minX = -1,
681  double maxX = 1)
682  :
683  Function1<ReturnT>(order + 1)
684  {
685  _initialize(minX, maxX);
686  }
687 
696  std::vector<double> params,
697  double minX = -1,
698  double maxX = 1)
699  :
700  Function1<ReturnT>(params)
701  {
702  if (params.size() < 1) {
703  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
704  "Chebyshev1Function1 called with empty vector");
705  }
706  _initialize(minX, maxX);
707  }
708 
709  virtual ~Chebyshev1Function1() {}
710 
711  virtual Function1Ptr clone() const {
712  return Function1Ptr(new Chebyshev1Function1(this->_params, _minX, _maxX));
713  }
714 
718  double getMinX() const { return _minX; };
719 
723  double getMaxX() const { return _maxX; };
724 
728  unsigned int getOrder() const { return this->getNParameters() - 1; };
729 
730  virtual bool isLinearCombination() const { return true; };
731 
732  virtual ReturnT operator() (double x) const {
733  double xPrime = (x + _offset) * _scale;
734 
735  // Clenshaw function for solving the Chebyshev polynomial
736  // Non-recursive version from Kresimir Cosic
737  int const order = _order;
738  if (order == 0) {
739  return this->_params[0];
740  } else if (order == 1) {
741  return this->_params[0] + (this->_params[1] * xPrime);
742  }
743  double cshPrev = this->_params[order];
744  double csh = (2 * xPrime * this->_params[order]) + this->_params[order-1];
745  for (int i = order - 2; i > 0; --i) {
746  double cshNext = (2 * xPrime * csh) + this->_params[i] - cshPrev;
747  cshPrev = csh;
748  csh = cshNext;
749  }
750  return (xPrime * csh) + this->_params[0] - cshPrev;
751  }
752 
753  virtual std::string toString(std::string const& prefix) const {
754  std::ostringstream os;
755  os << "Chebyshev1Function1 [" << _minX << ", " << _maxX << "]: ";
756  os << Function1<ReturnT>::toString(prefix);
757  return os.str();
758  }
759 
760  private:
761  double _minX;
762  double _maxX;
763  double _scale;
764  double _offset;
765  unsigned int _order;
766 
770  void _initialize(double minX, double maxX) {
771  _minX = minX;
772  _maxX = maxX;
773  _scale = 2.0 / (_maxX - _minX);
774  _offset = -(_minX + _maxX) * 0.5;
775  _order = this->getNParameters() - 1;
776  }
777 
778  protected:
779  /* Default constructor: intended only for serialization */
780  explicit Chebyshev1Function1() : Function1<ReturnT>(1),
781  _minX(0.0), _maxX(0.0), _scale(1.0), _offset(0.0), _order(0) {}
782 
783  private:
785  template <class Archive>
786  void serialize(Archive& ar, unsigned int const) {
787  ar & make_nvp("fn1", boost::serialization::base_object<Function1<ReturnT> >(*this));
788  ar & make_nvp("minX", this->_minX);
789  ar & make_nvp("minX", this->_minX);
790  ar & make_nvp("maxX", this->_maxX);
791  ar & make_nvp("scale", this->_scale);
792  ar & make_nvp("offset", this->_offset);
793  ar & make_nvp("maxInd", this->_order);
794  }
795  };
796 
822  template<typename ReturnT>
824  public:
826 
833  unsigned int order,
834  lsst::afw::geom::Box2D const &xyRange =
836  lsst::afw::geom::Point2D( 1.0, 1.0)))
837  :
838  BasePolynomialFunction2<ReturnT>(order),
839  _oldYPrime(0),
840  _yCheby(this->_order + 1),
841  _xCoeffs(this->_order + 1)
842  {
843  _initialize(xyRange);
844  }
845 
854  std::vector<double> params,
855  lsst::afw::geom::Box2D const &xyRange =
858  lsst::afw::geom::Point2D( 1.0, 1.0)))
859  :
860  BasePolynomialFunction2<ReturnT>(params),
861  _oldYPrime(0),
862  _yCheby(this->_order + 1),
863  _xCoeffs(this->_order + 1)
864  {
865  _initialize(xyRange);
866  }
867 
868  virtual ~Chebyshev1Function2() {}
869 
870  virtual Function2Ptr clone() const {
871  return Function2Ptr(new Chebyshev1Function2(this->_params, this->getXYRange()));
872  }
873 
880  };
881 
888  int truncOrder
889  ) const {
890  if (truncOrder > this->_order) {
891  std::ostringstream os;
892  os << "truncated order=" << truncOrder << " must be <= original order=" << this->_order;
893  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError, os.str());
894  }
895  int truncNParams = this->nParametersFromOrder(truncOrder);
896  std::vector<double> truncParams(this->_params.begin(), this->_params.begin() + truncNParams);
897  return Chebyshev1Function2(truncParams, this->getXYRange());
898  }
899 
900  virtual ReturnT operator() (double x, double y) const {
901  /* Solve as follows:
902  - f(x,y) = Cy0 T0(y') + Cy1 T1(y') + Cy2 T2(y') + Cy3 T3(y') + ...
903  where:
904  Cy0 = P0 T0(x') + P1 T1(x') + P3 T2(x') + P6 T3(x') + ...
905  Cy1 = P2 T0(x') + P4 T1(x') + P7 T2(x') + ...
906  Cy2 = P5 T0(x') + P8 T1(x') + ...
907  Cy3 = P9 T0(x') + ...
908  ...
909 
910  First compute Tn(x') for each n
911  Then use that to compute Cy0, Cy1, ...Cyn
912  Then solve the y Chebyshev polynomial using the Clenshaw algorithm
913  */
914  double const xPrime = (x + _offsetX) * _scaleX;
915  double const yPrime = (y + _offsetY) * _scaleY;
916 
917  const int nParams = static_cast<int>(this->_params.size());
918  const int order = this->_order;
919 
920  if (order == 0) {
921  return this->_params[0]; // No caching required
922  }
923 
924  if ((yPrime != _oldYPrime) || !this->_isCacheValid) {
925  // update cached _yCheby and _xCoeffs
926  _yCheby[0] = 1.0;
927  _yCheby[1] = yPrime;
928  for (int chebyInd = 2; chebyInd <= order; chebyInd++) {
929  _yCheby[chebyInd] = (2 * yPrime * _yCheby[chebyInd-1]) - _yCheby[chebyInd-2];
930  }
931 
932  for (int coeffInd=0; coeffInd <= order; coeffInd++) {
933  _xCoeffs[coeffInd] = 0;
934  }
935  for (int coeffInd = 0, endCoeffInd = 0, paramInd = 0; paramInd < nParams; paramInd++) {
936  _xCoeffs[coeffInd] += this->_params[paramInd] * _yCheby[endCoeffInd];
937  --coeffInd;
938  ++endCoeffInd;
939  if (coeffInd < 0) {
940  coeffInd = endCoeffInd;
941  endCoeffInd = 0;
942  }
943  }
944 
945  _oldYPrime = yPrime;
946  this->_isCacheValid = true;
947  }
948 
949  // Clenshaw function for solving the Chebyshev polynomial
950  // Non-recursive version from Kresimir Cosic
951  if (order == 1) {
952  return _xCoeffs[0] + (_xCoeffs[1] * xPrime);
953  }
954  double cshPrev = _xCoeffs[order];
955  double csh = (2 * xPrime * _xCoeffs[order]) + _xCoeffs[order-1];
956  for (int i = order - 2; i > 0; --i) {
957  double cshNext = (2 * xPrime * csh) + _xCoeffs[i] - cshPrev;
958  cshPrev = csh;
959  csh = cshNext;
960  }
961  return (xPrime * csh) + _xCoeffs[0] - cshPrev;
962  }
963 
964  virtual std::string toString(std::string const& prefix) const {
965  std::ostringstream os;
966  os << "Chebyshev1Function2 [";
967  os << this->_order << ", " << this->getXYRange() << "]";
968  os << Function2<ReturnT>::toString(prefix);
969  return os.str();
970  }
971 
972  virtual bool isPersistable() const { return true; }
973 
974  protected:
975 
976  virtual std::string getPersistenceName() const;
977 
978  virtual void write(afw::table::io::OutputArchiveHandle & handle) const;
979 
980  private:
981  mutable double _oldYPrime;
982  mutable std::vector<double> _yCheby;
983  mutable std::vector<double> _xCoeffs;
984  double _minX;
985  double _minY;
986  double _maxX;
987  double _maxY;
988  double _scaleX;
989  double _scaleY;
990  double _offsetX;
991  double _offsetY;
992 
996  void _initialize(lsst::afw::geom::Box2D const &xyRange) {
997  _minX = xyRange.getMinX();
998  _minY = xyRange.getMinY();
999  _maxX = xyRange.getMaxX();
1000  _maxY = xyRange.getMaxY();
1001  _scaleX = 2.0 / (_maxX - _minX);
1002  _scaleY = 2.0 / (_maxY - _minY);
1003  _offsetX = -(_minX + _maxX) * 0.5;
1004  _offsetY = -(_minY + _maxY) * 0.5;
1005  }
1006 
1007  protected:
1008  /* Default constructor: intended only for serialization */
1010  _oldYPrime(0),
1011  _yCheby(0),
1012  _xCoeffs(0),
1013  _minX(0.0), _minY(0.0),
1014  _maxX(0.0), _maxY(0.0),
1015  _scaleX(1.0), _scaleY(1.0),
1016  _offsetX(0.0), _offsetY(0.0) {}
1017 
1018  private:
1020  template <class Archive>
1021  void serialize(Archive& ar, unsigned int const version) {
1022  ar & make_nvp("fn2", boost::serialization::base_object<BasePolynomialFunction2<ReturnT> >(*this));
1023  ar & make_nvp("minX", this->_minX);
1024  ar & make_nvp("minY", this->_minY);
1025  ar & make_nvp("maxX", this->_maxX);
1026  ar & make_nvp("maxY", this->_maxY);
1027  ar & make_nvp("scaleX", this->_scaleX);
1028  ar & make_nvp("scaleY", this->_scaleY);
1029  ar & make_nvp("offsetX", this->_offsetX);
1030  ar & make_nvp("offsetY", this->_offsetY);
1031  ar & make_nvp("xCheby", this->_yCheby); // sets size of _yCheby; name is historical
1032  _xCoeffs.resize(_yCheby.size());
1033  }
1034  };
1035 
1048  template<typename ReturnT>
1049  class LanczosFunction1: public Function1<ReturnT> {
1050  public:
1052 
1057  unsigned int n,
1058  double xOffset = 0.0)
1059  :
1060  Function1<ReturnT>(1),
1061  _invN(1.0/static_cast<double>(n))
1062  {
1063  this->_params[0] = xOffset;
1064  }
1065 
1066  virtual ~LanczosFunction1() {}
1067 
1068  virtual Function1Ptr clone() const {
1069  return Function1Ptr(new LanczosFunction1(this->getOrder(), this->_params[0]));
1070  }
1071 
1072  virtual ReturnT operator() (double x) const {
1073  double xArg1 = (x - this->_params[0]) * lsst::afw::geom::PI;
1074  double xArg2 = xArg1 * _invN;
1075  if (std::fabs(xArg1) > 1.0e-5) {
1076  return static_cast<ReturnT>(std::sin(xArg1) * std::sin(xArg2) / (xArg1 * xArg2));
1077  } else {
1078  return static_cast<ReturnT>(1);
1079  }
1080  }
1081 
1085  unsigned int getOrder() const {
1086  return static_cast<unsigned int>(0.5 + (1.0 / _invN));
1087  };
1088 
1089  virtual std::string toString(std::string const& prefix) const {
1090  std::ostringstream os;
1091  os << "LanczosFunction1 [" << this->getOrder() << "]: ";;
1092  os << Function1<ReturnT>::toString(prefix);
1093  return os.str();
1094  }
1095 
1096  private:
1097  double _invN; // == 1/n
1098 
1099  protected:
1100  /* Default constructor: intended only for serialization */
1101  explicit LanczosFunction1() : Function1<ReturnT>(1), _invN(1.0) {}
1102 
1103  private:
1105  template <class Archive>
1106  void serialize(Archive& ar, unsigned int const version) {
1107  ar & make_nvp("fn1", boost::serialization::base_object<Function1<ReturnT> >(*this));
1108  ar & make_nvp("invN", this->_invN);
1109  }
1110  };
1111 
1124  template<typename ReturnT>
1125  class LanczosFunction2: public Function2<ReturnT> {
1126  public:
1128 
1133  unsigned int n,
1134  double xOffset = 0.0,
1135  double yOffset = 0.0)
1136  :
1137  Function2<ReturnT>(2),
1138  _invN(1.0 / static_cast<double>(n))
1139  {
1140  this->_params[0] = xOffset;
1141  this->_params[1] = yOffset;
1142  }
1143 
1144  virtual ~LanczosFunction2() {}
1145 
1146  virtual Function2Ptr clone() const {
1147  return Function2Ptr(new LanczosFunction2(this->getOrder(), this->_params[0], this->_params[1]));
1148  }
1149 
1150  virtual ReturnT operator() (double x, double y) const {
1151  double xArg1 = (x - this->_params[0]) * lsst::afw::geom::PI;
1152  double xArg2 = xArg1 * _invN;
1153  double xFunc = 1;
1154  if (std::fabs(xArg1) > 1.0e-5) {
1155  xFunc = std::sin(xArg1) * std::sin(xArg2) / (xArg1 * xArg2);
1156  }
1157  double yArg1 = (y - this->_params[1]) * lsst::afw::geom::PI;
1158  double yArg2 = yArg1 * _invN;
1159  double yFunc = 1;
1160  if (std::fabs(yArg1) > 1.0e-5) {
1161  yFunc = std::sin(yArg1) * std::sin(yArg2) / (yArg1 * yArg2);
1162  }
1163  return static_cast<ReturnT>(xFunc * yFunc);
1164  }
1165 
1169  unsigned int getOrder() const {
1170  return static_cast<unsigned int>(0.5 + (1.0 / _invN));
1171  };
1172 
1173  virtual std::string toString(std::string const& prefix) const {
1174  std::ostringstream os;
1175  os << "LanczosFunction2 [" << this->getOrder() << "]: ";;
1176  os << Function2<ReturnT>::toString(prefix);
1177  return os.str();
1178  }
1179 
1180  private:
1181  double _invN;
1182 
1183  protected:
1184  /* Default constructor: intended only for serialization */
1185  explicit LanczosFunction2() : Function2<ReturnT>(2), _invN(1.0) {}
1186 
1187  private:
1189  template <class Archive>
1190  void serialize(Archive& ar, unsigned int const version) {
1191  ar & make_nvp("fn2", boost::serialization::base_object<Function2<ReturnT> >(*this));
1192  ar & make_nvp("invN", this->_invN);
1193  }
1194  };
1195 
1196 }}} // lsst::afw::math
1197 
1198 #endif // #ifndef LSST_AFW_MATH_FUNCTIONLIBRARY_H
int y
void serialize(Archive &ar, unsigned int const version)
2-dimensional weighted sum of Chebyshev polynomials of the first kind.
virtual void write(afw::table::io::OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
virtual bool isPersistable() const
Return true if this particular object can be persisted using afw::table::io.
double _scale
x&#39; = (x + _offset) * _scale
const double _multFac
precomputed scale factor
int _order
order of polynomial
Definition: Function.h:492
virtual ReturnT operator()(double x, double y) const
Function1< ReturnT >::Ptr Function1Ptr
friend class boost::serialization::access
An include file to include the header files for lsst::afw::geom.
void serialize(Archive &ar, unsigned int const version)
friend class boost::serialization::access
virtual bool isLinearCombination() const
Is the function a linear combination of its parameters?
virtual std::string toString(std::string const &prefix="") const
Return a string representation of the function.
void serialize(Archive &ar, unsigned int const version)
double _minX
minimum allowed x
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
virtual bool isPersistable() const
Return true if this particular object can be persisted using afw::table::io.
1-dimensional Lanczos function
virtual ReturnT operator()(double x, double y) const
double Guassian (sum of two Gaussians)
virtual Function1Ptr clone() const
Return a pointer to a deep copy of this function.
IntegerDeltaFunction1(double xo)
Construct an integer delta function with specified xo, yo.
An object passed to Persistable::write to allow it to persist itself.
double getMinX() const
Definition: Box.h:344
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
virtual ReturnT operator()(double x) const
unsigned int getOrder() const
Get the order of Lanczos function.
void serialize(Archive &ar, unsigned int const version)
friend class boost::serialization::access
virtual ReturnT operator()(double x, double y) const
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
2-dimensional polynomial function with cross terms
virtual ReturnT operator()(double x) const
lsst::afw::geom::Box2D getXYRange() const
Get x,y range.
1-dimensional weighted sum of Chebyshev polynomials of the first kind.
Function2< ReturnT >::Ptr Function2Ptr
virtual Function1Ptr clone() const
Return a pointer to a deep copy of this function.
void serialize(Archive &ar, unsigned int const version)
PolynomialFunction2(unsigned int order)
Construct a polynomial function of specified order.
double _offsetX
x&#39; = (x + _offsetX) * _scaleX
2-dimensional integer delta function.
DoubleGaussianFunction2(double sigma1, double sigma2=0, double ampl2=0)
Construct a Gaussian function with specified x and y sigma.
Function1< ReturnT >::Ptr Function1Ptr
Chebyshev1Function1(std::vector< double > params, double minX=-1, double maxX=1)
Construct a Chebyshev polynomial with specified parameters and range.
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
Chebyshev1Function2(unsigned int order, lsst::afw::geom::Box2D const &xyRange=lsst::afw::geom::Box2D(lsst::afw::geom::Point2D(-1.0,-1.0), lsst::afw::geom::Point2D(1.0, 1.0)))
Construct a Chebyshev polynomial of specified order and range.
unsigned int _order
polynomial order
unsigned int getOrder() const
Get the polynomial order.
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
virtual void write(afw::table::io::OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
double const TWOPI
Definition: Angle.h:19
Function2< ReturnT >::Ptr Function2Ptr
Function2< ReturnT >::Ptr Function2Ptr
Definition: Function.h:386
2-dimensional separable Lanczos function
A Function taking two arguments.
Definition: Function.h:300
friend class boost::serialization::access
PolynomialFunction1(std::vector< double > params)
Construct a polynomial function with the specified parameters.
GaussianFunction1(double sigma)
Construct a Gaussian function with specified sigma.
double getMaxY() const
Definition: Box.h:349
friend class boost::serialization::access
double _oldY
value of y for which _xCoeffs is valid
friend class boost::serialization::access
void serialize(Archive &ar, unsigned int const version)
Function2< ReturnT >::Ptr Function2Ptr
virtual ReturnT operator()(double x, double y) const
Base class for 2-dimensional polynomials of the form:
Definition: Function.h:384
unsigned int getOrder() const
Get the polynomial order.
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:43
unsigned int getNParameters() const
Return the number of function parameters.
Definition: Function.h:125
void serialize(Archive &ar, unsigned int const version)
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
std::vector< double > _xCoeffs
working vector: transformed coeffs of x polynomial
const double _multFac
precomputed scale factor
double _scaleY
y&#39; = (y + _offsetY) * _scaleY
void serialize(Archive &ar, unsigned int const version)
static int nParametersFromOrder(int order)
Compute number of parameters from polynomial order.
Definition: Function.h:431
void serialize(Archive &ar, unsigned int const version)
double _maxY
maximum allowed y
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
IntegerDeltaFunction2(double xo, double yo)
Construct an integer delta function with specified xo, yo.
double _cosAngle
cached cos(angle)
PolynomialFunction1(unsigned int order)
Construct a polynomial function of the specified order.
double _scaleX
x&#39; = (x + _offsetX) * _scaleX
void serialize(Archive &ar, unsigned int const)
virtual ReturnT operator()(double x, double y) const
1-dimensional integer delta function.
friend class boost::serialization::access
friend class boost::serialization::access
virtual void write(afw::table::io::OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
virtual bool isPersistable() const
Return true if this particular object can be persisted using afw::table::io.
virtual bool isLinearCombination() const
Is the function a linear combination of its parameters?
Function2< ReturnT >::Ptr Function2Ptr
A Function taking one argument.
Definition: Function.h:229
LanczosFunction1(unsigned int n, double xOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
std::vector< double > _xCoeffs
working vector
virtual Function1Ptr clone() const
Return a pointer to a deep copy of this function.
LanczosFunction2(unsigned int n, double xOffset=0.0, double yOffset=0.0)
Construct a Lanczos function of specified order and x,y offset.
virtual ReturnT operator()(double x, double y) const
double _offsetY
y&#39; = (y + _offsetY) * _scaleY
virtual std::string toString(std::string const &prefix) const
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.
double _sinAngle
cached sin(angle)
double getMinY() const
Definition: Box.h:345
virtual std::vector< double > getDFuncDParameters(double x, double y) const
Definition: Function.cc:36
virtual Function1Ptr clone() const
Return a pointer to a deep copy of this function.
double _maxX
maximum allowed x
double _offset
x&#39; = (x + _offset) * _scale
Function1< ReturnT >::Ptr Function1Ptr
virtual ReturnT operator()(double x) const
Function1< ReturnT >::Ptr Function1Ptr
int x
Function2< ReturnT >::Ptr Function2Ptr
virtual Chebyshev1Function2 truncate(int truncOrder) const
Return a truncated copy of lower (or equal) order.
double _minY
minimum allowed y
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
friend class boost::serialization::access
Function2< ReturnT >::Ptr Function2Ptr
std::vector< double > _yCheby
working vector: value of Tn(y&#39;)
virtual ReturnT operator()(double x) const
std::vector< double > _params
Definition: Function.h:204
void _initialize(double minX, double maxX)
initialize private constants
PolynomialFunction2(std::vector< double > params)
Construct a polynomial function with specified parameters.
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
double getMaxX() const
Get maximum allowed x.
afw::table::Key< double > sigma1
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
const double _multFac
precomputed scale factor
friend class boost::serialization::access
Chebyshev1Function1(unsigned int order, double minX=-1, double maxX=1)
Construct a Chebyshev polynomial of specified order and range.
double getMinX() const
Get minimum allowed x.
Define the basic Function classes.
Chebyshev1Function2(std::vector< double > params, lsst::afw::geom::Box2D const &xyRange=lsst::afw::geom::Box2D(lsst::afw::geom::Point2D(-1.0,-1.0), lsst::afw::geom::Point2D(1.0, 1.0)))
Construct a Chebyshev polynomial with specified parameters and range.
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
void _updateCache() const
Update cached values.
afw::table::Key< double > b
double _minX
minimum allowed x
virtual void write(afw::table::io::OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
unsigned int getOrder() const
Get the order of the Lanczos function.
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
double const PI
The ratio of a circle&#39;s circumference to diameter.
Definition: Angle.h:18
A floating-point coordinate rectangle geometry.
Definition: Box.h:271
boost::shared_ptr< Function2< ReturnT > > Ptr
Definition: Function.h:304
virtual Function1Ptr clone() const
Return a pointer to a deep copy of this function.
double _maxX
maximum allowed x
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
double getMaxX() const
Definition: Box.h:348
friend class boost::serialization::access
void _initialize(lsst::afw::geom::Box2D const &xyRange)
initialize private constants
virtual ReturnT operator()(double x, double y) const
afw::table::Key< double > sigma2
boost::shared_ptr< Function1< ReturnT > > Ptr
Definition: Function.h:233
void serialize(Archive &ar, unsigned int const version)
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
virtual bool isPersistable() const
Return true if this particular object can be persisted using afw::table::io.
virtual std::string toString(std::string const &prefix) const
Return a string representation of the function.
Function1< ReturnT >::Ptr Function1Ptr
virtual Function2Ptr clone() const
Return a pointer to a deep copy of this function.
1-dimensional polynomial function.
GaussianFunction2(double sigma1, double sigma2, double angle=0.0)
Construct a 2-dimensional Gaussian function.