casacore
Public Types | Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
casacore::SparseDiff< T > Class Template Reference

More...

#include <SparseDiff.h>

Public Types

typedef T value_type
 
typedef value_typereference
 
typedef const value_typeconst_reference
 
typedef value_typeiterator
 
typedef const value_typeconst_iterator
 

Public Member Functions

 SparseDiff ()
 Construct a constant with a value of zero. More...
 
 SparseDiff (const T &v)
 Construct a constant with a value of v. More...
 
 SparseDiff (const T &v, const uInt n)
 A function f(x0,x1,...,xn,...) with a value of v. More...
 
 SparseDiff (const T &v, const uInt n, const T &der)
 A function f(x0,x1,...,xn,...) with a value of v. More...
 
 SparseDiff (const AutoDiff< T > &other)
 Construct from an AutoDiff. More...
 
 SparseDiff (const SparseDiff< T > &other)
 Construct one from another (deep copy) More...
 
 ~SparseDiff ()
 Destructor. More...
 
SparseDiff< T > & operator= (const T &v)
 Assignment operator. More...
 
SparseDiff< T > & operator= (const pair< uInt, T > &der)
 Assignment operator. More...
 
SparseDiff< T > & operator= (const vector< pair< uInt, T > > &der)
 Assignment operator. More...
 
SparseDiff< T > & operator= (const AutoDiff< T > &other)
 Assign from an Autodiff. More...
 
SparseDiff< T > & operator= (const SparseDiff< T > &other)
 Assign one to another (deep copy) More...
 
void operator*= (const SparseDiff< T > &other)
 Assignment operators. More...
 
void operator/= (const SparseDiff< T > &other)
 
void operator+= (const SparseDiff< T > &other)
 
void operator-= (const SparseDiff< T > &other)
 
void operator*= (const T other)
 
void operator/= (const T other)
 
void operator+= (const T other)
 
void operator-= (const T other)
 
AutoDiff< T > toAutoDiff (uInt n) const
 Convert to an AutoDiff of length n More...
 
SparseDiffRep< T > * theRep ()
 Returns the pointer to the structure of value and derivatives. More...
 
const SparseDiffRep< T > * theRep () const
 
T & value ()
 Returns the value of the function. More...
 
const T & value () const
 
vector< pair< uInt, T > > & derivatives () const
 Returns a vector of the derivatives of a SparseDiff. More...
 
void derivatives (vector< pair< uInt, T > > &res) const
 
const vector< pair< uInt, T > > & grad () const
 
vector< pair< uInt, T > > & grad ()
 
pair< uInt, T > & derivative (uInt which)
 Returns a specific derivative. More...
 
const pair< uInt, T > & derivative (uInt which) const
 
uInt nDerivatives () const
 Return total number of derivatives. More...
 
Bool isConstant () const
 Is it a constant, i.e., with zero derivatives? More...
 
void sort ()
 Sort derivative list; cater for doubles and zeroes. More...
 

Static Public Member Functions

static Bool ltSort (pair< uInt, T > &lhs, pair< uInt, T > &rhs)
 Sort criterium. More...
 

Private Attributes

SparseDiffRep< T > * rep_p
 Value representation. More...
 

Detailed Description

template<class T>
class casacore::SparseDiff< T >

Class that computes partial derivatives by automatic differentiation.

Intended use:

Public interface

Review Status

Reviewed By:
UNKNOWN
Test programs:
tSparseDiff
Demo programs:
dSparseDiff

Prerequisite

Etymology

Class that computes partial derivatives for some parameters by automatic differentiation, thus SparseDiff.

Synopsis

Class that computes partial derivatives by automatic differentiation. It does this by storing the value of a function and the values of its first derivatives with respect to some of its independent parameters. When a mathematical operation is applied to a SparseDiff object, the derivative values of the resulting new object are computed according to the chain rules of differentiation. SparseDiff operates like the AutoDiff class, but only determines the derivatives with respect to the actual dependent variables.

Suppose we have a function f(x0,x1,...,xn) and its differential is

df = (df/dx0)*dx0 + (df/dx1)*dx1 +... + (df/dxn)*dxn


We can build a class that has the value of the function, f(x0,x1,...,xn), and the values of the derivatives, (df/dx0), (df/dx1), ..., (df/dxn) at (x0,x1,...,xn), as class members.

Now if we have another function, g(x0,x1,...,xn) and its differential is dg = (dg/dx0)*dx0 + (dg/dx1)*dx1 +... + (dg/dxn)*dxn, since

