casa
$Rev:20696$
|
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: SparseDiffX.h,v 1.1 2007/11/16 04:34:46 wbrouw Exp $ 00028 00029 #ifndef SCIMATH_SPARSEDIFFX_H 00030 #define SCIMATH_SPARSEDIFFX_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 // SparseDiffX 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<SparseDiffX<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<SparseDiffX<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 SparseDiffX : public SparseDiff<T> { 00122 public: 00123 //# Constructors 00124 // Construct a constant with a value of zero. Zero derivatives. 00125 SparseDiffX() : SparseDiff<T>() {} 00126 00127 // Construct a constant with a value of v. Zero derivatives. 00128 SparseDiffX(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 SparseDiffX(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 SparseDiffX(const T &v, const uInt n, const T &der) : 00138 SparseDiff<T>(v, n, der) {} 00139 00140 // Construct one from another 00141 SparseDiffX(const SparseDiff<T> &other) : SparseDiff<T>(other) {} 00142 00143 ~SparseDiffX() {} 00144 00145 // Assignment operator. Assign a constant to variable. All derivatives 00146 // are zero. 00147 SparseDiffX<T> &operator=(const T &v) { 00148 SparseDiff<T>::operator=(v); 00149 return *this; 00150 } 00151 00152 // Assignment operator. Add a gradient to variable. 00153 SparseDiffX<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 SparseDiffX<T> &operator=(const vector<pair<uInt, T> > &der) { 00160 SparseDiff<T>::operator=(der); 00161 return *this; 00162 } 00163 00164 00165 // Assign one to another (deep copy). 00166 SparseDiffX<T> &operator=(const SparseDiff<T> &other) { 00167 SparseDiff<T>::operator=(other); 00168 return *this; 00169 } 00170 00171 private: 00172 //# Data 00173 00174 }; 00175 00176 00177 } //# NAMESPACE CASA - END 00178 00179 #endif