forked from devernay/cminpack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fdjac2.c
122 lines (91 loc) · 3.74 KB
/
fdjac2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "cminpack.h"
#include <math.h>
#include "cminpackP.h"
__cminpack_attr__
int __cminpack_func__(fdjac2)(__cminpack_decl_fcn_mn__ void *p, int m, int n, real *x,
const real *fvec, real *fjac, int ldfjac,
real epsfcn, real *wa)
{
/* Local variables */
real h;
int i, j;
real eps, temp, epsmch;
int iflag;
/* ********** */
/* subroutine fdjac2 */
/* this subroutine computes a forward-difference approximation */
/* to the m by n jacobian matrix associated with a specified */
/* problem of m functions in n variables. */
/* the subroutine statement is */
/* subroutine fdjac2(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa) */
/* where */
/* fcn is the name of the user-supplied subroutine which */
/* calculates the functions. fcn must be declared */
/* in an external statement in the user calling */
/* program, and should be written as follows. */
/* subroutine fcn(m,n,x,fvec,iflag) */
/* integer m,n,iflag */
/* double precision x(n),fvec(m) */
/* ---------- */
/* calculate the functions at x and */
/* return this vector in fvec. */
/* ---------- */
/* return */
/* end */
/* the value of iflag should not be changed by fcn unless */
/* the user wants to terminate execution of fdjac2. */
/* in this case set iflag to a negative integer. */
/* m is a positive integer input variable set to the number */
/* of functions. */
/* n is a positive integer input variable set to the number */
/* of variables. n must not exceed m. */
/* x is an input array of length n. */
/* fvec is an input array of length m which must contain the */
/* functions evaluated at x. */
/* fjac is an output m by n array which contains the */
/* approximation to the jacobian matrix evaluated at x. */
/* ldfjac is a positive integer input variable not less than m */
/* which specifies the leading dimension of the array fjac. */
/* iflag is an integer variable which can be used to terminate */
/* the execution of fdjac2. see description of fcn. */
/* epsfcn is an input variable used in determining a suitable */
/* step length for the forward-difference approximation. this */
/* approximation assumes that the relative errors in the */
/* functions are of the order of epsfcn. if epsfcn is less */
/* than the machine precision, it is assumed that the relative */
/* errors in the functions are of the order of the machine */
/* precision. */
/* wa is a work array of length m. */
/* subprograms called */
/* user-supplied ...... fcn */
/* minpack-supplied ... dpmpar */
/* fortran-supplied ... dabs,dmax1,dsqrt */
/* argonne national laboratory. minpack project. march 1980. */
/* burton s. garbow, kenneth e. hillstrom, jorge j. more */
/* ********** */
/* epsmch is the machine precision. */
epsmch = __cminpack_func__(dpmpar)(1);
eps = sqrt((max(epsfcn,epsmch)));
for (j = 0; j < n; ++j) {
temp = x[j];
h = eps * fabs(temp);
if (h == 0.) {
h = eps;
}
x[j] = temp + h;
/* the last parameter of fcn_mn() is set to 2 to differentiate
calls made to compute the function from calls made to compute
the Jacobian (see fcn() in examples/lmfdrv.c, and how njev
is used to compute the number of Jacobian evaluations) */
iflag = fcn_mn(p, m, n, x, wa, 2);
if (iflag < 0) {
return iflag;
}
x[j] = temp;
for (i = 0; i < m; ++i) {
fjac[i + j * ldfjac] = (wa[i] - fvec[i]) / h;
}
}
return 0;
/* last card of subroutine fdjac2. */
} /* fdjac2_ */