~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
cvs/emstar/libnl/nr/mnewt.c


  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 modied 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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.