d(f+g) = df + dg,
d(f*g) = g*df + f*dg,
d(f/g) = df/g - fdg/g^2,
dsin(f) = cos(f)df,
...,
LatticeExprNode cos(const LatticeExprNode &expr)


we can calculate

d(f+g), d(f*g),...,

based on our information on

df/dx0, df/dx1,..., dg/dx0, dg/dx1,..., dg/dxn.


All we need to do is to define the operators and derivatives of common mathematical functions.

To be able to use the class as an automatic differentiator of a function object, we need a templated function object, i.e. an object with:

A simple example of such a function object could be:

template <class T> f {
public:
T operator()(const T &x, const T &a, const T &b) {
return a*b*x; }
};
// Instantiate the following versions:
template class f<Double>;
template class f<SparseDiff<Double> >;

A call with values will produce the function value:

cout << f(7.0, 2.0, 3.0) << endl;
// will produce the value at x=7 for a=2; b=3:
42
// But a call indicating that we want derivatives to a and b:
cout << f(SparseDiff<Double>(7.0), SparseDiff<Double>(2.0, 0),
SparseDiff<Double>(3.0, 1)) << endl;
// will produce the value at x=7 for a=2; b=3:
// and the partial derivatives wrt a and b at x=7:
(42, [21, 14])
// The following will calculate the derivate wrt x:
cout << f(SparseDiff<Double>(7.0, 0), SparseDiff<Double>(2.0),
SparseDiff<Double>(3.0)) << endl;
(42,[6])

Note that in practice constants may be given as Double constants. In actual practice, there are a few rules to obey for the structure of the function object if you want to use the function object and its derivatives in least squares fitting procedures in the Fitting module. The major one is to view the function object having 'fixed' and 'variable' parameters. I.e., rather than viewing the function as depending on parameters a, b, x (f(a,b,x)), the function is considered to be f(x; a,b), where a, b are 'fixed' parameters, and x a variable parameter. Fixed parameters should be contained in a FunctionParam container object; while the variable parameter(s) are given in the function operator(). See Function class for details.

A Gaussian spectral profile would in general have the center frequency, the width and the amplitude as fixed parameters, and the frequency as a variable. Given a spectrum, you would solve for the fixed parameters, given spectrum values. However, in other cases the role of the parameters could be reversed. An example could be a whole stack of observed (in the laboratory) spectra at different temperatures at one frequency. In that case the width would be the variable parameter, and the frequency one of the fixed (and to be solved for)parameters.

Since the calculation of the derivatives is done with simple overloading, the calculation of second (and higher) derivatives is easy. It should be noted that higher deivatives are inefficient in the current incarnation (there is no knowledge e.g. about symmetry in the Jacobian). However, it is a very good way to get the correct answers of the derivatives. In practice actual production code will be better off with specialization of the f<SparseDiff<> > implementation.

The SparseDiff class is the class the user communicates with. Alias classes (SparseDiffA and SparseDiffX) exist to make it possible to have different incarnations of a templated method (e.g. a generic one and a specialized one). See the dSparseDiff demo for an example of its use.

All operators and functions are declared in (see (file=SparseDiffMath.h)) SparseDiffMath. The output operator in (see (file=SparseDiffIO.h))SparseDiffIO. The actual structure of the data block used by SparseDiff is described in SparseDiffRep.

A SparseDiff can be constructed from an AutoDiff. toAutoDiff(n) can convert it to an AutoDiff.

Example

// First a simple example.
// We have a function of the form f(x,y,z); and want to know the
// value of the function for x=10; y=20; z=30; and for
// the derivatives at those points.
// Specify the values; and indicate the parameter dependence:
SparseDiff<Double> x(10.0, 0);
SparseDiff<Double> y(20.0, 1);
SparseDiff<Double> z(30.0, 2);
// The result will be:
SparseDiff<Double> result = x*y + sin(z);
cout << result.value() << endl;
// 199.012
cout << result.derivatives() << endl;
// [20, 10, 0.154251]
// Note: sin(30) = -0.988; cos(30) = 0.154251;
LatticeExprNode sin(const LatticeExprNode &expr)
Numerical 1-argument functions.

See for an extensive example the demo program dSparseDiff. It is based on the example given above, and shows also the use of second derivatives (which is just using SparseDiff<SparseDiff<Double> > as template argument).

