36#include <irplib_polynomial.h>
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__)
54static cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial *,
57static void irplib_polynomial_solve_1d_all_test(
void);
59static void irplib_polynomial_test_root_all_macro(
const cpl_vector *, cpl_size,
60 double,
double,
double,
69 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
71 irplib_polynomial_solve_1d_all_test();
73 return cpl_test_end(0);
85static void irplib_polynomial_solve_1d_all_test(
void)
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;
99 code = irplib_polynomial_solve_1d_all(NULL, xtrue, &nreal);
100 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
102 code = irplib_polynomial_solve_1d_all(p1d, NULL, &nreal);
103 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
105 code = irplib_polynomial_solve_1d_all(p1d, xtrue, NULL);
106 cpl_test_eq_error(code, CPL_ERROR_NULL_INPUT);
108 code = irplib_polynomial_solve_1d_all(p2d, xtrue, &nreal);
109 cpl_test_eq_error(code, CPL_ERROR_INVALID_TYPE);
111 code = irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal);
112 cpl_test_eq_error(code, CPL_ERROR_DATA_NOT_FOUND);
116 code = cpl_polynomial_set_coeff(p1d, &i, 1.0);
117 cpl_test_eq_error(code, CPL_ERROR_NONE);
118 code = irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal);
119 cpl_test_eq_error(code, CPL_ERROR_INCOMPATIBLE_INPUT);
121 cpl_polynomial_delete(p1d);
122 cpl_polynomial_delete(p2d);
124 for (nreal = 1; nreal <= maxdegree; nreal++) {
129 cpl_vector_set_size(xtrue, nreal);
131 (void)cpl_vector_fill(xtrue, xreal);
133 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
134 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
139 (void)cpl_vector_fill(xtrue, xreal);
141 irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
142 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
145 for (i = 0; i < nreal; i++) {
146 (void)cpl_vector_set(xtrue, i, 2.0 * (
double)i - CPL_MATH_E);
149 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
151 550.0 * DBL_EPSILON);
154 for (i = 0; i < nreal-1; i++) {
155 (void)cpl_vector_set(xtrue, nreal-i-2, (
double)(-i));
157 (void)cpl_vector_set(xtrue, nreal-1, (
double)(nreal-1));
159 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
160 16.0*DBL_EPSILON, 600.0*DBL_EPSILON);
162 if (nreal < 2)
continue;
166 (void)cpl_vector_fill(xtrue, 2.0);
167 (void)cpl_vector_set(xtrue, nreal-2, -1.0);
168 (void)cpl_vector_set(xtrue, nreal-1, 1.0);
170 irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
171 30.0*DBL_EPSILON, 25.0*DBL_EPSILON);
173 if (nreal < 3)
continue;
176 (void)cpl_vector_fill(xtrue, 1.0);
177 (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
179 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
180 DBL_EPSILON, DBL_EPSILON);
182 (void)cpl_vector_fill(xtrue, -1.0);
183 (void)cpl_vector_set(xtrue, 0 , -2.0);
185 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
186 DBL_EPSILON, DBL_EPSILON);
188 (void)cpl_vector_fill(xtrue, 2.0);
189 (void)cpl_vector_set(xtrue, 0, 1.0);
191 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
192 DBL_EPSILON, DBL_EPSILON);
195 if (nreal > 3)
continue;
198 (void)cpl_vector_fill(xtrue, -2.0 * FLT_EPSILON);
199 (void)cpl_vector_set(xtrue, 0, -1.0);
201 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
202 DBL_EPSILON, 2.0*DBL_EPSILON);
205#if defined SIZE_MAX && SIZE_MAX <= 4294967295
208 (void)cpl_vector_fill(xtrue, -0.2 * FLT_EPSILON);
210 (void)cpl_vector_set(xtrue, 0, -1.0);
212 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
213 FLT_EPSILON, 3.0*DBL_EPSILON);
219 (void)cpl_vector_fill(xtrue, -2.0 * DBL_EPSILON);
220 (void)cpl_vector_set(xtrue, 0, -1.0);
222 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
223 DBL_EPSILON, 2.0*DBL_EPSILON);
226 (void)cpl_vector_set(xtrue, 0, -1.0);
227 (void)cpl_vector_set(xtrue, 1, -2.0e-4 * FLT_EPSILON);
228 (void)cpl_vector_set(xtrue, 2, 2.0e-4 * FLT_EPSILON);
230 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
231 FLT_EPSILON, 2.0*DBL_EPSILON);
236 (void)cpl_vector_fill(xtrue, 2.0*DBL_EPSILON);
237 (void)cpl_vector_set(xtrue, nreal - 2 , 3.0);
238 (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
240 irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
241 4.0 * DBL_EPSILON, DBL_EPSILON);
245 (void)cpl_vector_fill(xtrue, 3.0);
246 (void)cpl_vector_set(xtrue, nreal - 2 , -1.0);
247 (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
249 irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
250 6.0*DBL_EPSILON, 220.0*DBL_EPSILON);
260 cpl_vector_set_size(xtrue, nreal);
263 (void)cpl_vector_set(xtrue, 0, -2.0);
264 (void)cpl_vector_set(xtrue, 1, 2.0 * DBL_EPSILON);
265 (void)cpl_vector_set(xtrue, 2, 1.5);
267 irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
268 4.0*DBL_EPSILON, 30.0*DBL_EPSILON);
270 (void)cpl_vector_set(xtrue, 0, 1.0);
271 (void)cpl_vector_set(xtrue, 1, 2.0);
272 (void)cpl_vector_set(xtrue, 2, 1.0);
274 irplib_polynomial_test_root_all(xtrue, nreal-2, 1.0,
275 4.0*DBL_EPSILON, 30.0*DBL_EPSILON);
280 cpl_vector_set_size(xtrue, nreal);
283 (void)cpl_vector_set(xtrue, 0, -1.0);
284 (void)cpl_vector_set(xtrue, 1, 1.0);
285 (void)cpl_vector_set(xtrue, 2, 2.0);
286 (void)cpl_vector_set(xtrue, 3, 2.0);
288 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
289 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
292 irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
293 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
297 (void)cpl_vector_set(xtrue, 0, -2.0);
298 (void)cpl_vector_set(xtrue, 1, -1.0);
299 (void)cpl_vector_set(xtrue, 2, 1.0);
300 (void)cpl_vector_set(xtrue, 3, 2.0);
302 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
303 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
306 (void)cpl_vector_set(xtrue, 0, -1.0);
307 (void)cpl_vector_set(xtrue, 1, 1.0);
308 (void)cpl_vector_set(xtrue, 2, 0.0);
309 (void)cpl_vector_set(xtrue, 3, 2.0);
311 irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
312 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
316 (void)cpl_vector_set(xtrue, 0, 1.0);
317 (void)cpl_vector_set(xtrue, 1, 2.0);
318 (void)cpl_vector_set(xtrue, 2, 1.0);
319 (void)cpl_vector_set(xtrue, 3, 3.0);
321 irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
322 10.0 * DBL_EPSILON, 10.0 * DBL_EPSILON);
325 (void)cpl_vector_set(xtrue, 0, 0.0);
326 (void)cpl_vector_set(xtrue, 1, 0.0);
327 (void)cpl_vector_set(xtrue, 2, 0.0);
328 (void)cpl_vector_set(xtrue, 3, 2.0);
330 irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
331 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
333 p1d = cpl_polynomial_new(1);
336 cpl_polynomial_set_coeff(p1d, &i, -5.0);
338 cpl_polynomial_set_coeff(p1d, &i, -1.0);
340 cpl_polynomial_set_coeff(p1d, &i, -2.0);
342 cpl_polynomial_set_coeff(p1d, &i, 1.0);
344 code = irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal);
345 cpl_test_eq_error(code, CPL_ERROR_NONE);
347 cpl_msg_info(cpl_func,
"Computed roots (%" CPL_SIZE_FORMAT
" real): ",
349 if (cpl_msg_get_level() <= CPL_MSG_INFO)
350 cpl_vector_dump(xtrue, stderr);
351 cpl_msg_info(cpl_func,
"Residual: %g -> %g ", cpl_vector_get(xtrue, 0),
352 cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 0), NULL) );
353 cpl_msg_info(cpl_func,
"Residual: %g -> %g ", cpl_vector_get(xtrue, 1),
354 cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 1), NULL) );
356 cpl_polynomial_delete(p1d);
358 (void)cpl_vector_set(xtrue, 0, 0.0);
359 (void)cpl_vector_set(xtrue, 1, 2.0);
360 (void)cpl_vector_set(xtrue, 2, 1.0);
361 (void)cpl_vector_set(xtrue, 3, 1.0);
363 irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
364 2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
366 (void)cpl_vector_set(xtrue, 0, -1.0);
367 (void)cpl_vector_set(xtrue, 1, 2.0);
368 (void)cpl_vector_set(xtrue, 2, 1.0);
369 (void)cpl_vector_set(xtrue, 3, 3.0);
371 irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
372 3.0 * DBL_EPSILON, 3.0 * DBL_EPSILON);
376 cpl_vector_set_size(xtrue, nreal);
379 (void)cpl_vector_set(xtrue, 0, -1.0);
380 (void)cpl_vector_set(xtrue, 1, 1.0);
381 (void)cpl_vector_set(xtrue, 2, 2.0);
382 (void)cpl_vector_set(xtrue, 3, 3.0);
383 (void)cpl_vector_set(xtrue, 4, 4.0);
385 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
386 48.0 * DBL_EPSILON, 2800.0 * DBL_EPSILON);
388 irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
389 8.0 * DBL_EPSILON, 4000.0 * DBL_EPSILON);
391 irplib_polynomial_test_root_all(xtrue, nreal-4, CPL_MATH_PI,
392 4.0 * DBL_EPSILON, 600.0 * DBL_EPSILON);
394 (void)cpl_vector_set(xtrue, 0, -1.0);
395 (void)cpl_vector_set(xtrue, 1, 10.0);
396 (void)cpl_vector_set(xtrue, 2, 1.0);
397 (void)cpl_vector_set(xtrue, 3, 20.0);
398 (void)cpl_vector_set(xtrue, 4, 1.0);
400 irplib_polynomial_test_root_all(xtrue, 1, 1.0,
401 DBL_EPSILON, DBL_EPSILON);
403 (void)cpl_vector_set(xtrue, 0, 4.0);
404 (void)cpl_vector_set(xtrue, 1, -10.0);
405 (void)cpl_vector_set(xtrue, 2, 4.0);
406 (void)cpl_vector_set(xtrue, 3, 10.0);
407 (void)cpl_vector_set(xtrue, 4, 4.0);
409 irplib_polynomial_test_root_all(xtrue, 1, 1.0,
410 DBL_EPSILON, DBL_EPSILON);
411 irplib_polynomial_test_root_all(xtrue, 1, -1.0,
412 DBL_EPSILON, DBL_EPSILON);
417 cpl_vector_set_size(xtrue, nreal);
419 (void)cpl_vector_set(xtrue, 0, -1.0);
420 (void)cpl_vector_set(xtrue, 1, 1.0);
421 (void)cpl_vector_set(xtrue, 2, 2.0);
422 (void)cpl_vector_set(xtrue, 3, 3.0);
423 (void)cpl_vector_set(xtrue, 4, 4.0);
424 (void)cpl_vector_set(xtrue, 5, 5.0);
426 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
427 240.0 * DBL_EPSILON, 50.0e3 * DBL_EPSILON);
429 irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
430 10.0 * DBL_EPSILON, 25.0e3 * DBL_EPSILON);
432 irplib_polynomial_test_root_all(xtrue, nreal-4, CPL_MATH_PI,
433 12.0 * DBL_EPSILON, 1600.0 * DBL_EPSILON);
436 (void)cpl_vector_set(xtrue, 0, 1.0);
437 (void)cpl_vector_set(xtrue, 1, 1.0);
438 (void)cpl_vector_set(xtrue, 2, 3.0);
439 (void)cpl_vector_set(xtrue, 3, 3.0);
440 (void)cpl_vector_set(xtrue, 4, 2.0);
441 (void)cpl_vector_set(xtrue, 5, 1.0);
443 irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI, 0.07, 0.1);
446 (void)cpl_vector_set(xtrue, 0, 1.0);
447 (void)cpl_vector_set(xtrue, 1, 1.0);
448 (void)cpl_vector_set(xtrue, 2, 2.0);
449 (void)cpl_vector_set(xtrue, 3, 1.0);
450 (void)cpl_vector_set(xtrue, 4, 3.0);
451 (void)cpl_vector_set(xtrue, 5, 3.0);
453 irplib_polynomial_test_root_all(xtrue, nreal-4, CPL_MATH_PI,
454 FLT_EPSILON, 1600.0 * DBL_EPSILON);
457 (void)cpl_vector_set(xtrue, 0, 0.0);
458 (void)cpl_vector_set(xtrue, 1, 0.0);
459 (void)cpl_vector_set(xtrue, 2, 1.0);
460 (void)cpl_vector_set(xtrue, 3, 1.0);
461 (void)cpl_vector_set(xtrue, 4, 2.0);
462 (void)cpl_vector_set(xtrue, 5, 2.0);
464 irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
465 DBL_EPSILON, DBL_EPSILON);
468 (void)cpl_vector_set(xtrue, 0, 1.0);
469 (void)cpl_vector_set(xtrue, 1, 1.0);
470 (void)cpl_vector_set(xtrue, 2, 2.0);
471 (void)cpl_vector_set(xtrue, 3, 2.0);
472 (void)cpl_vector_set(xtrue, 4, 3.0);
473 (void)cpl_vector_set(xtrue, 5, 3.0);
475 irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
476 10.0 * FLT_EPSILON, 1500.0 * DBL_EPSILON);
479 (void)cpl_vector_set(xtrue, 0, 0.0);
480 (void)cpl_vector_set(xtrue, 1, 0.0);
481 (void)cpl_vector_set(xtrue, 2, 0.0);
482 (void)cpl_vector_set(xtrue, 3, 0.0);
483 (void)cpl_vector_set(xtrue, 4, 1.0);
484 (void)cpl_vector_set(xtrue, 5, 1.0);
486 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
487 DBL_EPSILON, DBL_EPSILON);
490 (void)cpl_vector_set(xtrue, 0, -1.0);
491 (void)cpl_vector_set(xtrue, 1, 1.0);
492 (void)cpl_vector_set(xtrue, 2, 1.0);
493 (void)cpl_vector_set(xtrue, 3, 1.0);
494 (void)cpl_vector_set(xtrue, 4, 2.0);
495 (void)cpl_vector_set(xtrue, 5, 3.0);
497 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
498 124.0 * FLT_EPSILON, 960e4 * DBL_EPSILON);
503 cpl_vector_set_size(xtrue, nreal);
506 (void)cpl_vector_set(xtrue, 0, 0.0);
507 (void)cpl_vector_set(xtrue, 1, 0.0);
508 (void)cpl_vector_set(xtrue, 2, 0.0);
509 (void)cpl_vector_set(xtrue, 3, 0.0);
510 (void)cpl_vector_set(xtrue, 4, 1.0);
511 (void)cpl_vector_set(xtrue, 5, 1.0);
512 (void)cpl_vector_set(xtrue, 6, 1.0);
514 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
515 DBL_EPSILON, DBL_EPSILON);
520 cpl_vector_set_size(xtrue, nreal);
522 (void)cpl_vector_set(xtrue, 0, -3.0);
523 (void)cpl_vector_set(xtrue, 1, -2.0);
524 (void)cpl_vector_set(xtrue, 2, -1.0);
525 (void)cpl_vector_set(xtrue, 3, 0.0);
526 (void)cpl_vector_set(xtrue, 4, 1.0);
527 (void)cpl_vector_set(xtrue, 5, 2.0);
528 (void)cpl_vector_set(xtrue, 6, 3.0);
529 (void)cpl_vector_set(xtrue, 7, 4.0);
531 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
532 50.0 * DBL_EPSILON, 350e3 * DBL_EPSILON);
534 (void)cpl_vector_set(xtrue, 0, 1.0);
535 (void)cpl_vector_set(xtrue, 1, 2.0);
536 (void)cpl_vector_set(xtrue, 2, 3.0);
537 (void)cpl_vector_set(xtrue, 3, 4.0);
538 (void)cpl_vector_set(xtrue, 4, 5.0);
539 (void)cpl_vector_set(xtrue, 5, 6.0);
540 (void)cpl_vector_set(xtrue, 6, 7.0);
541 (void)cpl_vector_set(xtrue, 7, 8.0);
543 irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
544 5e5 * DBL_EPSILON, FLT_EPSILON);
550 rtol = DBL_EPSILON * 1000.0;
554 cpl_vector_set_size(xtrue, nreal);
556 for (i = 0; i < nreal; i++) {
557 (void)cpl_vector_set(xtrue, i, (
double)i);
560 irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
564 }
while (nreal < MAXDEGREE);
574 cpl_vector_delete(xtrue);
592cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial * self,
593 const cpl_vector * roots,
597 const cpl_size nroots = cpl_vector_get_size(roots);
599 double prevroot = 0.0;
601 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
602 cpl_ensure_code(roots != NULL, CPL_ERROR_NULL_INPUT);
603 cpl_ensure_code(cpl_polynomial_get_dimension(self) == 1,
604 CPL_ERROR_ILLEGAL_INPUT);
606 cpl_ensure_code(nreal >= 0, CPL_ERROR_ILLEGAL_INPUT);
607 cpl_ensure_code(nreal <= nroots,
608 CPL_ERROR_ILLEGAL_INPUT);
609 cpl_ensure_code((cpl_vector_get_size(roots) - nreal) % 2 == 0,
610 CPL_ERROR_ILLEGAL_INPUT);
613 degree = cpl_polynomial_get_degree(self);
614 cpl_ensure_code(degree > 0 || cpl_polynomial_get_coeff(self, &i) != 0.0,
615 CPL_ERROR_DATA_NOT_FOUND);
617 for (i = 0; i < nreal; i++) {
618 const double root = cpl_vector_get(roots, i);
624 for (j = degree; j >= 0; j--) {
629 const cpl_size jj = j - 1;
630 newval = value = cpl_polynomial_get_coeff(self, &jj);
636 newval -= root * prev;
639 cpl_polynomial_set_coeff(self, &j, newval);
646 cpl_test_leq(prevroot, root);
652 for (; i < nroots; i += 2) {
653 const double a = cpl_vector_get(roots, i);
654 const double b = cpl_vector_get(roots, i+1);
655 cpl_vector * aroot = cpl_vector_new(2);
656 cpl_polynomial * copy = cpl_polynomial_duplicate(self);
658 cpl_vector_fill(aroot, a);
660 irplib_polynomial_multiply_1d_factor(self, aroot, 2);
662 cpl_test_lt(0.0, fabs(b));
664 cpl_polynomial_multiply_scalar(copy, copy, b * b);
666 cpl_polynomial_add(self, self, copy);
668 cpl_vector_delete(aroot);
669 cpl_polynomial_delete(copy);
672 cpl_test_assert(i == nroots);
674 for (i = 0; i < nreal; i++) {
675 const double root = cpl_vector_get(roots, i);
677 const double resid = cpl_polynomial_eval_1d(self, root, &d);
679 cpl_msg_info(cpl_func,
"Real, true root %d/%d of %d degree 1D-"
680 "polynomial at %g has non-zero residual: %g "
682 1+(
int)i, (
int)nreal, (
int)degree, root, resid, d);
686 return CPL_ERROR_NONE;
705irplib_polynomial_test_root_all_macro(
const cpl_vector * self, cpl_size nreal,
706 double factor,
double tolerance,
707 double resitol,
unsigned line)
710 const cpl_size nfail = cpl_test_get_failed();
711 const cpl_size degree = cpl_vector_get_size(self);
712 cpl_polynomial * p1d = cpl_polynomial_new(1);
713 cpl_vector * roots = cpl_vector_new(degree);
714 double maxerror = 0.0;
719 code = cpl_polynomial_set_coeff(p1d, &i, factor);
720 cpl_test_eq_error(code, CPL_ERROR_NONE);
722 code = irplib_polynomial_multiply_1d_factor(p1d, self, nreal);
723 cpl_test_eq_error(code, CPL_ERROR_NONE);
725 code = irplib_polynomial_solve_1d_all(p1d, roots, &jreal);
726 cpl_test_eq_error(code, CPL_ERROR_NONE);
728 cpl_test_eq(jreal, nreal);
729 if (jreal != nreal) {
730 cpl_vector * jroots = (jreal == 0 && code) ? NULL :
731 cpl_vector_wrap(code ? jreal : CPL_MAX(nreal, jreal),
732 cpl_vector_get_data(roots));
734 cpl_msg_info(cpl_func,
"1D-polynomial of degree %d:", (
int)degree);
735 cpl_polynomial_dump(p1d, stderr);
736 cpl_msg_error(cpl_func,
"True roots (%" CPL_SIZE_FORMAT
737 " real): (line=%u)", nreal, line);
738 cpl_vector_dump(self, stderr);
739 cpl_msg_error(cpl_func,
"Computed roots (%" CPL_SIZE_FORMAT
" real): ",
741 cpl_vector_dump(jroots, stderr);
742 (void)cpl_vector_unwrap(jroots);
744 if (cpl_msg_get_level() < CPL_MSG_WARNING) {
745 CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual)
746 cpl_bivector * dump =
747 cpl_bivector_wrap_vectors((cpl_vector*)self, roots);
750 cpl_msg_warning(cpl_func,
"Comparing %" CPL_SIZE_FORMAT
" roots (%"
751 CPL_SIZE_FORMAT
" real): (line=%u)",
752 degree, nreal, line);
753 cpl_bivector_dump(dump, stderr);
754 cpl_bivector_unwrap_vectors(dump);
757 for (i = 0; i < jreal; i++) {
758 const double root = cpl_vector_get(roots, i);
759 const double residual = cpl_polynomial_eval_1d(p1d, root, NULL);
761 cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
762 if (fabs(root - cpl_vector_get(self, i)) > maxerror)
763 maxerror = fabs(root - cpl_vector_get(self, i));
765 cpl_test_abs(residual, 0.0, resitol);
769 for (i = nreal; i < degree; i++) {
770 const double root = cpl_vector_get(roots, i);
772 cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
773 if (fabs(root - cpl_vector_get(self, i)) > maxerror)
774 maxerror = fabs(root - cpl_vector_get(self, i));
780 if (cpl_test_get_failed() != nfail) {
781 cpl_msg_error(cpl_func,
"Line %u failed test(s) on %d/%d real "
782 "roots:", line, (
int)nreal, (
int)degree);
783 cpl_vector_dump(self, stderr);
784 }
else if (maxerror > 0.0) {
785 cpl_msg_info(cpl_func,
"Max-error at degree=%d (line=%u): %g",
786 (
int)degree, line, maxerror);
790 cpl_vector_delete(roots);
791 cpl_polynomial_delete(p1d);