NACO Pipeline Reference Manual  4.4.0
irplib_polynomial-test.c
1 /* $Id: irplib_polynomial-test.c,v 1.37 2013-01-29 08:43:33 jtaylor Exp $
2  *
3  * This file is part of the ESO Common Pipeline Library
4  * Copyright (C) 2001-2004 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jtaylor $
23  * $Date: 2013-01-29 08:43:33 $
24  * $Revision: 1.37 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /*-----------------------------------------------------------------------------
29  Includes
30  -----------------------------------------------------------------------------*/
31 
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 
36 #include <irplib_polynomial.h>
37 #include <math.h>
38 #include <float.h>
39 #include <stdint.h>
40 
41 /*-----------------------------------------------------------------------------
42  Defines
43  -----------------------------------------------------------------------------*/
44 
45 #define MAXDEGREE 6
46 
47 #define irplib_polynomial_test_root_all(A, B, C, D, E) \
48  irplib_polynomial_test_root_all_macro(A, B, C, D, E, __LINE__)
49 
50 /*-----------------------------------------------------------------------------
51  Static functions
52  -----------------------------------------------------------------------------*/
53 
54 static cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial *,
55  const cpl_vector *,
56  cpl_size);
57 static void irplib_polynomial_solve_1d_all_test(void);
58 
59 static void irplib_polynomial_test_root_all_macro(const cpl_vector *, cpl_size,
60  double, double, double,
61  unsigned);
62 
63 /*-----------------------------------------------------------------------------
64  Main
65  -----------------------------------------------------------------------------*/
66 int main(void)
67 {
68  /* Initialize CPL */
69  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
70 
71  irplib_polynomial_solve_1d_all_test();
72 
73  return cpl_test_end(0);
74 }
75 
76 
77 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*/
85 static void irplib_polynomial_solve_1d_all_test(void)
86 {
87 
88  cpl_polynomial * p2d = cpl_polynomial_new(2);
89  cpl_polynomial * p1d = cpl_polynomial_new(1);
90  cpl_vector * xtrue = cpl_vector_new(2);
91  const cpl_size maxdegree = 4; /* Largest robustly handled degree */
92  cpl_size nreal = 0;
93  cpl_size i;
94 
95  cpl_test_eq(irplib_polynomial_solve_1d_all(NULL, xtrue, &nreal),
96  CPL_ERROR_NULL_INPUT);
97  cpl_test_error(CPL_ERROR_NULL_INPUT);
98 
99  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, NULL, &nreal),
100  CPL_ERROR_NULL_INPUT);
101  cpl_test_error(CPL_ERROR_NULL_INPUT);
102 
103  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, NULL),
104  CPL_ERROR_NULL_INPUT);
105  cpl_test_error(CPL_ERROR_NULL_INPUT);
106 
107  cpl_test_eq(irplib_polynomial_solve_1d_all(p2d, xtrue, &nreal),
108  CPL_ERROR_INVALID_TYPE);
109  cpl_test_error(CPL_ERROR_INVALID_TYPE);
110 
111  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
112  CPL_ERROR_DATA_NOT_FOUND);
113  cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
114 
115  /* Create a 1st degree polynomial, x = 0 */
116  i = 1;
117  cpl_test_eq(cpl_polynomial_set_coeff(p1d, &i, 1.0), CPL_ERROR_NONE);
118  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
119  CPL_ERROR_INCOMPATIBLE_INPUT);
120  cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
121 
122  cpl_polynomial_delete(p1d);
123  cpl_polynomial_delete(p2d);
124 
125  for (nreal = 1; nreal <= maxdegree; nreal++) {
126  /* A single, zero-valued root with multiplicity equal to degree */
127  double xreal = 0.0;
128 
129 
130  cpl_vector_set_size(xtrue, nreal);
131 
132  (void)cpl_vector_fill(xtrue, xreal);
133 
134  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
135  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
136 
137  /* A single, non-zero integer root with multiplicity equal to degree */
138  xreal = 1.0;
139 
140  (void)cpl_vector_fill(xtrue, xreal);
141 
142  irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
143  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
144 
145  /* degree distinct real roots - with rounding */
146  for (i = 0; i < nreal; i++) {
147  (void)cpl_vector_set(xtrue, i, 2.0 * (double)i - CPL_MATH_E);
148  }
149 
150  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
151  20.0 * DBL_EPSILON,
152  300.0 * DBL_EPSILON);
153 
154  /* All real, one zero, one positive, rest negative, sum zero */
155  for (i = 0; i < nreal-1; i++) {
156  (void)cpl_vector_set(xtrue, nreal-i-2, (double)(-i));
157  }
158  (void)cpl_vector_set(xtrue, nreal-1, (double)(nreal-1)); /* FIXME: ? */
159 
160  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
161  16.0*DBL_EPSILON, 600.0*DBL_EPSILON);
162 
163  if (nreal < 2) continue;
164  /* Two complex, conjugate roots, the rest is real
165  with multiplicity degree-2 */
166 
167  (void)cpl_vector_fill(xtrue, 2.0);
168  (void)cpl_vector_set(xtrue, nreal-2, -1.0);
169  (void)cpl_vector_set(xtrue, nreal-1, 1.0);
170 
171  irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
172  30.0*DBL_EPSILON, 25.0*DBL_EPSILON);
173 
174  if (nreal < 3) continue;
175  if (nreal > 4) {
176  /* Two real roots, the smaller with multiplicity degree-1 */
177  (void)cpl_vector_fill(xtrue, 1.0);
178  (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
179 
180  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
181  DBL_EPSILON, DBL_EPSILON);
182  /* Same with negative roots */
183  (void)cpl_vector_fill(xtrue, -1.0);
184  (void)cpl_vector_set(xtrue, 0 , -2.0);
185 
186  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
187  DBL_EPSILON, DBL_EPSILON);
188  /* Two real roots, the larger with multiplicity degree-1 */
189  (void)cpl_vector_fill(xtrue, 2.0);
190  (void)cpl_vector_set(xtrue, 0, 1.0);
191 
192  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
193  DBL_EPSILON, DBL_EPSILON);
194  }
195 
196  if (nreal > 3) continue;
197 
198  /* Same with negative roots */
199  (void)cpl_vector_fill(xtrue, -2.0 * FLT_EPSILON);
200  (void)cpl_vector_set(xtrue, 0, -1.0);
201 
202  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
203  DBL_EPSILON, 2.0*DBL_EPSILON);
204 
205  /* A more extreme case: Same with negative roots */
206 #if defined SIZE_MAX && SIZE_MAX <= 4294967295
207  /* Fails on 32-bit - also w. -0.1 * FLT_EPSILON */
208 #else
209  (void)cpl_vector_fill(xtrue, -0.2 * FLT_EPSILON);
210 
211  (void)cpl_vector_set(xtrue, 0, -1.0);
212 
213  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
214  FLT_EPSILON, 3.0*DBL_EPSILON);
215 #endif
216 
217 
218  if (nreal != 3) {
219  /* The most extreme case: Same with negative roots */
220  (void)cpl_vector_fill(xtrue, -2.0 * DBL_EPSILON);
221  (void)cpl_vector_set(xtrue, 0, -1.0);
222 
223  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
224  DBL_EPSILON, 2.0*DBL_EPSILON);
225 
226 
227  (void)cpl_vector_set(xtrue, 0, -1.0);
228  (void)cpl_vector_set(xtrue, 1, -2.0e-4 * FLT_EPSILON);
229  (void)cpl_vector_set(xtrue, 2, 2.0e-4 * FLT_EPSILON);
230 
231  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
232  FLT_EPSILON, 2.0*DBL_EPSILON);
233  }
234 
235  /* Two complex conjugate roots, remaining:
236  small, with multiplicity degree-2 */
237  (void)cpl_vector_fill(xtrue, 2.0*DBL_EPSILON);
238  (void)cpl_vector_set(xtrue, nreal - 2 , 3.0);
239  (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
240 
241  irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
242  4.0 * DBL_EPSILON, DBL_EPSILON);
243 
244  /* Two complex conjugate roots with small real part, remaining:
245  with multiplicity degree-2 */
246  (void)cpl_vector_fill(xtrue, 3.0);
247  (void)cpl_vector_set(xtrue, nreal - 2 , -1.0);
248  (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
249 
250  irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
251  6.0*DBL_EPSILON, 220.0*DBL_EPSILON);
252 
253 
254  }
255 
256 #if MAXDEGREE > 2
257  /* Cover branch fixing cancellation with one negative,
258  one positive near-zero and one positive root. */
259  nreal = 3;
260 
261  cpl_vector_set_size(xtrue, nreal);
262 
263  /* -2, epsilon, 1.5 */
264  (void)cpl_vector_set(xtrue, 0, -2.0);
265  (void)cpl_vector_set(xtrue, 1, 2.0 * DBL_EPSILON);
266  (void)cpl_vector_set(xtrue, 2, 1.5);
267 
268  irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
269  4.0*DBL_EPSILON, 30.0*DBL_EPSILON);
270 
271 #if MAXDEGREE > 3
272  nreal = 4;
273 
274  cpl_vector_set_size(xtrue, nreal);
275 
276  /* Depressed has zero as root */
277  (void)cpl_vector_set(xtrue, 0, -1.0);
278  (void)cpl_vector_set(xtrue, 1, 1.0);
279  (void)cpl_vector_set(xtrue, 2, 2.0);
280  (void)cpl_vector_set(xtrue, 3, 2.0);
281 
282  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
283  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
284 
285  /* Depressed has zero as root, and two complex roots*/
286  irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
287  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
288 
289 
290  /* Depressed is biquadratic, with 4 real roots */
291  (void)cpl_vector_set(xtrue, 0, -2.0);
292  (void)cpl_vector_set(xtrue, 1, -1.0);
293  (void)cpl_vector_set(xtrue, 2, 1.0);
294  (void)cpl_vector_set(xtrue, 3, 2.0);
295 
296  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
297  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
298 
299  /* Depressed is biquadratic, with 2 real roots */
300  (void)cpl_vector_set(xtrue, 0, -1.0);
301  (void)cpl_vector_set(xtrue, 1, 1.0);
302  (void)cpl_vector_set(xtrue, 2, 0.0);
303  (void)cpl_vector_set(xtrue, 3, 2.0);
304 
305  irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
306  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
307 
308  /* Depressed is biquadratic (the quadratic has real, negative roots),
309  with 0 real roots */
310  (void)cpl_vector_set(xtrue, 0, 1.0);
311  (void)cpl_vector_set(xtrue, 1, 2.0);
312  (void)cpl_vector_set(xtrue, 2, 1.0);
313  (void)cpl_vector_set(xtrue, 3, 3.0);
314 
315  irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
316  10.0 * DBL_EPSILON, 10.0 * DBL_EPSILON);
317 
318  /* roots: 0, 0, ai, -ai */
319  (void)cpl_vector_set(xtrue, 0, 0.0);
320  (void)cpl_vector_set(xtrue, 1, 0.0);
321  (void)cpl_vector_set(xtrue, 2, 0.0);
322  (void)cpl_vector_set(xtrue, 3, 2.0);
323 
324  irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
325  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
326 
327  p1d = cpl_polynomial_new(1);
328 
329  i = 0;
330  cpl_polynomial_set_coeff(p1d, &i, -5.0);
331  i = 1;
332  cpl_polynomial_set_coeff(p1d, &i, -1.0);
333  i = 2;
334  cpl_polynomial_set_coeff(p1d, &i, -2.0);
335  i = 4;
336  cpl_polynomial_set_coeff(p1d, &i, 1.0);
337 
338  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
339  CPL_ERROR_NONE);
340 
341  cpl_msg_info(cpl_func, "Computed roots (%" CPL_SIZE_FORMAT " real): ",
342  nreal);
343  if (cpl_msg_get_level() <= CPL_MSG_INFO)
344  cpl_vector_dump(xtrue, stderr);
345  cpl_msg_info(cpl_func, "Residual: %g -> %g ", cpl_vector_get(xtrue, 0),
346  cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 0), NULL) );
347  cpl_msg_info(cpl_func, "Residual: %g -> %g ", cpl_vector_get(xtrue, 1),
348  cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 1), NULL) );
349 
350  cpl_polynomial_delete(p1d);
351 
352  (void)cpl_vector_set(xtrue, 0, 0.0);
353  (void)cpl_vector_set(xtrue, 1, 2.0);
354  (void)cpl_vector_set(xtrue, 2, 1.0);
355  (void)cpl_vector_set(xtrue, 3, 1.0);
356 
357  irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
358  2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
359 
360  (void)cpl_vector_set(xtrue, 0, -1.0);
361  (void)cpl_vector_set(xtrue, 1, 2.0);
362  (void)cpl_vector_set(xtrue, 2, 1.0);
363  (void)cpl_vector_set(xtrue, 3, 3.0);
364 
365  irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
366  3.0 * DBL_EPSILON, 3.0 * DBL_EPSILON);
367 #if MAXDEGREE > 4
368  nreal = 5;
369 
370  cpl_vector_set_size(xtrue, nreal);
371 
372  /* Depressed has zero as root */
373  (void)cpl_vector_set(xtrue, 0, -1.0);
374  (void)cpl_vector_set(xtrue, 1, 1.0);
375  (void)cpl_vector_set(xtrue, 2, 2.0);
376  (void)cpl_vector_set(xtrue, 3, 3.0);
377  (void)cpl_vector_set(xtrue, 4, 4.0);
378 
379  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
380  48.0 * DBL_EPSILON, 2800.0 * DBL_EPSILON);
381 
382  irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
383  8.0 * DBL_EPSILON, 4000.0 * DBL_EPSILON);
384 
385  irplib_polynomial_test_root_all(xtrue, nreal-4, CPL_MATH_PI,
386  4.0 * DBL_EPSILON, 600.0 * DBL_EPSILON);
387 
388 #if MAXDEGREE > 5
389  nreal = 6;
390 
391  cpl_vector_set_size(xtrue, nreal);
392 
393  /* Depressed has zero as root */
394  (void)cpl_vector_set(xtrue, 0, -1.0);
395  (void)cpl_vector_set(xtrue, 1, 1.0);
396  (void)cpl_vector_set(xtrue, 2, 2.0);
397  (void)cpl_vector_set(xtrue, 3, 3.0);
398  (void)cpl_vector_set(xtrue, 4, 4.0);
399  (void)cpl_vector_set(xtrue, 5, 5.0);
400 
401  irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
402  240.0 * DBL_EPSILON, 50.0e3 * DBL_EPSILON);
403 
404  irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
405  10.0 * DBL_EPSILON, 25.0e3 * DBL_EPSILON);
406 
407  irplib_polynomial_test_root_all(xtrue, nreal-4, CPL_MATH_PI,
408  12.0 * DBL_EPSILON, 1600.0 * DBL_EPSILON);
409 
410 #endif
411 #endif
412 #endif
413 #endif
414 
415  cpl_vector_delete(xtrue);
416 
417  return;
418 }
419 
420 /*----------------------------------------------------------------------------*/
431 /*----------------------------------------------------------------------------*/
432 static
433 cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial * self,
434  const cpl_vector * roots,
435  cpl_size nreal)
436 {
437 
438  const cpl_size nroots = cpl_vector_get_size(roots);
439  cpl_size i, degree;
440 
441  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
442  cpl_ensure_code(roots != NULL, CPL_ERROR_NULL_INPUT);
443  cpl_ensure_code(cpl_polynomial_get_dimension(self) == 1,
444  CPL_ERROR_ILLEGAL_INPUT);
445 
446  cpl_ensure_code(nreal >= 0, CPL_ERROR_ILLEGAL_INPUT);
447  cpl_ensure_code(nreal <= nroots,
448  CPL_ERROR_ILLEGAL_INPUT);
449  cpl_ensure_code((cpl_vector_get_size(roots) - nreal) % 2 == 0,
450  CPL_ERROR_ILLEGAL_INPUT);
451 
452  i = 0;
453  degree = cpl_polynomial_get_degree(self);
454  cpl_ensure_code(degree > 0 || cpl_polynomial_get_coeff(self, &i) != 0.0,
455  CPL_ERROR_DATA_NOT_FOUND);
456 
457  for (i = 0; i < nreal; i++) {
458  const double root = cpl_vector_get(roots, i);
459  double prev = 0.0;
460  cpl_size j;
461 
462  degree++;
463 
464  for (j = degree; j >= 0; j--) {
465  double value = 0.0;
466  double newval;
467 
468  if (j > 0) {
469  const cpl_size jj = j - 1;
470  newval = value = cpl_polynomial_get_coeff(self, &jj);
471  } else {
472  newval = 0.0;
473  }
474 
475  if (j < degree) {
476  newval -= root * prev;
477  }
478 
479  cpl_polynomial_set_coeff(self, &j, newval);
480 
481  prev = value;
482 
483  }
484  }
485 
486  /* Multiplication with the complex conjugate root
487  (x-a-ib) (x-a+ib) p(x) = (x-a)^2 p(x) + b^2 p(x) */
488  for (; i < nroots; i += 2) {
489  const double a = cpl_vector_get(roots, i);
490  const double b = cpl_vector_get(roots, i+1);
491  cpl_vector * aroot = cpl_vector_new(2);
492  cpl_polynomial * copy = cpl_polynomial_duplicate(self);
493 
494  cpl_vector_fill(aroot, a);
495 
496  irplib_polynomial_multiply_1d_factor(self, aroot, 2);
497 
498  cpl_polynomial_multiply_scalar(copy, copy, b * b);
499 
500  cpl_polynomial_add(self, self, copy);
501 
502  cpl_vector_delete(aroot);
503  cpl_polynomial_delete(copy);
504 
505  }
506 
507  return CPL_ERROR_NONE;
508 
509 }
510 
511 /*----------------------------------------------------------------------------*/
524 /*----------------------------------------------------------------------------*/
525 static void
526 irplib_polynomial_test_root_all_macro(const cpl_vector * self, cpl_size nreal,
527  double factor, double tolerance,
528  double resitol, unsigned line)
529 {
530 
531  const cpl_size degree = cpl_vector_get_size(self);
532  cpl_polynomial * p1d = cpl_polynomial_new(1);
533  cpl_vector * roots = cpl_vector_new(degree);
534  cpl_size i = 0;
535  cpl_size jreal;
536 
537  cpl_test_eq(cpl_polynomial_set_coeff(p1d, &i, factor), CPL_ERROR_NONE);
538 
539  cpl_test_eq(irplib_polynomial_multiply_1d_factor(p1d, self, nreal),
540  CPL_ERROR_NONE);
541 
542  cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, roots, &jreal),
543  CPL_ERROR_NONE);
544 
545  cpl_test_eq(jreal, nreal);
546  if (jreal != nreal) {
547  cpl_msg_info(cpl_func, "1D-polynomial:");
548  cpl_polynomial_dump(p1d, stderr);
549  cpl_msg_error(cpl_func, "True roots (%" CPL_SIZE_FORMAT
550  " real): (line=%u)", nreal, line);
551  cpl_vector_dump(self, stderr);
552  cpl_msg_error(cpl_func, "Computed roots (%" CPL_SIZE_FORMAT " real): ",
553  jreal);
554  cpl_vector_dump(roots, stderr);
555  } else if (cpl_msg_get_level() < CPL_MSG_WARNING) {
556  cpl_bivector * dump =
557  cpl_bivector_wrap_vectors((cpl_vector*)self, roots);
558 
559  cpl_msg_warning(cpl_func, "Comparing %" CPL_SIZE_FORMAT " roots (%"
560  CPL_SIZE_FORMAT " real): (line=%u)",
561  degree, nreal, line);
562  cpl_bivector_dump(dump, stderr);
563  cpl_bivector_unwrap_vectors(dump);
564  }
565 
566  for (i = 0; i < jreal; i++) {
567  const double root = cpl_vector_get(roots, i);
568  const double residual = cpl_polynomial_eval_1d(p1d, root, NULL);
569 
570  cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
571 
572  cpl_test_abs(residual, 0.0, resitol);
573 
574  }
575 
576  for (i = nreal; i < degree; i++) {
577  const double root = cpl_vector_get(roots, i);
578 
579  cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
580 
581  /* FIXME: Verify residual as well */
582 
583  }
584 
585  cpl_vector_delete(roots);
586  cpl_polynomial_delete(p1d);
587 
588  return;
589 }
int main(void)
Find a plugin and submit it to some tests.
Definition: recipe_main.c:61
cpl_error_code irplib_polynomial_solve_1d_all(const cpl_polynomial *self, cpl_vector *roots, cpl_size *preal)
Compute all n roots of p(x) = 0, where p(x) is of degree n, n > 0.