00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 #ifdef HAVE_CONFIG_H
00111 # include <config.h>
00112 #endif
00113
00114
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 #define COLUMN_ORDER1 "Order1"
00145 #define COLUMN_ORDER2 "Order2"
00146 #define COLUMN_COEFF "Coeff"
00147
00150
00151
00152
00153 #include <uves_utils_polynomial.h>
00154
00155 #include <uves_utils.h>
00156 #include <uves_utils_wrappers.h>
00157 #include <uves_dump.h>
00158 #include <uves_msg.h>
00159 #include <uves_error.h>
00160
00161 #include <irplib_access.h>
00162
00163 #include <cpl.h>
00164
00165
00166
00167
00170 struct _polynomial
00171 {
00173 cpl_polynomial *pol;
00174
00176 cpl_vector *vec;
00177 double *vec_data;
00178
00179 int dimension;
00180
00182 double *shift;
00183
00185 double *scale;
00186 };
00187
00188
00189
00190
00191
00202
00203 polynomial *
00204 uves_polynomial_new(const cpl_polynomial *pol)
00205 {
00206 polynomial *p = NULL;
00207 int i;
00208
00209
00210 assure(pol != NULL, CPL_ERROR_ILLEGAL_INPUT, "Null polynomial");
00211
00212
00213 p = cpl_calloc(1, sizeof(polynomial)) ;
00214 assure_mem( p );
00215
00216 check( p->dimension = cpl_polynomial_get_dimension(pol), "Error reading dimension");
00217
00218
00219 p->vec = cpl_vector_new(p->dimension);
00220 assure_mem( p->vec );
00221 p->vec_data = cpl_vector_get_data(p->vec);
00222
00223
00224 p->shift = cpl_calloc(p->dimension + 1, sizeof(double));
00225 assure_mem( p->shift );
00226
00227 p->scale = cpl_malloc((p->dimension + 1) * sizeof(double));
00228 assure_mem( p->scale );
00229 for (i = 0; i <= p->dimension; i++)
00230 p->scale[i] = 1.0;
00231
00232 check( p->pol = cpl_polynomial_duplicate(pol), "Error copying polynomial");
00233
00234 cleanup:
00235 if (cpl_error_get_code() != CPL_ERROR_NONE)
00236 uves_polynomial_delete(&p);
00237
00238 return p;
00239 }
00240
00241
00249
00250 polynomial *
00251 uves_polynomial_new_zero(int dim)
00252 {
00253 polynomial *result = NULL;
00254 cpl_polynomial *p = NULL;
00255
00256 assure( dim >= 1, CPL_ERROR_ILLEGAL_INPUT, "Illegal dimension: %d", dim);
00257
00258 p = cpl_polynomial_new(dim);
00259 assure_mem( p );
00260
00261 result = uves_polynomial_new(p);
00262 assure_mem( result );
00263
00264 cleanup:
00265 uves_free_polynomial(&p);
00266
00267 return result;
00268 }
00269
00270
00277
00278 void
00279 uves_polynomial_delete(polynomial **p)
00280 {
00281 uves_polynomial_delete_const((const polynomial **)p);
00282 }
00283
00284
00291
00292 void
00293 uves_polynomial_delete_const(const polynomial **p)
00294 {
00295 if (*p == NULL) return;
00296 irplib_polynomial_delete((*p)->pol);
00297 irplib_vector_delete((*p)->vec);
00298 cpl_free((*p)->shift);
00299 cpl_free((*p)->scale);
00300 irplib_free(*p);
00301 *p = NULL;
00302 return;
00303 }
00304
00310
00311 int
00312 uves_polynomial_get_degree(const polynomial *p)
00313 {
00314 int result = -1;
00315 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00316
00317 result = cpl_polynomial_get_degree(p->pol);
00318
00319 cleanup:
00320 return result;
00321 }
00322
00323
00329
00330 polynomial *
00331 uves_polynomial_duplicate(const polynomial *p)
00332 {
00333 polynomial *result = NULL;
00334 int dimension;
00335 int i;
00336
00337 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00338 dimension = uves_polynomial_get_dimension(p);
00339
00340 check( result = uves_polynomial_new(p->pol),
00341 "Error allocating polynomial");
00342
00343 for (i = 0; i <= dimension; i++)
00344 {
00345 result->shift[i] = p->shift[i];
00346 result->scale[i] = p->scale[i];
00347 }
00348
00349 cleanup:
00350 if (cpl_error_get_code() != CPL_ERROR_NONE)
00351 {
00352 uves_polynomial_delete(&result);
00353 return NULL;
00354 }
00355
00356 return result;
00357 }
00358
00359
00360
00371
00372 cpl_table *
00373 uves_polynomial_convert_to_table(const polynomial *p)
00374 {
00375 cpl_table *t = NULL;
00376 int degree;
00377 int i, j, row;
00378
00379
00380 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00381 assure( uves_polynomial_get_dimension(p) == 2,
00382 CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 2D");
00383
00384 degree = cpl_polynomial_get_degree(p->pol);
00385
00386
00387
00388 t = cpl_table_new(3 + 3 + (degree + 1)*(degree + 2)/2);
00389 cpl_table_new_column(t, COLUMN_ORDER1, CPL_TYPE_INT);
00390 cpl_table_new_column(t, COLUMN_ORDER2, CPL_TYPE_INT);
00391 cpl_table_new_column(t, COLUMN_COEFF , CPL_TYPE_DOUBLE);
00392
00393 row = 0;
00394
00395
00396 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00397 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00398 cpl_table_set_double(t, COLUMN_COEFF , row, p->shift[0]); row++;
00399
00400 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00401 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00402 cpl_table_set_double(t, COLUMN_COEFF , row, p->shift[1]); row++;
00403
00404 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00405 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00406 cpl_table_set_double(t, COLUMN_COEFF , row, p->shift[2]); row++;
00407
00408
00409 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00410 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00411 cpl_table_set_double(t, COLUMN_COEFF, row, p->scale[0]); row++;
00412
00413 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00414 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00415 cpl_table_set_double(t, COLUMN_COEFF, row, p->scale[1]); row++;
00416
00417 cpl_table_set_int (t, COLUMN_ORDER1, row, -1);
00418 cpl_table_set_int (t, COLUMN_ORDER2, row, -1);
00419 cpl_table_set_double(t, COLUMN_COEFF, row, p->scale[2]); row++;
00420
00421
00422 for (i = 0; i <= degree; i++){
00423 for (j = 0; j+i <= degree; j++){
00424 double coeff;
00425 int power[2];
00426 power[0] = i;
00427 power[1] = j;
00428
00429 coeff = cpl_polynomial_get_coeff(p->pol, power);
00430 cpl_table_set_int (t, COLUMN_ORDER1, row, power[0]);
00431 cpl_table_set_int (t, COLUMN_ORDER2, row, power[1]);
00432 cpl_table_set_double(t, COLUMN_COEFF , row, coeff);
00433
00434 row++;
00435 }
00436 }
00437
00438 cleanup:
00439 return t;
00440 }
00441
00442
00451
00452 polynomial *
00453 uves_polynomial_convert_from_table(cpl_table *t)
00454 {
00455 polynomial *p = NULL;
00456 cpl_polynomial *pol = NULL;
00457 cpl_type type;
00458 int i;
00459
00460
00461 check( pol = cpl_polynomial_new(2), "Error initializing polynomial");
00462
00463
00464 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
00465 assure(cpl_table_has_column(t, COLUMN_ORDER1), CPL_ERROR_ILLEGAL_INPUT,
00466 "No '%s' column found in table", COLUMN_ORDER1);
00467 assure(cpl_table_has_column(t, COLUMN_ORDER2), CPL_ERROR_ILLEGAL_INPUT,
00468 "No '%s' column found in table", COLUMN_ORDER2);
00469 assure(cpl_table_has_column(t, COLUMN_COEFF ), CPL_ERROR_ILLEGAL_INPUT,
00470 "No '%s' column found in table", COLUMN_COEFF );
00471
00472 type = cpl_table_get_column_type(t, COLUMN_ORDER1);
00473 assure(type == CPL_TYPE_INT , CPL_ERROR_INVALID_TYPE,
00474 "Column '%s' has type %s. Integer expected", COLUMN_ORDER1,
00475 uves_tostring_cpl_type(type));
00476
00477 type = cpl_table_get_column_type(t, COLUMN_ORDER2);
00478 assure(type == CPL_TYPE_INT , CPL_ERROR_INVALID_TYPE,
00479 "Column '%s' has type %s. Integer expected", COLUMN_ORDER2,
00480 uves_tostring_cpl_type(type));
00481
00482 type = cpl_table_get_column_type(t, COLUMN_COEFF);
00483 assure(type == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
00484 "Column '%s' has type %s. Double expected", COLUMN_COEFF ,
00485 uves_tostring_cpl_type(type));
00486
00487 assure(cpl_table_get_nrow(t) > 1 + 2 + 1 + 2, CPL_ERROR_ILLEGAL_INPUT,
00488 "Table must contain at least one coefficient");
00489
00490
00491 for(i = 3 + 3; i < cpl_table_get_nrow(t); i++) {
00492 double coeff;
00493 int power[2];
00494
00495 check(( power[0] = cpl_table_get_int(t, COLUMN_ORDER1, i, NULL),
00496 power[1] = cpl_table_get_int(t, COLUMN_ORDER2, i, NULL),
00497 coeff = cpl_table_get_double(t, COLUMN_COEFF , i, NULL)),
00498 "Error reading table row %d", i);
00499
00500 uves_msg_debug("Pol.coeff.(%d, %d) = %e", power[0], power[1], coeff);
00501
00502 check( cpl_polynomial_set_coeff(pol, power, coeff), "Error creating polynomial");
00503 }
00504 p = uves_polynomial_new(pol);
00505
00506
00507 uves_polynomial_rescale(p, 0, cpl_table_get_double( t, COLUMN_COEFF, 3, NULL));
00508 uves_polynomial_rescale(p, 1, cpl_table_get_double( t, COLUMN_COEFF, 4, NULL));
00509 uves_polynomial_rescale(p, 2, cpl_table_get_double( t, COLUMN_COEFF, 5, NULL));
00510 uves_polynomial_shift (p, 0, cpl_table_get_double( t, COLUMN_COEFF, 0, NULL));
00511 uves_polynomial_shift (p, 1, cpl_table_get_double( t, COLUMN_COEFF, 1, NULL));
00512 uves_polynomial_shift (p, 2, cpl_table_get_double( t, COLUMN_COEFF, 2, NULL));
00513
00514 cleanup:
00515 uves_free_polynomial(&pol);
00516 if (cpl_error_get_code() != CPL_ERROR_NONE)
00517 uves_polynomial_delete(&p);
00518
00519 return p;
00520 }
00521
00522
00538
00539 polynomial *
00540 uves_polynomial_convert_from_plist_midas(const uves_propertylist *plist,
00541 const char *regression_name)
00542 {
00543 polynomial *result = NULL;
00544 cpl_polynomial *pol = NULL;
00545 int N = strlen(regression_name);
00546 int degree1 = -1;
00547 int degree2 = -1;
00548 bool found = false;
00549 const long int plist_size = uves_propertylist_get_size(plist);
00550 int i;
00551
00552 for (i = 0; !found && i < plist_size; i++){
00553 const cpl_property *p = uves_propertylist_get_const(plist, i);
00554 const char *name = cpl_property_get_name(p);
00555
00556 if (strcmp(name, "HISTORY") == 0) {
00557 const char *value;
00558 check( value = cpl_property_get_string(p),
00559 "Error reading property value");
00560
00561
00562 if ((int)strlen(value) >= 1+N+2 &&
00563 value[0] == '\'' &&
00564 value[1+N] == 'I' &&
00565 value[1+N+1] == '\'' &&
00566 strncmp(value+1, regression_name, N) == 0
00567 ) {
00568 long number;
00569 char *next;
00570
00571 assure(i+1 < plist_size, CPL_ERROR_ILLEGAL_INPUT,
00572 "Missing header data");
00573 p = uves_propertylist_get_const(plist, i+1);
00574 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
00575 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
00576 CPL_ERROR_ILLEGAL_INPUT,
00577 "Error parsing polynomial");
00578 value = cpl_property_get_string(
00579 uves_propertylist_get_const(plist, i+1));
00580
00581
00582 number = strtol(value, &next, 10);
00583
00584
00585 value = next;
00586 assure( strtol(value, &next, 10) == 2, CPL_ERROR_UNSUPPORTED_MODE,
00587 "Regressions is %ld-dimensional (2D expected)",
00588 strtol(value, &next, 10));
00589
00590
00591
00592
00593
00594
00595 value = next; number = strtol(value, &next, 10);
00596 value = next; number = strtol(value, &next, 10);
00597 value = next; number = strtol(value, &next, 10);
00598
00599
00600
00601 value = next; degree1 = strtol(value, &next, 10);
00602 value = next; degree2 = strtol(value, &next, 10);
00603
00604 uves_msg_debug("Degree of 2D regression %s is (%d, %d)",
00605 regression_name, degree1, degree2);
00606
00607
00608 found = true;
00609 }
00610 }
00611 }
00612
00613 assure( found, CPL_ERROR_ILLEGAL_INPUT, "No MIDAS-regression named %s found in propertylist",
00614 regression_name);
00615
00616
00617
00618 pol = cpl_polynomial_new(2);
00619
00620
00621 found = false;
00622 for (i = 0; !found && i < plist_size; i++){
00623 const cpl_property *p = uves_propertylist_get_const(plist, i);
00624 const char *name = cpl_property_get_name(p);
00625
00626 if (strcmp(name, "HISTORY") == 0) {
00627 const char *value;
00628 check( value = cpl_property_get_string(p),
00629 "Error reading property value");
00630
00631
00632
00633 if ((int)strlen(value) >= 1+N+2 &&
00634 value[0] == '\'' &&
00635 value[1+N] == 'D' &&
00636 value[1+N+1] == '\'' &&
00637 strncmp(value+1, regression_name, N) == 0
00638 ) {
00639 double coeff;
00640 char *next;
00641 int power[2];
00642 int j = i;
00643
00644 power[0] = 0;
00645 power[1] = 0;
00646
00647 found = true;
00648 value = "dummy";
00649
00650 while (power[1] <= degree2){
00651
00652 coeff = strtod(value, &next);
00653
00654 if (next != value) {
00655
00656 cpl_polynomial_set_coeff(pol, power, coeff);
00657 uves_msg_debug("Polynomial coefficient of order (%d, %d) is %e",
00658 power[0], power[1], coeff);
00659
00660 power[0]++;
00661 if (power[0] > degree1){
00662 power[0] = 0;
00663 power[1]++;
00664 }
00665 value = next;
00666 }
00667 else {
00668
00669
00670 j = j + 1;
00671
00672 assure(j < plist_size, CPL_ERROR_ILLEGAL_INPUT,
00673 "Missing header data");
00674
00675 p = uves_propertylist_get_const(plist, j);
00676 assure( cpl_property_get_type(p) == CPL_TYPE_STRING &&
00677 strcmp(cpl_property_get_name(p), "HISTORY") == 0,
00678 CPL_ERROR_ILLEGAL_INPUT, "Error parsing polynomial");
00679
00680 value = cpl_property_get_string(p);
00681
00682
00683 uves_msg_debug("Parsing string '%s'", value);
00684 }
00685 }
00686 }
00687 }
00688 }
00689
00690 assure( found, CPL_ERROR_ILLEGAL_INPUT, "Could not find '%sD' in property list",
00691 regression_name);
00692
00693
00694 result = uves_polynomial_new(pol);
00695
00696 cleanup:
00697 uves_free_polynomial(&pol);
00698 if (cpl_error_get_code() != CPL_ERROR_NONE)
00699 {
00700 uves_polynomial_delete(&result);
00701 }
00702
00703 return result;
00704 }
00705
00706
00712
00713 int
00714 uves_polynomial_get_dimension(const polynomial *p)
00715 {
00716 int dim = -1;
00717 assure(p != NULL, CPL_ERROR_ILLEGAL_INPUT, "Null polynomial");
00718
00719
00720 dim = p->dimension;
00721
00722 cleanup:
00723 return dim;
00724 }
00725
00726
00734
00735 void uves_polynomial_dump(const polynomial *p, FILE *stream)
00736 {
00737 if (p == NULL)
00738 fprintf(stream, "Null polynomial\n");
00739 else {
00740 int i;
00741 cpl_polynomial_dump(p->pol, stream);
00742 fprintf(stream, "shift_y \t= %f \tscale_y \t= %f\n", p->shift[0], p->scale[0]);
00743 for (i = 1; i <= uves_polynomial_get_dimension(p); i++)
00744 {
00745 fprintf(stream, "shift_x%d \t= %f \tscale_x%d \t= %f\n",
00746 i, p->shift[i], i, p->scale[i]);
00747 }
00748 }
00749 return;
00750 }
00751
00752
00766
00767 cpl_error_code
00768 uves_polynomial_rescale(polynomial *p, int varno, double scale)
00769 {
00770 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00771 assure(0 <= varno && varno <= uves_polynomial_get_dimension(p),
00772 CPL_ERROR_ILLEGAL_INPUT, "Illegal variable number: %d", varno);
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 p->shift[varno] *= scale;
00787 p->scale[varno] *= scale;
00788
00789 cleanup:
00790 return cpl_error_get_code();
00791 }
00792
00793
00807
00808 cpl_error_code
00809 uves_polynomial_shift(polynomial *p, int varno, double shift)
00810 {
00811 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00812 assure(0 <= varno && varno <= uves_polynomial_get_dimension(p),
00813 CPL_ERROR_ILLEGAL_INPUT, "Illegal variable number: %d", varno);
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 p->shift[varno] += shift;
00825
00826 cleanup:
00827 return cpl_error_get_code();
00828 }
00829
00830
00839
00840 double
00841 uves_polynomial_evaluate_1d(const polynomial *p, double x)
00842 {
00843 double result = 0;
00844
00845 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00846 assure(uves_polynomial_get_dimension(p) == 1,
00847 CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 1d");
00848
00849 check( result =
00850 cpl_polynomial_eval_1d(p->pol, (x - p->shift[1])/p->scale[1], NULL)
00851 * p->scale[0] + p->shift[0],
00852 "Could not evaluate polynomial");
00853
00854 cleanup:
00855 return result;
00856 }
00857
00858
00859
00869
00870
00871 double
00872 uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
00873 {
00874 double result = 0;
00875
00876 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00877 assure(p->dimension == 2, CPL_ERROR_ILLEGAL_INPUT,
00878 "Polynomial must be 2d. It's %dd", p->dimension);
00879 {
00880 double scale = p->scale[0];
00881 double shift = p->shift[0];
00882
00883
00884
00885 p->vec_data[0] = (x1 - p->shift[1]) / p->scale[1];
00886 p->vec_data[1] = (x2 - p->shift[2]) / p->scale[2];
00887
00888 result = cpl_polynomial_eval(p->pol, p->vec) * scale + shift;
00889 }
00890
00891 cleanup:
00892 return result;
00893 }
00894
00895
00908
00909 double
00910 uves_polynomial_solve_1d(const polynomial *p, double value, double guess, int multiplicity)
00911 {
00912 double result = 0;
00913 int power[1];
00914 double coeff0;
00915
00916 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
00917 assure(uves_polynomial_get_dimension(p) == 1, CPL_ERROR_ILLEGAL_INPUT,
00918 "Polynomial must be 1d");
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 power[0] = 0;
00929 check(( coeff0 = cpl_polynomial_get_coeff(p->pol, power),
00930 cpl_polynomial_set_coeff(p->pol, power, coeff0 + (p->shift[0] - value)/p->scale[0])),
00931 "Error setting coefficient");
00932
00933 check( cpl_polynomial_solve_1d(p->pol, (guess - p->shift[1]) / p->scale[1],
00934 &result, multiplicity), "Could not find root");
00935
00936 cpl_polynomial_set_coeff(p->pol, power, coeff0);
00937
00938
00939 result = result * p->scale[1] + p->shift[1];
00940
00941 cleanup:
00942 return result;
00943 }
00944
00945
00962
00963 double
00964 uves_polynomial_solve_2d(const polynomial *p, double value, double guess,
00965 int multiplicity, int varno, double x_value)
00966 {
00967 double result = 0;
00968 polynomial *pol_1d = NULL;
00969
00970 assure( 1 <= varno && varno <= 2, CPL_ERROR_ILLEGAL_INPUT,
00971 "Illegal variable number: %d", varno);
00972
00973 check( pol_1d = uves_polynomial_collapse(p, varno, x_value),
00974 "Could not collapse polynomial");
00975
00976 check( result = uves_polynomial_solve_1d(pol_1d, value, guess, multiplicity),
00977 "Could not find root");
00978
00979 cleanup:
00980 uves_polynomial_delete(&pol_1d);
00981 return result;
00982 }
00983
00984
00993
00994 double
00995 uves_polynomial_derivative_2d(const polynomial *p, double x1, double x2, int varno)
00996 {
00997 double result = 0;
00998 int power[2];
00999
01000 assure (1 <= varno && varno <= 2, CPL_ERROR_ILLEGAL_INPUT,
01001 "Illegal variable number (%d)", varno);
01002
01003 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01004 assure(uves_polynomial_get_dimension(p) == 2, CPL_ERROR_ILLEGAL_INPUT,
01005 "Polynomial must be 2d. It's %dd", uves_polynomial_get_dimension(p));
01006
01007
01008
01009
01010
01011
01012
01013 x1 = (x1 - p->shift[1])/p->scale[1];
01014 x2 = (x2 - p->shift[2])/p->scale[2];
01015
01016
01017
01018
01019 {
01020 int degree = cpl_polynomial_get_degree(p->pol);
01021 double yj = 1;
01022 int i, j;
01023
01024 result = 0;
01025 for (j = 0, yj = 1;
01026 j <= degree; j++,
01027 yj *= (varno == 1) ? x2 : x1)
01028 {
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 double sum = 0;
01040 for (i = degree; i >= 1; i--)
01041 {
01042 double c_ij;
01043
01044 power[0] = (varno == 1) ? i : j;
01045 power[1] = (varno == 1) ? j : i;
01046
01047 c_ij = cpl_polynomial_get_coeff(p->pol, power);
01048
01049 sum += (i * c_ij);
01050 if (i >= 2) sum *= (varno == 1) ? x1 : x2;
01051 }
01052
01053
01054 result += yj * sum;
01055 }
01056 }
01057
01058 result *= p->scale[0];
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 cleanup:
01072 return result;
01073 }
01074
01075
01082
01083 double
01084 uves_polynomial_derivative_1d(const polynomial *p, double x)
01085 {
01086 double result = 0;
01087 double dummy;
01088
01089 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01090 assure(uves_polynomial_get_dimension(p) == 1,
01091 CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 1d");
01092
01093 check( dummy = cpl_polynomial_eval_1d(p->pol, (x - p->shift[1])/p->scale[1], &result),
01094 "Error evaluating derivative");
01095
01096 cleanup:
01097 return result;
01098 }
01099
01100
01107
01108 polynomial *
01109 uves_polynomial_add_2d(const polynomial *p1, const polynomial *p2)
01110 {
01111 polynomial *result = NULL;
01112 cpl_polynomial *pol = NULL;
01113
01114 assure(p1 != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01115 assure(p2 != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01116 assure(uves_polynomial_get_dimension(p1) == 2,
01117 CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 2d");
01118 assure(uves_polynomial_get_dimension(p2) == 2,
01119 CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 2d");
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 {
01131 int degree, i, j;
01132
01133 degree = uves_max_int(uves_polynomial_get_degree(p1),
01134 uves_polynomial_get_degree(p2));
01135
01136 pol = cpl_polynomial_new(2);
01137 for (i = 0; i <= degree; i++)
01138 for (j = 0; j <= degree; j++) {
01139 double coeff1, coeff2;
01140 int power[2];
01141
01142
01143 coeff1 = uves_polynomial_get_coeff_2d(p1, i, j);
01144 coeff2 = uves_polynomial_get_coeff_2d(p2, i, j);
01145
01146 power[0] = i;
01147 power[1] = j;
01148 cpl_polynomial_set_coeff(pol, power, coeff1 + coeff2);
01149 }
01150 }
01151
01152 result = uves_polynomial_new(pol);
01153
01154 cleanup:
01155 uves_free_polynomial(&pol);
01156 return result;
01157 }
01158
01159
01172
01173 static cpl_error_code
01174 derivative_cpl_polynomial(cpl_polynomial *p, int varno)
01175 {
01176 int dimension, degree;
01177 int i, j;
01178 int power[2];
01179
01180 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01181 dimension = cpl_polynomial_get_dimension(p);
01182 degree = cpl_polynomial_get_degree(p);
01183 assure( 1 <= dimension && dimension <= 2, CPL_ERROR_ILLEGAL_INPUT,
01184 "Illegal dimension: %d", dimension);
01185 assure( 1 <= varno && varno <= dimension, CPL_ERROR_ILLEGAL_INPUT,
01186 "Illegal variable number: %d", varno);
01187
01188 if (dimension == 1)
01189 {
01190
01191 for(i = 0; i <= degree; i++)
01192 {
01193 double coeff;
01194 power[0] = i+1;
01195
01196
01197 coeff = cpl_polynomial_get_coeff(p, power);
01198
01199 power[0] = i;
01200 cpl_polynomial_set_coeff(p, power, (i+1) * coeff);
01201 }
01202 }
01203
01204 if (dimension == 2)
01205 {
01206
01207 for(i = 0; i <= degree; i++)
01208 {
01209 for(j = 0; i + j <= degree; j++)
01210 {
01211 double coeff;
01212 power[varno - 1] = i+1;
01213 power[2 - varno] = j;
01214
01215 coeff = cpl_polynomial_get_coeff(p, power);
01216
01217 power[varno - 1] = i;
01218
01219 cpl_polynomial_set_coeff(p, power, (i+1) * coeff);
01220 }
01221 }
01222 }
01223
01224 cleanup:
01225 return cpl_error_get_code();
01226 }
01227
01228
01238
01239 cpl_error_code
01240 uves_polynomial_derivative(polynomial *p, int varno)
01241 {
01242 int dimension;
01243
01244 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01245 check ( dimension = uves_polynomial_get_dimension(p), "Error reading dimension");
01246 assure( 1 <= varno && varno <= dimension, CPL_ERROR_ILLEGAL_INPUT,
01247 "Illegal variable number: %d", varno);
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 p->shift[0] = 0;
01262 p->scale[0] = p->scale[0] / p->scale[varno];
01263
01264 check( derivative_cpl_polynomial(p->pol, varno),
01265 "Error calculating derivative of CPL-polynomial");
01266
01267 cleanup:
01268 return cpl_error_get_code();
01269 }
01270
01271
01272
01281
01282 double
01283 uves_polynomial_get_coeff_2d(const polynomial *p, int degree1, int degree2)
01284 {
01285 polynomial *pp = NULL;
01286 int dimension;
01287 double result = 0;
01288 double factorial;
01289
01290 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01291 check ( dimension = uves_polynomial_get_dimension(p), "Error reading dimension");
01292 assure(dimension == 2, CPL_ERROR_ILLEGAL_INPUT, "Illegal dimension: %d", dimension);
01293 assure( 0 <= degree1, CPL_ERROR_ILLEGAL_INPUT, "Illegal degree: %d", degree1);
01294 assure( 0 <= degree2, CPL_ERROR_ILLEGAL_INPUT, "Illegal degree: %d", degree2);
01295
01296
01297
01298
01299
01300
01301 pp = uves_polynomial_duplicate(p);
01302
01303 factorial = 1;
01304 while(degree1 > 0)
01305 {
01306 check( uves_polynomial_derivative(pp, 1), "Error calculating derivative");
01307
01308 factorial *= degree1;
01309 degree1 -= 1;
01310 }
01311
01312 while(degree2 > 0)
01313 {
01314 check( uves_polynomial_derivative(pp, 2), "Error calculating derivative");
01315
01316 factorial *= degree2;
01317 degree2 -= 1;
01318 }
01319
01320 check( result = uves_polynomial_evaluate_2d(pp, 0, 0) / factorial,
01321 "Error evaluating polynomial");
01322
01323 cleanup:
01324 uves_polynomial_delete(&pp);
01325 return result;
01326 }
01327
01337
01338 double
01339 uves_polynomial_get_coeff_1d(const polynomial *p, int degree)
01340 {
01341 polynomial *pp = NULL;
01342 int dimension;
01343 double result = 0;
01344 double factorial;
01345
01346 assure( p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01347 check ( dimension = uves_polynomial_get_dimension(p), "Error reading dimension");
01348 assure(dimension == 1, CPL_ERROR_ILLEGAL_INPUT, "Illegal dimension: %d", dimension);
01349 assure( 0 <= degree, CPL_ERROR_ILLEGAL_INPUT, "Illegal degree: %d", degree);
01350
01351
01352
01353
01354
01355
01356 pp = uves_polynomial_duplicate(p);
01357
01358 factorial = 1;
01359 while(degree > 0)
01360 {
01361 check( uves_polynomial_derivative(pp, 1), "Error calculating derivative");
01362
01363 factorial *= degree;
01364 degree -= 1;
01365 }
01366
01367 check( result = uves_polynomial_evaluate_1d(pp, 0) / factorial,
01368 "Error evaluating polynomial");
01369
01370 cleanup:
01371 uves_polynomial_delete(&pp);
01372 return result;
01373 }
01374
01375
01376
01392
01393 polynomial *
01394 uves_polynomial_collapse(const polynomial *p, int varno, double value)
01395 {
01396 polynomial *result = NULL;
01397 cpl_polynomial *pol = NULL;
01398 int *power = NULL;
01399
01400 int i, j;
01401 int degree, dimension;
01402
01403 assure(p != NULL, CPL_ERROR_NULL_INPUT, "Null polynomial");
01404 dimension = uves_polynomial_get_dimension(p);
01405 assure(dimension > 0, CPL_ERROR_ILLEGAL_INPUT,
01406 "Polynomial has non-positive dimension: %d", dimension);
01407 assure(dimension != 1, CPL_ERROR_ILLEGAL_OUTPUT,
01408 "Don't collapse a 1d polynomial. Evaluate it!");
01409
01410
01411
01412
01413 assure(dimension == 2, CPL_ERROR_ILLEGAL_INPUT, "Polynomial must be 2d");
01414
01415 assure(1 <= varno && varno <= dimension, CPL_ERROR_ILLEGAL_INPUT,
01416 "Wrong variable number");
01417 value = (value - p->shift[varno]) / p->scale[varno];
01418
01419
01420 degree = cpl_polynomial_get_degree(p->pol);
01421 pol = cpl_polynomial_new(dimension - 1);
01422 power = cpl_malloc(sizeof(int) * dimension);
01423 assure_mem( power );
01424 for (i = 0; i <= degree; i++)
01425 {
01426 double coeff;
01427
01428 power[2-varno] = i;
01429
01430
01431 coeff = 0;
01432 for (j = degree - i; j >= 0; j--)
01433 {
01434 power[varno-1] = j;
01435 coeff += cpl_polynomial_get_coeff(p->pol, power);
01436 if (j > 0) coeff *= value;
01437 }
01438
01439 power[0] = i;
01440 cpl_polynomial_set_coeff(pol, power, coeff);
01441 }
01442
01443
01444 result = uves_polynomial_new(pol);
01445
01446
01447 j = 0;
01448 for(i = 0; i <= dimension - 1; i++)
01449 {
01450 if (i == varno)
01451 {
01452
01453 j += 2;
01454
01455 }
01456 else
01457 {
01458 result->shift[i] = p->shift[j];
01459 result->scale[i] = p->scale[j];
01460 j += 1;
01461 }
01462 }
01463
01464 assure(cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
01465 "Error collapsing polynomial");
01466
01467 cleanup:
01468 cpl_free(power); power = NULL;
01469 uves_free_polynomial(&pol);
01470 if (cpl_error_get_code() != CPL_ERROR_NONE)
01471 {
01472 uves_polynomial_delete(&result);
01473 }
01474 return result;
01475 }
01476
01477
01478
01479
01499
01500 polynomial * uves_polynomial_fit_1d(
01501 const cpl_vector * x_pos,
01502 const cpl_vector * values,
01503 const cpl_vector * sigmas,
01504 int poly_deg,
01505 double * mse)
01506 {
01507 int nc ;
01508 int np ;
01509 cpl_matrix * ma = NULL;
01510 cpl_matrix * mb = NULL;
01511 cpl_matrix * mx = NULL;
01512 const double * x_pos_data ;
01513 const double * values_data ;
01514 const double * sigmas_data = NULL;
01515 double mean_x, mean_z;
01516 polynomial * result = NULL;
01517 cpl_polynomial * out ;
01518 cpl_vector * x_val = NULL;
01519 int i, j ;
01520
01521
01522 assure_nomsg( x_pos != NULL && values != NULL, CPL_ERROR_NULL_INPUT);
01523 assure( poly_deg >= 0, CPL_ERROR_ILLEGAL_INPUT,
01524 "Polynomial degree is %d. Must be non-negative", poly_deg);
01525 np = cpl_vector_get_size(x_pos) ;
01526
01527 nc = 1 + poly_deg ;
01528 assure( np >= nc, CPL_ERROR_ILLEGAL_INPUT,
01529 "Not enough points (%d) to fit %d-order polynomial. %d point(s) needed",
01530 np, poly_deg, nc);
01531
01532
01533
01534
01535
01536 ma = cpl_matrix_new(np, nc) ;
01537 mb = cpl_matrix_new(np, 1) ;
01538
01539
01540 mean_x = cpl_vector_get_mean(x_pos);
01541 mean_z = cpl_vector_get_mean(values);
01542
01543
01544 x_pos_data = irplib_vector_get_data_const(x_pos) ;
01545 values_data = irplib_vector_get_data_const(values) ;
01546 if (sigmas != NULL)
01547 {
01548 sigmas_data = irplib_vector_get_data_const(sigmas) ;
01549 }
01550
01551 if (sigmas != NULL)
01552 {
01553 for (i=0 ; i<np ; i++)
01554 {
01555
01556 if (sigmas_data[i] == 0)
01557 {
01558 uves_free_matrix(&ma) ;
01559 uves_free_matrix(&mb) ;
01560 assure(false, CPL_ERROR_DIVISION_BY_ZERO,
01561 "Sigmas must be non-zero");
01562 }
01563 for (j=0 ; j<nc ; j++)
01564 {
01565 cpl_matrix_set(ma, i, j,
01566 uves_pow_int(x_pos_data[i] - mean_x, j) /
01567 sigmas_data[i]) ;
01568 }
01569
01570 cpl_matrix_set(mb, i, 0, (values_data[i] - mean_z) / sigmas_data[i]);
01571 }
01572 }
01573 else
01574 {
01575 for (i=0 ; i<np ; i++)
01576 {
01577 for (j=0 ; j<nc ; j++)
01578 {
01579 cpl_matrix_set(ma, i, j,
01580 uves_pow_int(x_pos_data[i] - mean_x, j) / 1);
01581 }
01582
01583 cpl_matrix_set(mb, i, 0, (values_data[i] - mean_z) / 1) ;
01584 }
01585 }
01586
01587
01588 check( mx = cpl_matrix_solve_normal(ma, mb),
01589 "Could not invert matrix");
01590 uves_free_matrix(&ma);
01591 uves_free_matrix(&mb);
01592
01593
01594 out = cpl_polynomial_new(1) ;
01595
01596 for (i=0 ; i<nc ; i++) {
01597 cpl_polynomial_set_coeff(out, &i, cpl_matrix_get(mx, i, 0)) ;
01598 }
01599 uves_free_matrix(&mx);
01600
01601
01602 if (mse != NULL) {
01603 *mse = 0.00 ;
01604 x_val = cpl_vector_new(1) ;
01605 for (i=0 ; i<np ; i++)
01606 {
01607 double residual;
01608 cpl_vector_set(x_val, 0, x_pos_data[i] - mean_x) ;
01609
01610 residual = (values_data[i] - mean_z) - cpl_polynomial_eval(out, x_val);
01611 *mse += residual*residual;
01612 }
01613 uves_free_vector(&x_val) ;
01614
01615 *mse /= (double)np ;
01616 }
01617
01618
01619 result = uves_polynomial_new(out);
01620 uves_free_polynomial(&out);
01621
01622 uves_polynomial_shift(result, 0, mean_z);
01623 uves_polynomial_shift(result, 1, mean_x);
01624
01625 cleanup:
01626 uves_free_vector(&x_val);
01627 uves_free_matrix(&ma);
01628 uves_free_matrix(&mb);
01629 uves_free_matrix(&mx);
01630 return result;
01631 }
01632
01633
01634
01678
01679 polynomial *
01680 uves_polynomial_fit_2d(
01681 const cpl_bivector * xy_pos,
01682 const cpl_vector * values,
01683 const cpl_vector * sigmas,
01684 int poly_deg1,
01685 int poly_deg2,
01686 double * mse,
01687 double * red_chisq,
01688 polynomial ** variance)
01689 {
01690 int nc ;
01691 int degx, degy ;
01692 int * degx_tab ;
01693 int * degy_tab ;
01694 int np ;
01695 cpl_matrix * ma ;
01696 cpl_matrix * mb ;
01697 cpl_matrix * mx ;
01698 cpl_matrix * mat;
01699 cpl_matrix * mat_ma;
01700 cpl_matrix * cov = NULL;
01701 const double * xy_pos_data_x ;
01702 const double * xy_pos_data_y ;
01703 const double * values_data ;
01704 const double * sigmas_data = NULL;
01705 const cpl_vector* xy_pos_x;
01706 const cpl_vector* xy_pos_y;
01707 double mean_x, mean_y, mean_z;
01708 cpl_polynomial * out ;
01709 cpl_polynomial * variance_cpl ;
01710 polynomial * result = NULL;
01711 int * powers ;
01712
01713
01714 assure(xy_pos && values, CPL_ERROR_NULL_INPUT, "Null input");
01715 assure(poly_deg1 >= 0, CPL_ERROR_ILLEGAL_INPUT, "Polynomial degree1 is %d", poly_deg1);
01716 assure(poly_deg2 >= 0, CPL_ERROR_ILLEGAL_INPUT, "Polynomial degree2 is %d", poly_deg2);
01717 np = cpl_bivector_get_size(xy_pos) ;
01718
01719
01720 assure( (variance == NULL && red_chisq == NULL) || sigmas != NULL,
01721 CPL_ERROR_ILLEGAL_INPUT,
01722 "Cannot calculate variance or chi_sq without knowing");
01723
01724
01725 nc = (1 + poly_deg1)*(1 + poly_deg2) ;
01726
01727 assure(np >= nc, CPL_ERROR_SINGULAR_MATRIX, "%d coefficients. Only %d points", nc, np);
01728
01729
01730
01731
01732 assure(red_chisq == NULL || np > nc, CPL_ERROR_ILLEGAL_INPUT,
01733 "%d coefficients. %d points. Cannot calculate chi square", nc, np);
01734
01735 degx_tab = cpl_malloc(nc * sizeof(int)) ;
01736 assure_mem( degx_tab );
01737
01738 degy_tab = cpl_malloc(nc * sizeof(int)) ;
01739 if (degy_tab == NULL) {
01740 cpl_free(degx_tab);
01741 assure_mem( false );
01742 }
01743
01744 {
01745 int i=0 ;
01746 for (degy=0 ; degy<=poly_deg2 ; degy++) {
01747 for (degx=0 ; degx<=poly_deg1 ; degx++) {
01748 degx_tab[i] = degx ;
01749 degy_tab[i] = degy ;
01750 i++ ;
01751 }
01752 }
01753 }
01754
01755
01756
01757
01758
01759 ma = cpl_matrix_new(np, nc) ;
01760 mb = cpl_matrix_new(np, 1) ;
01761
01762
01763 xy_pos_x = irplib_bivector_get_x_const(xy_pos);
01764 xy_pos_y = irplib_bivector_get_y_const(xy_pos);
01765
01766 mean_x = cpl_vector_get_mean(xy_pos_x);
01767 mean_y = cpl_vector_get_mean(xy_pos_y);
01768 mean_z = cpl_vector_get_mean(values);
01769
01770
01771
01772 xy_pos_data_x = irplib_vector_get_data_const(xy_pos_x) ;
01773 xy_pos_data_y = irplib_vector_get_data_const(xy_pos_y) ;
01774 values_data = irplib_vector_get_data_const(values) ;
01775 if (sigmas != NULL)
01776 {
01777 sigmas_data = irplib_vector_get_data_const(sigmas) ;
01778 }
01779
01780 if (sigmas != NULL)
01781 {
01782 int i;
01783 for (i=0 ; i<np ; i++) {
01784 double *ma_data = cpl_matrix_get_data(ma);
01785 double *mb_data = cpl_matrix_get_data(mb);
01786
01787 int j = 0;
01788 double valy = 1;
01789
01790
01791 if (sigmas_data[i] == 0)
01792 {
01793 uves_free_matrix(&ma) ;
01794 uves_free_matrix(&mb) ;
01795 cpl_free(degx_tab) ;
01796 cpl_free(degy_tab) ;
01797 assure(false, CPL_ERROR_DIVISION_BY_ZERO,
01798 "Sigmas must be non-zero. sigma[%d] is %f", i, sigmas_data[i]);
01799 }
01800
01801 for (degy=0 ; degy<=poly_deg2 ; degy++) {
01802 double valx = 1;
01803 for (degx=0 ; degx<=poly_deg1 ; degx++) {
01804 ma_data[j + i*nc] = valx * valy / sigmas_data[i];
01805 valx *= (xy_pos_data_x[i] - mean_x);
01806 j++;
01807 }
01808 valy *= (xy_pos_data_y[i] - mean_y);
01809 }
01810
01811
01812
01813 mb_data[0 + i*1] = (values_data[i] - mean_z) / sigmas_data[i];
01814 }
01815 }
01816 else
01817 {
01818 int i;
01819 for (i=0 ; i<np ; i++) {
01820 double *ma_data = cpl_matrix_get_data(ma);
01821 double *mb_data = cpl_matrix_get_data(mb);
01822
01823 double valy = 1;
01824 int j = 0;
01825 for (degy=0 ; degy<=poly_deg2 ; degy++) {
01826 double valx = 1;
01827 for (degx=0 ; degx<=poly_deg1 ; degx++) {
01828 ma_data[j + i*nc] = valx * valy / 1;
01829 valx *= (xy_pos_data_x[i] - mean_x);
01830 j++;
01831 }
01832 valy *= (xy_pos_data_y[i] - mean_y);
01833 }
01834
01835
01836
01837 mb_data[0 + i*1] = (values_data[i] - mean_z) / 1;
01838 }
01839 }
01840
01841
01842
01843 if (variance != NULL)
01844 {
01845 mat = cpl_matrix_transpose_create(ma);
01846 if (mat != NULL)
01847 {
01848 mat_ma = cpl_matrix_product_create(mat, ma);
01849 if (mat_ma != NULL)
01850 {
01851 cov = cpl_matrix_invert_create(mat_ma);
01852
01853
01854
01855
01856 variance_cpl = cpl_polynomial_new(2);
01857 }
01858 }
01859 uves_free_matrix(&mat);
01860 uves_free_matrix(&mat_ma);
01861 }
01862
01863
01864 mx = cpl_matrix_solve_normal(ma, mb) ;
01865
01866 uves_free_matrix(&ma) ;
01867 uves_free_matrix(&mb) ;
01868 if (mx == NULL) {
01869 cpl_free(degx_tab) ;
01870 cpl_free(degy_tab) ;
01871 uves_free_matrix(&cov) ;
01872 assure(false, CPL_ERROR_ILLEGAL_OUTPUT, "Matrix inversion failed") ;
01873 }
01874
01875
01876 out = cpl_polynomial_new(2) ;
01877 powers = cpl_malloc(2 * sizeof(int)) ;
01878 if (powers == NULL) {
01879 cpl_free(degx_tab) ;
01880 cpl_free(degy_tab) ;
01881 uves_free_matrix(&mx) ;
01882 uves_free_matrix(&cov) ;
01883 uves_free_polynomial(&out) ;
01884 assure_mem( false );
01885 }
01886
01887 {
01888 int i;
01889 for (i = 0 ; i < nc ; i++)
01890 {
01891 powers[0] = degx_tab[i] ;
01892 powers[1] = degy_tab[i] ;
01893 cpl_polynomial_set_coeff(out, powers, cpl_matrix_get(mx, i, 0)) ;
01894
01895
01896 if (variance != NULL &&
01897 cov != NULL && variance_cpl != NULL
01898 )
01899 {
01900 int j;
01901 for (j = 0; j < nc; j++)
01902 {
01903 double coeff;
01904
01905
01906
01907
01908
01909
01910 powers[0] = degx_tab[i] + degx_tab[j] ;
01911 powers[1] = degy_tab[i] + degy_tab[j] ;
01912
01913 coeff = cpl_polynomial_get_coeff(variance_cpl, powers);
01914 cpl_polynomial_set_coeff(variance_cpl, powers,
01915 coeff + cpl_matrix_get(cov, i, j)) ;
01916 }
01917 }
01918 }
01919 }
01920
01921 cpl_free(powers) ;
01922 cpl_free(degx_tab) ;
01923 cpl_free(degy_tab) ;
01924 uves_free_matrix(&cov) ;
01925 uves_free_matrix(&mx) ;
01926
01927
01928 result = uves_polynomial_new(out);
01929 uves_free_polynomial(&out);
01930 uves_polynomial_shift(result, 0, mean_z);
01931 uves_polynomial_shift(result, 1, mean_x);
01932 uves_polynomial_shift(result, 2, mean_y);
01933
01934
01935 if (variance != NULL)
01936 {
01937 *variance = uves_polynomial_new(variance_cpl);
01938 uves_free_polynomial(&variance_cpl);
01939
01940
01941
01942
01943 uves_polynomial_shift(*variance, 1, mean_x);
01944 uves_polynomial_shift(*variance, 2, mean_y);
01945
01946
01947
01948 }
01949
01950
01951 if (mse != NULL || red_chisq != NULL)
01952 {
01953 int i;
01954
01955 if (mse != NULL) *mse = 0.00 ;
01956 if (red_chisq != NULL) *red_chisq = 0.00 ;
01957 for (i = 0 ; i < np ; i++)
01958 {
01959 double regress = uves_polynomial_evaluate_2d(result,
01960 xy_pos_data_x[i],
01961 xy_pos_data_y[i]);
01962
01963 if (mse != NULL)
01964 {
01965 double residual = values_data[i] - regress;
01966 *mse += residual*residual;
01967 }
01968 if (red_chisq != NULL)
01969 {
01970 *red_chisq += uves_pow_int((values_data[i] - regress) /
01971 sigmas_data[i], 2);
01972 }
01973 }
01974
01975 if (mse != NULL) *mse /= (double) np ;
01976
01977 if (red_chisq != NULL)
01978 {
01979 passure( np > nc, "%d %d", np, nc);
01980 *red_chisq /= (double) (np - nc) ;
01981 }
01982 }
01983
01984 cleanup:
01985 return result ;
01986 }
01987
01988