casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SparseDiffA.h
Go to the documentation of this file.
00001 //# SparseDiff!A.h: An automatic differentiating class for functions
00002 //# Copyright (C) 2001,2002
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: SparseDiffA.h,v 1.1 2007/11/16 04:34:46 wbrouw Exp $
00028 
00029 #ifndef SCIMATH_SPARSEDIFFA_H
00030 #define SCIMATH_SPARSEDIFFA_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <scimath/Mathematics/SparseDiff.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038   //# Forward declarations
00039   template <class T> class Vector;
00040 
00041   // <summary>
00042   // Class that computes partial derivatives by automatic differentiation.
00043   // </summary>
00044   //
00045   // <use visibility=export>
00046   //
00047   // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tSparseDiff.cc" demos="dSparseDiff.cc">
00048   // </reviewed>
00049   //
00050   // <prerequisite>
00051   // <li> <linkto class=SparseDiff>SparseDiff</linkto>
00052   // </prerequisite>
00053   //
00054   // <etymology>
00055   // Class that computes partial derivatives by automatic differentiation, thus
00056   // SparseDiff.
00057   // </etymology>
00058   //
00059   // <synopsis>
00060   // SparseDiffA is an <linkto class=SparseDiff>SparseDiff</linkto>. It is used
00061   // to be able to distinguish between two template incarnations; e.g. to
00062   // have one or more specializations, in addition to the general template
00063   // version.
00064   // </synopsis>
00065   //
00066   // <example>
00067   // See for an extensive example the demo program dSparseDiff. It is
00068   // based on the example given in the <linkto class=SparseDiff>SparseDiff</linkto>
00069   // class, and shows how to have both an automatic and a specific version
00070   // of a function object.
00071   // <srcblock>
00072   //    // The function, with fixed parameters a,b:
00073   //    template <class T> class f {
00074   //    public:
00075   //      T operator()(const T& x) { return a_p*a_p*a_p*b_p*b_p*x; }
00076   //      void set(const T& a, const T& b) { a_p = a; b_p = b; }
00077   //    private:
00078   //      T a_p;
00079   //      T b_p;
00080   //    };
00081   //    // The specialized function
00082   //    template <> class f<SparseDiffA<Double> > {
00083   //    public:
00084   //      T operator()(const T& x) { return a_p*a_p*a_p*b_p*b_p*x; }
00085   //      void set(const T& a, const T& b) { a_p = a; b_p = b; }
00086   //    private:
00087   //      T a_p;
00088   //      T b_p;
00089   //    };
00090   //    // Call it with different template arguments:
00091   //      SparseDiff<Double> a1(2,0), b1(3,1), x1(7);
00092   //      f<SparseDiff<Double> > f1; f1.set(a1, b1);
00093   //      cout << "Diff a,b:   " << f1(x1) << endl;
00094   //    
00095   //      f<SparseDiffA<Double> > f12; f12.set(a1, b1);
00096   //      cout << "Same....:   " << f12(x1) << endl;
00097   //
00098   //    // Result will be:
00099   //    // Diff a,b:  (504, [756, 336])
00100   //    // Same....:  (504, [756, 336])
00101   //
00102   //    // It needed the template instantiations definitions:
00103   //    template class f<SparseDiff<Double> >;
00104   // </srcblock>
00105   // </example>
00106   //
00107   // <motivation>
00108   // The class was created to enable separate calculations of the same
00109   // function.
00110   // </motivation>
00111   //
00112   // <templating arg=T>
00113   //  <li> any class that has the standard mathematical and comparisons
00114   //    defined
00115   // </templating>
00116   //
00117   // <todo asof="2001/06/07">
00118   // <li> Nothing I know
00119   // </todo>
00120 
00121   template <class T> class SparseDiffA : public SparseDiff<T> {
00122   public:
00123     //# Constructors
00124     // Construct a constant with a value of zero.  Zero derivatives.
00125     SparseDiffA() : SparseDiff<T>() {}
00126 
00127     // Construct a constant with a value of v.  Zero derivatives.
00128     SparseDiffA(const T &v) : SparseDiff<T>(v) {}
00129 
00130     // A function f(x0,x1,...,xn,...) with a value of v.
00131     // The nth derivative is one, and all others are zero. 
00132     SparseDiffA(const T &v, const uInt n) :
00133       SparseDiff<T>(v, n) {} 
00134 
00135     // A function f(x0,x1,...,xn,...) with a value of v.  The 
00136     // nth derivative is der, and all other derivatives are zero. 
00137     SparseDiffA(const T &v, const uInt n, const T &der) :
00138       SparseDiff<T>(v, n, der) {} 
00139 
00140     // Construct one from another
00141     SparseDiffA(const SparseDiff<T> &other) : SparseDiff<T>(other) {}
00142 
00143     ~SparseDiffA() {}
00144 
00145     // Assignment operator.  Assign a constant to variable.  All derivatives
00146     // are zero.
00147     SparseDiffA<T> &operator=(const T &v) {
00148       SparseDiff<T>::operator=(v);
00149       return *this;
00150     }
00151 
00152     // Assignment operator.  Add a gradient to variable.
00153     SparseDiffA<T> &operator=(const pair<uInt, T> &der) {
00154       SparseDiff<T>::operator=(der);
00155       return *this;
00156     }
00157 
00158     // Assignment operator.  Assign gradients to variable.
00159     SparseDiffA<T> &operator=(const vector<pair<uInt, T> > &der) {
00160       SparseDiff<T>::operator=(der);
00161       return *this;
00162     }
00163 
00164     // Assign one to another (deep copy).
00165     SparseDiffA<T> &operator=(const SparseDiff<T> &other) {
00166       SparseDiff<T>::operator=(other);
00167       return *this;
00168     }
00169 
00170   private:
00171     //# Data
00172 
00173   };
00174 
00175 
00176 } //# NAMESPACE CASA - END
00177 
00178 #endif