3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <gsl/gsl_vector.h>
24 #include <gsl/gsl_test.h>
25 #include <gsl/gsl_multiroots.h>
27 #include <gsl/gsl_ieee_utils.h>
29 #include "test_funcs.h"
30 int test_fdf (const char * desc, gsl_multiroot_function_fdf * function, initpt_function initpt, double factor, const gsl_multiroot_fdfsolver_type * T);
31 int test_f (const char * desc, gsl_multiroot_function_fdf * fdf, initpt_function initpt, double factor, const gsl_multiroot_fsolver_type * T);
37 const gsl_multiroot_fsolver_type * fsolvers[5] ;
38 const gsl_multiroot_fsolver_type ** T1 ;
40 const gsl_multiroot_fdfsolver_type * fdfsolvers[5] ;
41 const gsl_multiroot_fdfsolver_type ** T2 ;
45 fsolvers[0] = gsl_multiroot_fsolver_dnewton;
46 fsolvers[1] = gsl_multiroot_fsolver_broyden;
47 fsolvers[2] = gsl_multiroot_fsolver_hybrid;
48 fsolvers[3] = gsl_multiroot_fsolver_hybrids;
51 fdfsolvers[0] = gsl_multiroot_fdfsolver_newton;
52 fdfsolvers[1] = gsl_multiroot_fdfsolver_gnewton;
53 fdfsolvers[2] = gsl_multiroot_fdfsolver_hybridj;
54 fdfsolvers[3] = gsl_multiroot_fdfsolver_hybridsj;
66 test_f ("Rosenbrock", &rosenbrock, rosenbrock_initpt, f, *T1);
67 test_f ("Roth", &roth, roth_initpt, f, *T1);
68 test_f ("Powell badly scaled", &powellscal, powellscal_initpt, f, *T1);
69 test_f ("Brown badly scaled", &brownscal, brownscal_initpt, f, *T1);
70 test_f ("Powell singular", &powellsing, powellsing_initpt, f, *T1);
71 test_f ("Wood", &wood, wood_initpt, f, *T1);
72 test_f ("Helical", &helical, helical_initpt, f, *T1);
73 test_f ("Discrete BVP", &dbv, dbv_initpt, f, *T1);
74 test_f ("Trig", &trig, trig_initpt, f, *T1);
82 test_fdf ("Rosenbrock", &rosenbrock, rosenbrock_initpt, f, *T2);
83 test_fdf ("Roth", &roth, roth_initpt, f, *T2);
84 test_fdf ("Powell badly scaled", &powellscal, powellscal_initpt, f, *T2);
85 test_fdf ("Brown badly scaled", &brownscal, brownscal_initpt, f, *T2);
86 test_fdf ("Powell singular", &powellsing, powellsing_initpt, f, *T2);
87 test_fdf ("Wood", &wood, wood_initpt, f, *T2);
88 test_fdf ("Helical", &helical, helical_initpt, f, *T2);
89 test_fdf ("Discrete BVP", &dbv, dbv_initpt, f, *T2);
90 test_fdf ("Trig", &trig, trig_initpt, f, *T2);
94 exit (gsl_test_summary ());
97 void scale (gsl_vector * x, double factor);
100 scale (gsl_vector * x, double factor)
102 size_t i, n = x->size;
104 if (gsl_vector_isnull(x))
106 for (i = 0; i < n; i++)
108 gsl_vector_set (x, i, factor);
113 for (i = 0; i < n; i++)
115 double xi = gsl_vector_get(x, i);
116 gsl_vector_set(x, i, factor * xi);
122 test_fdf (const char * desc, gsl_multiroot_function_fdf * function,
123 initpt_function initpt, double factor,
124 const gsl_multiroot_fdfsolver_type * T)
128 size_t i, n = function->n, iter = 0;
130 gsl_vector *x = gsl_vector_alloc (n);
131 gsl_matrix *J = gsl_matrix_alloc (n, n);
133 gsl_multiroot_fdfsolver *s;
137 if (factor != 1.0) scale(x, factor);
139 s = gsl_multiroot_fdfsolver_alloc (T, n);
140 gsl_multiroot_fdfsolver_set (s, function, x);
145 status = gsl_multiroot_fdfsolver_iterate (s);
150 status = gsl_multiroot_test_residual (s->f, 0.0000001);
152 while (status == GSL_CONTINUE && iter < 1000);
155 printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); printf("\n");
156 printf("f "); gsl_vector_fprintf (stdout, s->f, "%g"); printf("\n");
162 double r,sum; size_t j;
164 gsl_multiroot_function f1 ;
167 f1.params = function->params ;
169 gsl_multiroot_fdjacobian (&f1, s->x, s->f, GSL_SQRT_DBL_EPSILON, J);
171 /* compare J and s->J */
174 for (i = 0; i < n; i++)
175 for (j = 0; j< n ; j++)
177 double u = gsl_matrix_get(J,i,j);
178 double su = gsl_matrix_get(s->J, i, j);
179 r = fabs(u - su)/(1e-6 + 1e-6 * fabs(u)); sum+=r;
180 if (fabs(u - su) > 1e-6 + 1e-6 * fabs(u))
181 printf("broken jacobian %g\n", r);
183 printf("avg r = %g\n", sum/(n*n));
187 for (i = 0; i < n ; i++)
189 residual += fabs(gsl_vector_get(s->f, i));
192 gsl_multiroot_fdfsolver_free (s);
196 gsl_test(status, "%s on %s (%g), %u iterations, residual = %.2g", T->name, desc, factor, iter, residual);
203 test_f (const char * desc, gsl_multiroot_function_fdf * fdf,
204 initpt_function initpt, double factor,
205 const gsl_multiroot_fsolver_type * T)
208 size_t i, n = fdf->n, iter = 0;
213 gsl_multiroot_fsolver *s;
214 gsl_multiroot_function function;
217 function.params = fdf->params;
220 x = gsl_vector_alloc (n);
224 if (factor != 1.0) scale(x, factor);
226 s = gsl_multiroot_fsolver_alloc (T, n);
227 gsl_multiroot_fsolver_set (s, &function, x);
229 /* printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); printf("\n"); */
230 /* printf("f "); gsl_vector_fprintf (stdout, s->f, "%g"); printf("\n"); */
235 status = gsl_multiroot_fsolver_iterate (s);
240 status = gsl_multiroot_test_residual (s->f, 0.0000001);
242 while (status == GSL_CONTINUE && iter < 1000);
245 printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); printf("\n");
246 printf("f "); gsl_vector_fprintf (stdout, s->f, "%g"); printf("\n");
249 for (i = 0; i < n ; i++)
251 residual += fabs(gsl_vector_get(s->f, i));
254 gsl_multiroot_fsolver_free (s);
257 gsl_test(status, "%s on %s (%g), %u iterations, residual = %.2g", T->name, desc, factor, iter, residual);