irplib_polynomial-test.c

00001 /* $Id: irplib_polynomial-test.c,v 1.20 2008/03/25 11:12:45 llundin Exp $
00002  *
00003  * This file is part of the ESO Common Pipeline Library
00004  * Copyright (C) 2001-2004 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2008/03/25 11:12:45 $
00024  * $Revision: 1.20 $
00025  * $Name: uves-3_9_0 $
00026  */
00027 
00028 /*-----------------------------------------------------------------------------
00029                                    Includes
00030  -----------------------------------------------------------------------------*/
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include <irplib_polynomial.h>
00037 #include <math.h>
00038 #include <float.h>
00039 
00040 /*-----------------------------------------------------------------------------
00041                                    Defines
00042  -----------------------------------------------------------------------------*/
00043 
00044 #define MAXDEGREE 0
00045 
00046 /*-----------------------------------------------------------------------------
00047                                    Static functions
00048  -----------------------------------------------------------------------------*/
00049 
00050 static cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial *,
00051                                                         const cpl_vector *,
00052                                                         int);
00053 static void irplib_polynomial_solve_1d_all_test(void);
00054 
00055 static void irplib_polynomial_test_root_all(const cpl_vector *, int, double,
00056                                             double, double);
00057 
00058 static cpl_error_code irplib_polynomial_add(cpl_polynomial *,
00059                                             const cpl_polynomial *,
00060                                             const cpl_polynomial *);
00061 
00062 static cpl_error_code irplib_polynomial_multiply_scalar(cpl_polynomial *,
00063                                                         double);
00064 
00065 /*-----------------------------------------------------------------------------
00066                                   Main
00067  -----------------------------------------------------------------------------*/
00068 int main(void)
00069 {
00070     /* Initialize CPL + IRPLIB */
00071     cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
00072 
00073     irplib_polynomial_solve_1d_all_test();
00074 
00075     return cpl_test_end(0);
00076 }
00077 
00078 
00079 /*----------------------------------------------------------------------------*/
00086 /*----------------------------------------------------------------------------*/
00087 static void irplib_polynomial_solve_1d_all_test(void)
00088 {
00089 
00090     cpl_polynomial * p2d   = cpl_polynomial_new(2);
00091     cpl_polynomial * p1d   = cpl_polynomial_new(1);
00092     cpl_vector     * xtrue = cpl_vector_new(2);
00093     const int        maxdegree = MAXDEGREE; /* Largest supported degree */
00094     int              nreal = 0;
00095     int              i;
00096 
00097     cpl_test_eq(irplib_polynomial_solve_1d_all(NULL, xtrue, &nreal),
00098                 CPL_ERROR_NULL_INPUT);
00099     cpl_test_error(CPL_ERROR_NULL_INPUT);
00100 
00101     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, NULL, &nreal),
00102                 CPL_ERROR_NULL_INPUT);
00103     cpl_test_error(CPL_ERROR_NULL_INPUT);
00104 
00105     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, NULL),
00106                 CPL_ERROR_NULL_INPUT);
00107     cpl_test_error(CPL_ERROR_NULL_INPUT);
00108 
00109     cpl_test_eq(irplib_polynomial_solve_1d_all(p2d, xtrue, &nreal),
00110                 CPL_ERROR_INVALID_TYPE);
00111     cpl_test_error(CPL_ERROR_INVALID_TYPE);
00112 
00113     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
00114                 CPL_ERROR_DATA_NOT_FOUND);
00115     cpl_test_error(CPL_ERROR_DATA_NOT_FOUND);
00116 
00117     /* Create a 1st degree polynomial, x = 0 */
00118     i = 1;
00119     cpl_test_eq(cpl_polynomial_set_coeff(p1d, &i, 1.0), CPL_ERROR_NONE);
00120     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
00121                 CPL_ERROR_INCOMPATIBLE_INPUT);
00122     cpl_test_error(CPL_ERROR_INCOMPATIBLE_INPUT);
00123 
00124     cpl_polynomial_delete(p1d);
00125     cpl_polynomial_delete(p2d);
00126 
00127     for (nreal = 1; nreal <= maxdegree; nreal++) {
00128         /* A single, zero-valued root with multiplicity equal to degree */
00129         double xreal = 0.0;
00130 
00131 
00132         cpl_vector_set_size(xtrue, nreal);
00133 
00134         (void)cpl_vector_fill(xtrue, xreal);
00135 
00136         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00137                                         2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00138 
00139         /* A single, non-zero integer root with multiplicity equal to degree */
00140         xreal = 1.0;
00141 
00142         (void)cpl_vector_fill(xtrue, xreal);
00143 
00144         irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
00145                                         2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00146 
00147         /* degree distinct real roots - with rounding */
00148         for (i = 0; i < nreal; i++) {
00149             (void)cpl_vector_set(xtrue, i, 2.0 * (double)i - CPL_MATH_E);
00150         }
00151 
00152         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00153                                         20.0 * DBL_EPSILON,
00154                                         230.0 * DBL_EPSILON);
00155 
00156         /* All real, one zero, one positive, rest negative, sum zero */
00157         for (i = 0; i < nreal-1; i++) {
00158             (void)cpl_vector_set(xtrue, nreal-i-2, (double)(-i));
00159         }
00160         (void)cpl_vector_set(xtrue, nreal-1, (double)(nreal-1)); /* FIXME: ? */
00161 
00162         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00163                                         16.0*DBL_EPSILON, 127.0*DBL_EPSILON);
00164 
00165         if (nreal < 2) continue;
00166         /* Two complex, conjugate roots, the rest is real
00167            with multiplicity degree-2 */
00168 
00169         (void)cpl_vector_fill(xtrue, 2.0);
00170         (void)cpl_vector_set(xtrue, nreal-2, -1.0);
00171         (void)cpl_vector_set(xtrue, nreal-1, 1.0);
00172 
00173         irplib_polynomial_test_root_all(xtrue, nreal-2, CPL_MATH_PI,
00174                                         30.0*DBL_EPSILON, 25.0*DBL_EPSILON);
00175 
00176         if (nreal < 3) continue;
00177         /* Two real roots, the smaller with multiplicity degree-1 */
00178         (void)cpl_vector_fill(xtrue, 1.0);
00179         (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
00180 
00181         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00182                                         DBL_EPSILON, DBL_EPSILON);
00183 
00184         /* Same with negative roots */
00185         (void)cpl_vector_fill(xtrue, -1.0);
00186         (void)cpl_vector_set(xtrue, 0 , -2.0);
00187 
00188         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00189                                         DBL_EPSILON, DBL_EPSILON);
00190 
00191         /* Two real roots, the larger with multiplicity degree-1 */
00192         (void)cpl_vector_fill(xtrue, 2.0);
00193         (void)cpl_vector_set(xtrue, 0, 1.0);
00194 
00195         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00196                                         DBL_EPSILON, DBL_EPSILON);
00197 
00198         if (nreal > 3) continue;
00199 
00200         /* Same with negative roots */
00201         (void)cpl_vector_fill(xtrue, -2.0 * FLT_EPSILON);
00202         (void)cpl_vector_set(xtrue, 0, -1.0);
00203 
00204         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00205                                         DBL_EPSILON, 2.0*DBL_EPSILON);
00206 
00207         /* A more extreme case: Same with negative roots */
00208         (void)cpl_vector_fill(xtrue, -2.0e-4 * FLT_EPSILON);
00209         (void)cpl_vector_set(xtrue, 0, -1.0);
00210 
00211         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00212                                         FLT_EPSILON, 2.0*DBL_EPSILON);
00213 
00214         /* The most extreme case: Same with negative roots */
00215         (void)cpl_vector_fill(xtrue, -2.0 * DBL_EPSILON);
00216         (void)cpl_vector_set(xtrue, 0, -1.0);
00217 
00218         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00219                                         DBL_EPSILON, 2.0*DBL_EPSILON);
00220 
00221 
00222         (void)cpl_vector_set(xtrue, 0, -1.0);
00223         (void)cpl_vector_set(xtrue, 1, -2.0e-4 * FLT_EPSILON);
00224         (void)cpl_vector_set(xtrue, 2,  2.0e-4 * FLT_EPSILON);
00225 
00226         irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00227                                         FLT_EPSILON, 2.0*DBL_EPSILON);
00228 
00229         /* Two complex conjugate roots, remaining:
00230            small, with multiplicity degree-2 */
00231         (void)cpl_vector_fill(xtrue, 2.0*DBL_EPSILON);
00232         (void)cpl_vector_set(xtrue, nreal - 2 , 3.0);
00233         (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
00234 
00235         irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
00236                                         4.0 * DBL_EPSILON, DBL_EPSILON);
00237 
00238         /* Two complex conjugate roots with small real part, remaining:
00239            with multiplicity degree-2 */
00240         (void)cpl_vector_fill(xtrue, 3.0);
00241         (void)cpl_vector_set(xtrue, nreal - 2 , -1.0);
00242         (void)cpl_vector_set(xtrue, nreal - 1 , 2.0);
00243 
00244         irplib_polynomial_test_root_all(xtrue, nreal - 2, CPL_MATH_PI,
00245                                         6.0*DBL_EPSILON, 220.0*DBL_EPSILON);
00246 
00247 
00248     }
00249 
00250 #if MAXDEGREE > 2
00251     /* Cover branch fixing cancellation with one negative,
00252          one positive near-zero and one positive root. */
00253     nreal = 3;
00254 
00255     cpl_vector_set_size(xtrue, nreal);
00256 
00257     /* -2, epsilon, 1  */
00258     (void)cpl_vector_set(xtrue, 0, -2.0);
00259     (void)cpl_vector_set(xtrue, 1,  2.0 * DBL_EPSILON);
00260     (void)cpl_vector_set(xtrue, 2,  1.5);
00261 
00262     irplib_polynomial_test_root_all(xtrue, nreal, 1.0,
00263                                     4.0*DBL_EPSILON, 30.0*DBL_EPSILON);
00264 
00265 #endif
00266 
00267 #if MAXDEGREE > 3
00268     nreal = 4;
00269 
00270     cpl_vector_set_size(xtrue, nreal);
00271 
00272     /* Depressed has zero as root */
00273     (void)cpl_vector_set(xtrue, 0, -1.0);
00274     (void)cpl_vector_set(xtrue, 1,  1.0);
00275     (void)cpl_vector_set(xtrue, 2,  2.0);
00276     (void)cpl_vector_set(xtrue, 3,  2.0);
00277 
00278     irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00279                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00280 
00281     /* Depressed has zero as root, and two complex roots*/
00282     irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
00283                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00284 
00285 
00286     /* Depressed is biquadratic, with 4 real roots */
00287     (void)cpl_vector_set(xtrue, 0, -2.0);
00288     (void)cpl_vector_set(xtrue, 1, -1.0);
00289     (void)cpl_vector_set(xtrue, 2,  1.0);
00290     (void)cpl_vector_set(xtrue, 3,  2.0);
00291 
00292     irplib_polynomial_test_root_all(xtrue, nreal, CPL_MATH_PI,
00293                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00294 
00295     /* Depressed is biquadratic, with 2 real roots */
00296     (void)cpl_vector_set(xtrue, 0, -1.0);
00297     (void)cpl_vector_set(xtrue, 1, 1.0);
00298     (void)cpl_vector_set(xtrue, 2, 0.0);
00299     (void)cpl_vector_set(xtrue, 3, 2.0);
00300 
00301     irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
00302                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00303 
00304     /* Depressed is biquadratic (the quadratic has real, negative roots),
00305        with 0 real roots */
00306     (void)cpl_vector_set(xtrue, 0, 1.0);
00307     (void)cpl_vector_set(xtrue, 1, 2.0);
00308     (void)cpl_vector_set(xtrue, 2, 1.0);
00309     (void)cpl_vector_set(xtrue, 3, 3.0);
00310 
00311     irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
00312                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00313 
00314     /* roots: 0, 0, ai, -ai */
00315     (void)cpl_vector_set(xtrue, 0,  0.0);
00316     (void)cpl_vector_set(xtrue, 1,  0.0);
00317     (void)cpl_vector_set(xtrue, 2,  0.0);
00318     (void)cpl_vector_set(xtrue, 3,  2.0);
00319 
00320     irplib_polynomial_test_root_all(xtrue, 2, CPL_MATH_PI,
00321                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00322 
00323 #if 1
00324     p1d = cpl_polynomial_new(1);
00325 
00326     i = 0;
00327     cpl_polynomial_set_coeff(p1d, &i, -5.0);
00328     i = 1;
00329     cpl_polynomial_set_coeff(p1d, &i, -1.0);
00330     i = 2;
00331     cpl_polynomial_set_coeff(p1d, &i, -2.0);
00332     i = 4;
00333     cpl_polynomial_set_coeff(p1d, &i,  1.0);
00334 
00335     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, xtrue, &nreal),
00336                 CPL_ERROR_NONE);
00337 
00338     cpl_msg_info(cpl_func, "Computed roots (%d real): ", nreal);
00339     if (cpl_msg_get_level() <= CPL_MSG_INFO)
00340         cpl_vector_dump(xtrue, stderr);
00341     cpl_msg_info(cpl_func, "Residual: %g -> %g ", cpl_vector_get(xtrue, 0),
00342                  cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 0), NULL) );
00343     cpl_msg_info(cpl_func, "Residual: %g -> %g ", cpl_vector_get(xtrue, 1),
00344                  cpl_polynomial_eval_1d(p1d, cpl_vector_get(xtrue, 1), NULL) );
00345 
00346     cpl_polynomial_delete(p1d);
00347 #endif
00348 
00349     (void)cpl_vector_set(xtrue, 0, 0.0);
00350     (void)cpl_vector_set(xtrue, 1, 2.0);
00351     (void)cpl_vector_set(xtrue, 2, 1.0);
00352     (void)cpl_vector_set(xtrue, 3, 1.0);
00353 
00354     irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
00355                                     2.0 * DBL_EPSILON, 2.0 * DBL_EPSILON);
00356 
00357     (void)cpl_vector_set(xtrue, 0, -1.0);
00358     (void)cpl_vector_set(xtrue, 1, 2.0);
00359     (void)cpl_vector_set(xtrue, 2, 1.0);
00360     (void)cpl_vector_set(xtrue, 3, 3.0);
00361 
00362     irplib_polynomial_test_root_all(xtrue, 0, CPL_MATH_PI,
00363                                     3.0 * DBL_EPSILON, 3.0 * DBL_EPSILON);
00364 #endif
00365 
00366     cpl_vector_delete(xtrue);
00367 
00368     return;
00369 }
00370 
00371 /*----------------------------------------------------------------------------*/
00382 /*----------------------------------------------------------------------------*/
00383 static
00384 cpl_error_code irplib_polynomial_multiply_1d_factor(cpl_polynomial * self,
00385                                                     const cpl_vector * roots,
00386                                                     int nreal)
00387 {
00388 
00389     int i, degree;
00390     const int nroots = cpl_vector_get_size(roots);
00391 
00392     cpl_ensure_code(self  != NULL, CPL_ERROR_NULL_INPUT);
00393     cpl_ensure_code(roots != NULL, CPL_ERROR_NULL_INPUT);
00394     cpl_ensure_code(cpl_polynomial_get_dimension(self) == 1,
00395                      CPL_ERROR_ILLEGAL_INPUT);
00396 
00397     cpl_ensure_code(nreal >= 0,    CPL_ERROR_ILLEGAL_INPUT);
00398     cpl_ensure_code(nreal <= nroots,
00399                      CPL_ERROR_ILLEGAL_INPUT);
00400     cpl_ensure_code((cpl_vector_get_size(roots) - nreal) % 2 == 0,
00401                      CPL_ERROR_ILLEGAL_INPUT);
00402 
00403     i = 0;
00404     degree = cpl_polynomial_get_degree(self);
00405     cpl_ensure_code(degree > 0 || cpl_polynomial_get_coeff(self, &i) != 0.0,
00406                      CPL_ERROR_DATA_NOT_FOUND);
00407 
00408     for (i = 0; i < nreal; i++) {
00409         const double root = cpl_vector_get(roots, i);
00410         double prev = 0.0;
00411         int j;
00412 
00413         degree++;
00414 
00415         for (j = degree; j >= 0; j--) {
00416             double value = 0.0;
00417             double newval;
00418 
00419             if (j > 0) {
00420                 const int jj = j - 1;
00421                 newval = value = cpl_polynomial_get_coeff(self, &jj);
00422             } else {
00423                 newval = 0.0;
00424             }
00425 
00426             if (j < degree) {
00427                 newval -= root * prev;
00428             }
00429 
00430             cpl_polynomial_set_coeff(self, &j, newval);
00431 
00432             prev = value;
00433 
00434         }
00435     }
00436 
00437     /* Multiplication with the complex conjugate root
00438        (x-a-ib) (x-a+ib) p(x) = (x-a)^2 p(x) + b^2 p(x) */
00439     for (; i < nroots; i += 2) {
00440         const double a = cpl_vector_get(roots, i);
00441         const double b = cpl_vector_get(roots, i+1);
00442         cpl_vector * aroot = cpl_vector_new(2);
00443         cpl_polynomial * copy = cpl_polynomial_duplicate(self);
00444 
00445         cpl_vector_fill(aroot, a);
00446 
00447         irplib_polynomial_multiply_1d_factor(self, aroot, 2);
00448 
00449         irplib_polynomial_multiply_scalar(copy, b * b);
00450 
00451         irplib_polynomial_add(self, self, copy);
00452 
00453         cpl_vector_delete(aroot);
00454         cpl_polynomial_delete(copy);
00455 
00456     }
00457 
00458     return CPL_ERROR_NONE;
00459 
00460 }
00461 
00462 
00463 /*----------------------------------------------------------------------------*/
00478 /*----------------------------------------------------------------------------*/
00479 static cpl_error_code irplib_polynomial_add(cpl_polynomial * self,
00480                                             const cpl_polynomial * first,
00481                                             const cpl_polynomial * second)
00482 {
00483 
00484     int degree0;
00485     int degree1;
00486     int degree2;
00487 
00488     cpl_ensure_code(self   != NULL, CPL_ERROR_NULL_INPUT);
00489     cpl_ensure_code(first  != NULL, CPL_ERROR_NULL_INPUT);
00490     cpl_ensure_code(second != NULL, CPL_ERROR_NULL_INPUT);
00491 
00492     cpl_ensure_code(cpl_polynomial_get_dimension(self) ==
00493                     cpl_polynomial_get_dimension(first),
00494                     CPL_ERROR_INCOMPATIBLE_INPUT);
00495     cpl_ensure_code(cpl_polynomial_get_dimension(self) ==
00496                     cpl_polynomial_get_dimension(second),
00497                     CPL_ERROR_INCOMPATIBLE_INPUT);
00498 
00499     cpl_ensure_code(cpl_polynomial_get_dimension(self) == 1,
00500                     CPL_ERROR_UNSUPPORTED_MODE);
00501 
00502     degree0 = cpl_polynomial_get_degree(self);
00503     degree1 = cpl_polynomial_get_degree(first);
00504     degree2 = cpl_polynomial_get_degree(second);
00505 
00506     if (degree1 > degree2) {
00507         for (; degree0 > degree1; degree0--) {
00508             cpl_polynomial_set_coeff(self, &degree0, 0.0);
00509         }
00510         for (; degree0 > degree2; degree0--) {
00511             const double val1 = cpl_polynomial_get_coeff(first, &degree0);
00512             cpl_polynomial_set_coeff(self, &degree0, val1);
00513         }
00514     } else {
00515         for (; degree0 > degree2; degree0--) {
00516             cpl_polynomial_set_coeff(self, &degree0, 0.0);
00517         }
00518         for (; degree0 > degree1; degree0--) {
00519             const double val2 = cpl_polynomial_get_coeff(second, &degree0);
00520             cpl_polynomial_set_coeff(self, &degree0, val2);
00521         }
00522     }
00523 
00524     for (; degree0 >=0; degree0--) {
00525         const double val1 = cpl_polynomial_get_coeff(first, &degree0);
00526         const double val2 = cpl_polynomial_get_coeff(second, &degree0);
00527         cpl_polynomial_set_coeff(self, &degree0, val1 + val2);
00528     }
00529 
00530     return CPL_ERROR_NONE;
00531 }
00532 
00533 /*----------------------------------------------------------------------------*/
00545 /*----------------------------------------------------------------------------*/
00546 static cpl_error_code irplib_polynomial_multiply_scalar(cpl_polynomial * self,
00547                                                         double factor)
00548 {
00549 
00550     int degree0;
00551 
00552     cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
00553 
00554     cpl_ensure_code(cpl_polynomial_get_dimension(self) == 1,
00555                     CPL_ERROR_UNSUPPORTED_MODE);
00556 
00557     degree0 = cpl_polynomial_get_degree(self);
00558 
00559     for (; degree0 >=0; degree0--) {
00560         const double val = cpl_polynomial_get_coeff(self, &degree0);
00561         cpl_polynomial_set_coeff(self, &degree0, factor * val);
00562     }
00563 
00564     return CPL_ERROR_NONE;
00565 }
00566 
00567 /*----------------------------------------------------------------------------*/
00580 /*----------------------------------------------------------------------------*/
00581 static void irplib_polynomial_test_root_all(const cpl_vector * self, int nreal,
00582                                             double factor, double tolerance,
00583                                             double resitol)
00584 {
00585 
00586     const int degree = cpl_vector_get_size(self);
00587     cpl_polynomial * p1d = cpl_polynomial_new(1);
00588     cpl_vector * roots = cpl_vector_new(degree);
00589     int i = 0;
00590     int jreal;
00591 
00592     cpl_test_eq(cpl_polynomial_set_coeff(p1d, &i, factor), CPL_ERROR_NONE);
00593 
00594     cpl_test_eq(irplib_polynomial_multiply_1d_factor(p1d, self, nreal),
00595                 CPL_ERROR_NONE);
00596 
00597     cpl_test_eq(irplib_polynomial_solve_1d_all(p1d, roots, &jreal),
00598                 CPL_ERROR_NONE);
00599 
00600     cpl_test_eq(jreal, nreal);
00601     if (jreal != nreal) {
00602         cpl_msg_error(cpl_func, "True roots (%d real): ", nreal);
00603         cpl_vector_dump(self, stderr);
00604         cpl_msg_error(cpl_func, "Computed roots (%d real): ", jreal);
00605         cpl_vector_dump(roots, stderr);
00606     } else if (cpl_msg_get_level() < CPL_MSG_WARNING) {
00607         cpl_bivector * dump =
00608             cpl_bivector_wrap_vectors((cpl_vector*)self, roots);
00609 
00610         cpl_msg_warning(cpl_func, "Comparing %d roots (%d real): ", degree,
00611                         nreal);
00612         cpl_bivector_dump(dump, stderr);
00613         cpl_bivector_unwrap_vectors(dump);
00614     }
00615 
00616     for (i = 0; i < jreal; i++) {
00617         const double root = cpl_vector_get(roots, i);
00618         const double residual = cpl_polynomial_eval_1d(p1d, root, NULL);
00619 
00620         cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
00621 
00622         cpl_test_abs(residual, 0.0, resitol);
00623 
00624     }
00625 
00626     for (i = nreal; i < degree; i++) {
00627         const double root = cpl_vector_get(roots, i);
00628 
00629         cpl_test_abs(root, cpl_vector_get(self, i), tolerance);
00630         /* FIXME: Verify residual as well */
00631 
00632     }
00633 
00634     cpl_vector_delete(roots);
00635     cpl_polynomial_delete(p1d);
00636 
00637     return;
00638 }

Generated on Fri Apr 18 14:11:41 2008 for UVES Pipeline Reference Manual by  doxygen 1.5.1