LSSTApplications  18.1.0
LSSTDataManagementBasePackage
Function.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_FUNCTION_H
26 #define LSST_AFW_MATH_FUNCTION_H
27 /*
28  * Define the basic Function classes.
29  */
30 #include <cmath>
31 #include <stdexcept>
32 #include <sstream>
33 #include <vector>
34 
35 #include "boost/format.hpp"
36 
37 #include "lsst/daf/base/Citizen.h"
38 #include "lsst/pex/exceptions.h"
39 
41 
42 namespace lsst {
43 namespace afw {
44 namespace math {
45 
51 template <typename T>
52 bool constexpr IS_NOTHROW_INIT = noexcept(static_cast<T>(1.0));
53 
83 template <typename ReturnT>
85  public afw::table::io::PersistableFacade<Function<ReturnT>>,
87 public:
93  explicit Function(unsigned int nParams)
94  : lsst::daf::base::Citizen(typeid(this)), _params(nParams), _isCacheValid(false) {}
95 
99  explicit Function(std::vector<double> const& params)
100  : lsst::daf::base::Citizen(typeid(this)), _params(params), _isCacheValid(false) {}
101 
102  Function(Function const&) = default;
103  Function(Function&&) = default;
104  Function& operator=(Function const&) = default;
105  Function& operator=(Function&&) = default;
106 
107  ~Function() noexcept override = default;
108 
114  unsigned int getNParameters() const noexcept { return _params.size(); }
115 
121  virtual double getParameter(unsigned int ind)
122  const {
123  return _params[ind];
124  }
125 
131  std::vector<double> const& getParameters() const noexcept { return _params; }
132 
140  virtual bool isLinearCombination() const noexcept { return false; }
141 
145  void setParameter(unsigned int ind,
146  double newValue)
147  {
148  _isCacheValid = false;
149  _params[ind] = newValue;
150  }
151 
158  void setParameters(std::vector<double> const& params)
159  {
160  if (_params.size() != params.size()) {
161  throw LSST_EXCEPT(
163  (boost::format("params has %d entries instead of %d") % params.size() % _params.size())
164  .str());
165  }
166  _isCacheValid = false;
167  _params = params;
168  }
169 
175  virtual std::string toString(std::string const&) const {
177  os << "parameters: [ ";
178  for (std::vector<double>::const_iterator i = _params.begin(); i != _params.end(); ++i) {
179  if (i != _params.begin()) os << ", ";
180  os << *i;
181  }
182  os << " ]";
183  return os.str();
184  }
185 
186 protected:
188  mutable bool _isCacheValid;
189 
190  std::string getPythonModule() const override { return "lsst.afw.math"; }
191 
192  /* Default constructor: intended only for serialization */
193  explicit Function() : lsst::daf::base::Citizen(typeid(this)), _params(0), _isCacheValid(false) {}
194 };
195 
203 template <typename ReturnT>
204 class Function1 : public afw::table::io::PersistableFacade<Function1<ReturnT>>, public Function<ReturnT> {
205 public:
211  explicit Function1(unsigned int nParams)
212  : Function<ReturnT>(nParams) {}
213 
217  explicit Function1(std::vector<double> const& params)
218  : Function<ReturnT>(params) {}
219 
220  Function1(Function1 const&) = default;
221  Function1(Function1&&) = default;
222  Function1& operator=(Function1 const&) = default;
223  Function1& operator=(Function1&&) = default;
224 
225  ~Function1() noexcept override = default;
226 
238  virtual std::shared_ptr<Function1<ReturnT>> clone() const = 0;
239 
240  virtual ReturnT operator()(double x) const = 0;
241 
242  std::string toString(std::string const& prefix = "") const override {
243  return std::string("Function1: ") + Function<ReturnT>::toString(prefix);
244  }
245 
246  virtual void computeCache(int const n) {}
247 
248 protected:
249  /* Default constructor: intended only for serialization */
250  explicit Function1() : Function<ReturnT>() {}
251 };
252 
260 template <typename ReturnT>
261 class Function2 : public afw::table::io::PersistableFacade<Function2<ReturnT>>, public Function<ReturnT> {
262 public:
268  explicit Function2(unsigned int nParams)
269  : Function<ReturnT>(nParams) {}
270 
276  explicit Function2(std::vector<double> const& params)
277  : Function<ReturnT>(params) {}
278 
279  Function2(Function2 const&) = default;
280  Function2(Function2&&) = default;
281  Function2& operator=(Function2 const&) = default;
282  Function2& operator=(Function2&&) = default;
283 
284  ~Function2() noexcept override = default;
285 
297  virtual std::shared_ptr<Function2<ReturnT>> clone() const = 0;
298 
299  virtual ReturnT operator()(double x, double y) const = 0;
300 
301  std::string toString(std::string const& prefix = "") const override {
302  return std::string("Function2: ") + Function<ReturnT>::toString(prefix);
303  }
307  virtual std::vector<double> getDFuncDParameters(double, double) const {
309  "getDFuncDParameters is not implemented for this class");
310  }
311 
312 protected:
313  /* Default constructor: intended only for serialization */
314  explicit Function2() : Function<ReturnT>() {}
315 };
316 
327 template <typename ReturnT>
328 class BasePolynomialFunction2 : public Function2<ReturnT> {
329 public:
337  explicit BasePolynomialFunction2(unsigned int order)
338  : Function2<ReturnT>(BasePolynomialFunction2::nParametersFromOrder(order)), _order(order) {}
339 
349  : Function2<ReturnT>(params),
350  _order(BasePolynomialFunction2::orderFromNParameters(static_cast<int>(params.size()))) {}
351 
356 
357  ~BasePolynomialFunction2() noexcept override = default;
358 
362  int getOrder() const noexcept { return _order; }
363 
364  bool isLinearCombination() const noexcept override { return true; }
365 
371  static int nParametersFromOrder(int order) {
372  if (order < 0) {
374  os << "order=" << order << " invalid: must be >= 0";
376  }
377  return (order + 1) * (order + 2) / 2;
378  }
379 
394  static int orderFromNParameters(int nParameters) {
395  int order = static_cast<int>(
396  0.5 + ((-3.0 + (std::sqrt(1.0 + (8.0 * static_cast<double>(nParameters))))) / 2.0));
397  if (nParameters != BasePolynomialFunction2::nParametersFromOrder(order)) {
399  os << "nParameters=" << nParameters << " invalid: order is not an integer";
401  }
402  return order;
403  }
404 
413  std::vector<double> getDFuncDParameters(double x, double y) const override {
414  unsigned int const numParams = this->getNParameters(); // Number of parameters
415  std::vector<double> deriv(numParams); // Derivatives, to return
416 
418  this->clone(); // Dummy function to evaluate for derivatives
419  for (unsigned int i = 0; i < numParams; ++i) {
420  dummy->setParameter(i, 0.0);
421  }
422 
423  for (unsigned int i = 0; i < numParams; ++i) {
424  dummy->setParameter(i, 1.0);
425  deriv[i] = (*dummy)(x, y);
426  dummy->setParameter(i, 0.0);
427  }
428 
429  return deriv;
430  }
431 
432 protected:
433  int _order;
434 
435  /* Default constructor: intended only for serialization */
436  explicit BasePolynomialFunction2() : Function2<ReturnT>(1), _order(0) {}
437 };
438 
442 template <typename ReturnT>
443 class NullFunction1 : public Function1<ReturnT> {
444 public:
445  explicit NullFunction1() : Function1<ReturnT>(0) {}
448  }
449 
450 private:
451  ReturnT operator()(double) const noexcept(IS_NOTHROW_INIT<ReturnT>) override { return static_cast<ReturnT>(0); }
452 };
453 
457 template <typename ReturnT>
458 class NullFunction2 : public Function2<ReturnT> {
459 public:
460  explicit NullFunction2() : Function2<ReturnT>(0) {}
463  }
464 
465 private:
466  ReturnT operator()(double, double) const noexcept(IS_NOTHROW_INIT<ReturnT>) override {
467  return static_cast<ReturnT>(0);
468  }
469 };
470 } // namespace math
471 } // namespace afw
472 } // namespace lsst
473 
474 #endif // #ifndef LSST_AFW_MATH_FUNCTION_H
unsigned int getNParameters() const noexcept
Return the number of function parameters.
Definition: Function.h:114
std::vector< double > getDFuncDParameters(double x, double y) const override
Return the derivative of the Function with respect to its parameters.
Definition: Function.h:413
int _order
order of polynomial
Definition: Function.h:433
bool isLinearCombination() const noexcept override
Is the function a linear combination of its parameters?
Definition: Function.h:364
bool constexpr IS_NOTHROW_INIT
Test that a Function&#39;s return value is nothrow-castable to T.
Definition: Function.h:52
std::shared_ptr< Function1< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
Definition: Function.h:446
~Function() noexcept override=default
int y
Definition: SpanSet.cc:49
Function2(unsigned int nParams)
Construct a Function2 given the number of function parameters.
Definition: Function.h:268
T end(T... args)
std::string prefix
Definition: SchemaMapper.cc:79
BasePolynomialFunction2(std::vector< double > params)
Construct a polynomial function with specified parameters.
Definition: Function.h:348
Function1(unsigned int nParams)
Construct a Function1 given the number of function parameters.
Definition: Function.h:211
A Function taking two arguments.
Definition: Function.h:261
Base class for 2-dimensional polynomials of the form:
Definition: Function.h:328
STL class.
A base class for objects that can be persisted via afw::table::io Archive classes.
Definition: Persistable.h:74
BasePolynomialFunction2(unsigned int order)
Construct a polynomial function of specified order.
Definition: Function.h:337
static int nParametersFromOrder(int order)
Compute number of parameters from polynomial order.
Definition: Function.h:371
a class used in function calls to indicate that no Function2 is being provided
Definition: Function.h:458
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
std::vector< double > _params
Definition: Function.h:187
std::string toString(std::string const &prefix="") const override
Return a string representation of the function.
Definition: Function.h:301
A base class for image defects.
virtual double getParameter(unsigned int ind) const
Get one function parameter without range checking.
Definition: Function.h:121
virtual std::vector< double > getDFuncDParameters(double, double) const
Return the derivative of the Function with respect to its parameters.
Definition: Function.h:307
std::vector< double > const & getParameters() const noexcept
Return all function parameters.
Definition: Function.h:131
Function(unsigned int nParams)
Construct a Function given the number of function parameters.
Definition: Function.h:93
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
virtual bool isLinearCombination() const noexcept
Is the function a linear combination of its parameters?
Definition: Function.h:140
A Function taking one argument.
Definition: Function.h:204
T str(T... args)
Function & operator=(Function const &)=default
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: Function.h:190
Basic Function class.
Definition: Function.h:84
double x
a class used in function calls to indicate that no Function1 is being provided
Definition: Function.h:443
T size(T... args)
Function(std::vector< double > const &params)
Construct a Function given the function parameters.
Definition: Function.h:99
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
Function2(std::vector< double > const &params)
Construct a Function2 given the function parameters.
Definition: Function.h:276
void setParameters(std::vector< double > const &params)
Set all function parameters.
Definition: Function.h:158
Citizen(const std::type_info &)
Definition: Citizen.cc:163
T begin(T... args)
void setParameter(unsigned int ind, double newValue)
Set one function parameter without range checking.
Definition: Function.h:145
std::string toString(std::string const &prefix="") const override
Return a string representation of the function.
Definition: Function.h:242
Reports invalid arguments.
Definition: Runtime.h:66
Function1(std::vector< double > const &params)
Construct a Function1 given the function parameters.
Definition: Function.h:217
int getOrder() const noexcept
Get the polynomial order.
Definition: Function.h:362
virtual void computeCache(int const n)
Definition: Function.h:246
T sqrt(T... args)
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...
Definition: Citizen.h:55
virtual std::string toString(std::string const &) const
Return a string representation of the function.
Definition: Function.h:175
A CRTP facade class for subclasses of Persistable.
Definition: Persistable.h:176
static int orderFromNParameters(int nParameters)
Compute polynomial order from the number of parameters.
Definition: Function.h:394
std::shared_ptr< Function2< ReturnT > > clone() const override
Return a pointer to a deep copy of this function.
Definition: Function.h:461
std::ostream * os
Definition: Schema.cc:746