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, < ); 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