1 /* Usage: lmddrv < lm.data */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include "minpack.h"
6 #include "vec.h"
7 #define real __minpack_real__
8 
9 /*     ********** */
10 
11 /*     this program tests codes for the solution of n nonlinear */
12 /*     equations in n variables. it consists of a driver and an */
13 /*     interface subroutine fcn. the driver reads in data, calls the */
14 /*     nonlinear equation solver, and finally prints out information */
15 /*     on the performance of the solver. this is only a sample driver, */
16 /*     many other drivers are possible. the interface subroutine fcn */
17 /*     is necessary to take into account the forms of calling */
18 /*     sequences used by the function subroutines in the various */
19 /*     nonlinear equation solvers. */
20 
21 /*     subprograms called */
22 
23 /*       user-supplied ...... fcn */
24 
25 /*       minpack-supplied ... dpmpar,enorm,hybrd1,initpt,vecfcn */
26 
27 /*       fortran-supplied ... dsqrt */
28 
29 /*     argonne national laboratory. minpack project. march 1980. */
30 /*     burton s. garbow, kenneth e. hillstrom, jorge j. more */
31 
32 /*     ********** */
33 
34 void fcn(const int *n, const real *x, real *fvec, int *iflag);
35 
36 struct refnum {
37     int nprob, nfev, njev;
38 };
39 
40 struct refnum hybrdtest;
41 
printvec(int n,const real * x)42 static void printvec(int n, const real *x)
43 {
44     int i, num5, ilow, numleft;
45     num5 = n/5;
46 
47     for (i = 0; i < num5; ++i) {
48         ilow = i*5;
49         printf("     %15.7e%15.7e%15.7e%15.7e%15.7e\n",
50                (double)x[ilow+0], (double)x[ilow+1], (double)x[ilow+2], (double)x[ilow+3], (double)x[ilow+4]);
51     }
52 
53     numleft = n%5;
54     ilow = n - numleft;
55 
56     switch (numleft) {
57         case 1:
58             printf("     %15.7e\n",
59                    (double)x[ilow+0]);
60             break;
61         case 2:
62             printf("     %15.7e%15.7e\n",
63                    (double)x[ilow+0], (double)x[ilow+1]);
64             break;
65         case 3:
66             printf("     %15.7e%15.7e%15.7e\n",
67                    (double)x[ilow+0], (double)x[ilow+1], (double)x[ilow+2]);
68             break;
69         case 4:
70             printf("     %15.7e%15.7e%15.7e%15.7e\n",
71                    (double)x[ilow+0], (double)x[ilow+1], (double)x[ilow+2], (double)x[ilow+3]);
72             break;
73     }
74 }
75 
76 /* Main program */
main(int argc,char ** argv)77 int main(int argc, char **argv)
78 {
79 
80     int i,ic,k,n,ntries;
81     int info;
82 
83     int na[60];
84     int nf[60];
85     int nj[60];
86     int np[60];
87     int nx[60];
88 
89     real factor,fnorm1,fnorm2,tol;
90 
91     real fnm[60];
92     real fvec[40];
93     real x[40];
94 
95     real wa[2660];
96     const int lwa = 2660;
97     const int i1 = 1;
98     (void)argc; (void)argv;
99 
100     tol = sqrt(__minpack_func__(dpmpar)(&i1));
101 
102     ic = 0;
103 
104     for (;;) {
105         scanf("%5d%5d%5d\n", &hybrdtest.nprob, &n, &ntries);
106         if (hybrdtest.nprob <= 0.)
107             break;
108 
109         factor = 1.;
110 
111         for (k = 0; k < ntries; ++k, ++ic) {
112             hybipt(n,x,hybrdtest.nprob,factor);
113 
114             vecfcn(n,x,fvec,hybrdtest.nprob);
115 
116             fnorm1 = __minpack_func__(enorm)(&n,fvec);
117 
118             printf("\n\n\n\n      problem%5d      dimension%5d\n\n", hybrdtest.nprob, n);
119 
120             hybrdtest.nfev = 0;
121             hybrdtest.njev = 0;
122 
123             __minpack_func__(hybrd1)(fcn,&n,x,fvec,&tol,&info,wa,&lwa);
124 
125             fnorm2 = __minpack_func__(enorm)(&n,fvec);
126 
127             np[ic] = hybrdtest.nprob;
128             na[ic] = n;
129             nf[ic] = hybrdtest.nfev;
130             hybrdtest.njev /= n;
131             nj[ic] = hybrdtest.njev;
132             nx[ic] = info;
133 
134             fnm[ic] = fnorm2;
135 
136             printf("\n      initial l2 norm of the residuals%15.7e\n"
137                    "\n      final l2 norm of the residuals  %15.7e\n"
138                    "\n      number of function evaluations  %10d\n"
139                    "\n      number of Jacobian evaluations  %10d\n"
140                    "\n      exit parameter                  %10d\n"
141                    "\n      final approximate solution\n\n",
142                    (double)fnorm1, (double)fnorm2, hybrdtest.nfev, hybrdtest.njev, info);
143             printvec(n, x);
144 
145             factor *= 10.;
146 
147         }
148 
149     }
150 
151     printf("\f summary of %d calls to hybrd1\n", ic);
152     printf("\n nprob   n    nfev   njev  info  final l2 norm\n\n");
153     for (i = 0; i < ic; ++i) {
154         printf("%4d%6d%7d%7d%6d%16.7e\n",
155                np[i], na[i], nf[i], nj[i], nx[i], (double)fnm[i]);
156     }
157     exit(0);
158 }
159 
160 
fcn(const int * n,const real * x,real * fvec,int * iflag)161 void fcn(const int *n, const real *x, real *fvec, int *iflag)
162 {
163 /*     ********** */
164 
165 /*     the calling sequence of fcn should be identical to the */
166 /*     calling sequence of the function subroutine in the nonlinear */
167 /*     equation solver. fcn should only call the testing function */
168 /*     subroutine vecfcn with the appropriate value of problem */
169 /*     number (nprob). */
170 
171 /*     subprograms called */
172 
173 /*       minpack-supplied ... vecfcn */
174 
175 /*     argonne national laboratory. minpack project. march 1980. */
176 /*     burton s. garbow, kenneth e. hillstrom, jorge j. more */
177 
178 /*     ********** */
179     vecfcn(*n, x, fvec, hybrdtest.nprob);
180     if (*iflag == 1) {
181         hybrdtest.nfev++;
182     }
183     if (*iflag == 2) {
184         hybrdtest.njev++;
185     }
186 } /* fcn_ */
187