The parameter interface is provided by the
FunctionParam class.
A Function can have a name() which can be used in generic
interfaces.
The function calls implemented are:
A shorter version, where all parameter handling is done at user level
could be:
Constructors
Destructor
Manipulate the nth parameter (0-based) with no index check
Specify the name associated with the function (default will be
unknown)
get/set the function mode. These provide an interface to
function-specific configuration or state that controls how the
function calculates its values but otherwise does not qualify as
a parameter. Some part of the state, for example, might have a
type different from that of T. The state is passed as fields of a
record, mode--the names, types and values of which are specific to
the implementing function and should be documented in the implementing
class. It is recommended that all possible inputs passed to this
function via setMode() be considered optional such that if the
record omits a legal field, that part of the state is left unchanged.
Fields not recognized by the implementing class should be ignored.
An exception should be thrown if a recognized field contains illegal
data. The default implementations for both getMode() and setMode()
ignore the input record.
return True if the implementing function supports a mode. The default
implementation returns False.
Print the function (i.e. the parameters)
Prerequisite
Synopsis
A Function is used for classes which map a
scalar or n-dimensional Vector of type T into a T.
The object also has zero or more parameters which can be masked
if necessary, and be used in the Fitting module, and, implicitly,
in the AutoDiff differentiation module.
The T in the above is the Function::ArgType
as derived from the FunctionTraits
class.
These calls are (in debug mode) tested for the correct number of arguments,
after which they call a T eval(FunctionArg x) const = 0 to
be implemented in derived classes. The derived class should also implement
an uInt ndim() const = 0. The derived class can access the
nth parameter with the [n] operator, and the corresponding
mask with mask(n) method.
The variables are referenced with x[i].
Example
A complete implementation of say an A.sin(2pi.f.x) with
parameters amplitude(A) and frequency(f) and variable
time(x) could be:
//# Sinusoid.h
#include <casa/aips.h>
#include <scimath/Functionals/Function.h>
#include <casa/BasicSL/Constants.h>
#include <casa/BasicMath/Math.h>
// The sinusoid class
template<class T> class Sinusoid : public Function<T> {
public:
// For easy reference of the parameters
enum { AMPL=0, FREQ };
// Constructors. Defaults are A=1, f=1
Sinusoid() : Function<T>(2) {
param_p[AMPL] = T(1.0); param_p[FREQ] = T(1.0); }
explicit Sinusoid(const T &l) : Function<T>(2) {
param_p[AMPL] = ampl; param_p[FREQ] = T(1.0); }
Sinusoid(const T &l, const T &freq) : Function<T>(2) {
param_p[AMPL] = ampl; param_p[FREQ] = freq; }
Sinusoid(const Sinusoid &other) : Function<T>(2) {
param_p[AMPL] = other.param_p[AMPL];
param_p[FREQ] = other.parameter[FREQ]; }
Sinusoid<T> &operator=(const Sinusoid<T> &other) {
if (this != &other) param_p = other.param_p;
return *this; }
virtual ~Sinusoid() {};
// Dimensionality
virtual uInt ndim() const { return 2; };
// Evaluate
virtual T eval(Function<T>::FunctionArg x) const {
return param_p[AMPL]*sin(T(C::_2pi)*param_p[FREQ]*x[0]); };
// Copy it
virtual Function<T> *clone() const { return new Sinusoid<T>(param_p); };
};
The following will calculate the value and the derivative for
A=2; f=3; x=0.1;
// The function objects for value, and for value + derivative
Sinusoid<Double> soid1(2.0, 3.0);
typedef AutoDiff<Double> Adif;
Sinusoid<Adif> soid2(Adif(2,2,0), Adif(3,2,1));
cout << "Value: " << soid1(0.1) << endl;
cout << "(val, deriv): " << soid2(Adif(0.1)) << endl;
//# Sinusoid.h
#include <casa/aips.h>
#include <scimath/Functionals/Function.h>
#include <casa/BasicSL/Constants.h>
#include <casa/BasicMath/Math.h>
template<class T> class Sinusoid : public Function<T> {
public:
enum { AMPL=0, FREQ };
Sinusoid() : Function<T>(2){param_p[AMPL] T(1);param_p[FREQ]=T(1);}
virtual ~Sinusoid() {};
virtual uInt ndim() const { return 2; };
virtual T eval(Function<T>::FunctionArg x) const {
return param_p[AMPL]*sin(T(C::_2pi)*param_p[FREQ]*x[0]); };
virtual Function<T> *clone() const { return new Sinusoid<T>param_p; };
};
The following will calculate the value and the derivative for
A=2; f=3; x=0.1;
// The function objects for value, and for value + derivative
typedef AutoDiff<Double> Adif;
typedef Function<Double> FD;
typedef Function<AutoDiff<Double> > FAdif
Sinusoid<Double> soid1;
Sinusoid<Adif> soid2;
soid1[FD::AMPL] = 2; soid1[FD::FREQ] = 3;
soid2[FAdif::AMPL] = Adif(2,2,0);
soid2[FAdif::FREQ] = Adif(3,2,1);
cout << "Value: " << soid1(0.1) << endl;
cout << "(val, deriv): " << soid2(Adif(0.1)) << endl;
Motivation
A function of more than one variable was required for a function which
represents the sky brightness. Adjustable parameters were required for
non-linear least squares fitting.
Template Type Argument Requirements (T)
To Do
Member Description
Function() : param_p(), arg_p(0), parset_p(False), locked_p(False)
explicit Function(const uInt n) : param_p(n), arg_p(0), parset_p(False), locked_p(False)
explicit Function(const Vector<T> &in) : param_p(in), arg_p(0), parset_p(False), locked_p(False)
Function(const FunctionParam<T> &other) : param_p(other), arg_p(0), parset_p(False), locked_p(False)
template <class W, class X> Function(const Function<W,X> &other) : param_p(other.parameters()), arg_p(0), parset_p(other.parsetp()), locked_p(False)
Function(const Function<T,U> &other) : param_p(other.param_p), arg_p(other.arg_p), parset_p(other.parset_p), locked_p(False)
virtual ~Function()
virtual uInt ndim() const = 0
Returns the number of dimensions of function
uInt nparameters() const
Returns the number of parameters
virtual U eval(FunctionArg x) const = 0
Evaluate the function object
T &operator[](const uInt n)
const T &operator[](const uInt n) const
virtual U operator()() const
Evaluate this function object at xor at x, y.
The length of x must be greater than or equal to
ndim().
virtual U operator()(const ArgType &x) const
virtual U operator()(const Vector<ArgType> &x) const
virtual U operator()(FunctionArg x) const
virtual U operator()(const ArgType &x, const ArgType &y) const
virtual U operator()(const ArgType &x, const ArgType &y, const ArgType &z) const
virtual const String &name() const
Bool &mask(const uInt n)
Manipulate the mask associated with the nth parameter
(e.g. to indicate whether the parameter is adjustable or
nonadjustable).
Note: no index check.
const Bool &mask(const uInt n) const
const FunctionParam<T> ¶meters() const
Return the parameter interface
FunctionParam<T> ¶meters()
const Vector<ArgType> &argp() const
Get arg_p and parset_p. Necessary for reasons
of protection in the copying of non-conforming Functions.
const Bool parsetp() const
void lockParam()
Compiler cannot always find the correct 'const' version of parameter
access. In cases where this would lead to excessive overheads in
moving parameters around (like in CompoundFunction) the
parameter changing can be set to be locked, and no changes are
assumed.
void unlockParam()
virtual void setMode(const RecordInterface& mode)
virtual void getMode(RecordInterface& mode) const
virtual Bool hasMode() const
ostream &print(ostream &os) const
virtual Function<T,U> *clone() const = 0
Return a copy of this object from the heap. The caller is responsible
for deleting this pointer. The cloneAD will return a clone
with an AutoDef<T>; the cloneNonAD a clone
with <T>. An AipsError will be thrown if the
cloneAD() or cloneNonAD() is not implemented
for a specific function.
virtual Function<typename FunctionTraits<T>::DiffType> *cloneAD() const
virtual Function<typename FunctionTraits<T>::BaseType> *cloneNonAD() const
Global functions (source)
Interface
Description
Member Description
ostream &operator<<(ostream &os, const Function<T,U> &fun)
Output declaration