/******************************************************************** * THIS PROGRAM TESTS CODES FOR THE LEAST-SQUARES SOLUTION OF * * M NONLINEAR EQUATIONS IN N VARIABLES. IT CONSISTS OF A DRIVER * * AND AN INITIALIZATION SUBROUTINE INIPT. THE DRIVER READS IN DATA,* * CALLS THE NONLINEAR LEAST-SQUARES SOLVER, AND FINALLY PRINTS * * OUT INFORMATION ON THE PERFORMANCE OF THE SOLVER. THIS IS * * ONLY A SAMPLE DRIVER, MANY OTHER DRIVERS ARE POSSIBLE. THE * * INTERFACE SUBROUTINE FCN IS NECESSARY TO TAKE INTO ACCOUNT THE * * FORMS OF CALLING SEQUENCES USED BY THE FUNCTION AND JACOBIAN * * SUBROUTINES IN THE VARIOUS NONLINEAR LEAST-SQUARES SOLVERS. * * * * PROCEDURES OR FUNCTIONS CALLED (SEE MODULE LM.CPP): * * * * INITPT, SSQFCN, LMDIF1, ENORM, FCN * * * * From F77 program By: * * ARGONNE NATIONAL LABORATORY. MINPACK PROJECT. MARCH 1980. * * BURTON S. GARBOW, KENNETH E. HILLSTROM, JORGE J. MORE * * ----------------------------------------------------------------- * * SAMPLE RUNS: * * Example #1 (size 2) * * Solve following system (with initial conditions x1=1, x2=1): * * X1^2 + X1 + X2^2 - 2 = 0 * * X1^2 + X2 - X2^2 - 1 + log(X1) = 0 * * * * Input #example(1 to 3), size N, Number of tries: 1 2 1 * * PROBLEM 1 DIMENSIONS 2 2 * * INITIAL L2 NORM OF THE RESIDUALS: 1.000000 * * FINAL L2 NORM OF THE RESIDUALS..: 0.000000 * * NUMBER OF FUNCTION EVALUATION...: 25 * * NUMBER OF JACOBIAN EVALUATIONS..: 6 * * EXIT PARAMETER..................: 2 * * FINAL APPROXIMATE SOLUTION......: * * 0.915554 0.496191 * * * * SUMMARY OF 1 CALL(S) TO LMDIF1: * * NPROB N M NFEV NJEV INFO FINAL L2 NORM * * 1 2 2 25 6 2 1.626303e-018 * * * * Example #2 (size 4) * * Solve following system (with initial conditions x1..x4 = 1): * * 10.0*x + x2 + x3 + x4 - 20.0 + Sqr(sin(x1)) + Sqr(cos(x2)) = 0 * * x1 + 20.0*x2 + x3 + x4 - 48.0 + one/pow^6 = 0 * * Sqr(x1 + x2) + 30.0*x3 + x4 - 97.0 + log(x1) + log(x2+x3) = 0 * * x1 + x2 + x3 + 40.0*x4 - 166.0 + Sqr(x1) = 0 * * * * Input #example(1 to 3), size N, Number of tries: 2 4 1 * * PROBLEM 2 DIMENSIONS 4 4 * * INITIAL L2 NORM OF THE RESIDUALS: 138.760694 * * FINAL L2 NORM OF THE RESIDUALS..: 0.000000 * * NUMBER OF FUNCTION EVALUATION...: 31 * * NUMBER OF JACOBIAN EVALUATIONS..: 5 * * EXIT PARAMETER..................: 2 * * FINAL APPROXIMATE SOLUTION......: * * 1.040648 1.972398 2.745049 3.978974 * * * * SUMMARY OF 1 CALL(S) TO LMDIF1: * * NPROB N M NFEV NJEV INFO FINAL L2 NORM * * 2 4 4 31 5 2 1.147637e-014 * * * * Example #3 (size 6) - Stiff system * * Solve following system (with initial conditions x1..x6 = 1): * * X1 + X2 + X4 - .001 = 0 * * X5 + X6 -55 = 0 * * X1 + X2 + X3 + 2X5 + X6 - 110.001 = 0 * * X1 - 0.1X2 = 0 * * X1 - 10000 X3 X4 = 0 * * X5 - 5.5e15 X3 X6 = 0 * * * * Input #example(1 to 3), size N, Number of tries: 3 6 1 * * PROBLEM 3 DIMENSIONS 6 6 * * INITIAL L2 NORM OF THE RESIDUALS: 5499999999999999.000000 * * FINAL L2 NORM OF THE RESIDUALS..: 0.000000 * * NUMBER OF FUNCTION EVALUATION...: 161 * * NUMBER OF JACOBIAN EVALUATIONS..: 20 * * EXIT PARAMETER..................: 2 * * FINAL APPROXIMATE SOLUTION......: * * 0.000083 0.000826 0.000091 0.000091 55.000000 0.000000 * * * * SUMMARY OF 1 CALL(S) TO LMDIF1: * * NPROB N M NFEV NJEV INFO FINAL L2 NORM * * 3 6 6 161 20 2 1.355253e-020 * * * * Visual C++ Release By J-P Moreau, Paris. * * (www.jpmoreau.fr) * ********************************************************************/ #include //For REAL, etc. #include //For memory allocations. extern nprob, nfev, njev; int i, ic, info, k, m, n, ntries; int *iwa, *ma, *na, *nf, *nj, *np, *nx; REAL factor, fnorm1, fnorm2, tol; REAL *fnm, *fvec, *x; void *vmblock = NULL; REAL enorm(int, REAL *); void lmdif1 (int, int, REAL *, REAL *, REAL, int *, int *); void ssqfcn (int, int, REAL *, REAL *, int); void initpt (int n, REAL *x, int nprob, REAL factor) { /**************************************************************** ! SUBROUTINE INITPT ! THIS SUBROUTINE SPECIFIES THE STANDARD STARTING POINTS FOR THE ! FUNCTIONS DEFINED BY SUBROUTINE SSQFCN. THE SUBROUTINE RETURNS ! IN X A MULTIPLE (FACTOR) OF THE STANDARD STARTING POINT. FOR ! THE 11TH FUNCTION THE STANDARD STARTING POINT IS ZERO, SO IN ! THIS CASE, IF FACTOR IS NOT UNITY, THEN THE SUBROUTINE RETURNS ! THE VECTOR X(J) = FACTOR, J=1,...,N. ! THE SUBROUTINE STATEMENT IS ! PROCEDURE INITPT(N,X,NPROB,FACTOR) ! WHERE ! N IS A POSITIVE INTEGER INPUT VARIABLE. ! X IS AN OUTPUT ARRAY OF LENGTH N WHICH CONTAINS THE STANDARD ! STARTING POINT FOR PROBLEM NPROB MULTIPLIED BY FACTOR. ! NPROB IS A POSITIVE INTEGER INPUT VARIABLE WHICH DEFINES THE ! NUMBER OF THE PROBLEM. NPROB MUST NOT EXCEED 18. ! FACTOR IS AN INPUT VARIABLE WHICH SPECIFIES THE MULTIPLE OF ! THE STANDARD STARTING POINT. IF FACTOR IS UNITY, NO ! MULTIPLICATION IS PERFORMED. ! ARGONNE NATIONAL LABORATORY. MINPACK PROJECT. MARCH 1980. ! BURTON S. GARBOW, KENNETH E. HILLSTROM, JORGE J. MORE ! **************************************************************/ int j; // SELECTION OF INITIAL POINT for (j=1; j<=n; j++) x[j] = ONE; // COMPUTE MULTIPLE OF INITIAL POINT if (factor == ONE) return; for (j=1; j<=n; j++) x[j] *= factor; } // initpt() void main() { printf("\n Input #example(1 to 3), size N, Number of tries: "); scanf("%d %d %d", &nprob, &n, &ntries); // allocate memory for vectors (index 0 not used) vmblock = vminit(); iwa = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); ma = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); na = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); nf = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); nj = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); np = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); nx = (int *) vmalloc(vmblock, VEKTOR, n+1, 0); fnm = (REAL *) vmalloc(vmblock, VEKTOR, n+1, 0); fvec = (REAL *) vmalloc(vmblock, VEKTOR, n+1, 0); x = (REAL *) vmalloc(vmblock, VEKTOR, n+1, 0); if (! vmcomplete(vmblock)) { LogError ("No Memory", 0, __FILE__, __LINE__); return; } tol = 1e-8; ic = 0; m=n; //m < n not tested here. factor = ONE; for (k=1; k<=ntries; k++) { ic++; initpt (n, x, nprob, factor); ssqfcn (m, n, x, fvec, nprob); fnorm1 = enorm(m, fvec); printf(" PROBLEM%5d DIMENSIONS%5d%5d\n", nprob, n, m); nfev = 0; njev = 0; lmdif1 (m, n, x, fvec, tol, &info, iwa); ssqfcn (m, n, x, fvec, nprob); fnorm2 = enorm(m,fvec); np[ic] = nprob; na[ic] = n; ma[ic] = m; nf[ic] = nfev; njev = njev / n; nj[ic] = njev; nx[ic] = info; fnm[ic] = fnorm2; printf(" INITIAL L2 NORM OF THE RESIDUALS: %f\n", fnorm1); printf(" FINAL L2 NORM OF THE RESIDUALS..: %f\n", fnorm2); printf(" NUMBER OF FUNCTION EVALUATION...: %d\n", nfev); printf(" NUMBER OF JACOBIAN EVALUATIONS..: %d\n", njev); printf(" EXIT PARAMETER..................: %d\n", info); printf(" FINAL APPROXIMATE SOLUTION......: \n"); for (i=1; i<=n; i++) printf(" %f", x[i]); printf("\n"); factor = TEN*factor; } printf("\n SUMMARY OF %d CALLS TO LMDIF1:\n", ic); printf(" NPROB N M NFEV NJEV INFO FINAL L2 NORM\n"); for (i=1; i<=ic; i++) printf(" %d %d %d %3d %2d %d %e\n", np[i], na[i], ma[i], nf[i], nj[i], nx[i], fnm[i]); vmfree(vmblock); } // end of file tlm.cpp