1 /*
2 
3 -Procedure uddf_c ( First derivative of a function, df(x)/dx )
4 
5 -Abstract
6 
7    Routine to calculate the first derivative of a caller-specified
8    function using a three-point estimation.
9 
10 -Disclaimer
11 
12    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
13    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
14    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
15    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
16    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
17    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
18    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
19    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
20    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
21    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
22 
23    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
24    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
25    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
26    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
27    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
28    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
29 
30    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
31    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
32    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
33    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
34 
35 -Required_Reading
36 
37    None.
38 
39 -Keywords
40 
41    DERIVATIVE
42 
43 */
44 
45    #include "SpiceUsr.h"
46    #include "SpiceZfc.h"
47    #undef   uddf_c
48 
uddf_c(void (* udfunc)(SpiceDouble et,SpiceDouble * value),SpiceDouble x,SpiceDouble dx,SpiceDouble * deriv)49    void uddf_c (  void             ( * udfunc ) ( SpiceDouble    et,
50                                                   SpiceDouble  * value ),
51                   SpiceDouble          x,
52                   SpiceDouble          dx,
53                   SpiceDouble        * deriv )
54 
55 /*
56 -Brief_I/O
57 
58      Variable  I/O  Description
59      --------  ---  --------------------------------------------------
60      udfunc     I   Name of the routine that computes the scalar value
61                     of interest.
62      x          I   Independent variable of 'udfunc'
63      dx         I   Interval from 'x' for derivative calculation
64      deriv      O   Approximate derivative of 'udfunc' at 'x'
65 
66 -Detailed_Input
67 
68      udfunc     is an externally specified routine that returns the
69                 value of the scalar quantity function of interest
70                 at x.
71 
72                 The prototype for 'udfunc' is
73 
74                     void   ( * udfunc ) ( SpiceDouble    et,
75                                           SpiceDouble  * value )
76 
77                 where:
78 
79                     et      an input double precision value of the independent
80                             variable the function at which to determine the
81                             scalar value.
82 
83                     value   the scalar double precision value of 'udfunc'
84                             at 'x'.
85 
86      x          a scalar double precision value representing the independent
87                 variable at which to determine the derivative of 'udfunc'.
88 
89                 For many SPICE uses, 'x' will represent the TDB ephemeris
90                 time.
91 
92      dx         a scalar double precision value representing half the
93                 interval in units of X separating the evaluation
94                 epochs of UDFUNC; the evaluations occur at (x + dx))
95                 and (x - dx).
96 
97                 'dx' may be negative but must be non-zero.
98 
99 -Detailed_Output
100 
101      deriv      the scalar double precision approximate value of the
102                 first derivative of udfunc with respect to 'x'.
103 
104                 Functionally:
105 
106                             d  udfunc ( x )
107                    deriv =  --
108                             dx
109 
110 -Parameters
111 
112    None.
113 
114 -Exceptions
115 
116    None.
117 
118 -Files
119 
120    None.
121 
122 -Particulars
123 
124    This routine provides a simple interface to numerically calculate
125    the first derivative of a scalar quantity function.
126 
127 -Examples
128 
129    The numerical results shown for these examples may differ across
130    platforms. The results depend on the SPICE kernels used as
131    input, the compiler and supporting libraries, and the machine
132    specific arithmetic implementation.
133 
134 
135       #include <stdio.h>
136       #include "SpiceUsr.h"
137 
138       void udfunc ( SpiceDouble et, SpiceDouble * value );
139 
140       int main()
141          {
142 
143          SpiceDouble       et;
144          SpiceDouble       dt;
145          SpiceDouble       deriv;
146 
147          /.
148          Load leapsecond and SPK kernels. The name of the
149          meta kernel file shown here is fictitious; you
150          must supply the name of a file available
151          on your own computer system.
152          ./
153 
154          furnsh_c ( "standard.tm" );
155 
156          /.
157          Use a shift of one second off the epoch of interest.
158          ./
159          dt = 1.;
160 
161          /.
162          Convert the epoch date string to ephemeris seconds.
163          ./
164          str2et_c ( "JAN 1 2009", &et );
165 
166          /.
167          Calculate the derivative of UDFUNC at ET.
168          ./
169          uddf_c( udfunc, et, dt, &deriv );
170 
171          /.
172          Output the calculated derivative.
173          ./
174 
175          printf( "%18.12f\n", deriv );
176 
177          return ( 0 );
178          }
179 
180 
181       /.
182       A scalar quantity function that returns the light-time
183       between the Moon and Mercury at 'et'.
184       ./
185 
186       void udfunc ( SpiceDouble et, SpiceDouble * value )
187          {
188 
189          SpiceDouble          lt;
190          SpiceDouble          pos[3];
191 
192          /.
193          Evaluate the apparent position of Mercury with respect
194          to the Moon at 'et'.
195          ./
196          spkpos_c ( "MERCURY", et, "J2000", "LT+S", "MOON", pos, &lt );
197 
198          /.
199          Return the light-time value as the scalar quantity.
200          ./
201          *value = lt;
202 
203          return;
204          }
205 
206    The program outputs:
207 
208       -0.000135670940
209 
210 -Restrictions
211 
212    'udfunc' must evaluate to real values at x + dx and x - dx.
213 
214 -Literature_References
215 
216    See qderiv.c header.
217 
218 -Author_and_Institution
219 
220    N.J. Bachman   (JPL)
221    E.D. Wright    (JPL)
222 
223 -Version
224 
225    CSPICE Version 1.0.0  31-MAR-2010 (EDW)
226 
227 -Index_Entries
228 
229    first derivative of a function
230 
231 -&
232 */
233 
234    {  /* Begin uddf_c */
235 
236    /*
237    Local variables
238    */
239 
240    SpiceInt                  n;
241    SpiceDouble               dfdx  [1];
242    SpiceDouble               udval [2];
243 
244    /*
245    Participate in error tracing.
246    */
247    if ( return_c() )
248       {
249       return;
250       }
251    chkin_c ( "uddf_c" );
252 
253    /*
254    Apply a three-point estimation of the derivative for 'udfunc' at
255    'x' by evaluating udfunc at [x-dx, x+dx].
256 
257    The qderiv_ call returns a single value in the 'dfdx' array.
258    */
259    n = 1;
260 
261    udfunc ( x - dx, &(udval[0]) );
262    udfunc ( x + dx, &(udval[1]) );
263 
264    (void) qderiv_( (integer    *) &n,
265                    (doublereal *) &(udval[0]),
266                    (doublereal *) &(udval[1]),
267                    (doublereal *) &dx,
268                    (doublereal *) dfdx );
269 
270    *deriv = dfdx[0];
271 
272    chkout_c (  "uddf_c" );
273    }
274 
275