1
2 /*
3 * mnewt.c
4 *
5 * Newton Raphson Method from Numerical Recipes
6 */
7
8 #include <math.h>
9 #include "nr.h"
10
11 // A small number.
12 #define TINY 1.0e-20;
13
14 /*
15 * Given a matrix a[1..n][1..n], this routine replaces it by the LU
16 * decomposition of a rowwise permutation of itself. a and n are input. a
17 * is output, arranged as in equation (2.3.14) above; indx[1..n] is an
18 * output vector that records the row permutation eected by the partial
19 * pivoting; d is output as 1 depending on whether the number of row
20 * interchanges was even or odd, respectively. This routine is used in
21 * combination with lubksb to solve linear equations or invert a matrix.
22 */
23
24 void ludcmp(float **a, int n, int *indx, float *d)
25 {
26 int i,imax=0,j,k;
27 float big,dum,sum,temp;
28
29 // vv stores the implicit scaling of each row.
30 float *vv;
31
32 vv=vector(1,n);
33
34 // No row interchanges yet.
35 *d=1.0;
36
37 // Loop over rows to get the implicit scaling information
38 for (i=1;i<=n;i++) {
39 big=0.0;
40 for (j=1;j<=n;j++)
41 if ((temp=fabs(a[i][j])) > big) big=temp;
42 if (big == 0.0) nrerror("Singular matrix in routine ludcmp");
43 // No nonzero largest element.
44 // Save the scaling.
45 vv[i]=1.0/big;
46 }
47
48 // This is the loop over columns of Crout's method.
49 for (j=1;j<=n;j++) {
50
51 // This is equation (2.3.12) except for i = j.
52 for (i=1;i<j;i++) {
53 sum=a[i][j];
54 for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];
55 a[i][j]=sum;
56 }
57
58 // Initialize for the search for largest pivot element.
59 big=0.0;
60
61 // This is i = j of equation (2.3.12) and i = j +1: ::N
62 // of equation (2.3.13).
63 for (i=j;i<=n;i++) {
64 sum=a[i][j];
65 for (k=1;k<j;k++)
66 sum -= a[i][k]*a[k][j];
67 a[i][j]=sum;
68 if ( (dum=vv[i]*fabs(sum)) >= big) {
69 // Is the Figure of merit for the pivot better than the best so far?
70 big=dum;
71 imax=i;
72 }
73 }
74
75 // Do we need to interchange rows?
76 if (j != imax) {
77 // Yes, do so...
78 for (k=1;k<=n;k++) {
79 dum=a[imax][k];
80 a[imax][k]=a[j][k];
81 a[j][k]=dum;
82 }
83
84 // ...and change the parity of d.
85 *d = -(*d);
86
87 // Also interchange the scale factor.
88 vv[imax]=vv[j];
89 }
90 indx[j]=imax;
91 if (a[j][j] == 0.0) a[j][j]=TINY;
92 // If the pivot element is zero the matrix is singular (at least to the precision of the
93 // algorithm). For some applications on singular matrices, it is desirable to substitute
94 // TINY for zero.
95
96 // Now, Finally, divide by the pivot element.
97 if (j != n) {
98 dum=1.0/(a[j][j]);
99 for (i=j+1;i<=n;i++) a[i][j] *= dum;
100 }
101
102 // Go back for the next column in the reduction.
103 }
104 free_vector(vv,1,n);
105 }
106
107
108 /*
109 * Here is the routine for forward substitution and backsubstitution,
110 * implementing equations (2.3.6) and (2.3.7).
111 *
112 * Solves the set of n linear equations A X = B. Herea[1..n][1..n] is
113 * input, not as the matrix A but rather as its LU decomposition,
114 * determined by the routine ludcmp. indx[1..n] is input as the
115 * permutation vector returned by ludcmp. b[1..n] is input as the
116 * right-hand side vector B, and returns with the solution vector X. a,
117 * n, andindx are not modied by this routine and can be left in place
118 * for successive calls with dierent right-hand sides b. This routine
119 * takes into account the possibility that b will begin with many zero
120 * elements, so it is efficient for use in matrix inversion.
121 */
122
123 void lubksb(float **a, int n, int *indx, float b[])
124 {
125 int i,ii=0,ip,j;
126 float sum;
127
128 // When ii is set to a positive value, it will become the
129 // index of the rst nonvanishing element of b. Wenow
130 // do the forward substitution, equation (2.3.6). The
131 // only new wrinkle is to unscramble the permutation
132 // as we go.
133
134 for (i=1;i<=n;i++) {
135 ip=indx[i];
136 sum=b[ip];
137 b[ip]=b[i];
138 if (ii)
139 for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
140 else
141 if (sum) ii=i;
142 // A nonzero element was encountered, so from now on we
143 // will have to do the sums in the loop above. b[i]=sum;
144 }
145
146 // Now we do the backsubstitution, equation (2.3.7).
147 for (i=n;i>=1;i--) {
148 sum=b[i];
149 for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
150
151 // Store a component of the solution vector X.
152 b[i]=sum/a[i][i];
153 }
154 // All done!
155 }
156
157
158
159
160
161 // Set to maximum number of iterations.
162 #define JMAX 20
163
164 /*
165 * Using the Newton-Raphson method, nd the root of a function known to
166 * lie in the interval [x1; x2]. The root rtnewt will be refined until its
167 * accuracy is known within fixacc. funcd is a user-supplied routine
168 * that returns both the function value and the first derivative of the
169 * function at the point x.
170 */
171
172 float rtnewt(void (*funcd)(float, float *, float *), float x1, float x2,
173 float xacc)
174 {
175 int j;
176 float df,dx,f,rtn;
177 // Initial guess.
178 rtn=0.5*(x1+x2);
179 for (j=1;j<=JMAX;j++) {
180 (*funcd)(rtn,&f,&df);
181 dx=f/df;
182 rtn -= dx;
183 if ((x1-rtn)*(rtn-x2) < 0.0)
184 nrerror("Jumped out of brackets in rtnewt");
185
186 // Convergence.
187 if (fabs(dx) < xacc) return rtn;
188 }
189
190 // Never get here.
191 nrerror("Maximum number of iterations exceeded in rtnewt");
192 return 0.0;
193 }
194
195 /*
196 * While Newton-Raphson’s global convergence properties are poor, it
197 * is fai easy to design a fail-safe routine that utilizes a combination
198 * of bisection and Newton-Raphson. The hybrid algorithm takes a
199 * bisection step whenever Newton-Raphson would take the solution out of
200 * bounds, or whenever Newton-Raphson is not reducing the size of the
201 * brackets rapidly enough.
202 */
203
204 // Maximum allowed number of iterations.
205 #define MAXIT 100
206
207 /*
208 * Using a combination of Newton-Raphson and bisection, find the root of
209 * a function bracketed between x1 and x2. The root, returned as the
210 * function value rtsafe, will be refined until its accuracy is known
211 * within xacc. funcd is a user-supplied routine that returns both the
212 * function value and the first derivative of the function.
213 */
214
215 float rtsafe(void (*funcd)(float, float *, float *), float x1, float x2,
216 float xacc)
217 {
218 int j;
219 float df,dx,dxold,f,fh,fl;
220 float temp,xh,xl,rts;
221 (*funcd)(x1,&fl,&df);
222 (*funcd)(x2,&fh,&df);
223 if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0))
224 nrerror("Root must be bracketed in rtsafe");
225 if (fl == 0.0) return x1;
226 if (fh == 0.0) return x2;
227
228 // Orient the search so that f(xl) < 0.
229 if (fl < 0.0) {
230 xl=x1;
231 xh=x2;
232 }
233
234 else {
235 xh=x1;
236 xl=x2;
237 }
238
239 // Initialize the guess for root,
240 rts=0.5*(x1+x2);
241
242 // the stepsize before last,
243 // and the last step.
244 dxold=fabs(x2-x1);
245 dx=dxold;
246 (*funcd)(rts,&f,&df);
247
248 // Loop over allowed iterations.
249 for (j=1;j<=MAXIT;j++) {
250
251 // Bisect if Newton out of range,
252 // or not decreasing fast enough.
253 if ((((rts-xh)*df-f)*((rts-xl)*df-f) > 0.0)
254 || (fabs(2.0*f) > fabs(dxold*df))) {
255 dxold=dx;
256 dx=0.5*(xh-xl);
257 rts=xl+dx;
258
259 // Change in root is negligible.
260 if (xl == rts) return rts;
261 }
262
263 // Newton step acceptable. Take it.
264 else {
265 dxold=dx;
266 dx=f/df;
267 temp=rts;
268 rts -= dx;
269 if (temp == rts) return rts;
270 }
271
272 // Convergence criterion.
273 if (fabs(dx) < xacc) return rts;
274
275 // The one new function evaluation per iteration.
276 (*funcd)(rts,&f,&df);
277
278 // Maintain the bracket on the root.
279 if (f < 0.0)
280 xl=rts;
281 else
282 xh=rts;
283 }
284
285 // Never get here.
286 nrerror("Maximum number of iterations exceeded in rtsafe");
287 return 0.0;
288 }
289
290
291
292 /*
293 * Given an initial guess x[1..n] for a root in n dimensions, take ntrial
294 * Newton-Raphson steps to improve the root. Stop if the root converges
295 * in either summed absolute variable increments tolx or summed absolute
296 * function values tolf.
297 */
298
299 void mnewt(int ntrial, float x[], int n, float tolx, float tolf, mnewt_func func)
300 {
301 int k,i,*indx;
302 float errx,errf,d,*fvec,**fjac,*p;
303
304 indx=ivector(1,n);
305 p=vector(1,n);
306 fvec=vector(1,n);
307 fjac=matrix(1,n,1,n);
308
309 for (k=1;k<=ntrial;k++) {
310
311 // User function supplies function values at x in
312 // fvec and Jacobian matrix in fjac.
313 func(x,n,fvec,fjac);
314
315 // Check function convergence.
316 errf=0.0;
317 for (i=1;i<=n;i++) errf += fabs(fvec[i]);
318 if (errf <= tolf)
319 goto out;
320
321 // Right-hand side of linear equations.
322 for (i=1;i<=n;i++) p[i] = -fvec[i];
323
324 // Solve linear equations using LU decomposition.
325 ludcmp(fjac,n,indx,&d);
326 lubksb(fjac,n,indx,p);
327
328 // Check root convergence.
329 errx=0.0;
330 for (i=1;i<=n;i++) {
331 // Update solution.
332 errx += fabs(p[i]);
333 x[i] += p[i];
334 }
335 if (errx <= tolx)
336 goto out;
337 }
338
339 out:
340 free_matrix(fjac,1,n,1,n);
341 free_vector(fvec,1,n);
342 free_vector(p,1,n);
343 free_ivector(indx,1,n);
344 }
345
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.