// The function, with fixed parameters a,b:
template <class T> class f {
public:
T operator()(const T& x) { return a_p*a_p*a_p*b_p*b_p*x; }
void set(const T& a, const T& b) { a_p = a; b_p = b; }
private:
T a_p;
T b_p;
};
// Call it with different template arguments:
Double a0(2), b0(3), x0(7);
f<Double> f0; f0.set(a0, b0);
cout << "Value: " << f0(x0) << endl;
SparseDiff<Double> a1(2,0), b1(3,1), x1(7);
f<SparseDiff<Double> > f1; f1.set(a1, b1);
cout << "Diff a,b: " << f1(x1) << endl;
SparseDiff<Double> a2(2), b2(3), x2(7,0);
f<SparseDiff<Double> > f2; f2.set(a2, b2);
cout << "Diff x: " << f2(x2) << endl;
SparseDiff<SparseDiff<Double> > a3(SparseDiff<Double>(2,0),0),
b3(SparseDiff<Double>(3,1),1), x3(SparseDiff<Double>(7));
f<SparseDiff<SparseDiff<Double> > > f3; f3.set(a3, b3);
cout << "Diff2 a,b: " << f3(x3) << endl;
SparseDiff<SparseDiff<Double> > a4(SparseDiff<Double>(2)),
b4(SparseDiff<Double>(3)),
x4(SparseDiff<Double>(7,0),0);
f<SparseDiff<SparseDiff<Double> > > f4; f4.set(a4, b4);
cout << "Diff2 x: " << f4(x4) << endl;
// Result will be:
// Value: 504
// Diff a,b: (504, [756, 336])
// Diff x: (504, [72])
// Diff2 a,b: ((504, [756, 336]), [(756, [756, 504]), (336, [504, 112])])
// Diff2 x: ((504, [72]), [(72, [0])])
// It needed the template instantiations definitions:
template class f<Double>;
template class f<SparseDiff<Double> >;
template class f<SparseDiff<SparseDiff<Double> > >;
double Double
Definition: aipstype.h:55

Motivation

The creation of the class was motivated by least-squares non-linear fits in cases where each individual condition equation depends only on a fraction of the fixed parameters (e.g. self-calibration where only pairs of antennas are present per equation), and hence only a few partial derivatives of a fitted function are needed. It would be tedious to create functionals for all partial derivatives of a function.

Template Type Argument Requirements (T)

To Do

Definition at line 279 of file SparseDiff.h.

Member Typedef Documentation

◆ const_iterator

template<class T >
typedef const value_type* casacore::SparseDiff< T >::const_iterator

Definition at line 286 of file SparseDiff.h.

◆ const_reference

template<class T >
typedef const value_type& casacore::SparseDiff< T >::const_reference

Definition at line 284 of file SparseDiff.h.

◆ iterator

template<class T >
typedef value_type* casacore::SparseDiff< T >::iterator

Definition at line 285 of file SparseDiff.h.

◆ reference

template<class T >
typedef value_type& casacore::SparseDiff< T >::reference

Definition at line 283 of file SparseDiff.h.

◆ value_type

template<class T >
typedef T casacore::SparseDiff< T >::value_type

Definition at line 282 of file SparseDiff.h.

Constructor & Destructor Documentation

◆ SparseDiff() [1/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( )

Construct a constant with a value of zero.

Zero derivatives.

◆ SparseDiff() [2/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( const T &  v)

Construct a constant with a value of v.

Zero derivatives.

◆ SparseDiff() [3/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( const T &  v,
const uInt  n 
)

A function f(x0,x1,...,xn,...) with a value of v.

The nth derivative is one, and all other derivatives are zero.

◆ SparseDiff() [4/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( const T &  v,
const uInt  n,
const T &  der 
)

A function f(x0,x1,...,xn,...) with a value of v.

The nth derivative is der, and all other derivatives are zero.

◆ SparseDiff() [5/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( const AutoDiff< T > &  other)

Construct from an AutoDiff.

◆ SparseDiff() [6/6]

template<class T >
casacore::SparseDiff< T >::SparseDiff ( const SparseDiff< T > &  other)

Construct one from another (deep copy)

◆ ~SparseDiff()

template<class T >
casacore::SparseDiff< T >::~SparseDiff ( )

Destructor.

Member Function Documentation

◆ derivative() [1/2]

template<class T >
pair<uInt, T>& casacore::SparseDiff< T >::derivative ( uInt  which)
inline

Returns a specific derivative.

No check for a valid which.

Definition at line 366 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ derivative() [2/2]

template<class T >
const pair<uInt, T>& casacore::SparseDiff< T >::derivative ( uInt  which) const
inline

Definition at line 367 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ derivatives() [1/2]

template<class T >
vector<pair<uInt, T> >& casacore::SparseDiff< T >::derivatives ( ) const

Returns a vector of the derivatives of a SparseDiff.

◆ derivatives() [2/2]

template<class T >
void casacore::SparseDiff< T >::derivatives ( vector< pair< uInt, T > > &  res) const

◆ grad() [1/2]

template<class T >
vector<pair<uInt, T> >& casacore::SparseDiff< T >::grad ( )
inline

Definition at line 361 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ grad() [2/2]

template<class T >
const vector<pair<uInt, T> >& casacore::SparseDiff< T >::grad ( ) const
inline

Definition at line 360 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ isConstant()

template<class T >
Bool casacore::SparseDiff< T >::isConstant ( ) const
inline

Is it a constant, i.e., with zero derivatives?

Definition at line 375 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ ltSort()

template<class T >
static Bool casacore::SparseDiff< T >::ltSort ( pair< uInt, T > &  lhs,
pair< uInt, T > &  rhs 
)
static

Sort criterium.

◆ nDerivatives()

template<class T >
uInt casacore::SparseDiff< T >::nDerivatives ( ) const
inline

Return total number of derivatives.

Definition at line 372 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ operator*=() [1/2]

template<class T >
void casacore::SparseDiff< T >::operator*= ( const SparseDiff< T > &  other)

Assignment operators.

◆ operator*=() [2/2]

template<class T >
void casacore::SparseDiff< T >::operator*= ( const T  other)
inline

◆ operator+=() [1/2]

template<class T >
void casacore::SparseDiff< T >::operator+= ( const SparseDiff< T > &  other)

◆ operator+=() [2/2]

template<class T >
void casacore::SparseDiff< T >::operator+= ( const T  other)
inline

Definition at line 337 of file SparseDiff.h.

References casacore::SparseDiff< T >::value().

◆ operator-=() [1/2]

template<class T >
void casacore::SparseDiff< T >::operator-= ( const SparseDiff< T > &  other)

◆ operator-=() [2/2]

template<class T >
void casacore::SparseDiff< T >::operator-= ( const T  other)
inline

Definition at line 338 of file SparseDiff.h.

References casacore::SparseDiff< T >::value().

◆ operator/=() [1/2]

template<class T >
void casacore::SparseDiff< T >::operator/= ( const SparseDiff< T > &  other)

◆ operator/=() [2/2]

template<class T >
void casacore::SparseDiff< T >::operator/= ( const T  other)
inline

◆ operator=() [1/5]

template<class T >
SparseDiff<T>& casacore::SparseDiff< T >::operator= ( const AutoDiff< T > &  other)

Assign from an Autodiff.

◆ operator=() [2/5]

template<class T >
SparseDiff<T>& casacore::SparseDiff< T >::operator= ( const pair< uInt, T > &  der)

Assignment operator.

Add a gradient to variable.

◆ operator=() [3/5]

template<class T >
SparseDiff<T>& casacore::SparseDiff< T >::operator= ( const SparseDiff< T > &  other)

Assign one to another (deep copy)

◆ operator=() [4/5]

template<class T >
SparseDiff<T>& casacore::SparseDiff< T >::operator= ( const T &  v)

Assignment operator.

Assign a constant to variable.

Referenced by casacore::SparseDiffA< T >::operator=(), and casacore::SparseDiffX< T >::operator=().

◆ operator=() [5/5]

template<class T >
SparseDiff<T>& casacore::SparseDiff< T >::operator= ( const vector< pair< uInt, T > > &  der)

Assignment operator.

Assign gradients to variable.

◆ sort()

template<class T >
void casacore::SparseDiff< T >::sort ( )

Sort derivative list; cater for doubles and zeroes.

◆ theRep() [1/2]

template<class T >
SparseDiffRep<T>* casacore::SparseDiff< T >::theRep ( )
inline

Returns the pointer to the structure of value and derivatives.

Definition at line 346 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ theRep() [2/2]

template<class T >
const SparseDiffRep<T>* casacore::SparseDiff< T >::theRep ( ) const
inline

Definition at line 347 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

◆ toAutoDiff()

template<class T >
AutoDiff<T> casacore::SparseDiff< T >::toAutoDiff ( uInt  n) const

Convert to an AutoDiff of length n

◆ value() [1/2]

template<class T >
T& casacore::SparseDiff< T >::value ( )
inline

◆ value() [2/2]

template<class T >
const T& casacore::SparseDiff< T >::value ( ) const
inline

Definition at line 353 of file SparseDiff.h.

References casacore::SparseDiff< T >::rep_p.

Member Data Documentation

◆ rep_p

template<class T >
SparseDiffRep<T>* casacore::SparseDiff< T >::rep_p
private

The documentation for this class was generated from the following file: