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
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 #ifdef HAVE_CONFIG_H
00218 # include <config.h>
00219 #endif
00220
00221
00229
00230
00231 #include <uves_utils_wrappers.h>
00232
00233 #include <uves_utils.h>
00234 #include <uves_utils_cpl.h>
00235 #include <uves_error.h>
00236 #include <uves_dump.h>
00237 #include <cpl.h>
00238
00239 #include <irplib_utils.h>
00240 #include <irplib_access.h>
00241 #include <stdbool.h>
00242 #include <assert.h>
00243
00244
00245
00246
00247
00248 static int get_candidate(const double *a, const int ia[],
00249 int M, int N, int D,
00250 double lambda,
00251 int (*f)(const double x[], const double a[],
00252 double *result),
00253 int (*dfda)(const double x[], const double a[],
00254 double result[]),
00255 const double *x,
00256 const double *y,
00257 const double *sigma,
00258 double *partials,
00259 cpl_matrix *alpha,
00260 cpl_matrix *beta,
00261 double *a_da);
00262
00263 static double get_chisq(int N, int D,
00264 int (*f)(const double x[], const double a[],
00265 double *result),
00266 const double *a,
00267 const double *x,
00268 const double *y,
00269 const double *sigma);
00270
00271
00272
00273
00274
00276 #define image_is_rejected(badmap, x, y) \
00277 ((badmap) != NULL && (badmap)[((x)-1) + ((y)-1)*nx] == CPL_BINARY_1)
00278
00279 #ifndef UVES_FIT_MAXITER
00280 #define UVES_FIT_MAXITER 1000
00281 #endif
00282
00283
00284
00285
00286
00287 typedef struct {
00288 double x;
00289 double y;
00290 } uves_fit_1d_input;
00291
00292
00293
00294
00295
00299
00306
00307 void uves_image_reject_all(cpl_image *image)
00308 {
00309 int nx, ny;
00310 int x, y;
00311
00312 assure_nomsg( image != NULL, CPL_ERROR_NULL_INPUT );
00313 nx = cpl_image_get_size_x(image);
00314 ny = cpl_image_get_size_y(image);
00315
00316 for (y = 1; y <= ny; y++) {
00317 for (x = 1; x <= nx; x++) {
00318 cpl_image_reject(image, x, y);
00319 }
00320 }
00321
00322 cleanup:
00323 return;
00324 }
00325
00326
00327
00386
00387
00388 cpl_error_code
00389 uves_fit_1d_image(const cpl_image *image, const cpl_image *noise,
00390 const cpl_binary *image_badmap,
00391 bool horizontal, bool fix_back, bool fit_back,
00392 int xlo, int xhi, int y_0,
00393 double *x0, double *sigma, double *norm, double *background,
00394 double *slope,
00395 double *mse, double *red_chisq,
00396 cpl_matrix **covariance,
00397 int (*f) (const double x[], const double a[], double *result),
00398 int (*dfda)(const double x[], const double a[], double result[]),
00399 int M)
00400 {
00401 cpl_vector *x = NULL;
00402 cpl_vector *y = NULL;
00403 cpl_vector *sigma_y = NULL;
00404
00405 cpl_fit_mode fit_pattern;
00406 int nx, ny;
00407 int N;
00408 int i, j;
00409 cpl_type image_type;
00410
00411 const double *image_data = NULL;
00412 const double *noise_data = NULL;
00413
00414 assure( x0 != NULL , CPL_ERROR_NULL_INPUT, "Null fit parameter");
00415 assure( sigma != NULL , CPL_ERROR_NULL_INPUT, "Null fit parameter");
00416 assure( norm != NULL , CPL_ERROR_NULL_INPUT, "Null fit parameter");
00417 assure( background != NULL, CPL_ERROR_NULL_INPUT, "Null fit parameter");
00418
00419
00420 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
00421
00422 image_type = cpl_image_get_type(image);
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 assure( image_type == CPL_TYPE_DOUBLE, CPL_ERROR_UNSUPPORTED_MODE,
00433 "Unsupported type: %s", uves_tostring_cpl_type(image_type));
00434
00435 image_data = irplib_image_get_data_double_const(image);
00436
00437 if (noise != NULL)
00438 {
00439 image_type = cpl_image_get_type(noise);
00440
00441
00442
00443
00444
00445
00446 assure( image_type == CPL_TYPE_DOUBLE, CPL_ERROR_UNSUPPORTED_MODE,
00447 "Unsupported type: %s", uves_tostring_cpl_type(image_type));
00448
00449 noise_data = irplib_image_get_data_double_const(noise);
00450 }
00451
00452 nx = cpl_image_get_size_x(image);
00453 ny = cpl_image_get_size_y(image);
00454
00455 if (horizontal)
00456 {
00457 assure( 1 <= xlo && xlo <= xhi && xhi <= nx &&
00458 1 <= y_0 && y_0 <= ny, CPL_ERROR_ACCESS_OUT_OF_RANGE,
00459 "Illegal window (%d, %d)-(%d, %d), image: %dx%d",
00460 xlo, y_0, xhi, y_0,
00461 nx, ny);
00462 }
00463 else
00464 {
00465 assure( 1 <= xlo && xlo <= xhi && xhi <= ny &&
00466 1 <= y_0 && y_0 <= nx,
00467 CPL_ERROR_ACCESS_OUT_OF_RANGE,
00468 "Illegal window (%d, %d)-(%d, %d), image: %dx%d",
00469 y_0, xlo, y_0, xhi,
00470 nx, ny);
00471 }
00472
00473
00474
00475
00476 if (noise != NULL)
00477 {
00478 assure( cpl_image_get_size_x(noise) == nx &&
00479 cpl_image_get_size_y(noise) == ny,
00480 CPL_ERROR_INCOMPATIBLE_INPUT, "Noise image: %dx%d, image: %dx%d:",
00481 cpl_image_get_size_x(noise),
00482 cpl_image_get_size_y(noise),
00483 nx, ny);
00484 }
00485
00486
00487 N = 0;
00488 for (i = xlo; i <= xhi; i++)
00489 {
00490 if ( !image_is_rejected(image_badmap,
00491 (horizontal) ? i : y_0,
00492 (horizontal) ? y_0 : i) )
00493 {
00494 if ( noise != NULL)
00495 {
00496 if( !image_is_rejected(image_badmap,
00497 (horizontal) ? i : y_0,
00498 (horizontal) ? y_0 : i) )
00499 {
00500
00501
00502 assure(
00503
00504
00505
00506 noise_data[(((horizontal) ? i : y_0) - 1) +
00507 (((horizontal) ? y_0 : i) - 1) * nx]
00508 > 0,
00509 CPL_ERROR_ILLEGAL_INPUT,
00510 "Non-positive noise at (%d, %d): %e",
00511 (horizontal) ? i : y_0,
00512 (horizontal) ? y_0 : i,
00513 noise_data[(((horizontal) ? i : y_0) - 1) +
00514 (((horizontal) ? y_0 : i) - 1) * nx]
00515 );
00516
00517 N += 1;
00518 }
00519 else
00520 {
00521
00522
00523 }
00524 }
00525 else
00526 {
00527
00528 N += 1;
00529 }
00530 }
00531 }
00532
00533
00534 assure( N >= 1, CPL_ERROR_ILLEGAL_INPUT, "Only %d good pixel(s)", N);
00535
00536
00537 x = cpl_vector_new(N);
00538 y = cpl_vector_new(N);
00539 if (noise != NULL)
00540 {
00541 sigma_y = cpl_vector_new(N);
00542 assure_mem( sigma_y );
00543 }
00544
00545 if (fix_back)
00546 {
00547 fit_pattern = CPL_FIT_CENTROID | CPL_FIT_STDEV | CPL_FIT_AREA;
00548 }
00549 else if (fit_back)
00550 {
00551 fit_pattern = CPL_FIT_AREA | CPL_FIT_OFFSET;
00552 }
00553 else
00554 {
00555 fit_pattern = CPL_FIT_ALL;
00556 }
00557
00558 assure_mem( x );
00559 assure_mem( y );
00560
00561
00562
00563 for (i = xlo, j = 0;
00564 i <= xhi;
00565 i++)
00566 {
00567 double flux;
00568
00569
00570
00571
00572
00573
00574
00575
00576 flux = image_data[(((horizontal) ? i : y_0) - 1) +
00577 (((horizontal) ? y_0 : i) - 1) * nx];
00578
00579
00580 if ( !image_is_rejected(image_badmap,
00581 (horizontal) ? i : y_0,
00582 (horizontal) ? y_0 : i) )
00583 {
00584 if (noise != NULL)
00585 {
00586 double flux_noise;
00587
00588
00589
00590
00591
00592
00593
00594 flux_noise = noise_data
00595 [(((horizontal) ? i : y_0) - 1) +
00596 (((horizontal) ? y_0 : i) - 1) * nx];
00597
00598
00599 if ( !image_is_rejected(image_badmap,
00600 (horizontal) ?
00601 i : y_0,
00602 (horizontal)
00603 ? y_0 : i) )
00604 {
00605 cpl_vector_set(x, j, i);
00606 cpl_vector_set(y, j, flux);
00607 cpl_vector_set(sigma_y, j, flux_noise);
00608 j++;
00609 }
00610 }
00611 else
00612 {
00613 cpl_vector_set(x, j, i);
00614 cpl_vector_set(y, j, flux);
00615 j++;
00616 }
00617 }
00618 }
00619 passure( j == N, "%d %d", j, N);
00620
00621 check( uves_fit_1d(x, NULL,
00622 y, sigma_y,
00623 fit_pattern, fit_back,
00624 x0, sigma, norm, background,
00625 slope,
00626 mse, red_chisq,
00627 covariance,
00628 f, dfda, M),
00629 "Fit failed");
00630
00631
00632 cleanup:
00633 uves_free_vector(&x);
00634 uves_free_vector(&y);
00635 uves_free_vector(&sigma_y);
00636
00637 return cpl_error_get_code();
00638 }
00639
00640
00648
00649 static int uves_fit_1d_compare(const void *left,
00650 const void *right)
00651 {
00652 return
00653 (((uves_fit_1d_input *)left )->x <
00654 ((uves_fit_1d_input *)right)->x) ? -1 :
00655 (((uves_fit_1d_input *)left )->x ==
00656 ((uves_fit_1d_input *)right)->x) ? 0 : 1;
00657 }
00658
00659
00681 cpl_error_code
00682 uves_fit_1d(const cpl_vector *x, const cpl_vector *sigma_x,
00683 const cpl_vector *y, const cpl_vector *sigma_y,
00684 cpl_fit_mode fit_pars, bool fit_back,
00685 double *x0, double *sigma, double *area, double *offset, double *slope,
00686 double *mse, double *red_chisq,
00687 cpl_matrix **covariance,
00688 int (*f) (const double x[], const double a[], double *result),
00689 int (*dfda)(const double x[], const double a[], double result[]),
00690 int M)
00691 {
00692 const cpl_matrix *x_matrix = NULL;
00693
00694
00695 int N;
00696 double xlo, xhi;
00697
00698
00699 double x0_guess = 0;
00700 double sigma_guess = 0;
00701 double area_guess;
00702 double offset_guess;
00703
00704 cpl_ensure_code( M == 4 || M == 5, CPL_ERROR_UNSUPPORTED_MODE);
00705
00706
00707 cpl_ensure_code( x != NULL, CPL_ERROR_NULL_INPUT);
00708 cpl_ensure_code( sigma_x == NULL, CPL_ERROR_UNSUPPORTED_MODE);
00709 cpl_ensure_code( y != NULL, CPL_ERROR_NULL_INPUT);
00710
00711
00712 N = cpl_vector_get_size(x);
00713
00714 cpl_ensure_code( N == cpl_vector_get_size(y),
00715 CPL_ERROR_INCOMPATIBLE_INPUT);
00716
00717 if (sigma_x != NULL)
00718 {
00719 cpl_ensure_code( N == cpl_vector_get_size(sigma_x),
00720 CPL_ERROR_INCOMPATIBLE_INPUT);
00721 }
00722 if (sigma_y != NULL)
00723 {
00724 cpl_ensure_code( N == cpl_vector_get_size(sigma_y),
00725 CPL_ERROR_INCOMPATIBLE_INPUT);
00726 }
00727
00728 cpl_ensure_code( x0 != NULL &&
00729 sigma != NULL &&
00730 area != NULL &&
00731 offset != NULL &&
00732 (M != 5 || slope != NULL), CPL_ERROR_NULL_INPUT);
00733
00734 if (! (fit_pars & CPL_FIT_STDEV))
00735 {
00736 cpl_ensure_code( *sigma > 0, CPL_ERROR_ILLEGAL_INPUT);
00737 }
00738
00739 cpl_ensure_code( !fit_back || fit_pars == (CPL_FIT_OFFSET | CPL_FIT_AREA),
00740 CPL_ERROR_INCOMPATIBLE_INPUT);
00741
00742
00743 if (! (fit_pars & CPL_FIT_AREA) && !fit_back)
00744 {
00745 cpl_ensure_code( *area > 0, CPL_ERROR_ILLEGAL_INPUT);
00746 }
00747
00748
00749
00750
00751
00752 cpl_ensure_code( red_chisq == NULL || N >= 5, CPL_ERROR_ILLEGAL_INPUT);
00753
00754 if (covariance != NULL) *covariance = NULL;
00755
00756
00757
00758
00759
00760
00761 cpl_ensure_code( (red_chisq == NULL && covariance == NULL) ||
00762 sigma_y != NULL,
00763 CPL_ERROR_INCOMPATIBLE_INPUT);
00764
00765
00766 x_matrix = irplib_matrix_wrap_const(N, 1, irplib_vector_get_data_const(x));
00767 if (x_matrix == NULL)
00768 {
00769 cpl_ensure_code(
00770 CPL_FALSE,
00771 CPL_ERROR_ILLEGAL_OUTPUT);
00772 }
00773
00774
00775 if (sigma_x != NULL && cpl_vector_get_min(sigma_x) <= 0)
00776 {
00777 irplib_matrix_unwrap_const(x_matrix);
00778 cpl_ensure_code(
00779 CPL_FALSE,
00780 CPL_ERROR_ILLEGAL_INPUT);
00781 }
00782 if (sigma_y != NULL && cpl_vector_get_min(sigma_y) <= 0)
00783 {
00784 irplib_matrix_unwrap_const(x_matrix);
00785 cpl_ensure_code(
00786 CPL_FALSE,
00787 CPL_ERROR_ILLEGAL_INPUT);
00788 }
00789
00790
00791
00792
00793
00794 if (fit_back)
00795 {
00796
00797 assert( fit_pars == CPL_FIT_OFFSET || CPL_FIT_AREA);
00798
00799 offset_guess = cpl_vector_get_median(y);
00800 area_guess = N*(cpl_vector_get_mean(y) - offset_guess);
00801
00802
00803 x0_guess = *x0;
00804 sigma_guess = *sigma;
00805 }
00806 else {
00807 double sum = 0.0;
00808 double quartile[3];
00809 double fraction[3] = {0.25 , 0.50 , 0.75};
00810 const double *y_data = irplib_vector_get_data_const(y);
00811
00812 if (fit_pars & CPL_FIT_OFFSET)
00813 {
00814
00815
00816
00817
00818
00819
00820
00821 cpl_vector *y_dup = cpl_vector_duplicate(y);
00822
00823 if (y_dup == NULL)
00824 {
00825 irplib_matrix_unwrap_const(x_matrix);
00826 cpl_ensure_code(
00827 CPL_FALSE,
00828 CPL_ERROR_ILLEGAL_OUTPUT);
00829 }
00830
00831 offset_guess = uves_utils_get_kth_double(
00832 irplib_vector_get_data(y_dup), N, N/4);
00833
00834 cpl_vector_delete(y_dup);
00835 }
00836 else
00837 {
00838 offset_guess = *offset;
00839 }
00840
00841
00842
00843 if ( (fit_pars & CPL_FIT_CENTROID) ||
00844 (fit_pars & CPL_FIT_STDEV )
00845 )
00846 {
00847
00848
00849
00850
00851
00852
00853
00854 uves_fit_1d_input
00855 *sorted_input = cpl_malloc(N * sizeof(*sorted_input));
00856 const double *x_data = irplib_matrix_get_data_const(x_matrix);
00857 cpl_boolean is_sorted = CPL_TRUE;
00858 int i;
00859
00860 if (sorted_input == NULL)
00861 {
00862 irplib_matrix_unwrap_const(x_matrix);
00863 cpl_ensure_code(
00864 CPL_FALSE,
00865 CPL_ERROR_ILLEGAL_INPUT);
00866 }
00867
00868 for (i = 0; i < N; i++)
00869 {
00870 sorted_input[i].x = x_data[i];
00871 sorted_input[i].y = y_data[i];
00872
00873 is_sorted = is_sorted &&
00874 (i==0 || (x_data[i-1] < x_data[i]));
00875 }
00876
00877 if (!is_sorted)
00878 {
00879 qsort(sorted_input, N, sizeof(*sorted_input),
00880 &uves_fit_1d_compare);
00881 }
00882
00883 for(i = 0; i < N; i++)
00884 {
00885 double flux = sorted_input[i].y;
00886
00887 sum += (flux - offset_guess);
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897 if (sum > 0.0)
00898 {
00899 double flux, x1, x2;
00900 double running_sum = 0.0;
00901 int j;
00902
00903 i = 0;
00904 flux = sorted_input[i].y - offset_guess;
00905
00906 for (j = 0; j < 3; j++)
00907 {
00908 double limit = fraction[j] * sum;
00909 double k;
00910
00911 while (running_sum + flux < limit && i < N-1)
00912 {
00913 running_sum += flux;
00914 i++;
00915 flux = sorted_input[i].y - offset_guess;
00916 }
00917
00918
00919
00920 k = (limit - running_sum)/flux;
00921
00922 if (k <= 0.5)
00923 {
00924
00925
00926
00927 if (0 < i)
00928 {
00929 x1 = sorted_input[i-1].x;
00930 x2 = sorted_input[i].x;
00931
00932 quartile[j] =
00933 x1*(0.5-k) +
00934 x2*(0.5+k);
00935
00936
00937
00938
00939 }
00940 else
00941 {
00942 quartile[j] = sorted_input[i].x;
00943 }
00944 }
00945 else
00946 {
00947
00948
00949 if (i < N-1)
00950 {
00951 x1 = sorted_input[i].x;
00952 x2 = sorted_input[i+1].x;
00953
00954 quartile[j] =
00955 x1*( 1.5-k) +
00956 x2*(-0.5+k);
00957
00958
00959
00960
00961 }
00962 else
00963 {
00964 quartile[j] = sorted_input[i].x;
00965 }
00966 }
00967 }
00968 }
00969 else
00970 {
00971
00972
00973
00974
00975 quartile[1] = cpl_matrix_get_mean(x_matrix);
00976
00977 quartile[2] = quartile[1];
00978 quartile[0] = quartile[2] - 1.0;
00979
00980 }
00981
00982 cpl_free(sorted_input);
00983 }
00984
00985
00986 x0_guess = (fit_pars & CPL_FIT_CENTROID) ? quartile[1] : *x0;
00987
00988
00989
00990
00991
00992
00993 sigma_guess = (fit_pars & CPL_FIT_STDEV) ?
00994 (quartile[2] - quartile[0]) / (2*0.6744) : *sigma;
00995
00996 area_guess = (fit_pars & CPL_FIT_AREA) ?
00997 (cpl_vector_get_max(y) - offset_guess) * sqrt(2*M_PI) * sigma_guess : *area;
00998
00999
01000
01001 if ( area_guess <= 0) area_guess = 1.0;
01002 if (sigma_guess <= 0) sigma_guess = 1.0;
01003 }
01004
01005
01006 {
01007 cpl_vector *a;
01008 int ia[5];
01009
01010
01011 cpl_error_code ec;
01012
01013 assert(M == 4 || M == 5);
01014 a = cpl_vector_new(M);
01015
01016 if (a == NULL)
01017 {
01018 irplib_matrix_unwrap_const(x_matrix);
01019 cpl_ensure_code(
01020 CPL_FALSE,
01021 CPL_ERROR_ILLEGAL_OUTPUT);
01022 }
01023
01024 cpl_vector_set(a, 0, x0_guess);
01025 cpl_vector_set(a, 1, sigma_guess);
01026 cpl_vector_set(a, 2, area_guess);
01027 cpl_vector_set(a, 3, offset_guess);
01028
01029 ia[0] = fit_pars & CPL_FIT_CENTROID;
01030 ia[1] = fit_pars & CPL_FIT_STDEV;
01031 ia[2] = fit_pars & CPL_FIT_AREA;
01032 ia[3] = fit_pars & CPL_FIT_OFFSET;
01033
01034 if (M == 5)
01035 {
01036
01037
01038
01039 if (fit_pars & CPL_FIT_OFFSET)
01040 {
01041 cpl_vector_set(a, 4, 0);
01042 }
01043 else
01044 {
01045 cpl_vector_set(a, 4, *slope);
01046 }
01047
01048 ia[4] = 0;
01049 }
01050
01051 ec = uves_fit(x_matrix, NULL,
01052 y, sigma_y,
01053 a, ia, f, dfda,
01054 mse, red_chisq,
01055 covariance);
01056
01057
01058 if (M == 5)
01059 {
01060 ia[4] = fit_pars & CPL_FIT_OFFSET;
01061
01062 if (covariance != NULL)
01063 {
01064 uves_free_matrix(covariance);
01065 }
01066
01067 ec = uves_fit(x_matrix, NULL,
01068 y, sigma_y,
01069 a, ia, f, dfda,
01070 mse, red_chisq,
01071 covariance);
01072
01073 }
01074
01075 irplib_matrix_unwrap_const(x_matrix);
01076
01077
01078 if (ec == CPL_ERROR_NONE ||
01079 ec == CPL_ERROR_SINGULAR_MATRIX)
01080 {
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 if (CPL_FIT_CENTROID) *x0 = cpl_vector_get(a, 0);
01092 if (CPL_FIT_STDEV ) *sigma = fabs(cpl_vector_get(a, 1));
01093 if (CPL_FIT_AREA ) *area = cpl_vector_get(a, 2);
01094 if (CPL_FIT_OFFSET ) {
01095 *offset = cpl_vector_get(a, 3);
01096 if (M == 5) *slope = cpl_vector_get(a, 4);
01097 }
01098 }
01099
01100 cpl_vector_delete(a);
01101
01102 xlo = cpl_vector_get_min(x);
01103 xhi = cpl_vector_get_max(x);
01104
01105 if (ec == CPL_ERROR_CONTINUE ||
01106 !(
01107 !irplib_isnan(*x0 ) && !irplib_isinf(*x0 ) &&
01108 !irplib_isnan(*sigma ) && !irplib_isinf(*sigma ) &&
01109 !irplib_isnan(*area ) && !irplib_isinf(*area ) &&
01110 !irplib_isnan(*offset) && !irplib_isinf(*offset) &&
01111 ((M != 5) || (!irplib_isnan(*slope ) && !irplib_isinf(*slope ))) &&
01112 xlo <= *x0 && *x0 <= xhi &&
01113 0 < *sigma && *sigma < (xhi - xlo + 1) &&
01114 (fit_back || 0 < *area)
01115
01116
01117
01118 )
01119 )
01120 {
01121
01122
01123
01124
01125 *x0 = x0_guess;
01126 *sigma = sigma_guess;
01127 *area = area_guess;
01128 *offset = offset_guess;
01129 if (M == 5) *slope = 0;
01130
01131
01132
01133 if (covariance != NULL && *covariance != NULL)
01134 {
01135 cpl_matrix_delete(*covariance);
01136 *covariance = NULL;
01137 }
01138
01139
01140 cpl_ensure_code(
01141 CPL_FALSE,
01142 CPL_ERROR_CONTINUE);
01143 }
01144 }
01145
01146 return CPL_ERROR_NONE;
01147 }
01148
01149
01150 #define DEBUG_LM 0
01151
01218
01219 cpl_error_code
01220 uves_fit(const cpl_matrix *x, const cpl_matrix *sigma_x,
01221 const cpl_vector *y, const cpl_vector *sigma_y,
01222 cpl_vector *a, const int ia[],
01223 int (*f)(const double x[], const double a[], double *result),
01224 int (*dfda)(const double x[], const double a[], double result[]),
01225 double *mse,
01226 double *red_chisq,
01227 cpl_matrix **covariance)
01228 {
01229 const double *x_data = NULL;
01230 const double *y_data = NULL;
01231 const double *sigma_data = NULL;
01232 int N = 0;
01233 int D = 0;
01234 int M = 0;
01235 int Mfit = 0;
01236
01237
01238 double lambda = 0.0;
01239 double MAXLAMBDA = 10e40;
01240
01241 double chi_sq = 0.0;
01242 int count = 0;
01243
01244 int iterations = 0;
01245
01246 cpl_matrix *alpha = NULL;
01247 cpl_matrix *beta = NULL;
01248 double *a_data = NULL;
01249 double *a_da = NULL;
01250 double *part = NULL;
01251 int *ia_local = NULL;
01252
01253
01254
01255
01256 if (covariance != NULL) *covariance = NULL;
01257
01258
01259 cpl_ensure_code(x != NULL, CPL_ERROR_NULL_INPUT);
01260 cpl_ensure_code(sigma_x == NULL, CPL_ERROR_UNSUPPORTED_MODE);
01261 cpl_ensure_code(y != NULL, CPL_ERROR_NULL_INPUT);
01262 cpl_ensure_code(a != NULL, CPL_ERROR_NULL_INPUT);
01263
01264 cpl_ensure_code(f != NULL, CPL_ERROR_NULL_INPUT);
01265 cpl_ensure_code(dfda != NULL, CPL_ERROR_NULL_INPUT);
01266
01267
01268 cpl_ensure_code( sigma_y != NULL || (red_chisq == NULL && covariance == NULL),
01269 CPL_ERROR_INCOMPATIBLE_INPUT);
01270
01271 D = cpl_matrix_get_ncol(x);
01272 N = cpl_matrix_get_nrow(x);
01273 M = cpl_vector_get_size(a);
01274 cpl_ensure_code(N > 0 && D > 0 && M > 0, CPL_ERROR_ILLEGAL_INPUT);
01275
01276 cpl_ensure_code( cpl_vector_get_size(y) == N,
01277 CPL_ERROR_INCOMPATIBLE_INPUT);
01278
01279 x_data = irplib_matrix_get_data_const(x);
01280 y_data = irplib_vector_get_data_const(y);
01281 a_data = irplib_vector_get_data(a);
01282
01283 if (sigma_y != NULL)
01284 {
01285 cpl_ensure_code( cpl_vector_get_size(sigma_y) == N,
01286 CPL_ERROR_INCOMPATIBLE_INPUT);
01287
01288 cpl_ensure_code( cpl_vector_get_min (sigma_y) > 0,
01289 CPL_ERROR_ILLEGAL_INPUT);
01290 sigma_data = irplib_vector_get_data_const(sigma_y);
01291 }
01292
01293 ia_local = cpl_malloc(M * sizeof(int));
01294 cpl_ensure_code(ia_local != NULL, CPL_ERROR_ILLEGAL_OUTPUT);
01295
01296
01297 if (ia != NULL)
01298 {
01299 int i;
01300
01301 Mfit = 0;
01302 for (i = 0; i < M; i++)
01303 {
01304 ia_local[i] = ia[i];
01305
01306 if (ia[i] != 0)
01307 {
01308 Mfit += 1;
01309 }
01310 }
01311
01312 if (! (Mfit > 0))
01313 {
01314 cpl_free(ia_local);
01315 cpl_ensure_code( CPL_FALSE,
01316 CPL_ERROR_ILLEGAL_INPUT);
01317 }
01318 }
01319 else
01320 {
01321
01322 int i;
01323
01324 Mfit = M;
01325
01326 for (i = 0; i < M; i++)
01327 {
01328 ia_local[i] = 1;
01329 }
01330 }
01331
01332
01333 if (! ( red_chisq == NULL || N > Mfit ) )
01334 {
01335 cpl_free(ia_local);
01336 cpl_ensure_code(
01337 CPL_FALSE,
01338 CPL_ERROR_ILLEGAL_INPUT);
01339 }
01340
01341
01342 alpha = cpl_matrix_new(Mfit, Mfit);
01343 if (alpha == NULL)
01344 {
01345 cpl_free(ia_local);
01346 cpl_ensure_code(
01347 CPL_FALSE,
01348 CPL_ERROR_ILLEGAL_OUTPUT);
01349 }
01350
01351 beta = cpl_matrix_new(Mfit, 1);
01352 if (beta == NULL)
01353 {
01354 cpl_free(ia_local);
01355 cpl_matrix_delete(alpha);
01356 cpl_ensure_code(
01357 CPL_FALSE,
01358 CPL_ERROR_ILLEGAL_OUTPUT);
01359 }
01360
01361 a_da = cpl_malloc(M * sizeof(double));
01362 if (a_da == NULL)
01363 {
01364 cpl_free(ia_local);
01365 cpl_matrix_delete(alpha);
01366 cpl_matrix_delete(beta);
01367 cpl_ensure_code(
01368 CPL_FALSE,
01369 CPL_ERROR_ILLEGAL_OUTPUT);
01370 }
01371
01372 part = cpl_malloc(M * sizeof(double));
01373 if (part == NULL)
01374 {
01375 cpl_free(ia_local);
01376 cpl_matrix_delete(alpha);
01377 cpl_matrix_delete(beta);
01378 cpl_free(a_da);
01379 cpl_ensure_code(
01380 CPL_FALSE,
01381 CPL_ERROR_ILLEGAL_OUTPUT);
01382 }
01383
01384
01385 lambda = 0.001;
01386 count = 0;
01387 iterations = 0;
01388 if( (chi_sq = get_chisq(N, D, f, a_data, x_data, y_data, sigma_data)) < 0)
01389 {
01390 cpl_free(ia_local);
01391 cpl_matrix_delete(alpha);
01392 cpl_matrix_delete(beta);
01393 cpl_free(a_da);
01394 cpl_free(part);
01395 cpl_ensure_code(
01396 CPL_FALSE,
01397 cpl_error_get_code());
01398 }
01399
01400 #if DEBUG_LM
01401 uves_msg_error("Initial chi^2 = %f", chi_sq);
01402 {int i;
01403 for (i = 0; i < M; i++)
01404 {
01405 uves_msg_error("Initial a[%d] = %e", i, a_data[i]);
01406 }
01407 }
01408 #endif
01409
01410
01411
01412 while (count < 5 && lambda < MAXLAMBDA && iterations < UVES_FIT_MAXITER)
01413 {
01414
01415
01416
01417
01418 double chi_sq_candidate = 0.0;
01419 int returncode = 0;
01420
01421
01422
01423
01424
01425
01426 while( (returncode = get_candidate(a_data, ia_local,
01427 M, N, D,
01428 lambda, f, dfda,
01429 x_data, y_data, sigma_data,
01430 part, alpha, beta, a_da)
01431 ) != 0
01432 && cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX
01433 && lambda < MAXLAMBDA)
01434 {
01435 #if DEBUG_LM
01436 uves_msg_error("Singular matrix. lambda = %e", lambda);
01437 #endif
01438 cpl_error_reset();
01439 lambda *= 9.0;
01440 }
01441
01442
01443 if ( !( lambda < MAXLAMBDA ) )
01444 {
01445 cpl_free(ia_local);
01446 cpl_matrix_delete(alpha);
01447 cpl_matrix_delete(beta);
01448 cpl_free(a_da);
01449 cpl_free(part);
01450 cpl_ensure_code(
01451 CPL_FALSE,
01452 CPL_ERROR_CONTINUE);
01453 }
01454
01455 if (returncode != 0)
01456 {
01457 cpl_free(ia_local);
01458 cpl_matrix_delete(alpha);
01459 cpl_matrix_delete(beta);
01460 cpl_free(a_da);
01461 cpl_free(part);
01462 cpl_ensure_code(
01463 CPL_FALSE,
01464 cpl_error_get_code());
01465 }
01466
01467
01468 if ((chi_sq_candidate = get_chisq(N, D, f, a_da,
01469 x_data, y_data, sigma_data)) < 0)
01470 {
01471 cpl_free(ia_local);
01472 cpl_matrix_delete(alpha);
01473 cpl_matrix_delete(beta);
01474 cpl_free(a_da);
01475 cpl_free(part);
01476 cpl_ensure_code(
01477 CPL_FALSE,
01478 cpl_error_get_code());
01479 }
01480
01481 if (chi_sq_candidate > 1.000001 * chi_sq)
01482 {
01483
01484 #if DEBUG_LM
01485 uves_msg_error("Chi^2 = %f Candidate = %f Lambda = %e",
01486 chi_sq, chi_sq_candidate, lambda);
01487 #endif
01488 lambda *= 9.0;
01489 }
01490 else
01491 {
01492 #if DEBUG_LM
01493 uves_msg_error("Chi^2 = %f Candidate = %f* Lambda = %e count = %d",
01494 chi_sq, chi_sq_candidate, lambda, count);
01495 #endif
01496
01497
01498 lambda /= 10.0;
01499
01500
01501
01502 if ( chi_sq == 0 ||
01503 (chi_sq - chi_sq_candidate)/chi_sq < .01)
01504 {
01505 count += 1;
01506 }
01507 else
01508 {
01509
01510
01511 count = 0;
01512 }
01513
01514 if (chi_sq_candidate < chi_sq)
01515 {
01516
01517 int i;
01518 for (i = 0; i < M; i++)
01519 {
01520 a_data[i] = a_da[i];
01521 #if DEBUG_LM
01522 uves_msg_error("-> a[%d] = %e", i, a_da[i]);
01523 #endif
01524 }
01525 chi_sq = chi_sq_candidate;
01526 }
01527 }
01528 iterations++;
01529 }
01530
01531
01532 if ( !( lambda < MAXLAMBDA && iterations < UVES_FIT_MAXITER ) )
01533 {
01534 #if DEBUG_LM
01535 uves_msg_error("Failed to converge, lambda=%f iterations=%d",
01536 lambda, iterations);
01537 #endif
01538 cpl_free(ia_local);
01539 cpl_matrix_delete(alpha);
01540 cpl_matrix_delete(beta);
01541 cpl_free(a_da);
01542 cpl_free(part);
01543 cpl_ensure_code(
01544 CPL_FALSE,
01545 CPL_ERROR_CONTINUE);
01546 }
01547
01548
01549 if (mse != NULL)
01550 {
01551 int i;
01552
01553 *mse = 0.0;
01554
01555 for(i = 0; i < N; i++)
01556 {
01557 double fx_i = 0.0;
01558 double residual = 0.0;
01559
01560
01561 if( f(&(x_data[i*D]),
01562 a_data,
01563 &fx_i) != 0)
01564 {
01565 cpl_free(ia_local);
01566 cpl_matrix_delete(alpha);
01567 cpl_matrix_delete(beta);
01568 cpl_free(a_da);
01569 cpl_free(part);
01570 cpl_ensure_code(
01571 CPL_FALSE,
01572 CPL_ERROR_ILLEGAL_INPUT);
01573 }
01574
01575 residual = y_data[i] - fx_i;
01576 *mse += residual * residual;
01577 }
01578 *mse /= N;
01579 }
01580
01581
01582 if (red_chisq != NULL)
01583 {
01584
01585 *red_chisq = chi_sq / (N-Mfit);
01586 }
01587
01588
01589
01590
01591 if (covariance != NULL)
01592 {
01593 cpl_matrix *cov;
01594
01595 if( get_candidate(a_data, ia_local,
01596 M, N, D, 0.0, f, dfda,
01597 x_data, y_data, sigma_data,
01598 part, alpha, beta, a_da)
01599 != 0)
01600 {
01601 cpl_free(ia_local);
01602 cpl_matrix_delete(alpha);
01603 cpl_matrix_delete(beta);
01604 cpl_free(a_da);
01605 cpl_free(part);
01606 cpl_ensure_code(
01607 CPL_FALSE,
01608 cpl_error_get_code());
01609 }
01610
01611 cov = cpl_matrix_invert_create(alpha);
01612 if (cov == NULL)
01613 {
01614 cpl_free(ia_local);
01615 cpl_matrix_delete(alpha);
01616 cpl_matrix_delete(beta);
01617 cpl_free(a_da);
01618 cpl_free(part);
01619 cpl_ensure_code(
01620 CPL_FALSE,
01621 cpl_error_get_code());
01622 }
01623
01624
01625 {
01626 int i;
01627 for (i = 0; i < Mfit; i++)
01628 {
01629 if ( !(cpl_matrix_get(cov, i, i) > 0) )
01630 {
01631 cpl_free(ia_local);
01632 cpl_matrix_delete(alpha);
01633 cpl_matrix_delete(beta);
01634 cpl_free(a_da);
01635 cpl_free(part);
01636 cpl_matrix_delete(cov);
01637 *covariance = NULL;
01638 cpl_ensure_code(
01639 CPL_FALSE,
01640 CPL_ERROR_SINGULAR_MATRIX);
01641 }
01642 }
01643 }
01644
01645
01646
01647
01648
01649 *covariance = cpl_matrix_new(M, M);
01650 if (*covariance == NULL)
01651 {
01652 cpl_free(ia_local);
01653 cpl_matrix_delete(alpha);
01654 cpl_matrix_delete(beta);
01655 cpl_free(a_da);
01656 cpl_free(part);
01657 cpl_matrix_delete(cov);
01658 cpl_ensure_code(
01659 CPL_FALSE,
01660 CPL_ERROR_ILLEGAL_OUTPUT);
01661 }
01662
01663 {
01664 int j, jmfit;
01665
01666 for (j = 0, jmfit = 0; j < M; j++)
01667 if (ia_local[j] != 0)
01668 {
01669 int i, imfit;
01670
01671 for (i = 0, imfit = 0; i < M; i++)
01672 if (ia_local[i] != 0)
01673 {
01674 cpl_matrix_set(*covariance, i, j,
01675 cpl_matrix_get(
01676 cov, imfit, jmfit));
01677 imfit += 1;
01678 }
01679
01680 assert( imfit == Mfit );
01681
01682 jmfit += 1;
01683 }
01684
01685 assert( jmfit == Mfit );
01686 }
01687
01688 cpl_matrix_delete(cov);
01689 }
01690
01691 cpl_free(ia_local);
01692 cpl_matrix_delete(alpha);
01693 cpl_matrix_delete(beta);
01694 cpl_free(a_da);
01695 cpl_free(part);
01696
01697 return CPL_ERROR_NONE;
01698 }
01699
01700
01710
01711 cpl_error_code
01712 uves_cast_image(cpl_image **image, cpl_type to_type)
01713 {
01714 cpl_image *temp = NULL;
01715
01716 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
01717
01718 temp = *image;
01719
01720 check( *image = cpl_image_cast(temp, to_type), "Couldn't convert image to %s",
01721 uves_tostring_cpl_type(to_type));
01722
01723 cleanup:
01724 uves_free_image(&temp);
01725 return cpl_error_get_code();
01726 }
01727
01728
01729
01744
01745 cpl_error_code
01746 uves_crop_image(cpl_image **image, int x1, int y_1, int x2, int y2)
01747 {
01748 cpl_image *temp = NULL;
01749
01750 assure( image != NULL, CPL_ERROR_NULL_INPUT, "Null image");
01751
01752 temp = *image;
01753
01754 check( *image = cpl_image_extract(temp, x1, y_1, x2, y2),
01755 "Could not extract image");
01756
01757 cleanup:
01758 uves_free_image(&temp);
01759 return cpl_error_get_code();
01760 }
01761
01762
01786
01787 cpl_error_code
01788 uves_get_property_value(const uves_propertylist *plist, const char *keyword,
01789 cpl_type keywordtype, void *result)
01790 {
01791 cpl_type t;
01792
01793
01794 assure( plist != NULL , CPL_ERROR_NULL_INPUT, "Null property list");
01795 assure( keyword != NULL, CPL_ERROR_NULL_INPUT, "Null keyword");
01796
01797
01798 assure( uves_propertylist_contains(plist, keyword), CPL_ERROR_DATA_NOT_FOUND,
01799 "Keyword %s does not exist", keyword );
01800
01801 check( t = uves_propertylist_get_type(plist, keyword) ,
01802 "Could not read type of keyword '%s'", keyword );
01803 assure(t == keywordtype , CPL_ERROR_TYPE_MISMATCH,
01804 "Keyword '%s' has wrong type (%s). %s expected",
01805 keyword, uves_tostring_cpl_type(t), uves_tostring_cpl_type(keywordtype));
01806
01807
01808 switch (keywordtype)
01809 {
01810 case CPL_TYPE_INT :
01811 check( *(( int *)result) =
01812 uves_propertylist_get_int(plist, keyword),
01813 "Could not get (integer) value of %s", keyword );
01814 break;
01815 case CPL_TYPE_BOOL :
01816 check( *(( bool *)result) =
01817 uves_propertylist_get_bool(plist, keyword),
01818 "Could not get (boolean) value of %s", keyword );
01819 break;
01820 case CPL_TYPE_DOUBLE:
01821 check( *(( double *)result) =
01822 uves_propertylist_get_double(plist, keyword),
01823 "Could not get (double) value of %s" , keyword );
01824 break;
01825 case CPL_TYPE_STRING:
01826 check( *((const char * *)result) =
01827 uves_propertylist_get_string(plist, keyword),
01828 "Could not get (string) value of %s" , keyword );
01829 break;
01830 default:
01831 assure( false, CPL_ERROR_INVALID_TYPE, "Unknown type");
01832 break;
01833 }
01834
01835 cleanup:
01836 return cpl_error_get_code();
01837 }
01838
01839
01840
01865
01866
01867 const char *
01868 uves_find_frame(const cpl_frameset *frames, const char **wanted, int N, int *found,
01869 const cpl_frame **frame)
01870 {
01871 const char *filename = NULL;
01872 int i;
01873 const cpl_frame *f = NULL;
01874
01875
01876 *found = 0;
01877 if (frame != NULL)
01878 {
01879 *frame = NULL;
01880 }
01881
01882 for (i = 0; i < N; i++)
01883 {
01884 check( f = irplib_frameset_find_const(frames, wanted[i]),
01885 "Could not search through frame set");
01886 if (f != NULL)
01887 {
01888 check( filename = cpl_frame_get_filename(f),
01889 "Could not read frame filename");
01890 *found = i;
01891 if (frame != NULL)
01892 {
01893 *frame = f;
01894 }
01895
01896 i = N;
01897 }
01898 }
01899
01900
01901 assure(filename != NULL, CPL_ERROR_DATA_NOT_FOUND, "No such frame in frame set");
01902
01903 cleanup:
01904 return filename;
01905 }
01906
01907
01908
01915
01916 int
01917 uves_get_nextensions(const char *filename)
01918 {
01919 int result = 0;
01920 cpl_frame *f = NULL;
01921
01922
01923
01924
01925 check(( f = cpl_frame_new(),
01926 cpl_frame_set_filename(f, filename)),
01927 "Could not create frame");
01928
01929 check( result = cpl_frame_get_nextensions(f),
01930 "Error reading number of extensions of file '%s'", filename);
01931 cleanup:
01932 cpl_frame_delete(f);
01933 return result;
01934 }
01935
01936
01957
01958 cpl_error_code
01959 uves_get_parameter(const cpl_parameterlist *parameters, const char *context,
01960 const char *recipe_id, const char *name, cpl_type type,
01961 void *value)
01962 {
01963 char *fullname = NULL;
01964 const cpl_parameter *p = NULL;
01965
01966 passure( parameters != NULL, " ");
01967
01968 passure( recipe_id != NULL, " ");
01969 passure( name != NULL, " ");
01970 passure( value != NULL, " ");
01971
01972 if (context != NULL)
01973 {
01974 check( fullname = uves_sprintf("%s.%s.%s", context, recipe_id, name),
01975 "Error getting full parameter name");
01976 }
01977 else
01978 {
01979 check( fullname = uves_sprintf("%s.%s", recipe_id, name),
01980 "Error getting full parameter name");
01981 }
01982
01983
01984 check( p = irplib_parameterlist_find_const(parameters, fullname),
01985 "Error searching for parameter '%s'", fullname);
01986 assure( p != NULL, CPL_ERROR_DATA_NOT_FOUND,
01987 "No parameter '%s' in parameter list", fullname);
01988
01989
01990 {
01991 cpl_type partype;
01992 check( partype = cpl_parameter_get_type(p),
01993 "Could not read type of parameter '%s'", fullname);
01994 assure( partype == type, CPL_ERROR_TYPE_MISMATCH,
01995 "Parameter '%s' has type %s. Expected type was %s",
01996 fullname,
01997 uves_tostring_cpl_type(partype), uves_tostring_cpl_type(type));
01998 }
01999
02000
02001 switch(type)
02002 {
02003 case CPL_TYPE_INT:
02004 check( *(int * )value =
02005 cpl_parameter_get_int (p),
02006 "Could not read integer parameter '%s'", fullname);
02007 break;
02008 case CPL_TYPE_BOOL:
02009 check( *(bool * )value =
02010 cpl_parameter_get_bool (p),
02011 "Could not read boolean parameter '%s'", fullname);
02012 break;
02013 case CPL_TYPE_DOUBLE:
02014 check( *(double * )value =
02015 cpl_parameter_get_double(p),
02016 "Could not read double parameter '%s'" , fullname );
02017 break;
02018 case CPL_TYPE_STRING:
02019 check( *(const char ** )value =
02020 cpl_parameter_get_string(p),
02021 "Could not read string parameter '%s'" , fullname );
02022 break;
02023 default:
02024 assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02025 "Don't know how to read parameter '%s' of type %s",
02026 fullname, uves_tostring_cpl_type(type));
02027 break;
02028 }
02029
02030 cleanup:
02031 cpl_free(fullname); fullname = NULL;
02032 return cpl_error_get_code();
02033 }
02034
02035
02051
02052 cpl_error_code
02053 uves_set_parameter(cpl_parameterlist *parameters,
02054 const char *context,
02055 const char *name, cpl_type type, void *value)
02056 {
02057 char *fullname = NULL;
02058 cpl_parameter *p = NULL;
02059
02060 check( fullname = uves_sprintf("%s.%s", context, name),
02061 "Error getting full parameter name");
02062
02063
02064 check( p = cpl_parameterlist_find(parameters, fullname),
02065 "Error searching for parameter '%s'", fullname);
02066 assure( p != NULL, CPL_ERROR_DATA_NOT_FOUND,
02067 "No parameter '%s' in parameter list", fullname);
02068
02069
02070 {
02071 cpl_type partype;
02072 check( partype = cpl_parameter_get_type(p),
02073 "Could not read type of parameter '%s'", fullname);
02074 assure( partype == type, CPL_ERROR_TYPE_MISMATCH,
02075 "Parameter '%s' has type %s. Expected type was %s",
02076 fullname, uves_tostring_cpl_type(partype),
02077 uves_tostring_cpl_type(type));
02078 }
02079
02080
02081 switch(type)
02082 {
02083 case CPL_TYPE_INT:
02084 check( cpl_parameter_set_int (p, *((int *) value)),
02085 "Could not set integer parameter '%s'", fullname);
02086 break;
02087 case CPL_TYPE_BOOL:
02088 check( cpl_parameter_set_bool (p, *((bool *) value)),
02089 "Could not set boolean parameter '%s'", fullname);
02090 break;
02091 case CPL_TYPE_DOUBLE:
02092 check( cpl_parameter_set_double(p, *((double *) value)),
02093 "Could not set double parameter '%s'" , fullname);
02094 break;
02095 case CPL_TYPE_STRING:
02096 check( cpl_parameter_set_string(p, *((char **) value)),
02097 "Could not set string parameter '%s'" , fullname);
02098 break;
02099 default:
02100 assure(false, CPL_ERROR_UNSUPPORTED_MODE,
02101 "Don't know how to set parameter of type %s",
02102 uves_tostring_cpl_type(type));
02103 break;
02104 }
02105
02106 cleanup:
02107 cpl_free(fullname); fullname = NULL;
02108 return cpl_error_get_code();
02109 }
02110
02111
02125
02126
02127 cpl_error_code
02128 uves_set_parameter_default(cpl_parameterlist *parameters, const char *context,
02129 const char *parname,
02130 cpl_type type, void *value)
02131 {
02132 const char *full_name = NULL;
02133 cpl_parameter *p = NULL;
02134 cpl_type partype;
02135
02136 if (context != NULL)
02137 {
02138 full_name = uves_sprintf("%s.%s", context, parname);
02139 }
02140 else
02141 {
02142 full_name = uves_sprintf("%s", parname);
02143 }
02144
02145 if (full_name == NULL)
02146 {
02147 return CPL_ERROR_ILLEGAL_OUTPUT;
02148 }
02149
02150
02151 if ( (p = cpl_parameterlist_find(parameters, full_name)) == NULL)
02152 {
02153 uves_msg_error("Missing parameter: '%s'", full_name);
02154
02155 uves_free_string_const(&full_name);
02156 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
02157 else return CPL_ERROR_DATA_NOT_FOUND;
02158 }
02159
02160 partype = cpl_parameter_get_type(p);
02161
02162 if (partype != type)
02163 {
02164 uves_msg_error("Parameter '%s' has type %s. Expected type was %s",
02165 full_name, uves_tostring_cpl_type(partype),
02166 uves_tostring_cpl_type(type));
02167
02168 uves_free_string_const(&full_name);
02169 return CPL_ERROR_TYPE_MISMATCH;
02170 }
02171
02172 switch(type)
02173 {
02174 case CPL_TYPE_INT:
02175 cpl_parameter_set_default_int (p, *((int *) value));
02176 break;
02177 case CPL_TYPE_BOOL:
02178 cpl_parameter_set_default_bool (p, *((bool *) value));
02179 break;
02180 case CPL_TYPE_DOUBLE:
02181 cpl_parameter_set_default_double(p, *((double *) value));
02182 break;
02183 case CPL_TYPE_STRING:
02184 cpl_parameter_set_default_string(p, *((char **) value));
02185 break;
02186 default:
02187 uves_msg_error("Unknown type: %s", uves_tostring_cpl_type(type));
02188
02189 uves_free_string_const(&full_name);
02190 return CPL_ERROR_INVALID_TYPE;
02191 }
02192
02193 if (cpl_error_get_code() != CPL_ERROR_NONE)
02194 {
02195 uves_msg_error("Error changing value of parameter '%s'",
02196 full_name);
02197
02198 uves_free_string_const(&full_name);
02199 return cpl_error_get_code();
02200 }
02201
02202
02203 uves_free_string_const(&full_name);
02204 return CPL_ERROR_NONE;
02205 }
02206
02207
02208
02220
02221 void
02222 uves_raise_to_median_frac(cpl_table *t, const char *column, double fraction)
02223 {
02224 int i = 0;
02225 double threshold;
02226
02227 assure_nomsg(t != NULL, CPL_ERROR_NULL_INPUT);
02228 assure(cpl_table_has_column(t, column), CPL_ERROR_DATA_NOT_FOUND,
02229 "No such column: %s", column);
02230
02231 assure(cpl_table_get_column_type(t, column) == CPL_TYPE_DOUBLE,
02232 CPL_ERROR_UNSUPPORTED_MODE, "Column %s has type %s. %s expected",
02233 column,
02234 uves_tostring_cpl_type(cpl_table_get_column_type(t, column)),
02235 uves_tostring_cpl_type(CPL_TYPE_DOUBLE));
02236
02237
02238 threshold = fraction * cpl_table_get_column_median(t, column);
02239 for (i = 0; i < cpl_table_get_nrow(t); i++)
02240 {
02241 if (cpl_table_get_double(t, column, i, NULL) < threshold)
02242 {
02243 cpl_table_set_double(t, column, i, threshold);
02244 }
02245 }
02246
02247 cleanup:
02248 return;
02249 }
02250
02251
02252
02269
02270
02271 int
02272 uves_select_table_rows(cpl_table *t, const char *column,
02273 cpl_table_select_operator operator, double value)
02274 {
02275 int result = 0;
02276 cpl_type type;
02277
02278 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
02279 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
02280 "No such column: %s", column);
02281
02282 type = cpl_table_get_column_type(t, column);
02283
02284 assure( type == CPL_TYPE_DOUBLE || type == CPL_TYPE_FLOAT ||
02285 type == CPL_TYPE_INT, CPL_ERROR_INVALID_TYPE,
02286 "Column '%s' must be double or int. %s found", column,
02287 uves_tostring_cpl_type(type));
02288
02289 check( cpl_table_select_all(t), "Error selecting rows");
02290
02291 if (type == CPL_TYPE_DOUBLE)
02292 {
02293 result = cpl_table_and_selected_double(t, column, operator, value);
02294 }
02295 else if (type == CPL_TYPE_FLOAT)
02296 {
02297 result = cpl_table_and_selected_float(t, column, operator, value);
02298 }
02299 else if (type == CPL_TYPE_INT)
02300 {
02301 result = cpl_table_and_selected_int(t, column, operator,
02302 uves_round_double(value));
02303 }
02304 else { passure(false, ""); }
02305
02306 cleanup:
02307 return result;
02308
02309 }
02310
02311
02325
02326 int
02327 uves_extract_table_rows_local(cpl_table *t, const char *column,
02328 cpl_table_select_operator operator, double value)
02329 {
02330 int result = 0;
02331
02332 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
02333 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
02334 "No such column: %s", column);
02335
02336 check( result = uves_select_table_rows(t, column, operator, value),
02337 "Error selecting rows");
02338
02339 check( cpl_table_not_selected(t), "Error selecting rows");
02340
02341 check( uves_table_erase_selected_dfs02356(t), "Error deleting rows");
02342
02343 cleanup:
02344 return result;
02345 }
02346
02347
02366
02367 int
02368 uves_erase_table_rows(cpl_table *t, const char *column,
02369 cpl_table_select_operator operator, double value)
02370 {
02371 int result = 0;
02372
02373 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
02374 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
02375 "No such column: %s", column);
02376
02377 check( result = uves_select_table_rows(t, column, operator, value),
02378 "Error selecting rows");
02379
02380 check( uves_table_erase_selected_dfs02356(t), "Error deleting rows");
02381
02382 cleanup:
02383 return result;
02384 }
02385
02386
02387
02388
02389
02390
02399
02400
02401 void uves_propertylist_append_property(uves_propertylist *plist, const cpl_property *p)
02402 {
02403 switch(cpl_property_get_type(p)) {
02404 case CPL_TYPE_CHAR:
02405 uves_propertylist_append_char(plist, cpl_property_get_name(p), cpl_property_get_char(p));
02406 break;
02407 case CPL_TYPE_BOOL:
02408 uves_propertylist_append_bool(plist, cpl_property_get_name(p), cpl_property_get_bool(p));
02409 break;
02410 case CPL_TYPE_INT:
02411 uves_propertylist_append_int(plist, cpl_property_get_name(p), cpl_property_get_int(p));
02412 break;
02413 case CPL_TYPE_LONG:
02414 uves_propertylist_append_long(plist, cpl_property_get_name(p), cpl_property_get_long(p));
02415 break;
02416 case CPL_TYPE_FLOAT:
02417 uves_propertylist_append_float(plist, cpl_property_get_name(p), cpl_property_get_float(p));
02418 break;
02419 case CPL_TYPE_DOUBLE:
02420 uves_propertylist_append_double(plist, cpl_property_get_name(p), cpl_property_get_double(p));
02421 break;
02422 case CPL_TYPE_STRING:
02423 uves_propertylist_append_string(plist, cpl_property_get_name(p), cpl_property_get_string(p));
02424 break;
02425 default:
02426 assure( false, CPL_ERROR_UNSUPPORTED_MODE,
02427 "Type is %s", uves_tostring_cpl_type(cpl_property_get_type(p)));
02428 break;
02429 }
02430 cleanup:
02431 return;
02432 }
02433
02434
02435
02436
02437
02438
02439 typedef struct _xxx_table_ xxx_table;
02440 typedef int xxx_column_flag;
02441 typedef struct _xxx_column_ xxx_column;
02442
02443 typedef union _xxx_column_values_ {
02444 int *i;
02445 float *f;
02446 double *d;
02447 char **s;
02448 cpl_array **array;
02449 } xxx_column_values;
02450
02451 struct _xxx_column_ {
02452 char *name;
02453 char *unit;
02454 char *format;
02455 int length;
02456 int depth;
02457 cpl_type type;
02458 xxx_column_values *values;
02459 xxx_column_flag *null;
02460 int nullcount;
02461 cpl_array *dimensions;
02462 };
02463
02464 struct _xxx_table_ {
02465 int nc;
02466 int nr;
02467 xxx_column **columns;
02468 xxx_column_flag *select;
02469 int selectcount;
02470 };
02471
02472
02473
02474
02475
02476
02477
02478 #define CPL_INT_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; }
02479
02480 #define CPL_PIX_STACK_SIZE 50
02481
02492
02493 static cpl_error_code xxx_tools_sort_int(
02494 int * pix_arr,
02495 int n)
02496 {
02497 int i, ir, j, k, l;
02498 int i_stack[CPL_PIX_STACK_SIZE] ;
02499 int j_stack ;
02500 int a ;
02501
02502
02503 cpl_ensure(pix_arr, CPL_ERROR_NULL_INPUT,
02504 CPL_ERROR_NULL_INPUT) ;
02505
02506 ir = n ;
02507 l = 1 ;
02508 j_stack = 0 ;
02509 for (;;) {
02510 if (ir-l < 7) {
02511 for (j=l+1 ; j<=ir ; j++) {
02512 a = pix_arr[j-1];
02513 for (i=j-1 ; i>=1 ; i--) {
02514 if (pix_arr[i-1] <= a) break;
02515 pix_arr[i] = pix_arr[i-1];
02516 }
02517 pix_arr[i] = a;
02518 }
02519 if (j_stack == 0) break;
02520 ir = i_stack[j_stack-- -1];
02521 l = i_stack[j_stack-- -1];
02522 } else {
02523 k = (l+ir) >> 1;
02524 CPL_INT_SWAP(pix_arr[k-1], pix_arr[l])
02525 if (pix_arr[l] > pix_arr[ir-1]) {
02526 CPL_INT_SWAP(pix_arr[l], pix_arr[ir-1])
02527 }
02528 if (pix_arr[l-1] > pix_arr[ir-1]) {
02529 CPL_INT_SWAP(pix_arr[l-1], pix_arr[ir-1])
02530 }
02531 if (pix_arr[l] > pix_arr[l-1]) {
02532 CPL_INT_SWAP(pix_arr[l], pix_arr[l-1])
02533 }
02534 i = l+1;
02535 j = ir;
02536 a = pix_arr[l-1];
02537 for (;;) {
02538 do i++; while (pix_arr[i-1] < a);
02539 do j--; while (pix_arr[j-1] > a);
02540 if (j < i) break;
02541 CPL_INT_SWAP(pix_arr[i-1], pix_arr[j-1]);
02542 }
02543 pix_arr[l-1] = pix_arr[j-1];
02544 pix_arr[j-1] = a;
02545 j_stack += 2;
02546 if (j_stack > CPL_PIX_STACK_SIZE) {
02547
02548 return CPL_ERROR_ILLEGAL_INPUT ;
02549 }
02550 if (ir-i+1 >= j-l) {
02551 i_stack[j_stack-1] = ir;
02552 i_stack[j_stack-2] = i;
02553 ir = j-1;
02554 } else {
02555 i_stack[j_stack-1] = j-1;
02556 i_stack[j_stack-2] = l;
02557 l = i;
02558 }
02559 }
02560 }
02561 return CPL_ERROR_NONE ;
02562 }
02563 #undef CPL_PIX_STACK_SIZE
02564
02565 static cpl_error_code xxx_tools_sort_stable_pattern_int(const int *,
02566 int, int, int, int *);
02567 static cpl_error_code xxx_tools_sort_stable_pattern_float(const float *,
02568 int, int, int, int *);
02569 static cpl_error_code xxx_tools_sort_stable_pattern_double(const double *,
02570 int, int, int, int *);
02571 static cpl_error_code xxx_tools_sort_stable_pattern_string(char * const *,
02572 int, int, int, int *);
02573
02574
02575 #undef CONCAT
02576 #undef CONCAT2X
02577 #define CONCAT(a,b) a ## _ ## b
02578 #define CONCAT2X(a,b) CONCAT(a,b)
02579
02580 #define CPL_TYPE int
02581 #define CPL_TYPE_NAME int
02582 #define CPL_TOOLS_SORT_LT(x,y) ((x) < (y))
02583 #include "uves_tools_body.c"
02584 #undef CPL_TYPE
02585 #undef CPL_TYPE_NAME
02586 #undef CPL_TOOLS_SORT_LT
02587
02588 #define CPL_TYPE float
02589 #define CPL_TYPE_NAME float
02590 #define CPL_TOOLS_SORT_LT(x,y) ((x) < (y))
02591 #include "uves_tools_body.c"
02592 #undef CPL_TYPE
02593 #undef CPL_TYPE_NAME
02594 #undef CPL_TOOLS_SORT_LT
02595
02596 #define CPL_TYPE double
02597 #define CPL_TYPE_NAME double
02598 #define CPL_TOOLS_SORT_LT(x,y) ((x) < (y))
02599 #include "uves_tools_body.c"
02600 #undef CPL_TYPE
02601 #undef CPL_TYPE_NAME
02602 #undef CPL_TOOLS_SORT_LT
02603
02604 #define CPL_TYPE char *
02605 #define CPL_TYPE_NAME string
02606 #define CPL_TOOLS_SORT_LT(x,y) (((x) == NULL && (y) != NULL) || \
02607 ((x) != NULL && (y) != NULL && \
02608 strcmp((x), (y)) < 0))
02609 #include "uves_tools_body.c"
02610 #undef CPL_TYPE
02611 #undef CPL_TYPE_NAME
02612 #undef CPL_TOOLS_SORT_LT
02613
02614
02615
02616
02617
02618
02619
02620
02621 void xxx_column_dump_structure(xxx_column *column);
02622 void xxx_column_dump(xxx_column *column, int start, int count);
02623
02624
02625
02626
02627
02628 xxx_column *xxx_column_new_int(int length);
02629 xxx_column *xxx_column_new_float(int length);
02630 xxx_column *xxx_column_new_double(int length);
02631 xxx_column *xxx_column_new_string(int length);
02632 xxx_column *xxx_column_new_array(cpl_type, int, int);
02633
02634 xxx_column *xxx_column_wrap_int(int *data, int length);
02635 xxx_column *xxx_column_wrap_float(float *data, int length);
02636 xxx_column *xxx_column_wrap_double(double *data, int length);
02637 xxx_column *xxx_column_wrap_string(char **data, int length);
02638
02639 void *xxx_column_unwrap(xxx_column *);
02640 void xxx_column_delete_but_strings(xxx_column *);
02641 void xxx_column_delete_but_arrays(xxx_column *);
02642
02643 cpl_error_code xxx_column_copy_data(xxx_column *column,
02644 const double *data);
02645 cpl_error_code xxx_column_copy_data_int(xxx_column *column,
02646 const int *data);
02647 cpl_error_code xxx_column_copy_data_float(xxx_column *column,
02648 const float *data);
02649 cpl_error_code xxx_column_copy_data_double(xxx_column *column,
02650 const double *data);
02651 cpl_error_code xxx_column_copy_data_string(xxx_column *column,
02652 const char **data);
02653
02654 void xxx_column_delete(xxx_column *);
02655
02656
02657
02658
02659
02660
02661 cpl_error_code xxx_column_set_name(xxx_column *, const char *);
02662 const char *xxx_column_get_name(xxx_column *);
02663
02664 cpl_error_code xxx_column_set_unit(xxx_column *, const char *);
02665 const char *xxx_column_get_unit(xxx_column *);
02666
02667 cpl_error_code xxx_column_set_format(xxx_column *, const char *);
02668 const char *xxx_column_get_format(xxx_column *);
02669
02670 int xxx_column_get_depth(xxx_column *);
02671 int xxx_column_get_dimensions(xxx_column *);
02672 cpl_error_code xxx_column_set_dimensions(xxx_column *, cpl_array *);
02673 int xxx_column_get_dimension(xxx_column *, int);
02674
02675
02676 int *xxx_column_get_data_int(xxx_column *);
02677 float *xxx_column_get_data_float(xxx_column *);
02678 double *xxx_column_get_data_double(xxx_column *);
02679 char **xxx_column_get_data_string(xxx_column *);
02680 cpl_array **xxx_column_get_data_array(xxx_column *);
02681 xxx_column_flag *xxx_column_get_data_invalid(xxx_column *);
02682 cpl_error_code xxx_column_set_data_invalid(xxx_column *,
02683 xxx_column_flag *, int);
02684
02685 cpl_error_code xxx_column_set_size(xxx_column *, int);
02686 cpl_error_code xxx_column_set_depth(xxx_column *, int);
02687
02688 double xxx_column_get(xxx_column *, int, int *null);
02689 int xxx_column_get_int(xxx_column *, int, int *null);
02690 float xxx_column_get_float(xxx_column *, int, int *null);
02691 double xxx_column_get_double(xxx_column *, int, int *null);
02692 const char *xxx_column_get_string(xxx_column *, int);
02693 const cpl_array *xxx_column_get_array(xxx_column *, int);
02694
02695 cpl_error_code xxx_column_set(xxx_column *, int, double);
02696 cpl_error_code xxx_column_set_int(xxx_column *, int, int);
02697 cpl_error_code xxx_column_set_float(xxx_column *, int, float);
02698 cpl_error_code xxx_column_set_double(xxx_column *, int, double);
02699 cpl_error_code xxx_column_set_string(xxx_column *, int, const char *);
02700 cpl_error_code xxx_column_set_array(xxx_column *, int, const cpl_array *);
02701
02702 cpl_error_code xxx_column_fill(xxx_column *, int, int, double);
02703 cpl_error_code xxx_column_fill_int(xxx_column *, int, int, int);
02704 cpl_error_code xxx_column_fill_float(xxx_column *, int, int, float);
02705 cpl_error_code xxx_column_fill_double(xxx_column *, int, int, double);
02706 cpl_error_code xxx_column_fill_string(xxx_column *, int, int, const char *);
02707 cpl_error_code xxx_column_fill_array(xxx_column *, int, int, const cpl_array *);
02708
02709 cpl_error_code xxx_column_copy_segment(xxx_column *, int, int, double *);
02710 cpl_error_code xxx_column_copy_segment_int(xxx_column *, int, int, int *);
02711 cpl_error_code xxx_column_copy_segment_float(xxx_column *, int, int, float *);
02712 cpl_error_code xxx_column_copy_segment_double(xxx_column *, int, int, double *);
02713 cpl_error_code xxx_column_copy_segment_string(xxx_column *, int, int, char **);
02714 cpl_error_code xxx_column_copy_segment_array(xxx_column *, int, int,
02715 cpl_array **);
02716
02717 cpl_error_code xxx_column_shift(xxx_column *, int);
02718
02719 cpl_error_code xxx_column_set_invalid(xxx_column *, int);
02720 cpl_error_code xxx_column_fill_invalid(xxx_column *, int, int);
02721 int xxx_column_is_invalid(xxx_column *, int);
02722 int xxx_column_has_invalid(xxx_column *);
02723 int xxx_column_has_valid(xxx_column *);
02724 int xxx_column_count_invalid(xxx_column *);
02725
02726 cpl_error_code xxx_column_fill_invalid_int(xxx_column *, int);
02727 cpl_error_code xxx_column_fill_invalid_float(xxx_column *, float);
02728 cpl_error_code xxx_column_fill_invalid_double(xxx_column *, double);
02729
02730 cpl_error_code xxx_column_erase_segment(xxx_column *, int, int);
02731 cpl_error_code xxx_column_insert_segment(xxx_column *, int, int);
02732
02733 xxx_column *xxx_column_duplicate(xxx_column *);
02734
02735 xxx_column *xxx_column_extract(xxx_column *, int, int);
02736
02737 xxx_column *xxx_column_cast_to_int(xxx_column *);
02738 xxx_column *xxx_column_cast_to_float(xxx_column *);
02739 xxx_column *xxx_column_cast_to_double(xxx_column *);
02740
02741 cpl_error_code xxx_column_merge(xxx_column *, xxx_column *, int);
02742
02743 cpl_error_code xxx_column_add(xxx_column *, xxx_column *);
02744 cpl_error_code xxx_column_subtract(xxx_column *, xxx_column *);
02745 cpl_error_code xxx_column_multiply(xxx_column *, xxx_column *);
02746 cpl_error_code xxx_column_divide(xxx_column *, xxx_column *);
02747
02748 cpl_error_code xxx_column_add_scalar(xxx_column *, double);
02749 cpl_error_code xxx_column_subtract_scalar(xxx_column *, double);
02750 cpl_error_code xxx_column_multiply_scalar(xxx_column *, double);
02751 cpl_error_code xxx_column_divide_scalar(xxx_column *, double);
02752 cpl_error_code xxx_column_logarithm(xxx_column *, double);
02753 cpl_error_code xxx_column_power(xxx_column *, double);
02754 cpl_error_code xxx_column_exponential(xxx_column *, double);
02755
02756 double xxx_column_get_mean(xxx_column *);
02757 double xxx_column_get_median(xxx_column *);
02758 double xxx_column_get_stdev(xxx_column *);
02759
02760 double xxx_column_get_max(xxx_column *);
02761 double xxx_column_get_min(xxx_column *);
02762 cpl_error_code xxx_column_get_maxpos(xxx_column *, int *);
02763 cpl_error_code xxx_column_get_minpos(xxx_column *, int *);
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774 inline static int xxx_column_type_size(cpl_type type)
02775 {
02776
02777 switch (type) {
02778 case CPL_TYPE_INT:
02779 return sizeof(int);
02780 case CPL_TYPE_FLOAT:
02781 return sizeof(float);
02782 case CPL_TYPE_DOUBLE:
02783 return sizeof(double);
02784 case CPL_TYPE_STRING:
02785 return sizeof(char *);
02786 case CPL_TYPE_INT | CPL_TYPE_POINTER:
02787 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
02788 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
02789 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
02790 return sizeof(cpl_array *);
02791 default:
02792 return 0;
02793 }
02794
02795 }
02796 #define CPL_DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
02797 #define CPL_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; }
02798 #define CPL_PIX_SORT(a,b) { if ((a)>(b)) CPL_DOUBLE_SWAP((a),(b)); }
02799
02800
02801 static int xxx_column_get_size(xxx_column *column)
02802 {
02803
02804 if (column)
02805 return column->length;
02806
02807 cpl_error_set("xxx_column_get_size", CPL_ERROR_NULL_INPUT);
02808
02809 return 0;
02810
02811 }
02812
02813 static cpl_type xxx_column_get_type(xxx_column *column)
02814 {
02815
02816 if (column)
02817 return column->type;
02818
02819 cpl_error_set("xxx_column_get_type", CPL_ERROR_NULL_INPUT);
02820
02821 return CPL_TYPE_INVALID;
02822
02823 }
02824
02825
02826
02827 static cpl_error_code xxx_column_erase_pattern(xxx_column *column,
02828 int *pattern)
02829 {
02830
02831 const char *fid = "xxx_column_erase_pattern";
02832 cpl_type type = xxx_column_get_type(column);
02833 int old_length = xxx_column_get_size(column);
02834 int new_length;
02835 int i;
02836 int j;
02837 cpl_array **ap;
02838 char **sp;
02839 int *ip;
02840 float *fp;
02841 double *dp;
02842
02843
02844 if (column == 0x0)
02845 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
02846
02847 if (pattern == 0x0)
02848 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
02849
02850 new_length = 0;
02851 for (i = 0; i < old_length; i++)
02852 if (!pattern[i])
02853 new_length++;
02854
02855 if (type == CPL_TYPE_STRING) {
02856
02857
02858
02859
02860
02861
02862 for(i = 0; i < old_length; i++)
02863 if (pattern[i])
02864 if (column->values->s[i])
02865 cpl_free(column->values->s[i]);
02866
02867 }
02868
02869 if (type & CPL_TYPE_POINTER) {
02870
02871
02872
02873
02874
02875
02876 for(i = 0; i < old_length; i++)
02877 if (pattern[i])
02878 if (column->values->array[i])
02879 cpl_array_delete(column->values->array[i]);
02880
02881 }
02882
02883
02884
02885
02886
02887
02888
02889 if (column->null) {
02890
02891 for (i = 0; i < old_length; i++)
02892 if (pattern[i])
02893 if (column->null[i])
02894 column->nullcount--;
02895
02896 if (column->nullcount == 0 || column->nullcount == new_length) {
02897
02898
02899
02900
02901
02902
02903 if (column->null)
02904 cpl_free(column->null);
02905 column->null = NULL;
02906
02907 }
02908 else {
02909
02910
02911
02912
02913
02914 i = 0;
02915 for (j = 0; j < old_length; j++)
02916 if (!pattern[j]) {
02917 column->null[i] = column->null[j];
02918 i++;
02919 }
02920
02921
02922
02923
02924
02925 column->null = cpl_realloc(column->null,
02926 new_length * sizeof(xxx_column_flag));
02927
02928 }
02929 }
02930 else {
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940 if (column->nullcount == old_length)
02941 column->nullcount = new_length;
02942
02943 }
02944
02945
02946
02947
02948
02949
02950 if ((type == CPL_TYPE_STRING) || (type & CPL_TYPE_POINTER))
02951 column->nullcount = 0;
02952
02953 if (column->nullcount != new_length) {
02954
02955
02956
02957
02958
02959
02960 ip = column->values->i;
02961 fp = column->values->f;
02962 dp = column->values->d;
02963 sp = column->values->s;
02964 ap = column->values->array;
02965
02966 switch (type) {
02967 case CPL_TYPE_INT:
02968 i = 0;
02969 for(j = 0; j < old_length; j++)
02970 if (!pattern[j])
02971 ip[i++] = ip[j];
02972 break;
02973 case CPL_TYPE_FLOAT:
02974 i = 0;
02975 for(j = 0; j < old_length; j++)
02976 if (!pattern[j])
02977 fp[i++] = fp[j];
02978 break;
02979 case CPL_TYPE_DOUBLE:
02980 i = 0;
02981 for(j = 0; j < old_length; j++)
02982 if (!pattern[j])
02983 dp[i++] = dp[j];
02984 break;
02985 case CPL_TYPE_STRING:
02986 i = 0;
02987 for(j = 0; j < old_length; j++)
02988 if (!pattern[j])
02989 sp[i++] = sp[j];
02990 break;
02991 default:
02992 i = 0;
02993 for(j = 0; j < old_length; j++)
02994 if (!pattern[j])
02995 ap[i++] = ap[j];
02996 break;
02997 }
02998
02999 }
03000
03001
03002
03003
03004
03005
03006 column->values->i = cpl_realloc(column->values->i,
03007 new_length * xxx_column_type_size(type));
03008
03009 column->length = new_length;
03010
03011 return 0;
03012
03013 }
03014
03015
03016 static cpl_error_code xxx_table_erase_selected(xxx_table *table)
03017 {
03018
03019 const char *fid = "xxx_table_erase_selected";
03020 int length = cpl_table_get_nrow((cpl_table *)table);
03021 int i, width;
03022
03023 if (table == 0x0)
03024 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
03025
03026 if (table->selectcount == 0)
03027 return cpl_table_select_all((cpl_table *)table);
03028
03029 if (table->selectcount == length)
03030 return cpl_table_set_size((cpl_table *)table, 0);
03031
03032 width = cpl_table_get_ncol((cpl_table *)table);
03033
03034 for (i = 0; i < width; i++)
03035 if (xxx_column_erase_pattern(table->columns[i], table->select)) {
03036 cpl_error_set_where(fid);
03037 return cpl_error_get_code();
03038 }
03039
03040 table->nr -= table->selectcount;
03041
03042 return cpl_table_select_all((cpl_table *)table);
03043 }
03044
03045
03053
03054 cpl_error_code uves_table_erase_selected_dfs02356(cpl_table *t)
03055 {
03056 xxx_table_erase_selected((xxx_table *)t);
03057
03058 passure( cpl_table_count_selected(t) == cpl_table_get_nrow(t),
03059 "%d %d",
03060 cpl_table_count_selected(t), cpl_table_get_nrow(t) );
03061
03062
03063 cleanup:
03064 return cpl_error_get_code();
03065 }
03066
03067
03068 static xxx_column *xxx_table_find_column(const xxx_table *table,
03069 const char *name)
03070 {
03071
03072 xxx_column **column;
03073 const char *column_name;
03074 int i;
03075
03076
03077 column = table->columns;
03078
03079 for (i = 0; i < table->nc; i++, column++) {
03080 column_name = xxx_column_get_name(*column);
03081 if (strcmp(name, column_name) == 0) {
03082 return *column;
03083 }
03084 }
03085
03086 return NULL;
03087
03088 }
03089
03090
03091
03092 static double xxx_tools_get_kth_double(
03093 double * a,
03094 int n,
03095 int k)
03096 {
03097 register double x ;
03098 register int i, j, l, m ;
03099
03100 cpl_ensure(a, CPL_ERROR_NULL_INPUT, 0.00) ;
03101
03102 l=0 ; m=n-1 ;
03103 while (l<m) {
03104 x=a[k] ;
03105 i=l ;
03106 j=m ;
03107 do {
03108 while (a[i]<x) i++ ;
03109 while (x<a[j]) j-- ;
03110 if (i<=j) {
03111 CPL_DOUBLE_SWAP(a[i],a[j]) ;
03112 i++ ; j-- ;
03113 }
03114 } while (i<=j) ;
03115 if (j<k) l=i ;
03116 if (k<i) m=j ;
03117 }
03118 return a[k] ;
03119 }
03120
03121
03130
03131 static float xxx_tools_get_kth_float(
03132 float * a,
03133 int n,
03134 int k)
03135 {
03136 register float x ;
03137 register int i, j, l, m ;
03138
03139 cpl_ensure(a, CPL_ERROR_NULL_INPUT, 0.00) ;
03140
03141 l=0 ; m=n-1 ;
03142 while (l<m) {
03143 x=a[k] ;
03144 i=l ;
03145 j=m ;
03146 do {
03147 while (a[i]<x) i++ ;
03148 while (x<a[j]) j-- ;
03149 if (i<=j) {
03150 CPL_FLOAT_SWAP(a[i],a[j]) ;
03151 i++ ; j-- ;
03152 }
03153 } while (i<=j) ;
03154 if (j<k) l=i ;
03155 if (k<i) m=j ;
03156 }
03157 return a[k] ;
03158 }
03159
03160
03169
03170 static int xxx_tools_get_kth_int(
03171 int * a,
03172 int n,
03173 int k)
03174 {
03175 register float x ;
03176 register int i, j, l, m ;
03177
03178 cpl_ensure(a, CPL_ERROR_NULL_INPUT, 0) ;
03179
03180 l=0 ; m=n-1 ;
03181 while (l<m) {
03182 x=a[k] ;
03183 i=l ;
03184 j=m ;
03185 do {
03186 while (a[i]<x) i++ ;
03187 while (x<a[j]) j-- ;
03188 if (i<=j) {
03189 CPL_INT_SWAP(a[i],a[j]) ;
03190 i++ ; j-- ;
03191 }
03192 } while (i<=j) ;
03193 if (j<k) l=i ;
03194 if (k<i) m=j ;
03195 }
03196 return a[k] ;
03197 }
03198
03199
03200 #define INT_FORM "% 7d"
03201 #define FLOAT_FORM "% 1.5e"
03202 #define DOUBLE_FORM "% 1.5e"
03203 #define STRING_FORM "%s"
03204
03205 static cpl_error_code
03206 table_sort(xxx_table *table, const uves_propertylist *reflist, unsigned n,
03207 int *sort_pattern, int *sort_null_pattern)
03208 {
03209 const char *fid = "table_sort";
03210 cpl_property *info;
03211 const char *name;
03212 int reverse;
03213 const int stable = 1;
03214 xxx_column *column;
03215 xxx_column *column_sorted_null;
03216 cpl_type type;
03217 int i, j;
03218
03219 int nullcount;
03220 int *idata;
03221 int *sorted_idata;
03222 float *fdata;
03223 float *sorted_fdata;
03224 double *ddata;
03225 double *sorted_ddata;
03226 char **sdata;
03227 char **sorted_sdata;
03228 cpl_array **adata;
03229 cpl_array **sorted_adata;
03230 xxx_column_flag *ndata;
03231 xxx_column_flag *sorted_ndata;
03232
03233
03234 if (n == 0) {
03235 return CPL_ERROR_NONE;
03236 }
03237
03238
03239
03240
03241
03242
03243 info = uves_propertylist_get((uves_propertylist *)reflist, n - 1);
03244 name = cpl_property_get_name(info);
03245 if (cpl_property_get_type(info) == CPL_TYPE_BOOL) {
03246 reverse = cpl_property_get_bool(info);
03247 }
03248 else {
03249 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
03250 }
03251
03252 if (name == NULL) {
03253 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
03254 }
03255 if ((column = xxx_table_find_column(table, name)) == NULL) {
03256 return cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
03257 }
03258
03259 type = xxx_column_get_type(column);
03260 if (type & CPL_TYPE_POINTER) {
03261 return cpl_error_set(fid, CPL_ERROR_UNSUPPORTED_MODE);
03262 }
03263
03264
03265
03266
03267
03268
03269
03270 nullcount = xxx_column_count_invalid(column);
03271 ndata = xxx_column_get_data_invalid(column);
03272
03273 j = 0;
03274 for (i = 0; i < table->nr; i++) {
03275 if (ndata != NULL && ndata[i]) {
03276 sort_null_pattern[j++] = i;
03277 }
03278 }
03279
03280 assert( j == nullcount );
03281
03282 for (i = 0; i < table->nr; i++) {
03283 if (!(ndata != NULL && ndata[i])) {
03284 sort_null_pattern[j++] = i;
03285 }
03286 }
03287
03288 assert( j == table->nr );
03289
03290
03291
03292
03293
03294
03295 column_sorted_null = xxx_column_duplicate(column);
03296 for (i = 0; i < nullcount; i++) {
03297 xxx_column_set_invalid(column_sorted_null, i);
03298 }
03299 for (i = nullcount; i < table->nr; i++) {
03300 int isnull;
03301
03302 switch (type) {
03303 case CPL_TYPE_INT:
03304 xxx_column_set_int(
03305 column_sorted_null, i,
03306 xxx_column_get_int(column, sort_null_pattern[i], &isnull));
03307 break;
03308 case CPL_TYPE_FLOAT:
03309 xxx_column_set_float(
03310 column_sorted_null, i,
03311 xxx_column_get_float(column, sort_null_pattern[i], &isnull));
03312 break;
03313 case CPL_TYPE_DOUBLE:
03314 xxx_column_set_double(
03315 column_sorted_null, i,
03316 xxx_column_get_double(column, sort_null_pattern[i], &isnull));
03317 break;
03318 case CPL_TYPE_STRING:
03319 xxx_column_set_string(
03320 column_sorted_null, i,
03321 xxx_column_get_string(column, sort_null_pattern[i]));
03322 break;
03323 default:
03324 assert( 0 );
03325 break;
03326 }
03327 }
03328
03329
03330
03331
03332
03333 for (i = 0; i < nullcount; i++) {
03334 sort_pattern[i] = i;
03335 }
03336 switch (type) {
03337 case CPL_TYPE_INT:
03338 xxx_tools_sort_stable_pattern_int(
03339 xxx_column_get_data_int(column_sorted_null) + nullcount,
03340 table->nr - nullcount,
03341 reverse,
03342 stable,
03343 sort_pattern + nullcount);
03344 break;
03345 case CPL_TYPE_FLOAT:
03346 xxx_tools_sort_stable_pattern_float(
03347 xxx_column_get_data_float(column_sorted_null) + nullcount,
03348 table->nr - nullcount,
03349 reverse,
03350 stable,
03351 sort_pattern + nullcount);
03352 break;
03353 case CPL_TYPE_DOUBLE:
03354 xxx_tools_sort_stable_pattern_double(
03355 xxx_column_get_data_double(column_sorted_null) + nullcount,
03356 table->nr - nullcount,
03357 reverse,
03358 stable,
03359 sort_pattern + nullcount);
03360 break;
03361 case CPL_TYPE_STRING:
03362 xxx_tools_sort_stable_pattern_string(
03363 xxx_column_get_data_string(column_sorted_null) + nullcount,
03364 table->nr - nullcount,
03365 reverse,
03366 stable,
03367 sort_pattern + nullcount);
03368 break;
03369 default:
03370 assert( 0 );
03371 break;
03372 }
03373
03374 xxx_column_delete(column_sorted_null);
03375
03376
03377
03378
03379
03380
03381 for (i = nullcount; i < table->nr; i++) {
03382 sort_pattern[i] += nullcount;
03383 }
03384
03385
03386
03387
03388
03389
03390 j = 0;
03391 while (j < table->nc) {
03392 xxx_column *sorted_column;
03393
03394 switch (xxx_column_get_type(table->columns[j])) {
03395
03396 case CPL_TYPE_INT:
03397
03398 sorted_column = xxx_column_new_int(table->nr);
03399
03400 xxx_column_set_name(sorted_column,
03401 xxx_column_get_name(table->columns[j]));
03402
03403 nullcount = xxx_column_count_invalid(table->columns[j]);
03404
03405 if (nullcount != table->nr) {
03406
03407
03408
03409
03410
03411
03412 xxx_column_fill_int(sorted_column, 0,
03413 table->nr - nullcount, 0);
03414
03415 ndata = xxx_column_get_data_invalid(table->columns[j]);
03416
03417 if (ndata) {
03418 sorted_ndata = xxx_column_get_data_invalid(sorted_column);
03419
03420 for (i = 0; i < table->nr; i++)
03421 sorted_ndata[i] =
03422 ndata[sort_null_pattern[sort_pattern[i]]];
03423
03424 }
03425
03426 }
03427
03428 sorted_idata = xxx_column_get_data_int(sorted_column);
03429 idata = xxx_column_get_data_int(table->columns[j]);
03430
03431 for (i = 0; i < table->nr; i++)
03432 sorted_idata[i] = idata[sort_null_pattern[sort_pattern[i]]];
03433
03434 xxx_column_delete(table->columns[j]);
03435 table->columns[j] = sorted_column;
03436 break;
03437
03438 case CPL_TYPE_FLOAT:
03439
03440 sorted_column = xxx_column_new_float(table->nr);
03441
03442 xxx_column_set_name(sorted_column,
03443 xxx_column_get_name(table->columns[j]));
03444
03445 nullcount = xxx_column_count_invalid(table->columns[j]);
03446
03447 if (nullcount != table->nr) {
03448
03449
03450
03451
03452
03453
03454 xxx_column_fill_float(sorted_column, 0,
03455 table->nr - nullcount, 0.0);
03456
03457 ndata = xxx_column_get_data_invalid(table->columns[j]);
03458
03459 if (ndata) {
03460 sorted_ndata = xxx_column_get_data_invalid(sorted_column);
03461
03462 for (i = 0; i < table->nr; i++)
03463 sorted_ndata[i] =
03464 ndata[sort_null_pattern[sort_pattern[i]]];
03465
03466 }
03467
03468 }
03469
03470 sorted_fdata = xxx_column_get_data_float(sorted_column);
03471 fdata = xxx_column_get_data_float(table->columns[j]);
03472
03473 for (i = 0; i < table->nr; i++)
03474 sorted_fdata[i] = fdata[sort_null_pattern[sort_pattern[i]]];
03475
03476
03477 xxx_column_delete(table->columns[j]);
03478 table->columns[j] = sorted_column;
03479 break;
03480
03481 case CPL_TYPE_DOUBLE:
03482
03483 sorted_column = xxx_column_new_double(table->nr);
03484
03485 xxx_column_set_name(sorted_column,
03486 xxx_column_get_name(table->columns[j]));
03487
03488 nullcount = xxx_column_count_invalid(table->columns[j]);
03489
03490 if (nullcount != table->nr) {
03491
03492
03493
03494
03495
03496
03497 xxx_column_fill_double(sorted_column, 0,
03498 table->nr - nullcount, 0.0);
03499
03500 ndata = xxx_column_get_data_invalid(table->columns[j]);
03501
03502 if (ndata) {
03503 sorted_ndata = xxx_column_get_data_invalid(sorted_column);
03504
03505 for (i = 0; i < table->nr; i++)
03506 sorted_ndata[i] =
03507 ndata[sort_null_pattern[sort_pattern[i]]];
03508
03509 }
03510
03511 }
03512
03513 sorted_ddata = xxx_column_get_data_double(sorted_column);
03514 ddata = xxx_column_get_data_double(table->columns[j]);
03515
03516 for (i = 0; i < table->nr; i++)
03517 sorted_ddata[i] = ddata[sort_null_pattern[sort_pattern[i]]];
03518
03519 xxx_column_delete(table->columns[j]);
03520 table->columns[j] = sorted_column;
03521 break;
03522
03523 case CPL_TYPE_STRING:
03524
03525 sorted_column = xxx_column_new_string(table->nr);
03526
03527 xxx_column_set_name(sorted_column,
03528 xxx_column_get_name(table->columns[j]));
03529
03530 sorted_sdata = xxx_column_get_data_string(sorted_column);
03531 sdata = xxx_column_get_data_string(table->columns[j]);
03532
03533 for (i = 0; i < table->nr; i++)
03534 sorted_sdata[i] = sdata[sort_null_pattern[sort_pattern[i]]];
03535
03536 xxx_column_delete_but_strings(table->columns[j]);
03537 table->columns[j] = sorted_column;
03538 break;
03539
03540 case CPL_TYPE_INT | CPL_TYPE_POINTER:
03541 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
03542 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
03543 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
03544
03545 sorted_column =
03546 xxx_column_new_array(xxx_column_get_type(table->columns[j]),
03547 table->nr,
03548 xxx_column_get_depth(table->columns[j]));
03549
03550 xxx_column_set_name(sorted_column,
03551 xxx_column_get_name(table->columns[j]));
03552
03553 sorted_adata = xxx_column_get_data_array(sorted_column);
03554 adata = xxx_column_get_data_array(table->columns[j]);
03555
03556 for (i = 0; i < table->nr; i++)
03557 sorted_adata[i] = adata[sort_null_pattern[sort_pattern[i]]];
03558
03559 xxx_column_delete_but_arrays(table->columns[j]);
03560 table->columns[j] = sorted_column;
03561 break;
03562
03563 default:
03564
03565 break;
03566
03567 }
03568
03569 j++;
03570
03571 }
03572
03573
03574
03575
03576
03577
03578
03579 return table_sort(table, reflist, n - 1, sort_pattern, sort_null_pattern);
03580 }
03581 static
03582 cpl_error_code xxx_table_sort(xxx_table *table, const uves_propertylist *reflist)
03583 {
03584 const char *fid = "xxx_table_sort";
03585 int *sort_pattern, *sort_null_pattern;
03586 cpl_error_code ec;
03587
03588 if (table == NULL || reflist == NULL)
03589 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
03590
03591 if (uves_propertylist_get_size(reflist) == 0)
03592 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
03593
03594 if (table->nr < 2)
03595 return CPL_ERROR_NONE;
03596
03597 sort_pattern = cpl_malloc(table->nr * sizeof(int));
03598 sort_null_pattern = cpl_malloc(table->nr * sizeof(int));
03599
03600 ec = table_sort(table, reflist, uves_propertylist_get_size(reflist),
03601 sort_pattern, sort_null_pattern);
03602
03603 cpl_free(sort_pattern);
03604 cpl_free(sort_null_pattern);
03605
03606 return ec;
03607 }
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625 static xxx_column_values *xxx_column_values_new(void)
03626 {
03627
03628 xxx_column_values *value = cpl_calloc(1, sizeof(xxx_column_values));
03629
03630
03631 value->i = NULL;
03632
03633 return value;
03634
03635 }
03636
03637
03638
03639
03640
03641
03642
03643
03644 static xxx_column_values *xxx_column_get_values(xxx_column *column)
03645 {
03646
03647 if (column)
03648 return column->values;
03649
03650 return NULL;
03651
03652 }
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669 static void xxx_column_values_delete(xxx_column_values *values,
03670 int length, cpl_type type)
03671 {
03672
03673 int i;
03674
03675
03676 if (values) {
03677 switch (type) {
03678 case CPL_TYPE_INT | CPL_TYPE_POINTER:
03679 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
03680 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
03681 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
03682
03683 for (i = 0; i < length; i++)
03684 cpl_array_delete(values->array[i]);
03685
03686 cpl_free((void *)values->array);
03687 cpl_free(values);
03688
03689 break;
03690
03691 case CPL_TYPE_STRING:
03692
03693 for (i = 0; i < length; i++)
03694 if (values->s[i])
03695 cpl_free(values->s[i]);
03696
03697 default:
03698
03699 if (values->s)
03700 cpl_free((void *)values->s);
03701
03702 cpl_free(values);
03703
03704 break;
03705
03706 }
03707 }
03708
03709 }
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730 static int xxx_column_unset_null(xxx_column *column, int row)
03731 {
03732
03733 int length;
03734
03735
03736 if (column->nullcount == 0)
03737 return 0;
03738
03739 if (!column->null)
03740 column->null = cpl_malloc(column->length * sizeof(xxx_column_flag));
03741
03742 length = column->length;
03743
03744 if (column->nullcount == length)
03745 while (length--)
03746 column->null[length] = 1;
03747
03748 if (column->null[row] == 1) {
03749 column->null[row] = 0;
03750 column->nullcount--;
03751 }
03752
03753 if (column->nullcount == 0) {
03754 if (column->null)
03755 cpl_free(column->null);
03756 column->null = NULL;
03757 }
03758
03759 return 0;
03760
03761 }
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782 static int xxx_column_unset_null_segment(xxx_column *column,
03783 int start, int count)
03784 {
03785
03786 int length = xxx_column_get_size(column);
03787
03788
03789 if (start == 0 && count == length) {
03790 if (column->null)
03791 cpl_free(column->null);
03792 column->null = NULL;
03793 column->nullcount = 0;
03794 }
03795
03796 if (column->nullcount == 0)
03797 return 0;
03798
03799 if (!column->null)
03800 column->null = cpl_malloc(length * sizeof(xxx_column_flag));
03801
03802 if (column->nullcount == length) {
03803 while (length--)
03804 column->null[length] = 1;
03805 memset(column->null + start, 0, count * sizeof(xxx_column_flag));
03806 column->nullcount -= count;
03807 }
03808 else {
03809 while (count--) {
03810 if (column->null[start] == 1) {
03811 column->null[start] = 0;
03812 column->nullcount--;
03813 }
03814 start++;
03815 }
03816 }
03817
03818 if (column->nullcount == 0) {
03819 if (column->null)
03820 cpl_free(column->null);
03821 column->null = NULL;
03822 }
03823
03824 return 0;
03825
03826 }
03827
03828
03829 void xxx_column_dump_structure(xxx_column *column)
03830 {
03831
03832 const char *name = xxx_column_get_name(column);
03833 const char *unit = xxx_column_get_unit(column);
03834 const char *format = xxx_column_get_format(column);
03835 cpl_type type = xxx_column_get_type(column);
03836 int length = xxx_column_get_size(column);
03837
03838
03839 if (column) {
03840
03841 printf("Column name : ");
03842
03843 if (name)
03844 printf("\"%s\"\n", name);
03845 else
03846 printf("NONE\n");
03847
03848 printf("Column unit : ");
03849
03850 if (unit)
03851 printf("\"%s\"\n", unit);
03852 else
03853 printf("NONE\n");
03854
03855 printf("Column format : ");
03856
03857 if (format)
03858 printf("\"%s\"\n", format);
03859 else
03860 printf("NONE\n");
03861
03862 printf("Column type : ");
03863
03864 switch (type) {
03865 case CPL_TYPE_INT:
03866 printf("int\n");
03867 break;
03868 case CPL_TYPE_FLOAT:
03869 printf("float\n");
03870 break;
03871 case CPL_TYPE_DOUBLE:
03872 printf("double\n");
03873 break;
03874 case CPL_TYPE_STRING:
03875 printf("string\n");
03876 break;
03877 default:
03878 printf("UNDEFINED\n");
03879 }
03880
03881 printf("Column length : %d\n", length);
03882
03883 printf("Column nulls : %d\n", xxx_column_count_invalid(column));
03884 printf(" (the NULL column %sexists)\n",
03885 column->null ? "" : "does not ");
03886
03887 }
03888 else {
03889 printf("Column is NULL\n");
03890 cpl_error_reset();
03891 }
03892
03893 }
03894
03895
03896 void xxx_column_dump(xxx_column *column, int start, int count)
03897 {
03898
03899 cpl_type type = xxx_column_get_type(column);
03900 int length = xxx_column_get_size(column);
03901 int nulls = xxx_column_count_invalid(column);
03902 int i = start;
03903
03904
03905 if (column) {
03906 if (start < length) {
03907
03908 if (count > length - start)
03909 count = length - start;
03910
03911 switch (type) {
03912 case CPL_TYPE_INT:
03913 if (nulls == 0) {
03914 while (count--) {
03915 printf("%d %d\n", i, column->values->i[i]);
03916 i++;
03917 }
03918 }
03919 else if (nulls == length) {
03920 while (count--) {
03921 printf("%d %d NULL\n", i, column->values->i[i]);
03922 i++;
03923 }
03924 }
03925 else {
03926 while (count--) {
03927 printf("%d %d %d\n", i,
03928 column->values->i[i], column->null[i]);
03929 i++;
03930 }
03931 }
03932 break;
03933 case CPL_TYPE_FLOAT:
03934 if (nulls == 0) {
03935 while (count--) {
03936 printf("%d %f\n", i, column->values->f[i]);
03937 i++;
03938 }
03939 }
03940 else if (nulls == length) {
03941 while (count--) {
03942 printf("%d %f NULL\n", i, column->values->f[i]);
03943 i++;
03944 }
03945 }
03946 else {
03947 while (count--) {
03948 printf("%d %f %d\n", i,
03949 column->values->f[i], column->null[i]);
03950 i++;
03951 }
03952 }
03953 break;
03954 case CPL_TYPE_DOUBLE:
03955 if (nulls == 0) {
03956 while (count--) {
03957 printf("%d %f\n", i, column->values->d[i]);
03958 i++;
03959 }
03960 }
03961 else if (nulls == length) {
03962 while (count--) {
03963 printf("%d %f NULL\n", i, column->values->d[i]);
03964 i++;
03965 }
03966 }
03967 else {
03968 while (count--) {
03969 printf("%d %f %d\n", i,
03970 column->values->d[i], column->null[i]);
03971 i++;
03972 }
03973 }
03974 break;
03975 case CPL_TYPE_STRING:
03976 while (count--) {
03977 printf("%d %s\n", i,
03978 column->values->s[i] ? column->values->s[i] : "NULL");
03979 i++;
03980 }
03981 break;
03982 default:
03983 break;
03984 }
03985 }
03986 }
03987 else {
03988 printf("Column is NULL\n");
03989 cpl_error_reset();
03990 }
03991
03992 }
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008 static xxx_column *xxx_column_new(cpl_type type)
04009 {
04010
04011 xxx_column *column = cpl_calloc(1, sizeof(xxx_column));
04012
04013
04014 column->values = xxx_column_values_new();
04015 column->name = NULL;
04016 column->unit = NULL;
04017 column->format = NULL;
04018 column->length = 0;
04019 column->depth = 0;
04020 column->type = type;
04021 column->null = NULL;
04022 column->nullcount = 0;
04023 column->dimensions = NULL;
04024
04025 return column;
04026
04027 }
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044 xxx_column *xxx_column_new_int(int length)
04045 {
04046
04047 const char *fid = "xxx_column_new_int";
04048 xxx_column *column;
04049
04050
04051 if (length < 0) {
04052 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04053 return NULL;
04054 }
04055
04056 column = xxx_column_new(CPL_TYPE_INT);
04057
04058 if (length)
04059 column->values->i = (int *)cpl_malloc(length * sizeof(int));
04060 else
04061 column->values->i = NULL;
04062
04063 column->format = cpl_strdup(INT_FORM);
04064 column->length = length;
04065 column->nullcount = length;
04066
04067 return column;
04068
04069 }
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083 xxx_column *xxx_column_new_float(int length)
04084 {
04085
04086 const char *fid = "xxx_column_new_float";
04087 xxx_column *column;
04088
04089
04090 if (length < 0) {
04091 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04092 return NULL;
04093 }
04094
04095 column = xxx_column_new(CPL_TYPE_FLOAT);
04096
04097 if (length)
04098 column->values->f = (float *)cpl_malloc(length * sizeof(float));
04099 else
04100 column->values->f = NULL;
04101
04102 column->format = cpl_strdup(FLOAT_FORM);
04103 column->length = length;
04104 column->nullcount = length;
04105
04106 return column;
04107
04108 }
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122 xxx_column *xxx_column_new_double(int length)
04123 {
04124
04125 const char *fid = "xxx_column_new_double";
04126 xxx_column *column;
04127
04128
04129 if (length < 0) {
04130 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04131 return NULL;
04132 }
04133
04134 column = xxx_column_new(CPL_TYPE_DOUBLE);
04135
04136 if (length)
04137 column->values->d = (double *)cpl_malloc(length * sizeof(double));
04138 else
04139 column->values->d = NULL;
04140
04141 column->format = cpl_strdup(DOUBLE_FORM);
04142 column->length = length;
04143 column->nullcount = length;
04144
04145 return column;
04146
04147 }
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165 xxx_column *xxx_column_new_string(int length)
04166 {
04167
04168 const char *fid = "xxx_column_new_string";
04169 xxx_column *column;
04170
04171
04172 if (length < 0) {
04173 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04174 return NULL;
04175 }
04176
04177 column = xxx_column_new(CPL_TYPE_STRING);
04178
04179 if (length)
04180 column->values->s = (char **)cpl_calloc(length, sizeof (char *));
04181 else
04182 column->values->s = NULL;
04183
04184 column->format = cpl_strdup(STRING_FORM);
04185 column->length = length;
04186
04187 return column;
04188
04189 }
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208 xxx_column *xxx_column_new_array(cpl_type type, int length, int depth)
04209 {
04210
04211 const char *fid = "xxx_column_new_array";
04212 xxx_column *column;
04213
04214
04215 if (length < 0 || depth < 0) {
04216 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04217 return NULL;
04218 }
04219
04220 column = xxx_column_new(type | CPL_TYPE_POINTER);
04221
04222 if (length)
04223 column->values->array = cpl_calloc(length, sizeof (cpl_array *));
04224 else
04225 column->values->array = NULL;
04226
04227 switch(type) {
04228 case CPL_TYPE_INT:
04229 case CPL_TYPE_INT | CPL_TYPE_POINTER:
04230 column->format = cpl_strdup(INT_FORM);
04231 break;
04232 case CPL_TYPE_FLOAT:
04233 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
04234 column->format = cpl_strdup(FLOAT_FORM);
04235 break;
04236 case CPL_TYPE_DOUBLE:
04237 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
04238 column->format = cpl_strdup(DOUBLE_FORM);
04239 break;
04240 case CPL_TYPE_STRING:
04241 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
04242 column->format = cpl_strdup(STRING_FORM);
04243 break;
04244 default:
04245 xxx_column_delete(column);
04246 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
04247 return NULL;
04248 }
04249
04250 column->length = length;
04251 column->depth = depth;
04252
04253 return column;
04254
04255 }
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289 xxx_column *xxx_column_wrap_int(int *data, int length)
04290 {
04291
04292 const char *fid = "xxx_column_wrap_int";
04293 xxx_column *column;
04294
04295
04296 if (data == 0x0) {
04297 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04298 return NULL;
04299 }
04300
04301 if (length <= 0) {
04302 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04303 return NULL;
04304 }
04305
04306 column = xxx_column_new(CPL_TYPE_INT);
04307
04308 column->format = cpl_strdup(INT_FORM);
04309 column->length = length;
04310 column->values->i = data;
04311
04312 return column;
04313
04314 }
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329 xxx_column *xxx_column_wrap_float(float *data, int length)
04330 {
04331
04332 const char *fid = "xxx_column_wrap_float";
04333 xxx_column *column;
04334
04335
04336 if (data == 0x0) {
04337 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04338 return NULL;
04339 }
04340
04341 if (length <= 0) {
04342 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04343 return NULL;
04344 }
04345
04346 column = xxx_column_new(CPL_TYPE_FLOAT);
04347
04348 column->format = cpl_strdup(FLOAT_FORM);
04349 column->length = length;
04350 column->values->f = data;
04351
04352 return column;
04353
04354 }
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369 xxx_column *xxx_column_wrap_double(double *data, int length)
04370 {
04371
04372 const char *fid = "xxx_column_wrap_double";
04373 xxx_column *column;
04374
04375
04376 if (data == 0x0) {
04377 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04378 return NULL;
04379 }
04380
04381 if (length <= 0) {
04382 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04383 return NULL;
04384 }
04385
04386 column = xxx_column_new(CPL_TYPE_DOUBLE);
04387
04388 column->format = cpl_strdup(DOUBLE_FORM);
04389 column->length = length;
04390 column->values->d = data;
04391
04392 return column;
04393
04394 }
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409 xxx_column *xxx_column_wrap_string(char **data, int length)
04410 {
04411
04412 const char *fid = "xxx_column_wrap_string";
04413 xxx_column *column;
04414
04415
04416 if (data == 0x0) {
04417 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04418 return NULL;
04419 }
04420
04421 if (length <= 0) {
04422 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
04423 return NULL;
04424 }
04425
04426 column = xxx_column_new(CPL_TYPE_STRING);
04427
04428 column->format = cpl_strdup(STRING_FORM);
04429 column->length = length;
04430 column->values->s = data;
04431
04432 return column;
04433
04434 }
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459 cpl_error_code xxx_column_copy_data(xxx_column *column, const double *data)
04460 {
04461
04462 const char *fid = "xxx_column_copy_data";
04463 int length = xxx_column_get_size(column);
04464 cpl_type type = xxx_column_get_type(column);
04465 int *idata;
04466 float *fdata;
04467
04468
04469 if (data == 0x0 || column == 0x0)
04470 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04471
04472 if (length == 0)
04473 return CPL_ERROR_NONE;
04474
04475
04476 switch (type) {
04477 case CPL_TYPE_INT:
04478 idata = xxx_column_get_data_int(column);
04479 while (length--)
04480 *idata++ = *data++;
04481 break;
04482 case CPL_TYPE_FLOAT:
04483 fdata = xxx_column_get_data_float(column);
04484 while (length--)
04485 *fdata++ = *data++;
04486 break;
04487 case CPL_TYPE_DOUBLE:
04488 memcpy(column->values->d, data, column->length * sizeof(double));
04489 break;
04490 default:
04491 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
04492 }
04493
04494 if (column->null)
04495 cpl_free(column->null);
04496 column->null = NULL;
04497 column->nullcount = 0;
04498
04499 return CPL_ERROR_NONE;
04500
04501 }
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524 cpl_error_code xxx_column_copy_data_int(xxx_column *column, const int *data)
04525 {
04526
04527 const char *fid = "xxx_column_copy_data_int";
04528 cpl_type type = xxx_column_get_type(column);
04529
04530
04531 if (data == 0x0 || column == 0x0)
04532 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04533
04534 if (type != CPL_TYPE_INT)
04535 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
04536
04537 if (column->length == 0)
04538 return CPL_ERROR_NONE;
04539
04540 memcpy(column->values->i, data, column->length * sizeof(int));
04541
04542 if (column->null)
04543 cpl_free(column->null);
04544 column->null = NULL;
04545 column->nullcount = 0;
04546
04547 return CPL_ERROR_NONE;
04548
04549 }
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566 cpl_error_code xxx_column_copy_data_float(xxx_column *column,
04567 const float *data)
04568 {
04569
04570 const char *fid = "xxx_column_copy_data_float";
04571 cpl_type type = xxx_column_get_type(column);
04572
04573
04574 if (data == 0x0 || column == 0x0)
04575 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04576
04577 if (type != CPL_TYPE_FLOAT)
04578 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
04579
04580 if (column->length == 0)
04581 return CPL_ERROR_NONE;
04582
04583 memcpy(column->values->f, data, column->length * sizeof(float));
04584
04585 if (column->null)
04586 cpl_free(column->null);
04587 column->null = NULL;
04588 column->nullcount = 0;
04589
04590 return CPL_ERROR_NONE;
04591
04592 }
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609 cpl_error_code xxx_column_copy_data_double(xxx_column *column,
04610 const double *data)
04611 {
04612
04613 const char *fid = "xxx_column_copy_data_double";
04614 cpl_type type = xxx_column_get_type(column);
04615
04616
04617 if (data == 0x0 || column == 0x0)
04618 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04619
04620 if (type != CPL_TYPE_DOUBLE)
04621 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
04622
04623 if (column->length == 0)
04624 return CPL_ERROR_NONE;
04625
04626 memcpy(column->values->d, data, column->length * sizeof(double));
04627
04628 if (column->null)
04629 cpl_free(column->null);
04630 column->null = NULL;
04631 column->nullcount = 0;
04632
04633 return CPL_ERROR_NONE;
04634
04635 }
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660 cpl_error_code xxx_column_copy_data_string(xxx_column *column,
04661 const char **data)
04662 {
04663
04664 const char *fid = "xxx_column_copy_data_string";
04665 cpl_type type = xxx_column_get_type(column);
04666 int length = xxx_column_get_size(column);
04667
04668
04669 if (data == 0x0 || column == 0x0)
04670 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04671
04672 if (type != CPL_TYPE_STRING)
04673 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
04674
04675
04676 while (length--) {
04677 if (column->values->s[length])
04678 cpl_free(column->values->s[length]);
04679 if (data[length])
04680 column->values->s[length] = cpl_strdup((char *)data[length]);
04681 else
04682 column->values->s[length] = NULL;
04683 }
04684
04685 return CPL_ERROR_NONE;
04686
04687 }
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702 void xxx_column_delete(xxx_column *column)
04703 {
04704
04705 cpl_type type;
04706 xxx_column_values *values;
04707 int length;
04708
04709
04710 if (column != NULL) {
04711 type = xxx_column_get_type(column);
04712 values = xxx_column_get_values(column);
04713 length = xxx_column_get_size(column);
04714
04715 xxx_column_values_delete(values, length, type);
04716 if (column->name)
04717 cpl_free(column->name);
04718 if (column->unit)
04719 cpl_free(column->unit);
04720 if (column->format)
04721 cpl_free(column->format);
04722 if (column->null)
04723 cpl_free(column->null);
04724 if (column->dimensions)
04725 cpl_array_delete(column->dimensions);
04726 cpl_free(column);
04727 }
04728
04729 }
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747 void *xxx_column_unwrap(xxx_column *column)
04748 {
04749
04750 cpl_type type;
04751 xxx_column_values *values;
04752 void *d = NULL;
04753
04754
04755 if (column != NULL) {
04756 type = xxx_column_get_type(column);
04757 values = xxx_column_get_values(column);
04758 d = (void *)values->i;
04759 cpl_free(values);
04760 if (column->name)
04761 cpl_free(column->name);
04762 if (column->unit)
04763 cpl_free(column->unit);
04764 if (column->format)
04765 cpl_free(column->format);
04766 if (column->null)
04767 cpl_free(column->null);
04768 if (column->dimensions)
04769 cpl_array_delete(column->dimensions);
04770 cpl_free(column);
04771 }
04772
04773 return d;
04774
04775 }
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794 void xxx_column_delete_but_strings(xxx_column *column)
04795 {
04796
04797 cpl_type type;
04798 xxx_column_values *values;
04799
04800
04801 if (column == NULL)
04802 return;
04803
04804 type = xxx_column_get_type(column);
04805
04806 if (type == CPL_TYPE_STRING) {
04807 values = xxx_column_get_values(column);
04808 if (values->s)
04809 cpl_free(values->s);
04810 if (values)
04811 cpl_free(values);
04812 if (column->name)
04813 cpl_free(column->name);
04814 if (column->unit)
04815 cpl_free(column->unit);
04816 if (column->format)
04817 cpl_free(column->format);
04818 if (column->null)
04819 cpl_free(column->null);
04820 cpl_free(column);
04821 }
04822 else
04823 cpl_error_set("xxx_column_delete_but_strings", CPL_ERROR_INVALID_TYPE);
04824
04825 }
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844 void xxx_column_delete_but_arrays(xxx_column *column)
04845 {
04846
04847 cpl_type type;
04848 xxx_column_values *values;
04849
04850
04851 if (column == NULL)
04852 return;
04853
04854 type = xxx_column_get_type(column);
04855
04856 if (type & CPL_TYPE_POINTER) {
04857 values = xxx_column_get_values(column);
04858 if (values->array)
04859 cpl_free(values->array);
04860 if (values)
04861 cpl_free(values);
04862 if (column->name)
04863 cpl_free(column->name);
04864 if (column->unit)
04865 cpl_free(column->unit);
04866 if (column->format)
04867 cpl_free(column->format);
04868 if (column->null)
04869 cpl_free(column->null);
04870 if (column->dimensions)
04871 cpl_array_delete(column->dimensions);
04872 cpl_free(column);
04873 }
04874 else
04875 cpl_error_set("xxx_column_delete_but_arrays", CPL_ERROR_INVALID_TYPE);
04876
04877 }
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894 cpl_error_code xxx_column_set_name(xxx_column *column, const char *name)
04895 {
04896
04897 const char *fid = "xxx_column_set_name";
04898
04899
04900 if (column == 0x0)
04901 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
04902
04903 if (column->name)
04904 cpl_free(column->name);
04905
04906 if (name)
04907 column->name = cpl_strdup((char *)name);
04908 else
04909 column->name = NULL;
04910
04911 return CPL_ERROR_NONE;
04912
04913 }
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935 const char *xxx_column_get_name(xxx_column *column)
04936 {
04937
04938 if (column)
04939 return column->name;
04940
04941 cpl_error_set("xxx_column_get_name", CPL_ERROR_NULL_INPUT);
04942
04943 return NULL;
04944
04945 }
04946
04947
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964 cpl_error_code xxx_column_set_unit(xxx_column *column, const char *unit)
04965 {
04966
04967 if (column == 0x0)
04968 return cpl_error_set("xxx_column_set_unit", CPL_ERROR_NULL_INPUT);
04969
04970 if (column->unit)
04971 cpl_free(column->unit);
04972
04973 if (unit)
04974 column->unit = cpl_strdup((char *)unit);
04975 else
04976 column->unit = NULL;
04977
04978 return CPL_ERROR_NONE;
04979
04980 }
04981
04982
04983
04984
04985
04986
04987
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002 const char *xxx_column_get_unit(xxx_column *column)
05003 {
05004
05005 if (column)
05006 return column->unit;
05007
05008 cpl_error_set("xxx_column_get_unit", CPL_ERROR_NULL_INPUT);
05009
05010 return NULL;
05011
05012 }
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033 cpl_error_code xxx_column_set_format(xxx_column *column, const char *format)
05034 {
05035
05036 const char *fid = "xxx_column_set_format";
05037 cpl_type type;
05038
05039
05040 if (column == 0x0)
05041 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
05042
05043 type = xxx_column_get_type(column);
05044
05045 if (column->format)
05046 cpl_free(column->format);
05047
05048 if (format)
05049 column->format = cpl_strdup((char *)format);
05050 else
05051 switch (type) {
05052 case CPL_TYPE_INT:
05053 case CPL_TYPE_INT | CPL_TYPE_POINTER:
05054 column->format = cpl_strdup(INT_FORM);
05055 break;
05056 case CPL_TYPE_FLOAT:
05057 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
05058 column->format = cpl_strdup(FLOAT_FORM);
05059 break;
05060 case CPL_TYPE_DOUBLE:
05061 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
05062 column->format = cpl_strdup(DOUBLE_FORM);
05063 break;
05064 case CPL_TYPE_STRING:
05065 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
05066 column->format = cpl_strdup(STRING_FORM);
05067 break;
05068 default:
05069 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
05070 }
05071
05072 return CPL_ERROR_NONE;
05073
05074 }
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096 const char *xxx_column_get_format(xxx_column *column)
05097 {
05098
05099 if (column)
05100 return column->format;
05101
05102 cpl_error_set("xxx_column_get_format", CPL_ERROR_NULL_INPUT);
05103
05104 return NULL;
05105
05106 }
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120 int xxx_column_get_depth(xxx_column *column)
05121 {
05122
05123 if (column)
05124 return column->depth;
05125
05126 cpl_error_set("xxx_column_get_depth", CPL_ERROR_NULL_INPUT);
05127
05128 return 0;
05129
05130 }
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147 int xxx_column_get_dimensions(xxx_column *column)
05148 {
05149
05150 if (column) {
05151 if (xxx_column_get_type(column) & CPL_TYPE_POINTER)
05152 if (column->dimensions)
05153 return cpl_array_get_size(column->dimensions);
05154 return 1;
05155 }
05156
05157 cpl_error_set("xxx_column_get_dimensions", CPL_ERROR_NULL_INPUT);
05158
05159 return 0;
05160
05161 }
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183 cpl_error_code xxx_column_set_dimensions(xxx_column *column,
05184 cpl_array *dimensions)
05185 {
05186 const char *fid = "xxx_column_set_dimensions";
05187
05188 cpl_type type;
05189 int ndim;
05190 int size = 1;
05191
05192 if (column == NULL || dimensions == NULL)
05193 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
05194
05195 type = xxx_column_get_type(column);
05196
05197 if (type & CPL_TYPE_POINTER) {
05198 type = cpl_array_get_type(dimensions);
05199
05200 if (!(type & CPL_TYPE_INT))
05201 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05202
05203 ndim = cpl_array_get_size(dimensions);
05204
05205 if (ndim < 2)
05206 return CPL_ERROR_NONE;
05207
05208 if (cpl_array_has_invalid(dimensions))
05209 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
05210
05211 while (ndim--)
05212 size *= cpl_array_get(dimensions, ndim, NULL);
05213
05214 if (size != column->depth)
05215 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
05216
05217 if (column->dimensions)
05218 cpl_array_delete(column->dimensions);
05219
05220 column->dimensions = cpl_array_duplicate(dimensions);
05221 }
05222 else
05223 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
05224
05225 return CPL_ERROR_NONE;
05226
05227 }
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245
05246
05247 int xxx_column_get_dimension(xxx_column *column, int indx)
05248 {
05249 const char *fid = "xxx_column_get_dimension";
05250
05251 cpl_type type;
05252 int ndim;
05253
05254
05255 if (column == NULL) {
05256 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
05257 return 0;
05258 }
05259
05260 if (indx < 0) {
05261 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
05262 return 0;
05263 }
05264
05265 type = xxx_column_get_type(column);
05266
05267 if (type & CPL_TYPE_POINTER) {
05268
05269 if (column->dimensions)
05270 ndim = cpl_array_get_size(column->dimensions);
05271 else
05272 ndim = 1;
05273
05274 if (indx >= ndim) {
05275 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
05276 return 0;
05277 }
05278
05279 if (ndim > 1)
05280 return cpl_array_get(column->dimensions, indx, NULL);
05281 else
05282 return column->depth;
05283
05284 }
05285
05286 return cpl_error_set(fid, CPL_ERROR_UNSUPPORTED_MODE);
05287
05288
05289
05290 }
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311 int xxx_column_is_invalid(xxx_column *column, int indx)
05312 {
05313
05314 const char *fid = "xxx_column_is_invalid";
05315 cpl_type type = xxx_column_get_type(column);
05316 int length = xxx_column_get_size(column);
05317
05318
05319 if (column == 0x0) {
05320 cpl_error_set_where(fid);
05321 return 0;
05322 }
05323
05324 if (indx < 0 || indx >= length) {
05325 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
05326 return 0;
05327 }
05328
05329 if (type == CPL_TYPE_STRING)
05330 return (column->values->s[indx] == NULL);
05331 if (type & CPL_TYPE_POINTER)
05332 return (column->values->array[indx] == NULL);
05333 if (column->nullcount == 0)
05334 return 0;
05335 if (column->nullcount == length)
05336 return 1;
05337
05338 return column->null[indx];
05339
05340 }
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359 int xxx_column_has_invalid(xxx_column *column)
05360 {
05361
05362 cpl_type type = xxx_column_get_type(column);
05363 int length = xxx_column_get_size(column);
05364
05365
05366 if (column == 0x0) {
05367 cpl_error_set_where("xxx_column_has_invalid");
05368 return -1;
05369 }
05370
05371 if (type == CPL_TYPE_STRING) {
05372 while (length--)
05373 if (column->values->s[length] == NULL)
05374 return 1;
05375 return 0;
05376 }
05377 if (type & CPL_TYPE_POINTER) {
05378 while (length--)
05379 if (column->values->array[length] == NULL)
05380 return 1;
05381 return 0;
05382 }
05383
05384 return (column->nullcount > 0 ? 1 : 0);
05385
05386 }
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400
05401
05402 int xxx_column_has_valid(xxx_column *column)
05403 {
05404
05405 const char *fid = "xxx_column_has_valid";
05406 cpl_type type = xxx_column_get_type(column);
05407 int length = xxx_column_get_size(column);
05408
05409
05410 if (column == 0x0) {
05411 cpl_error_set_where(fid);
05412 return -1;
05413 }
05414
05415 if (type == CPL_TYPE_STRING) {
05416
05417 while (length--)
05418 if (column->values->s[length])
05419 return 1;
05420 return 0;
05421
05422 }
05423 if (type & CPL_TYPE_POINTER) {
05424
05425 while (length--)
05426 if (column->values->array[length])
05427 return 1;
05428 return 0;
05429
05430 }
05431
05432 return (column->nullcount < length ? 1 : 0);
05433
05434 }
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453 int xxx_column_count_invalid(xxx_column *column)
05454 {
05455
05456 cpl_type type = xxx_column_get_type(column);
05457 int length = xxx_column_get_size(column);
05458 char **p;
05459 cpl_array **a;
05460
05461
05462 if (column == 0x0) {
05463 cpl_error_set_where("xxx_column_count_invalid");
05464 return -1;
05465 }
05466
05467 if (type == CPL_TYPE_STRING) {
05468
05469 p = column->values->s;
05470
05471 column->nullcount = 0;
05472 while (length--)
05473 if (*p++ == NULL)
05474 column->nullcount++;
05475
05476 }
05477
05478 if (type & CPL_TYPE_POINTER) {
05479
05480 a = column->values->array;
05481
05482 column->nullcount = 0;
05483 while (length--)
05484 if (*a++ == NULL)
05485 column->nullcount++;
05486
05487 }
05488
05489 return column->nullcount;
05490
05491 }
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514 int *xxx_column_get_data_int(xxx_column *column)
05515 {
05516
05517 const char *fid = "xxx_column_get_data_int";
05518 cpl_type type = xxx_column_get_type(column);
05519
05520
05521 if (column == 0x0) {
05522 cpl_error_set_where(fid);
05523 return NULL;
05524 }
05525
05526 if (type == CPL_TYPE_INT)
05527 return column->values->i;
05528
05529 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05530
05531 return NULL;
05532
05533 }
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552 float *xxx_column_get_data_float(xxx_column *column)
05553 {
05554
05555 const char *fid = "xxx_column_get_data_float";
05556 cpl_type type = xxx_column_get_type(column);
05557
05558
05559 if (column == 0x0) {
05560 cpl_error_set_where(fid);
05561 return NULL;
05562 }
05563
05564 if (type == CPL_TYPE_FLOAT)
05565 return column->values->f;
05566
05567 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05568
05569 return NULL;
05570
05571 }
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590 double *xxx_column_get_data_double(xxx_column *column)
05591 {
05592
05593 const char *fid = "xxx_column_get_data_double";
05594 cpl_type type = xxx_column_get_type(column);
05595
05596
05597 if (column == 0x0) {
05598 cpl_error_set_where(fid);
05599 return NULL;
05600 }
05601
05602 if (type == CPL_TYPE_DOUBLE)
05603 return column->values->d;
05604
05605 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05606
05607 return NULL;
05608
05609 }
05610
05611
05612
05613
05614
05615
05616
05617
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628 char **xxx_column_get_data_string(xxx_column *column)
05629 {
05630
05631 const char *fid = "xxx_column_get_data_string";
05632 cpl_type type = xxx_column_get_type(column);
05633
05634
05635 if (column == 0x0) {
05636 cpl_error_set_where(fid);
05637 return NULL;
05638 }
05639
05640 if (type == CPL_TYPE_STRING)
05641 return column->values->s;
05642
05643 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05644
05645 return NULL;
05646
05647 }
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666 cpl_array **xxx_column_get_data_array(xxx_column *column)
05667 {
05668
05669 const char *fid = "xxx_column_get_data_array";
05670 cpl_type type = xxx_column_get_type(column);
05671
05672
05673 if (column == 0x0) {
05674 cpl_error_set_where(fid);
05675 return NULL;
05676 }
05677
05678 if (type & CPL_TYPE_POINTER)
05679 return column->values->array;
05680
05681 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
05682
05683 return NULL;
05684
05685 }
05686
05687
05688
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709 xxx_column_flag *xxx_column_get_data_invalid(xxx_column *column)
05710 {
05711
05712 if (column == 0x0) {
05713 cpl_error_set("xxx_column_get_data_invalid", CPL_ERROR_NULL_INPUT);
05714 return NULL;
05715 }
05716
05717 return column->null;
05718
05719 }
05720
05721
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755 cpl_error_code xxx_column_set_data_invalid(xxx_column *column,
05756 xxx_column_flag *nulls, int nullcount)
05757 {
05758
05759 const char *fid = "xxx_column_set_data_invalid";
05760 cpl_type type = xxx_column_get_type(column);
05761 int length = xxx_column_get_size(column);
05762
05763
05764 if (column == 0x0)
05765 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
05766
05767 if (type == CPL_TYPE_STRING)
05768 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
05769
05770 if (type & CPL_TYPE_POINTER)
05771 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
05772
05773 if (nullcount > length)
05774 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
05775
05776 if (nulls)
05777 while (length--)
05778 if (nulls[length] != 0)
05779 if (nulls[length] != 1)
05780 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
05781
05782 length = xxx_column_get_size(column);
05783
05784 if (nullcount < 0) {
05785
05786
05787
05788
05789
05790
05791
05792 if (nulls) {
05793 nullcount = 0;
05794 while (length--)
05795 nullcount += nulls[length];
05796 }
05797 else {
05798 nullcount = 0;
05799 }
05800 }
05801
05802
05803
05804
05805
05806
05807
05808 if (!nulls)
05809 if (nullcount != length && nullcount != 0)
05810 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
05811
05812
05813
05814
05815
05816
05817 if (nullcount == length || nullcount == 0)
05818 nulls = NULL;
05819
05820 if (column->null)
05821 cpl_free(column->null);
05822
05823 column->null = nulls;
05824 column->nullcount = nullcount;
05825
05826 return 0;
05827
05828 }
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841
05842
05843
05844
05845
05846
05847
05848
05849
05850
05851
05852
05853
05854
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877 cpl_error_code xxx_column_set_size(xxx_column *column, int new_length)
05878 {
05879
05880 const char *fid = "xxx_column_set_size";
05881 cpl_type type = xxx_column_get_type(column);
05882 int old_length = xxx_column_get_size(column);
05883 int element_size = xxx_column_type_size(type);
05884 int null_size = old_length * sizeof(xxx_column_flag);
05885 int new_size = element_size * new_length;
05886 int i = 0;
05887
05888 xxx_column_flag *np = NULL;
05889 char **sp;
05890 cpl_array **ap;
05891
05892
05893 if (column == 0x0)
05894 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
05895
05896 if (new_length < 0)
05897 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
05898
05899 if (new_length == old_length)
05900 return CPL_ERROR_NONE;
05901
05902 if (new_length == 0) {
05903
05904 switch (type) {
05905 case CPL_TYPE_INT | CPL_TYPE_POINTER:
05906 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
05907 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
05908 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
05909
05910 for (i = 0; i < old_length; i++)
05911 if (column->values->array[i])
05912 cpl_array_delete(column->values->array[i]);
05913
05914 cpl_free((void *)column->values->array);
05915
05916 break;
05917
05918 case CPL_TYPE_STRING:
05919
05920 for (i = 0; i < old_length; i++)
05921 if (column->values->s[i])
05922 cpl_free(column->values->s[i]);
05923
05924 default:
05925
05926 if (column->values->s)
05927 cpl_free((void *)column->values->s);
05928
05929 break;
05930
05931 }
05932
05933 column->values->i = NULL;
05934 if (column->null)
05935 cpl_free(column->null);
05936 column->null = NULL;
05937 column->nullcount = 0;
05938 column->length = 0;
05939
05940 return CPL_ERROR_NONE;
05941 }
05942
05943 if (old_length == 0) {
05944
05945 switch (type) {
05946 case CPL_TYPE_INT:
05947 column->values->i = cpl_malloc(new_length * sizeof(int));
05948 break;
05949 case CPL_TYPE_FLOAT:
05950 column->values->f = cpl_malloc(new_length * sizeof(float));
05951 break;
05952 case CPL_TYPE_DOUBLE:
05953 column->values->d = cpl_malloc(new_length * sizeof(double));
05954 break;
05955 case CPL_TYPE_STRING:
05956 column->values->s = cpl_calloc(new_length, sizeof(char *));
05957 break;
05958 case CPL_TYPE_INT | CPL_TYPE_POINTER:
05959 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
05960 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
05961 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
05962 column->values->array = cpl_calloc(new_length, sizeof(cpl_array *));
05963 break;
05964 default:
05965 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
05966 }
05967
05968 column->length = new_length;
05969
05970 if (type != CPL_TYPE_STRING && !(type & CPL_TYPE_POINTER))
05971 column->nullcount = new_length;
05972
05973 return CPL_ERROR_NONE;
05974 }
05975
05976
05977
05978
05979
05980
05981 if (column->null) {
05982
05983
05984
05985
05986
05987
05988 null_size = new_length * sizeof(xxx_column_flag);
05989 column->null = cpl_realloc((void *)column->null, null_size);
05990
05991 if (new_length < old_length) {
05992
05993
05994
05995
05996
05997
05998
05999 column->nullcount = 0;
06000 np = column->null;
06001 for (i = 0; i < new_length; i++)
06002 if (*np++)
06003 column->nullcount++;
06004
06005 if (column->nullcount == new_length ||
06006 column->nullcount == 0) {
06007 if (column->null)
06008 cpl_free(column->null);
06009 column->null = NULL;
06010 }
06011 }
06012 else {
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022 np = column->null + old_length;
06023 for (i = old_length; i < new_length; i++)
06024 *np++ = 1;
06025
06026 column->nullcount += new_length - old_length;
06027
06028 }
06029 }
06030 else {
06031
06032
06033
06034
06035
06036
06037 if (type != CPL_TYPE_STRING) {
06038
06039 if (new_length > old_length) {
06040
06041
06042
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052 if (column->nullcount == 0) {
06053
06054 column->null = cpl_calloc(new_length,
06055 sizeof(xxx_column_flag));
06056
06057 np = column->null + old_length;
06058 for (i = old_length; i < new_length; i++)
06059 *np++ = 1;
06060
06061 column->nullcount = new_length - old_length;
06062 }
06063 else
06064 column->nullcount = new_length;
06065 }
06066 else if (column->nullcount)
06067 column->nullcount = new_length;
06068
06069 }
06070 }
06071
06072
06073
06074
06075
06076
06077 if (type == CPL_TYPE_STRING)
06078 for (i = new_length; i < old_length; i++)
06079 if (column->values->s[i])
06080 cpl_free(column->values->s[i]);
06081
06082 if (type & CPL_TYPE_POINTER)
06083 for (i = new_length; i < old_length; i++)
06084 if (column->values->array[i])
06085 cpl_array_delete(column->values->array[i]);
06086
06087
06088
06089
06090
06091 column->values->i = cpl_realloc((void *)column->values->i, new_size);
06092 column->length = new_length;
06093
06094
06095
06096
06097
06098
06099 if (type == CPL_TYPE_STRING) {
06100 sp = column->values->s + old_length;
06101 for (i = old_length; i < new_length; i++)
06102 *sp++ = 0x0;
06103 }
06104
06105 if (type & CPL_TYPE_POINTER) {
06106 ap = column->values->array + old_length;
06107 for (i = old_length; i < new_length; i++)
06108 *ap++ = 0x0;
06109 }
06110
06111 return CPL_ERROR_NONE;
06112
06113 }
06114
06115
06116
06117
06118
06119
06120
06121
06122
06123
06124
06125
06126
06127
06128
06129
06130
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140 double xxx_column_get(xxx_column *column, int indx, int *null)
06141 {
06142
06143 const char *fid = "xxx_column_get";
06144 cpl_type type = xxx_column_get_type(column);
06145
06146
06147 if (null)
06148 *null = -1;
06149
06150 switch (type) {
06151 case CPL_TYPE_INT:
06152 return (double)xxx_column_get_int(column, indx, null);
06153 case CPL_TYPE_FLOAT:
06154 return (double)xxx_column_get_float(column, indx, null);
06155 case CPL_TYPE_DOUBLE:
06156 return xxx_column_get_double(column, indx, null);
06157 case CPL_TYPE_INT | CPL_TYPE_POINTER:
06158 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
06159 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
06160 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
06161 case CPL_TYPE_STRING:
06162 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
06163 break;
06164 default:
06165 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06166 }
06167
06168 return 0.0;
06169
06170 }
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182
06183
06184
06185
06186
06187
06188
06189
06190
06191
06192
06193
06194
06195 int xxx_column_get_int(xxx_column *column, int indx, int *null)
06196 {
06197
06198 const char *fid = "xxx_column_get_int";
06199 int isnull = xxx_column_is_invalid(column, indx);
06200 int length = xxx_column_get_size(column);
06201 cpl_type type = xxx_column_get_type(column);
06202
06203
06204 if (null)
06205 *null = -1;
06206
06207 if (column == 0x0) {
06208 cpl_error_set_where(fid);
06209 return 0;
06210 }
06211
06212 if (indx < 0 || indx >= length) {
06213 cpl_error_set_where(fid);
06214 return 0;
06215 }
06216
06217 if (type != CPL_TYPE_INT) {
06218 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06219 return 0;
06220 }
06221
06222 if (null)
06223 *null = isnull;
06224
06225 if (isnull)
06226 return 0;
06227
06228 return column->values->i[indx];
06229
06230 }
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248 float xxx_column_get_float(xxx_column *column, int indx, int *null)
06249 {
06250
06251 const char *fid = "xxx_column_get_float";
06252 int isnull = xxx_column_is_invalid(column, indx);
06253 int length = xxx_column_get_size(column);
06254 cpl_type type = xxx_column_get_type(column);
06255
06256
06257 if (null)
06258 *null = -1;
06259
06260 if (column == 0x0) {
06261 cpl_error_set_where(fid);
06262 return 0;
06263 }
06264
06265 if (indx < 0 || indx >= length) {
06266 cpl_error_set_where(fid);
06267 return 0;
06268 }
06269
06270 if (type != CPL_TYPE_FLOAT) {
06271 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06272 return 0;
06273 }
06274
06275 if (null)
06276 *null = isnull;
06277
06278 if (isnull)
06279 return 0;
06280
06281 return column->values->f[indx];
06282
06283 }
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301
06302 double xxx_column_get_double(xxx_column *column, int indx, int *null)
06303 {
06304
06305 const char *fid = "xxx_column_get_double";
06306 int isnull = xxx_column_is_invalid(column, indx);
06307 int length = xxx_column_get_size(column);
06308 cpl_type type = xxx_column_get_type(column);
06309
06310
06311 if (null)
06312 *null = -1;
06313
06314 if (column == 0x0) {
06315 cpl_error_set_where(fid);
06316 return 0;
06317 }
06318
06319 if (indx < 0 || indx >= length) {
06320 cpl_error_set_where(fid);
06321 return 0;
06322 }
06323
06324 if (type != CPL_TYPE_DOUBLE) {
06325 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06326 return 0;
06327 }
06328
06329 if (null)
06330 *null = isnull;
06331
06332 if (isnull)
06333 return 0;
06334
06335 return column->values->d[indx];
06336
06337 }
06338
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349
06350
06351
06352
06353
06354
06355
06356
06357
06358
06359
06360
06361
06362
06363
06364
06365
06366 const char *xxx_column_get_string(xxx_column *column, int indx)
06367 {
06368
06369 const char *fid = "xxx_column_get_string";
06370 int length = xxx_column_get_size(column);
06371 cpl_type type = xxx_column_get_type(column);
06372
06373
06374 if (column == 0x0) {
06375 cpl_error_set_where(fid);
06376 return NULL;
06377 }
06378
06379 if (indx < 0 || indx >= length) {
06380 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06381 return NULL;
06382 }
06383
06384 if (type != CPL_TYPE_STRING) {
06385 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06386 return NULL;
06387 }
06388
06389 return column->values->s[indx];
06390
06391 }
06392
06393
06394
06395
06396
06397
06398
06399
06400
06401
06402
06403
06404
06405
06406
06407
06408
06409
06410
06411
06412
06413
06414
06415
06416
06417
06418
06419
06420 const cpl_array *xxx_column_get_array(xxx_column *column, int indx)
06421 {
06422
06423 const char *fid = "xxx_column_get_array";
06424 int length = xxx_column_get_size(column);
06425 cpl_type type = xxx_column_get_type(column);
06426
06427
06428 if (column == 0x0) {
06429 cpl_error_set_where(fid);
06430 return NULL;
06431 }
06432
06433 if (indx < 0 || indx >= length) {
06434 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06435 return NULL;
06436 }
06437
06438 if (!(type & CPL_TYPE_POINTER)) {
06439 cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06440 return NULL;
06441 }
06442
06443 return column->values->array[indx];
06444
06445 }
06446
06447
06448
06449
06450
06451
06452
06453
06454
06455
06456
06457
06458
06459
06460
06461
06462
06463
06464
06465
06466
06467
06468
06469
06470 cpl_error_code xxx_column_set(xxx_column *column, int indx, double value)
06471 {
06472
06473 const char *fid = "xxx_column_set";
06474 cpl_type type = xxx_column_get_type(column);
06475
06476
06477 switch (type) {
06478 case CPL_TYPE_INT:
06479 return xxx_column_set_int(column, indx, value);
06480 case CPL_TYPE_FLOAT:
06481 return xxx_column_set_float(column, indx, value);
06482 case CPL_TYPE_DOUBLE:
06483 return xxx_column_set_double(column, indx, value);
06484 case CPL_TYPE_INT | CPL_TYPE_POINTER:
06485 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
06486 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
06487 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
06488 case CPL_TYPE_STRING:
06489 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
06490 default:
06491 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06492 }
06493
06494 }
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513
06514
06515
06516
06517
06518 cpl_error_code xxx_column_set_int(xxx_column *column, int indx, int value)
06519 {
06520
06521 const char *fid = "xxx_column_set_int";
06522 int length = xxx_column_get_size(column);
06523 cpl_type type = xxx_column_get_type(column);
06524
06525
06526 if (column == 0x0)
06527 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06528
06529 if (indx < 0 || indx >= length)
06530 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06531
06532 if (type != CPL_TYPE_INT)
06533 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06534
06535 column->values->i[indx] = value;
06536 xxx_column_unset_null(column, indx);
06537
06538 return CPL_ERROR_NONE;
06539
06540 }
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559
06560
06561
06562
06563
06564 cpl_error_code xxx_column_set_float(xxx_column *column, int indx, float value)
06565 {
06566
06567 const char *fid = "xxx_column_set_float";
06568 int length = xxx_column_get_size(column);
06569 cpl_type type = xxx_column_get_type(column);
06570
06571
06572 if (column == 0x0)
06573 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06574
06575 if (indx < 0 || indx >= length)
06576 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06577
06578 if (type != CPL_TYPE_FLOAT)
06579 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06580
06581 column->values->f[indx] = value;
06582 xxx_column_unset_null(column, indx);
06583
06584 return CPL_ERROR_NONE;
06585
06586 }
06587
06588
06589
06590
06591
06592
06593
06594
06595
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605
06606
06607
06608
06609
06610 cpl_error_code xxx_column_set_double(xxx_column *column, int indx,
06611 double value)
06612 {
06613
06614 const char *fid = "xxx_column_set_double";
06615 int length = xxx_column_get_size(column);
06616 cpl_type type = xxx_column_get_type(column);
06617
06618
06619 if (column == 0x0)
06620 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06621
06622 if (indx < 0 || indx >= length)
06623 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06624
06625 if (type != CPL_TYPE_DOUBLE)
06626 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06627
06628 column->values->d[indx] = value;
06629 xxx_column_unset_null(column, indx);
06630
06631 return CPL_ERROR_NONE;
06632
06633 }
06634
06635
06636
06637
06638
06639
06640
06641
06642
06643
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654
06655
06656
06657
06658
06659 cpl_error_code xxx_column_set_string(xxx_column *column,
06660 int indx, const char *string)
06661 {
06662
06663 const char *fid = "xxx_column_set_string";
06664 int length = xxx_column_get_size(column);
06665 cpl_type type = xxx_column_get_type(column);
06666
06667
06668 if (column == 0x0)
06669 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06670
06671 if (indx < 0 || indx >= length)
06672 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06673
06674 if (type != CPL_TYPE_STRING)
06675 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06676
06677 if (column->values->s[indx])
06678 cpl_free(column->values->s[indx]);
06679
06680 if (string)
06681 column->values->s[indx] = cpl_strdup((char *)string);
06682 else
06683 column->values->s[indx] = NULL;
06684
06685 return CPL_ERROR_NONE;
06686
06687 }
06688
06689
06690
06691
06692
06693
06694
06695
06696
06697
06698
06699
06700
06701
06702
06703
06704
06705
06706
06707
06708
06709
06710
06711
06712
06713
06714
06715 cpl_error_code xxx_column_set_array(xxx_column *column,
06716 int indx, const cpl_array *array)
06717 {
06718
06719 const char *fid = "xxx_column_set_array";
06720 int length = xxx_column_get_size(column);
06721 cpl_type type = xxx_column_get_type(column);
06722 cpl_type atype;
06723
06724
06725 if (column == 0x0)
06726 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06727
06728 if (indx < 0 || indx >= length)
06729 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06730
06731 if (!(type & CPL_TYPE_POINTER))
06732 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06733
06734 if (array) {
06735 atype = cpl_array_get_type(array);
06736 if (type != (atype | CPL_TYPE_POINTER))
06737 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06738 if (xxx_column_get_depth(column) != cpl_array_get_size(array))
06739 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
06740 }
06741
06742 if (column->values->array[indx])
06743 cpl_array_delete(column->values->array[indx]);
06744
06745 if (array)
06746 column->values->array[indx] = cpl_array_duplicate((cpl_array *)array);
06747 else
06748 column->values->array[indx] = NULL;
06749
06750 return CPL_ERROR_NONE;
06751
06752 }
06753
06754
06755
06756
06757
06758
06759
06760
06761
06762
06763
06764
06765
06766
06767
06768
06769
06770
06771
06772
06773 cpl_error_code xxx_column_set_invalid(xxx_column *column, int indx)
06774 {
06775
06776 const char *fid = "xxx_column_set_invalid";
06777 int length = xxx_column_get_size(column);
06778 cpl_type type = xxx_column_get_type(column);
06779
06780
06781 if (column == 0x0)
06782 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06783
06784 if (indx < 0 || indx >= length)
06785 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06786
06787
06788 if (type == CPL_TYPE_STRING) {
06789 if (column->values->s[indx]) {
06790 cpl_free(column->values->s[indx]);
06791 column->values->s[indx] = NULL;
06792 }
06793 return CPL_ERROR_NONE;
06794 }
06795
06796 if (type & CPL_TYPE_POINTER) {
06797 if (column->values->array[indx]) {
06798 cpl_array_delete(column->values->array[indx]);
06799 column->values->array[indx] = NULL;
06800 }
06801 return CPL_ERROR_NONE;
06802 }
06803
06804 if (column->nullcount == column->length)
06805 return CPL_ERROR_NONE;
06806
06807 if (!column->null)
06808 column->null = cpl_calloc(column->length, sizeof(xxx_column_flag));
06809
06810 if (column->null[indx] == 0) {
06811
06812 column->null[indx] = 1;
06813 column->nullcount++;
06814
06815 if (column->nullcount == column->length) {
06816 if (column->null)
06817 cpl_free(column->null);
06818 column->null = NULL;
06819 }
06820
06821 }
06822
06823 return CPL_ERROR_NONE;
06824
06825 }
06826
06827
06828
06829
06830
06831
06832
06833
06834
06835
06836
06837
06838
06839
06840
06841
06842
06843
06844
06845
06846
06847
06848
06849 cpl_error_code xxx_column_fill(xxx_column *column,
06850 int start, int count, double value)
06851 {
06852
06853 const char *fid = "xxx_column_fill";
06854 cpl_type type = xxx_column_get_type(column);
06855
06856
06857 switch (type) {
06858 case CPL_TYPE_INT:
06859 return xxx_column_fill_int(column, start, count, value);
06860 case CPL_TYPE_FLOAT:
06861 return xxx_column_fill_float(column, start, count, value);
06862 case CPL_TYPE_DOUBLE:
06863 return xxx_column_fill_double(column, start, count, value);
06864 case CPL_TYPE_INT | CPL_TYPE_POINTER:
06865 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
06866 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
06867 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
06868 case CPL_TYPE_STRING:
06869 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
06870 default:
06871 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06872 }
06873
06874 }
06875
06876
06877
06878
06879
06880
06881
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902 cpl_error_code xxx_column_fill_int(xxx_column *column,
06903 int start, int count, int value)
06904 {
06905
06906 const char *fid = "xxx_column_fill_int";
06907 int length = xxx_column_get_size(column);
06908 cpl_type type = xxx_column_get_type(column);
06909 int *ip;
06910
06911
06912 if (column == 0x0)
06913 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06914
06915 if (start < 0 || start >= length)
06916 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06917
06918 if (count < 0)
06919 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
06920
06921 if (type != CPL_TYPE_INT)
06922 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06923
06924 if (count == 0)
06925 return CPL_ERROR_NONE;
06926
06927 if (count > length - start)
06928 count = length - start;
06929
06930 xxx_column_unset_null_segment(column, start, count);
06931
06932 ip = column->values->i + start;
06933
06934 while (count--)
06935 *ip++ = value;
06936
06937 return CPL_ERROR_NONE;
06938
06939 }
06940
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963
06964
06965
06966
06967 cpl_error_code xxx_column_fill_float(xxx_column *column, int start,
06968 int count, float value)
06969 {
06970
06971 const char *fid = "xxx_column_fill_float";
06972 int length = xxx_column_get_size(column);
06973 cpl_type type = xxx_column_get_type(column);
06974 float *fp;
06975
06976
06977 if (column == 0x0)
06978 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
06979
06980 if (start < 0 || start >= length)
06981 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
06982
06983 if (count < 0)
06984 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
06985
06986 if (type != CPL_TYPE_FLOAT)
06987 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
06988
06989 if (count == 0)
06990 return CPL_ERROR_NONE;
06991
06992 if (count > length - start)
06993 count = length - start;
06994
06995 xxx_column_unset_null_segment(column, start, count);
06996
06997 fp = column->values->f + start;
06998
06999 while (count--)
07000 *fp++ = value;
07001
07002 return CPL_ERROR_NONE;
07003
07004 }
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032 cpl_error_code xxx_column_fill_double(xxx_column *column, int start,
07033 int count, double value)
07034 {
07035
07036 const char *fid = "xxx_column_fill_double";
07037 int length = xxx_column_get_size(column);
07038 cpl_type type = xxx_column_get_type(column);
07039 double *dp;
07040
07041
07042 if (column == 0x0)
07043 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07044
07045 if (start < 0 || start >= length)
07046 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07047
07048 if (count < 0)
07049 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07050
07051 if (type != CPL_TYPE_DOUBLE)
07052 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07053
07054 if (count == 0)
07055 return CPL_ERROR_NONE;
07056
07057 if (count > length - start)
07058 count = length - start;
07059
07060 xxx_column_unset_null_segment(column, start, count);
07061
07062 dp = column->values->d + start;
07063
07064 while (count--)
07065 *dp++ = value;
07066
07067 return CPL_ERROR_NONE;
07068
07069 }
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080
07081
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097
07098 cpl_error_code xxx_column_fill_string(xxx_column *column, int start,
07099 int count, const char *value)
07100 {
07101
07102 const char *fid = "xxx_column_fill_string";
07103 int length = xxx_column_get_size(column);
07104 cpl_type type = xxx_column_get_type(column);
07105 char **sp;
07106
07107
07108 if (column == 0x0)
07109 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07110
07111 if (start < 0 || start >= length)
07112 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07113
07114 if (count < 0)
07115 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07116
07117 if (type != CPL_TYPE_STRING)
07118 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07119
07120 if (count == 0)
07121 return CPL_ERROR_NONE;
07122
07123 if (count > length - start)
07124 count = length - start;
07125
07126 if (value == NULL)
07127 return xxx_column_fill_invalid(column, start, count);
07128
07129 sp = column->values->s + start;
07130 while (count--) {
07131 if (*sp)
07132 cpl_free(*sp);
07133 *sp++ = cpl_strdup((char *)value);
07134 }
07135
07136 return CPL_ERROR_NONE;
07137
07138 }
07139
07140
07141
07142
07143
07144
07145
07146
07147
07148
07149
07150
07151
07152
07153
07154
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166
07167
07168
07169
07170 cpl_error_code xxx_column_fill_array(xxx_column *column, int start,
07171 int count, const cpl_array *array)
07172 {
07173
07174 const char *fid = "xxx_column_fill_array";
07175 int length = xxx_column_get_size(column);
07176 cpl_type type = xxx_column_get_type(column);
07177 cpl_type atype;
07178 cpl_array **ap;
07179
07180
07181 if (column == 0x0)
07182 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07183
07184 if (start < 0 || start >= length)
07185 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07186
07187 if (count < 0)
07188 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07189
07190 if (!(type & CPL_TYPE_POINTER))
07191 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07192
07193 if (array) {
07194 atype = cpl_array_get_type(array);
07195 if (type != (atype | CPL_TYPE_POINTER))
07196 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07197 if (xxx_column_get_depth(column) != cpl_array_get_size(array))
07198 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
07199 }
07200
07201 if (count == 0)
07202 return CPL_ERROR_NONE;
07203
07204 if (count > length - start)
07205 count = length - start;
07206
07207 if (array == NULL)
07208 return xxx_column_fill_invalid(column, start, count);
07209
07210 ap = column->values->array + start;
07211 while (count--) {
07212 if (*ap)
07213 cpl_array_delete(*ap);
07214 *ap++ = cpl_array_duplicate(array);
07215 }
07216
07217 return CPL_ERROR_NONE;
07218
07219 }
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244
07245
07246 cpl_error_code xxx_column_fill_invalid(xxx_column *column, int start, int count)
07247 {
07248
07249 const char *fid = "xxx_column_fill_invalid";
07250 cpl_type type = xxx_column_get_type(column);
07251 int length = xxx_column_get_size(column);
07252 int c;
07253 int *np;
07254 char **sp;
07255 cpl_array **ap;
07256
07257
07258 if (column == 0x0)
07259 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07260
07261 if (start < 0 || start >= length)
07262 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07263
07264 if (count < 0)
07265 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07266
07267 if (count == 0)
07268 return CPL_ERROR_NONE;
07269
07270 if (count > length - start)
07271 count = length - start;
07272
07273 if (count == length) {
07274 if (type != CPL_TYPE_STRING && !(type & CPL_TYPE_POINTER)) {
07275 if (column->null)
07276 cpl_free(column->null);
07277 column->null = NULL;
07278 column->nullcount = length;
07279 return CPL_ERROR_NONE;
07280 }
07281 }
07282
07283 c = count;
07284
07285 if (type == CPL_TYPE_STRING) {
07286
07287 sp = column->values->s + start;
07288
07289 while (c--) {
07290 if (*sp)
07291 cpl_free(*sp);
07292 sp++;
07293 }
07294
07295 memset(column->values->s + start, 0, count * sizeof(char *));
07296
07297 return CPL_ERROR_NONE;
07298 }
07299
07300 if (type & CPL_TYPE_POINTER) {
07301
07302 ap = column->values->array + start;
07303
07304 while (c--) {
07305 if (*ap)
07306 cpl_array_delete(*ap);
07307 ap++;
07308 }
07309
07310 memset(column->values->array + start, 0, count * sizeof(cpl_array *));
07311
07312 return CPL_ERROR_NONE;
07313 }
07314
07315 if (column->nullcount == length)
07316 return CPL_ERROR_NONE;
07317
07318 if (!column->null)
07319 column->null = cpl_calloc(length, sizeof(xxx_column_flag));
07320
07321 np = column->null + start;
07322
07323 if (column->nullcount == 0) {
07324 column->nullcount = count;
07325 while (c--)
07326 *np++ = 1;
07327 }
07328 else {
07329 while (c--) {
07330 if (*np == 0) {
07331 *np = 1;
07332 column->nullcount++;
07333 }
07334 np++;
07335 }
07336
07337 if (column->nullcount == length) {
07338 if (column->null)
07339 cpl_free(column->null);
07340 column->null = NULL;
07341 }
07342 }
07343
07344 return CPL_ERROR_NONE;
07345
07346 }
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357
07358
07359
07360
07361
07362
07363
07364
07365
07366
07367
07368
07369
07370
07371
07372
07373 cpl_error_code xxx_column_copy_segment(xxx_column *column,
07374 int start, int count, double *values)
07375 {
07376
07377 const char *fid = "xxx_column_copy_segment";
07378 int length = xxx_column_get_size(column);
07379 cpl_type type = xxx_column_get_type(column);
07380 int *idata;
07381 float *fdata;
07382
07383
07384 if (column == 0x0)
07385 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07386
07387 if (start < 0 || start >= length)
07388 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07389
07390 if (count <= 0)
07391 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07392
07393 if (count > length - start)
07394 count = length - start;
07395
07396 xxx_column_unset_null_segment(column, start, count);
07397
07398 switch (type) {
07399 case CPL_TYPE_INT:
07400 idata = xxx_column_get_data_int(column);
07401 idata += start;
07402 while (count--)
07403 *idata++ = *values++;
07404 break;
07405 case CPL_TYPE_FLOAT:
07406 fdata = xxx_column_get_data_float(column);
07407 fdata += start;
07408 while (count--)
07409 *fdata++ = *values++;
07410 break;
07411 case CPL_TYPE_DOUBLE:
07412 memcpy(column->values->d + start, values, count * sizeof(double));
07413 break;
07414 default:
07415 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
07416 }
07417
07418 return CPL_ERROR_NONE;
07419
07420 }
07421 static double xxx_tools_get_median_9double(double * p)
07422 {
07423 cpl_ensure(p, CPL_ERROR_NULL_INPUT, 0.00) ;
07424
07425 CPL_PIX_SORT(p[1], p[2]); CPL_PIX_SORT(p[4], p[5]); CPL_PIX_SORT(p[7],p[8]);
07426 CPL_PIX_SORT(p[0], p[1]); CPL_PIX_SORT(p[3], p[4]); CPL_PIX_SORT(p[6],p[7]);
07427 CPL_PIX_SORT(p[1], p[2]); CPL_PIX_SORT(p[4], p[5]); CPL_PIX_SORT(p[7],p[8]);
07428 CPL_PIX_SORT(p[0], p[3]); CPL_PIX_SORT(p[5], p[8]); CPL_PIX_SORT(p[4],p[7]);
07429 CPL_PIX_SORT(p[3], p[6]); CPL_PIX_SORT(p[1], p[4]); CPL_PIX_SORT(p[2],p[5]);
07430 CPL_PIX_SORT(p[4], p[7]); CPL_PIX_SORT(p[4], p[2]); CPL_PIX_SORT(p[6],p[4]);
07431 CPL_PIX_SORT(p[4], p[2]); return(p[4]) ;
07432 }
07433 static double xxx_tools_get_median_double(
07434 double * a,
07435 int n)
07436 {
07437 if (n==9) return xxx_tools_get_median_9double(a) ;
07438 return xxx_tools_get_kth_double(a,n,(((n)&1)?((n)/2):(((n)/2)-1))) ;
07439 }
07440
07441
07442
07450
07451 static float xxx_tools_get_median_float(
07452 float * a,
07453 int n)
07454 {
07455 return xxx_tools_get_kth_float(a,n,(((n)&1)?((n)/2):(((n)/2)-1))) ;
07456 }
07457
07458
07466
07467 static int xxx_tools_get_median_int(
07468 int * a,
07469 int n)
07470 {
07471 return xxx_tools_get_kth_int(a,n,(((n)&1)?((n)/2):(((n)/2)-1))) ;
07472 }
07473
07474 static double xxx_tools_ipow(double x, int y)
07475 {
07476
07477 double result;
07478 double pow2 = x;
07479 int p = abs(y);
07480
07481
07482
07483
07484
07485
07486
07487 result = p & 1 ? x : 1.0;
07488
07489 while (p >>= 1) {
07490 pow2 *= pow2;
07491
07492 if (p & 1) result *= pow2;
07493 }
07494
07495
07496 return y < 0 ? 1.0/result : result;
07497 }
07498
07499
07500
07501
07502
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522
07523 cpl_error_code xxx_column_copy_segment_int(xxx_column *column,
07524 int start, int count, int *values)
07525 {
07526
07527 const char *fid = "xxx_column_copy_segment_int";
07528 int length = xxx_column_get_size(column);
07529 cpl_type type = xxx_column_get_type(column);
07530
07531
07532 if (column == 0x0)
07533 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07534
07535 if (start < 0 || start >= length)
07536 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07537
07538 if (count <= 0)
07539 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07540
07541 if (type != CPL_TYPE_INT)
07542 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07543
07544 if (count > length - start)
07545 count = length - start;
07546
07547 memcpy(column->values->i + start, values, count * sizeof(int));
07548
07549 xxx_column_unset_null_segment(column, start, count);
07550
07551 return CPL_ERROR_NONE;
07552
07553 }
07554
07555
07556
07557
07558
07559
07560
07561
07562
07563
07564
07565
07566
07567
07568
07569
07570
07571
07572
07573
07574
07575
07576
07577
07578
07579 cpl_error_code xxx_column_copy_segment_float(xxx_column *column, int start,
07580 int count, float *values)
07581 {
07582
07583 const char *fid = "xxx_column_copy_segment_float";
07584 int length = xxx_column_get_size(column);
07585 cpl_type type = xxx_column_get_type(column);
07586
07587
07588 if (column == 0x0)
07589 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07590
07591 if (start < 0 || start >= length)
07592 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07593
07594 if (count <= 0)
07595 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07596
07597 if (type != CPL_TYPE_FLOAT)
07598 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07599
07600 if (count > length - start)
07601 count = length - start;
07602
07603 memcpy(column->values->f + start, values, count * sizeof(float));
07604
07605 xxx_column_unset_null_segment(column, start, count);
07606
07607 return CPL_ERROR_NONE;
07608
07609 }
07610
07611
07612
07613
07614
07615
07616
07617
07618
07619
07620
07621
07622
07623
07624
07625
07626
07627
07628
07629
07630
07631
07632
07633
07634
07635 cpl_error_code xxx_column_copy_segment_double(xxx_column *column, int start,
07636 int count, double *values)
07637 {
07638
07639 const char *fid = "xxx_column_copy_segment_double";
07640 int length = xxx_column_get_size(column);
07641 cpl_type type = xxx_column_get_type(column);
07642
07643
07644 if (column == 0x0)
07645 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07646
07647 if (start < 0 || start >= length)
07648 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07649
07650 if (count <= 0)
07651 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07652
07653 if (type != CPL_TYPE_DOUBLE)
07654 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07655
07656 if (count > length - start)
07657 count = length - start;
07658
07659 memcpy(column->values->d + start, values, count * sizeof(double));
07660
07661 xxx_column_unset_null_segment(column, start, count);
07662
07663 return CPL_ERROR_NONE;
07664
07665 }
07666
07667
07668
07669
07670
07671
07672
07673
07674
07675
07676
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692 cpl_error_code xxx_column_copy_segment_string(xxx_column *column, int start,
07693 int count, char **strings)
07694 {
07695
07696 const char *fid = "xxx_column_copy_segment_string";
07697 cpl_type type = xxx_column_get_type(column);
07698 int length = xxx_column_get_size(column);
07699 int i;
07700 char **sp;
07701
07702
07703 if (column == 0x0)
07704 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07705
07706 if (start < 0 || start >= length)
07707 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07708
07709 if (count <= 0)
07710 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07711
07712 if (type != CPL_TYPE_STRING)
07713 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07714
07715 if (count > length - start)
07716 count = length - start;
07717
07718 sp = column->values->s + start;
07719
07720 if (strings) {
07721 for (i = 0; i < count; i++) {
07722 if (*sp)
07723 cpl_free(*sp);
07724 if (*strings)
07725 *sp++ = cpl_strdup(*strings++);
07726 else
07727 *sp++ = NULL;
07728 }
07729 }
07730 else {
07731 for (i = 0; i < count; i++) {
07732 if (*sp)
07733 cpl_free(*sp);
07734 *sp++ = NULL;
07735 }
07736 }
07737
07738 return CPL_ERROR_NONE;
07739
07740 }
07741
07742
07743
07744
07745
07746
07747
07748
07749
07750
07751
07752
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768
07769
07770 cpl_error_code xxx_column_copy_segment_array(xxx_column *column, int start,
07771 int count, cpl_array **arrays)
07772 {
07773
07774 const char *fid = "xxx_column_copy_segment_array";
07775 cpl_type type = xxx_column_get_type(column);
07776 cpl_type atype;
07777 int length = xxx_column_get_size(column);
07778 int i;
07779 cpl_array **ap;
07780 cpl_array **keep;
07781
07782
07783 if (column == 0x0)
07784 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07785
07786 if (start < 0 || start >= length)
07787 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07788
07789 if (count <= 0)
07790 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07791
07792 if (!(type & CPL_TYPE_POINTER))
07793 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07794
07795 if (count > length - start)
07796 count = length - start;
07797
07798 ap = column->values->array + start;
07799
07800 if (arrays) {
07801
07802
07803
07804
07805
07806 keep = arrays;
07807
07808 for (i = 0; i < count; i++) {
07809 if (*arrays) {
07810 atype = cpl_array_get_type(*arrays);
07811 if (type != (atype | CPL_TYPE_POINTER))
07812 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
07813 if (xxx_column_get_depth(column) != cpl_array_get_size(*arrays))
07814 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
07815 arrays++;
07816 }
07817 }
07818
07819 arrays = keep;
07820
07821 for (i = 0; i < count; i++) {
07822 if (*ap)
07823 cpl_array_delete(*ap);
07824 if (*arrays)
07825 *ap++ = cpl_array_duplicate(*arrays++);
07826 else
07827 *ap++ = NULL;
07828 }
07829 }
07830 else {
07831 for (i = 0; i < count; i++) {
07832 if (*ap)
07833 cpl_array_delete(*ap);
07834 *ap++ = NULL;
07835 }
07836 }
07837
07838 return CPL_ERROR_NONE;
07839
07840 }
07841
07842
07843
07844
07845
07846
07847
07848
07849
07850
07851
07852
07853
07854
07855
07856
07857
07858
07859
07860
07861
07862
07863
07864
07865
07866
07867
07868
07869
07870
07871
07872
07873
07874
07875
07876
07877
07878
07879
07880
07881
07882
07883
07884
07885
07886
07887
07888
07889
07890
07891
07892
07893
07894
07895
07896
07897
07898
07899
07900
07901
07902
07903
07904
07905
07906
07907
07908
07909
07910
07911
07912
07913
07914
07915
07916
07917
07918
07919
07920
07921
07922
07923
07924
07925
07926
07927
07928
07929
07930
07931
07932
07933
07934
07935
07936
07937
07938
07939
07940
07941
07942
07943
07944
07945
07946
07947
07948
07949
07950
07951
07952
07953
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963 cpl_error_code xxx_column_erase_segment(xxx_column *column,
07964 int start, int count)
07965 {
07966
07967 const char *fid = "xxx_column_erase_segment";
07968 cpl_type type = xxx_column_get_type(column);
07969 int old_length = xxx_column_get_size(column);
07970 int new_length;
07971 int end;
07972 int i;
07973 int j;
07974 cpl_array **ap1;
07975 cpl_array **ap2;
07976 char **sp1;
07977 char **sp2;
07978 int *ip1;
07979 int *ip2;
07980 float *fp1;
07981 float *fp2;
07982 double *dp1;
07983 double *dp2;
07984
07985
07986 if (column == 0x0)
07987 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
07988
07989 if (start < 0 || start >= old_length)
07990 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
07991
07992 if (count < 0)
07993 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
07994
07995 if (count == 0)
07996 return CPL_ERROR_NONE;
07997
07998 if (count > old_length - start)
07999 count = old_length - start;
08000
08001 new_length = old_length - count;
08002 end = start + count;
08003
08004 if (end == old_length)
08005 return xxx_column_set_size(column, start);
08006
08007 if (type == CPL_TYPE_STRING) {
08008
08009
08010
08011
08012
08013
08014 sp1 = column->values->s + start;
08015
08016 for (i = start; i < end; i++, sp1++)
08017 if (*sp1)
08018 cpl_free(*sp1);
08019 }
08020
08021 if (type & CPL_TYPE_POINTER) {
08022
08023
08024
08025
08026
08027
08028 ap1 = column->values->array + start;
08029
08030 for (i = start; i < end; i++, ap1++)
08031 if (*ap1)
08032 cpl_array_delete(*ap1);
08033 }
08034
08035
08036
08037
08038
08039
08040
08041 if (column->null) {
08042
08043 i = start;
08044 while (i < end) {
08045 if (column->null[i])
08046 column->nullcount--;
08047 i++;
08048 }
08049
08050 if (column->nullcount == 0 || column->nullcount == new_length) {
08051
08052
08053
08054
08055
08056
08057 if (column->null)
08058 cpl_free(column->null);
08059 column->null = NULL;
08060
08061 }
08062 else {
08063
08064
08065
08066
08067
08068 i = start;
08069 j = end;
08070 while (j < old_length) {
08071 column->null[i] = column->null[j];
08072 i++;
08073 j++;
08074 }
08075
08076
08077
08078
08079
08080 column->null = cpl_realloc(column->null,
08081 new_length * sizeof(xxx_column_flag));
08082
08083 }
08084 }
08085 else {
08086
08087
08088
08089
08090
08091
08092
08093
08094
08095 if (column->nullcount == old_length)
08096 column->nullcount = new_length;
08097
08098 }
08099
08100
08101
08102
08103
08104
08105 if ((type == CPL_TYPE_STRING) || (type & CPL_TYPE_POINTER))
08106 column->nullcount = 0;
08107
08108 if (column->nullcount != new_length) {
08109
08110
08111
08112
08113
08114
08115 ip1 = column->values->i + start;
08116 ip2 = column->values->i + end;
08117 fp1 = column->values->f + start;
08118 fp2 = column->values->f + end;
08119 dp1 = column->values->d + start;
08120 dp2 = column->values->d + end;
08121 sp1 = column->values->s + start;
08122 sp2 = column->values->s + end;
08123 ap1 = column->values->array + start;
08124 ap2 = column->values->array + end;
08125
08126 switch (type) {
08127 case CPL_TYPE_INT:
08128 for (j = end; j < old_length; j++)
08129 *ip1++ = *ip2++;
08130 break;
08131 case CPL_TYPE_FLOAT:
08132 for (j = end; j < old_length; j++)
08133 *fp1++ = *fp2++;
08134 break;
08135 case CPL_TYPE_DOUBLE:
08136 for (j = end; j < old_length; j++)
08137 *dp1++ = *dp2++;
08138 break;
08139 case CPL_TYPE_STRING:
08140 for (j = end; j < old_length; j++)
08141 *sp1++ = *sp2++;
08142 break;
08143 default:
08144 for (j = end; j < old_length; j++)
08145 *ap1++ = *ap2++;
08146 break;
08147 }
08148
08149 }
08150
08151
08152
08153
08154
08155
08156 column->values->i = cpl_realloc(column->values->i,
08157 new_length * xxx_column_type_size(type));
08158
08159 column->length = new_length;
08160
08161 return 0;
08162
08163 }
08164
08165
08166
08167
08168
08169
08170
08171
08172
08173
08174
08175
08176
08177
08178
08179
08180
08181
08182
08183
08184
08185
08186
08187
08188
08189
08190
08191
08192
08193
08194 cpl_error_code xxx_column_insert_segment(xxx_column *column,
08195 int start, int count)
08196 {
08197
08198 const char *fid = "xxx_column_insert_segment";
08199 cpl_type type = xxx_column_get_type(column);
08200 int old_length = xxx_column_get_size(column);
08201 int new_length = old_length + count;
08202 int i;
08203 cpl_array **ap1;
08204 cpl_array **ap2;
08205 char **sp1;
08206 char **sp2;
08207 int *ip1;
08208 int *ip2;
08209 float *fp1;
08210 float *fp2;
08211 double *dp1;
08212 double *dp2;
08213 int *np1;
08214 int *np2;
08215
08216
08217 if (column == 0x0)
08218 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
08219
08220 if (start < 0)
08221 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
08222
08223 if (count < 0)
08224 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
08225
08226 if (count == 0)
08227 return CPL_ERROR_NONE;
08228
08229 if (xxx_column_set_size(column, new_length)) {
08230 cpl_error_set_where(fid);
08231 return cpl_error_get_code();
08232 }
08233
08234 if (start > old_length)
08235 return CPL_ERROR_NONE;
08236
08237 ip1 = column->values->i + new_length;
08238 ip2 = column->values->i + old_length;
08239 fp1 = column->values->f + new_length;
08240 fp2 = column->values->f + old_length;
08241 dp1 = column->values->d + new_length;
08242 dp2 = column->values->d + old_length;
08243 sp1 = column->values->s + new_length;
08244 sp2 = column->values->s + old_length;
08245 ap1 = column->values->array + new_length;
08246 ap2 = column->values->array + old_length;
08247
08248 switch (type) {
08249 case CPL_TYPE_INT:
08250 for (i = old_length; i > start; i--) {
08251 *--ip1 = *--ip2;
08252 *ip2 = 0;
08253 }
08254 break;
08255
08256 case CPL_TYPE_FLOAT:
08257 for (i = old_length; i > start; i--) {
08258 *--fp1 = *--fp2;
08259 *fp2 = 0.0;
08260 }
08261 break;
08262
08263 case CPL_TYPE_DOUBLE:
08264 for (i = old_length; i > start; i--) {
08265 *--dp1 = *--dp2;
08266 *dp2 = 0.0;
08267 }
08268 break;
08269
08270 case CPL_TYPE_STRING:
08271 for (i = old_length; i > start; i--) {
08272 *--sp1 = *--sp2;
08273 *sp2 = 0x0;
08274 }
08275 break;
08276
08277 default:
08278 for (i = old_length; i > start; i--) {
08279 *--ap1 = *--ap2;
08280 *ap2 = 0x0;
08281 }
08282 break;
08283 }
08284
08285
08286
08287
08288
08289
08290
08291
08292
08293 if (column->null) {
08294
08295 np1 = column->null + new_length;
08296 np2 = column->null + old_length;
08297
08298 for (i = old_length; i > start; i--) {
08299 *--np1 = *--np2;
08300 *np2 = 1;
08301 }
08302
08303 }
08304
08305 return CPL_ERROR_NONE;
08306
08307 }
08308
08309
08310
08311
08312
08313
08314
08315
08316
08317
08318
08319
08320
08321
08322
08323 xxx_column *xxx_column_duplicate(xxx_column *column)
08324 {
08325
08326 const char *fid = "xxx_column_duplicate";
08327 cpl_type type = xxx_column_get_type(column);
08328 int length = xxx_column_get_size(column);
08329 int depth = xxx_column_get_depth(column);
08330 xxx_column *new_column = NULL;
08331
08332
08333 if (column == 0x0) {
08334 cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
08335 return NULL;
08336 }
08337
08338 switch (type) {
08339 case CPL_TYPE_INT:
08340 new_column = xxx_column_new_int(length);
08341 break;
08342 case CPL_TYPE_FLOAT:
08343 new_column = xxx_column_new_float(length);
08344 break;
08345 case CPL_TYPE_DOUBLE:
08346 new_column = xxx_column_new_double(length);
08347 break;
08348 case CPL_TYPE_STRING:
08349 new_column = xxx_column_new_string(length);
08350 break;
08351 case CPL_TYPE_INT | CPL_TYPE_POINTER:
08352 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
08353 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
08354 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
08355 new_column = xxx_column_new_array(type, length, depth);
08356 break;
08357 default:
08358 cpl_error_set(fid, CPL_ERROR_UNSPECIFIED);
08359 return NULL;
08360 }
08361
08362 xxx_column_set_name(new_column, xxx_column_get_name(column));
08363 xxx_column_set_unit(new_column, xxx_column_get_unit(column));
08364 xxx_column_set_format(new_column, xxx_column_get_format(column));
08365
08366 if (length == 0)
08367 return new_column;
08368
08369 if (type == CPL_TYPE_STRING) {
08370 while (length--) {
08371 if (column->values->s[length]) {
08372 new_column->values->s[length] =
08373 cpl_strdup(column->values->s[length]);
08374 }
08375 else {
08376 new_column->values->s[length] = NULL;
08377 }
08378 }
08379 return new_column;
08380 }
08381
08382 if (type & CPL_TYPE_POINTER) {
08383 while (length--) {
08384 if (column->values->array[length]) {
08385 new_column->values->array[length] =
08386 cpl_array_duplicate(column->values->array[length]);
08387 }
08388 else {
08389 new_column->values->array[length] = NULL;
08390 }
08391 }
08392
08393 if (column->dimensions)
08394 new_column->dimensions = cpl_array_duplicate(column->dimensions);
08395
08396 return new_column;
08397 }
08398
08399 memcpy(new_column->values->i, column->values->i,
08400 length * xxx_column_type_size(type));
08401
08402 new_column->nullcount = column->nullcount;
08403
08404 if (column->null) {
08405 new_column->null = cpl_malloc(length * sizeof(xxx_column_flag));
08406 memcpy(new_column->null, column->null,
08407 length * sizeof(xxx_column_flag));
08408 }
08409
08410 return new_column;
08411
08412 }
08413
08414
08415
08416
08417
08418
08419
08420
08421
08422
08423
08424
08425
08426
08427
08428
08429
08430
08431
08432
08433
08434
08435
08436
08437
08438
08439
08440
08441
08442
08443
08444
08445
08446
08447
08448
08449
08450
08451
08452
08453
08454
08455
08456
08457
08458
08459
08460
08461
08462
08463
08464
08465
08466
08467
08468
08469
08470
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480 xxx_column *xxx_column_extract(xxx_column *column, int start, int count)
08481 {
08482
08483 const char *fid = "xxx_column_extract";
08484 xxx_column *new_column = NULL;
08485 cpl_type type = xxx_column_get_type(column);
08486 int length = xxx_column_get_size(column);
08487 int depth = xxx_column_get_depth(column);
08488 int byte_count;
08489 int i;
08490 int j;
08491
08492
08493 if (column == 0x0) {
08494 cpl_error_set_where(fid);
08495 return NULL;
08496 }
08497
08498 if (start < 0 || start >= length) {
08499 cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
08500 return NULL;
08501 }
08502
08503 if (count < 0) {
08504 cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
08505 return NULL;
08506 }
08507
08508 if (count > length - start)
08509 count = length - start;
08510
08511 byte_count = count * xxx_column_type_size(type);
08512
08513 switch (type) {
08514
08515 case CPL_TYPE_INT:
08516 new_column = xxx_column_new_int(count);
08517 if (count)
08518 memcpy(new_column->values->i,
08519 column->values->i + start, byte_count);
08520 break;
08521
08522 case CPL_TYPE_FLOAT:
08523 new_column = xxx_column_new_float(count);
08524 if (count)
08525 memcpy(new_column->values->f,
08526 column->values->f + start, byte_count);
08527 break;
08528
08529 case CPL_TYPE_DOUBLE:
08530 new_column = xxx_column_new_double(count);
08531 if (count)
08532 memcpy(new_column->values->d,
08533 column->values->d + start, byte_count);
08534 break;
08535
08536 case CPL_TYPE_STRING:
08537 new_column = xxx_column_new_string(count);
08538 for (i = 0, j = start; i < count; i++, j++)
08539 if (column->values->s[j])
08540 new_column->values->s[i] = cpl_strdup(column->values->s[j]);
08541 else
08542 new_column->values->s[i] = NULL;
08543 break;
08544
08545 case CPL_TYPE_INT | CPL_TYPE_POINTER:
08546 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
08547 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
08548 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
08549
08550 new_column = xxx_column_new_array(type, count, depth);
08551 for (i = 0, j = start; i < count; i++, j++) {
08552 if (column->values->array[j])
08553 new_column->values->array[i] =
08554 cpl_array_duplicate(column->values->array[j]);
08555 else
08556 new_column->values->array[i] = NULL;
08557 }
08558
08559 if (column->dimensions)
08560 new_column->dimensions = cpl_array_duplicate(column->dimensions);
08561
08562 break;
08563
08564 default:
08565 cpl_error_set(fid, CPL_ERROR_UNSPECIFIED);
08566 return NULL;
08567 break;
08568 }
08569
08570 xxx_column_set_unit(new_column, xxx_column_get_unit(column));
08571 xxx_column_set_format(new_column, xxx_column_get_format(column));
08572
08573 if (column->null) {
08574
08575
08576
08577
08578
08579
08580
08581 new_column->nullcount = 0;
08582 for (i = 0, j = start; i < count; i++, j++)
08583 if (column->null[j])
08584 new_column->nullcount++;
08585
08586 if (new_column->nullcount != 0 &&
08587 new_column->nullcount != count) {
08588 new_column->null = cpl_calloc(count, sizeof(xxx_column_flag));
08589 for (i = 0, j = start; i < count; i++, j++)
08590 if (column->null[j])
08591 new_column->null[i] = 1;
08592 }
08593
08594 }
08595 else {
08596
08597
08598
08599
08600
08601
08602
08603 if (column->nullcount == 0)
08604 new_column->nullcount = 0;
08605 else
08606 new_column->nullcount = xxx_column_get_size(new_column);
08607
08608 }
08609
08610 return new_column;
08611
08612 }
08613
08614
08615
08616
08617
08618
08619
08620
08621
08622
08623
08624
08625
08626
08627
08628
08629
08630
08631
08632
08633
08634
08635
08636
08637
08638
08639
08640
08641 cpl_error_code xxx_column_merge(xxx_column *target_column,
08642 xxx_column *insert_column, int position)
08643 {
08644
08645 const char *fid = "xxx_column_merge";
08646 int t_length = xxx_column_get_size(target_column);
08647 int i_length = xxx_column_get_size(insert_column);
08648 cpl_type t_type = xxx_column_get_type(target_column);
08649 cpl_type i_type = xxx_column_get_type(insert_column);
08650 int i_size = i_length * xxx_column_type_size(i_type);
08651 int i;
08652 int j;
08653
08654
08655 if (target_column == 0x0 || insert_column == 0x0)
08656 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
08657
08658 if (position < 0)
08659 return cpl_error_set(fid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
08660
08661 if (t_type != i_type)
08662 return cpl_error_set(fid, CPL_ERROR_TYPE_MISMATCH);
08663
08664 if (i_length == 0)
08665 return CPL_ERROR_NONE;
08666
08667 if (position > t_length)
08668 position = t_length;
08669
08670
08671
08672
08673
08674
08675
08676 xxx_column_insert_segment(target_column, position, i_length);
08677
08678
08679
08680
08681
08682
08683
08684 if (xxx_column_count_invalid(insert_column) == i_length)
08685 return CPL_ERROR_NONE;
08686
08687
08688
08689
08690
08691
08692
08693 t_length = xxx_column_get_size(target_column);
08694
08695 switch (i_type) {
08696
08697 case CPL_TYPE_INT:
08698 memcpy(target_column->values->i + position,
08699 insert_column->values->i, i_size);
08700 break;
08701
08702 case CPL_TYPE_FLOAT:
08703 memcpy(target_column->values->f + position,
08704 insert_column->values->f, i_size);
08705 break;
08706
08707 case CPL_TYPE_DOUBLE:
08708 memcpy(target_column->values->d + position,
08709 insert_column->values->d, i_size);
08710 break;
08711
08712 case CPL_TYPE_STRING:
08713 for (i = 0, j = position; i < i_length; i++, j++)
08714 if (insert_column->values->s[i])
08715 target_column->values->s[j] =
08716 cpl_strdup(insert_column->values->s[i]);
08717 break;
08718
08719 case CPL_TYPE_INT | CPL_TYPE_POINTER:
08720 case CPL_TYPE_FLOAT | CPL_TYPE_POINTER:
08721 case CPL_TYPE_DOUBLE | CPL_TYPE_POINTER:
08722 case CPL_TYPE_STRING | CPL_TYPE_POINTER:
08723 for (i = 0, j = position; i < i_length; i++, j++)
08724 if (insert_column->values->array[i])
08725 target_column->values->array[j] =
08726 cpl_array_duplicate(insert_column->values->array[i]);
08727 break;
08728
08729 default:
08730 return cpl_error_set(fid, CPL_ERROR_UNSPECIFIED);
08731
08732 }
08733
08734 if ((i_type == CPL_TYPE_STRING) || (i_type & CPL_TYPE_POINTER))
08735 return CPL_ERROR_NONE;
08736
08737
08738
08739
08740
08741
08742 if (target_column->null) {
08743
08744 if (insert_column->null) {
08745
08746
08747
08748
08749
08750
08751
08752 for (i = 0, j = position; i < i_length; i++, j++) {
08753 if (!insert_column->null[i]) {
08754 target_column->null[j] = 0;
08755 target_column->nullcount--;
08756 }
08757 }
08758 }
08759 else {
08760
08761
08762
08763
08764
08765
08766
08767
08768
08769
08770
08771
08772 if (target_column->nullcount > i_length) {
08773
08774
08775
08776
08777
08778
08779
08780
08781
08782
08783
08784
08785 for (i = 0, j = position; i < i_length; i++, j++)
08786 target_column->null[j] = 0;
08787 }
08788
08789 target_column->nullcount -= i_length;
08790
08791 }
08792 }
08793 else {
08794
08795
08796
08797
08798
08799
08800
08801
08802
08803
08804
08805 target_column->null = cpl_malloc(t_length * sizeof(xxx_column_flag));
08806
08807 i = t_length;
08808 while (i--)
08809 target_column->null[i] = 1;
08810
08811 if (insert_column->null) {
08812
08813
08814
08815
08816
08817 for (i = 0, j = position; i < i_length; i++, j++) {
08818 if (!insert_column->null[i]) {
08819 target_column->null[j] = 0;
08820 target_column->nullcount--;
08821 }
08822 }
08823
08824 }
08825 else {
08826
08827
08828
08829
08830
08831 for (i = 0, j = position; i < i_length; i++, j++)
08832 target_column->null[j] = 0;
08833
08834 target_column->nullcount -= i_length;
08835 }
08836 }
08837
08838
08839
08840
08841
08842
08843 if (target_column->nullcount == 0) {
08844 if (target_column->null)
08845 cpl_free(target_column->null);
08846 target_column->null = NULL;
08847 }
08848
08849 return 0;
08850
08851 }
08852
08853
08854
08855
08856
08857
08858
08859
08860
08861
08862
08863
08864
08865
08866
08867
08868
08869
08870
08871
08872
08873
08874
08875
08876 cpl_error_code xxx_column_add(xxx_column *to_column, xxx_column *from_column)
08877 {
08878
08879 const char *fid = "xxx_column_add";
08880 int i;
08881 int to_length = xxx_column_get_size(to_column);
08882 int from_length = xxx_column_get_size(from_column);
08883 cpl_type to_type = xxx_column_get_type(to_column);
08884 cpl_type from_type = xxx_column_get_type(from_column);
08885
08886 int *fip;
08887 float *ffp;
08888 double *fdp;
08889 int *tip;
08890 float *tfp;
08891 double *tdp;
08892 int *tnp;
08893
08894
08895 if (to_column == 0x0 || from_column == 0x0)
08896 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
08897
08898 if ((to_type == CPL_TYPE_STRING) || (from_type == CPL_TYPE_STRING) ||
08899 (to_type & CPL_TYPE_POINTER) || (from_type & CPL_TYPE_POINTER))
08900 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
08901
08902 if (to_length != from_length)
08903 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
08904
08905 if (to_length == 0)
08906 return CPL_ERROR_NONE;
08907
08908 if (to_column->nullcount == to_length)
08909 return CPL_ERROR_NONE;
08910
08911 if (from_column->nullcount == from_length)
08912 return xxx_column_fill_invalid(to_column, 0, to_length);
08913
08914
08915 fip = from_column->values->i;
08916 ffp = from_column->values->f;
08917 fdp = from_column->values->d;
08918 tip = to_column->values->i;
08919 tfp = to_column->values->f;
08920 tdp = to_column->values->d;
08921
08922 if (to_column->nullcount == 0 && from_column->nullcount == 0) {
08923
08924
08925
08926
08927
08928
08929 switch (to_type) {
08930
08931 case CPL_TYPE_INT:
08932
08933 switch (from_type) {
08934
08935 case CPL_TYPE_INT:
08936 while (to_length--)
08937 *tip++ += *fip++;
08938 break;
08939
08940 case CPL_TYPE_FLOAT:
08941 while (to_length--)
08942 *tip++ += *ffp++;
08943 break;
08944
08945 case CPL_TYPE_DOUBLE:
08946 while (to_length--)
08947 *tip++ += *fdp++;
08948 break;
08949
08950 default:
08951 break;
08952 }
08953 break;
08954
08955 case CPL_TYPE_FLOAT:
08956
08957 switch (from_type) {
08958
08959 case CPL_TYPE_INT:
08960 while (to_length--)
08961 *tfp++ += (double)*fip++;
08962 break;
08963
08964 case CPL_TYPE_FLOAT:
08965 while (to_length--)
08966 *tfp++ += (double)*ffp++;
08967 break;
08968
08969 case CPL_TYPE_DOUBLE:
08970 while (to_length--)
08971 *tfp++ += *fdp++;
08972 break;
08973
08974 default:
08975 break;
08976 }
08977 break;
08978
08979 case CPL_TYPE_DOUBLE:
08980
08981 switch (from_type) {
08982
08983 case CPL_TYPE_INT:
08984 while (to_length--)
08985 *tdp++ += *fip++;
08986 break;
08987
08988 case CPL_TYPE_FLOAT:
08989 while (to_length--)
08990 *tdp++ += *ffp++;
08991 break;
08992
08993 case CPL_TYPE_DOUBLE:
08994 while (to_length--)
08995 *tdp++ += *fdp++;
08996 break;
08997
08998 default:
08999 break;
09000 }
09001 break;
09002
09003 default:
09004 break;
09005 }
09006 }
09007 else {
09008
09009
09010
09011
09012
09013
09014
09015 if (to_column->nullcount == 0 || from_column->nullcount == 0) {
09016
09017
09018
09019
09020
09021
09022
09023 if (from_column->nullcount) {
09024 to_column->null = cpl_calloc(to_length,
09025 sizeof(xxx_column_flag));
09026
09027 i = to_length;
09028 while (i--)
09029 if (from_column->null[i])
09030 to_column->null[i] = 1;
09031
09032 to_column->nullcount = from_column->nullcount;
09033
09034 }
09035 }
09036 else {
09037
09038
09039
09040
09041
09042 i = to_length;
09043 while (i--) {
09044 if (from_column->null[i]) {
09045 if (!to_column->null[i]) {
09046 to_column->null[i] = 1;
09047 to_column->nullcount++;
09048 }
09049 }
09050 }
09051
09052 if (to_column->nullcount == to_length) {
09053
09054
09055
09056
09057
09058
09059
09060 if (to_column->null)
09061 cpl_free(to_column->null);
09062 to_column->null = NULL;
09063 return 0;
09064 }
09065
09066 }
09067
09068
09069
09070
09071
09072
09073 tnp = to_column->null;
09074
09075 switch (to_type) {
09076
09077 case CPL_TYPE_INT:
09078
09079 switch (from_type) {
09080
09081 case CPL_TYPE_INT:
09082 while (to_length--) {
09083 if (*tnp++ == 0)
09084 *tip += *fip;
09085 tip++;
09086 fip++;
09087 }
09088 break;
09089
09090 case CPL_TYPE_FLOAT:
09091 while (to_length--) {
09092 if (*tnp++ == 0)
09093 *tip += *ffp;
09094 tip++;
09095 ffp++;
09096 }
09097 break;
09098
09099 case CPL_TYPE_DOUBLE:
09100 while (to_length--) {
09101 if (*tnp++ == 0)
09102 *tip += *fdp;
09103 tip++;
09104 fdp++;
09105 }
09106 break;
09107
09108 default:
09109 break;
09110 }
09111 break;
09112
09113 case CPL_TYPE_FLOAT:
09114
09115 switch (from_type) {
09116
09117 case CPL_TYPE_INT:
09118 while (to_length--) {
09119 if (*tnp++ == 0)
09120 *tfp += (double)*fip;
09121 tfp++;
09122 fip++;
09123 }
09124 break;
09125
09126 case CPL_TYPE_FLOAT:
09127 while (to_length--) {
09128 if (*tnp++ == 0)
09129 *tfp += (double)*ffp;
09130 tfp++;
09131 ffp++;
09132 }
09133 break;
09134
09135 case CPL_TYPE_DOUBLE:
09136 while (to_length--) {
09137 if (*tnp++ == 0)
09138 *tfp += *fdp;
09139 tfp++;
09140 fdp++;
09141 }
09142 break;
09143
09144 default:
09145 break;
09146 }
09147 break;
09148
09149 case CPL_TYPE_DOUBLE:
09150
09151 switch (from_type) {
09152
09153 case CPL_TYPE_INT:
09154 while (to_length--) {
09155 if (*tnp++ == 0)
09156 *tdp += *fip;
09157 tdp++;
09158 fip++;
09159 }
09160 break;
09161
09162 case CPL_TYPE_FLOAT:
09163 while (to_length--) {
09164 if (*tnp++ == 0)
09165 *tdp += *ffp;
09166 tdp++;
09167 ffp++;
09168 }
09169 break;
09170
09171 case CPL_TYPE_DOUBLE:
09172 while (to_length--) {
09173 if (*tnp++ == 0)
09174 *tdp += *fdp;
09175 tdp++;
09176 fdp++;
09177 }
09178 break;
09179
09180 default:
09181 break;
09182 }
09183 break;
09184
09185 default:
09186 break;
09187 }
09188 }
09189
09190 return CPL_ERROR_NONE;
09191
09192 }
09193
09194
09195
09196
09197
09198
09199
09200
09201
09202
09203
09204
09205
09206
09207
09208
09209
09210
09211
09212
09213
09214
09215
09216
09217 cpl_error_code xxx_column_subtract(xxx_column *to_column,
09218 xxx_column *from_column)
09219 {
09220
09221 const char *fid = "xxx_column_subtract";
09222 int i;
09223 int to_length = xxx_column_get_size(to_column);
09224 int from_length = xxx_column_get_size(from_column);
09225 cpl_type to_type = xxx_column_get_type(to_column);
09226 cpl_type from_type = xxx_column_get_type(from_column);
09227
09228 int *fip;
09229 float *ffp;
09230 double *fdp;
09231 int *tip;
09232 float *tfp;
09233 double *tdp;
09234 int *tnp;
09235
09236
09237 if (to_column == 0x0 || from_column == 0x0)
09238 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
09239
09240 if ((to_type == CPL_TYPE_STRING) || (from_type == CPL_TYPE_STRING) ||
09241 (to_type & CPL_TYPE_POINTER) || (from_type & CPL_TYPE_POINTER))
09242 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
09243
09244 if (to_length != from_length)
09245 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
09246
09247 if (to_length == 0)
09248 return CPL_ERROR_NONE;
09249
09250 if (to_column->nullcount == to_length)
09251 return CPL_ERROR_NONE;
09252
09253 if (from_column->nullcount == from_length)
09254 return xxx_column_fill_invalid(to_column, 0, to_length);
09255
09256
09257 fip = from_column->values->i;
09258 ffp = from_column->values->f;
09259 fdp = from_column->values->d;
09260 tip = to_column->values->i;
09261 tfp = to_column->values->f;
09262 tdp = to_column->values->d;
09263
09264 if (to_column->nullcount == 0 && from_column->nullcount == 0) {
09265
09266
09267
09268
09269
09270
09271 switch (to_type) {
09272
09273 case CPL_TYPE_INT:
09274
09275 switch (from_type) {
09276
09277 case CPL_TYPE_INT:
09278 while (to_length--)
09279 *tip++ -= *fip++;
09280 break;
09281
09282 case CPL_TYPE_FLOAT:
09283 while (to_length--)
09284 *tip++ -= *ffp++;
09285 break;
09286
09287 case CPL_TYPE_DOUBLE:
09288 while (to_length--)
09289 *tip++ -= *fdp++;
09290 break;
09291
09292 default:
09293 break;
09294 }
09295 break;
09296
09297 case CPL_TYPE_FLOAT:
09298
09299 switch (from_type) {
09300
09301 case CPL_TYPE_INT:
09302 while (to_length--)
09303 *tfp++ -= (double)*fip++;
09304 break;
09305
09306 case CPL_TYPE_FLOAT:
09307 while (to_length--)
09308 *tfp++ -= (double)*ffp++;
09309 break;
09310
09311 case CPL_TYPE_DOUBLE:
09312 while (to_length--)
09313 *tfp++ -= *fdp++;
09314 break;
09315
09316 default:
09317 break;
09318 }
09319 break;
09320
09321 case CPL_TYPE_DOUBLE:
09322
09323 switch (from_type) {
09324
09325 case CPL_TYPE_INT:
09326 while (to_length--)
09327 *tdp++ -= *fip++;
09328 break;
09329
09330 case CPL_TYPE_FLOAT:
09331 while (to_length--)
09332 *tdp++ -= *ffp++;
09333 break;
09334
09335 case CPL_TYPE_DOUBLE:
09336 while (to_length--)
09337 *tdp++ -= *fdp++;
09338 break;
09339
09340 default:
09341 break;
09342 }
09343 break;
09344
09345 default:
09346 break;
09347 }
09348 }
09349 else {
09350
09351
09352
09353
09354
09355
09356
09357 if (to_column->nullcount == 0 || from_column->nullcount == 0) {
09358
09359
09360
09361
09362
09363
09364
09365 if (from_column->nullcount) {
09366 to_column->null = cpl_calloc(to_length, sizeof(xxx_column_flag));
09367
09368 i = to_length;
09369 while (i--)
09370 if (from_column->null[i])
09371 to_column->null[i] = 1;
09372
09373 to_column->nullcount = from_column->nullcount;
09374
09375 }
09376 }
09377 else {
09378
09379
09380
09381
09382
09383 i = to_length;
09384 while (i--) {
09385 if (from_column->null[i]) {
09386 if (!to_column->null[i]) {
09387 to_column->null[i] = 1;
09388 to_column->nullcount++;
09389 }
09390 }
09391 }
09392
09393 if (to_column->nullcount == to_length) {
09394
09395
09396
09397
09398
09399
09400
09401 if (to_column->null)
09402 cpl_free(to_column->null);
09403 to_column->null = NULL;
09404 return 0;
09405 }
09406
09407 }
09408
09409
09410
09411
09412
09413
09414 tnp = to_column->null;
09415
09416 switch (to_type) {
09417
09418 case CPL_TYPE_INT:
09419
09420 switch (from_type) {
09421
09422 case CPL_TYPE_INT:
09423 while (to_length--) {
09424 if (*tnp++ == 0)
09425 *tip -= *fip;
09426 tip++;
09427 fip++;
09428 }
09429 break;
09430
09431 case CPL_TYPE_FLOAT:
09432 while (to_length--) {
09433 if (*tnp++ == 0)
09434 *tip -= *ffp;
09435 tip++;
09436 ffp++;
09437 }
09438 break;
09439
09440 case CPL_TYPE_DOUBLE:
09441 while (to_length--) {
09442 if (*tnp++ == 0)
09443 *tip -= *fdp;
09444 tip++;
09445 fdp++;
09446 }
09447 break;
09448
09449 default:
09450 break;
09451 }
09452 break;
09453
09454 case CPL_TYPE_FLOAT:
09455
09456 switch (from_type) {
09457
09458 case CPL_TYPE_INT:
09459 while (to_length--) {
09460 if (*tnp++ == 0)
09461 *tfp -= (double)*fip;
09462 tfp++;
09463 fip++;
09464 }
09465 break;
09466
09467 case CPL_TYPE_FLOAT:
09468 while (to_length--) {
09469 if (*tnp++ == 0)
09470 *tfp -= (double)*ffp;
09471 tfp++;
09472 ffp++;
09473 }
09474 break;
09475
09476 case CPL_TYPE_DOUBLE:
09477 while (to_length--) {
09478 if (*tnp++ == 0)
09479 *tfp -= *fdp;
09480 tfp++;
09481 fdp++;
09482 }
09483 break;
09484
09485 default:
09486 break;
09487 }
09488 break;
09489
09490 case CPL_TYPE_DOUBLE:
09491
09492 switch (from_type) {
09493
09494 case CPL_TYPE_INT:
09495 while (to_length--) {
09496 if (*tnp++ == 0)
09497 *tdp -= *fip;
09498 tdp++;
09499 fip++;
09500 }
09501 break;
09502
09503 case CPL_TYPE_FLOAT:
09504 while (to_length--) {
09505 if (*tnp++ == 0)
09506 *tdp -= *ffp;
09507 tdp++;
09508 ffp++;
09509 }
09510 break;
09511
09512 case CPL_TYPE_DOUBLE:
09513 while (to_length--) {
09514 if (*tnp++ == 0)
09515 *tdp -= *fdp;
09516 tdp++;
09517 fdp++;
09518 }
09519 break;
09520
09521 default:
09522 break;
09523 }
09524 break;
09525
09526 default:
09527 break;
09528 }
09529 }
09530
09531 return CPL_ERROR_NONE;
09532
09533 }
09534
09535
09536
09537
09538
09539
09540
09541
09542
09543
09544
09545
09546
09547
09548
09549
09550
09551
09552
09553
09554
09555
09556
09557
09558 cpl_error_code xxx_column_multiply(xxx_column *to_column,
09559 xxx_column *from_column)
09560 {
09561
09562 const char *fid = "xxx_column_multiply";
09563 int i;
09564 int to_length = xxx_column_get_size(to_column);
09565 int from_length = xxx_column_get_size(from_column);
09566 cpl_type to_type = xxx_column_get_type(to_column);
09567 cpl_type from_type = xxx_column_get_type(from_column);
09568
09569 int *fip;
09570 float *ffp;
09571 double *fdp;
09572 int *tip;
09573 float *tfp;
09574 double *tdp;
09575 int *tnp;
09576
09577
09578 if (to_column == 0x0 || from_column == 0x0)
09579 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
09580
09581 if ((to_type == CPL_TYPE_STRING) || (from_type == CPL_TYPE_STRING) ||
09582 (to_type & CPL_TYPE_POINTER) || (from_type & CPL_TYPE_POINTER))
09583 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
09584
09585 if (to_length != from_length)
09586 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
09587
09588 if (to_length == 0)
09589 return CPL_ERROR_NONE;
09590
09591 if (to_column->nullcount == to_length)
09592 return CPL_ERROR_NONE;
09593
09594 if (from_column->nullcount == from_length)
09595 return xxx_column_fill_invalid(to_column, 0, to_length);
09596
09597
09598 fip = from_column->values->i;
09599 ffp = from_column->values->f;
09600 fdp = from_column->values->d;
09601 tip = to_column->values->i;
09602 tfp = to_column->values->f;
09603 tdp = to_column->values->d;
09604
09605 if (to_column->nullcount == 0 && from_column->nullcount == 0) {
09606
09607
09608
09609
09610
09611
09612 switch (to_type) {
09613
09614 case CPL_TYPE_INT:
09615
09616 switch (from_type) {
09617
09618 case CPL_TYPE_INT:
09619 while (to_length--)
09620 *tip++ *= *fip++;
09621 break;
09622
09623 case CPL_TYPE_FLOAT:
09624 while (to_length--)
09625 *tip++ *= *ffp++;
09626 break;
09627
09628 case CPL_TYPE_DOUBLE:
09629 while (to_length--)
09630 *tip++ *= *fdp++;
09631 break;
09632
09633 default:
09634 break;
09635 }
09636 break;
09637
09638 case CPL_TYPE_FLOAT:
09639
09640 switch (from_type) {
09641
09642 case CPL_TYPE_INT:
09643 while (to_length--)
09644 *tfp++ *= (double)*fip++;
09645 break;
09646
09647 case CPL_TYPE_FLOAT:
09648 while (to_length--)
09649 *tfp++ *= (double)*ffp++;
09650 break;
09651
09652 case CPL_TYPE_DOUBLE:
09653 while (to_length--)
09654 *tfp++ *= *fdp++;
09655 break;
09656
09657 default:
09658 break;
09659 }
09660 break;
09661
09662 case CPL_TYPE_DOUBLE:
09663
09664 switch (from_type) {
09665
09666 case CPL_TYPE_INT:
09667 while (to_length--)
09668 *tdp++ *= *fip++;
09669 break;
09670
09671 case CPL_TYPE_FLOAT:
09672 while (to_length--)
09673 *tdp++ *= *ffp++;
09674 break;
09675
09676 case CPL_TYPE_DOUBLE:
09677 while (to_length--)
09678 *tdp++ *= *fdp++;
09679 break;
09680
09681 default:
09682 break;
09683 }
09684 break;
09685
09686 default:
09687 break;
09688 }
09689 }
09690 else {
09691
09692
09693
09694
09695
09696
09697
09698 if (to_column->nullcount == 0 || from_column->nullcount == 0) {
09699
09700
09701
09702
09703
09704
09705
09706 if (from_column->nullcount) {
09707 to_column->null = cpl_calloc(to_length, sizeof(xxx_column_flag));
09708
09709 i = to_length;
09710 while (i--)
09711 if (from_column->null[i])
09712 to_column->null[i] = 1;
09713
09714 to_column->nullcount = from_column->nullcount;
09715
09716 }
09717 }
09718 else {
09719
09720
09721
09722
09723
09724 i = to_length;
09725 while (i--) {
09726 if (from_column->null[i]) {
09727 if (!to_column->null[i]) {
09728 to_column->null[i] = 1;
09729 to_column->nullcount++;
09730 }
09731 }
09732 }
09733
09734 if (to_column->nullcount == to_length) {
09735
09736
09737
09738
09739
09740
09741
09742 if (to_column->null)
09743 cpl_free(to_column->null);
09744 to_column->null = NULL;
09745 return 0;
09746 }
09747
09748 }
09749
09750
09751
09752
09753
09754
09755 tnp = to_column->null;
09756
09757 switch (to_type) {
09758
09759 case CPL_TYPE_INT:
09760
09761 switch (from_type) {
09762
09763 case CPL_TYPE_INT:
09764 while (to_length--) {
09765 if (*tnp++ == 0)
09766 *tip *= *fip;
09767 tip++;
09768 fip++;
09769 }
09770 break;
09771
09772 case CPL_TYPE_FLOAT:
09773 while (to_length--) {
09774 if (*tnp++ == 0)
09775 *tip *= *ffp;
09776 tip++;
09777 ffp++;
09778 }
09779 break;
09780
09781 case CPL_TYPE_DOUBLE:
09782 while (to_length--) {
09783 if (*tnp++ == 0)
09784 *tip *= *fdp;
09785 tip++;
09786 fdp++;
09787 }
09788 break;
09789
09790 default:
09791 break;
09792 }
09793 break;
09794
09795 case CPL_TYPE_FLOAT:
09796
09797 switch (from_type) {
09798
09799 case CPL_TYPE_INT:
09800 while (to_length--) {
09801 if (*tnp++ == 0)
09802 *tfp *= (double)*fip;
09803 tfp++;
09804 fip++;
09805 }
09806 break;
09807
09808 case CPL_TYPE_FLOAT:
09809 while (to_length--) {
09810 if (*tnp++ == 0)
09811 *tfp *= (double)*ffp;
09812 tfp++;
09813 ffp++;
09814 }
09815 break;
09816
09817 case CPL_TYPE_DOUBLE:
09818 while (to_length--) {
09819 if (*tnp++ == 0)
09820 *tfp *= *fdp;
09821 tfp++;
09822 fdp++;
09823 }
09824 break;
09825
09826 default:
09827 break;
09828 }
09829 break;
09830
09831 case CPL_TYPE_DOUBLE:
09832
09833 switch (from_type) {
09834
09835 case CPL_TYPE_INT:
09836 while (to_length--) {
09837 if (*tnp++ == 0)
09838 *tdp *= *fip;
09839 tdp++;
09840 fip++;
09841 }
09842 break;
09843
09844 case CPL_TYPE_FLOAT:
09845 while (to_length--) {
09846 if (*tnp++ == 0)
09847 *tdp *= *ffp;
09848 tdp++;
09849 ffp++;
09850 }
09851 break;
09852
09853 case CPL_TYPE_DOUBLE:
09854 while (to_length--) {
09855 if (*tnp++ == 0)
09856 *tdp *= *fdp;
09857 tdp++;
09858 fdp++;
09859 }
09860 break;
09861
09862 default:
09863 break;
09864 }
09865 break;
09866
09867 default:
09868 break;
09869 }
09870 }
09871
09872 return CPL_ERROR_NONE;
09873
09874 }
09875
09876
09877
09878
09879
09880
09881
09882
09883
09884
09885
09886
09887
09888
09889
09890
09891
09892
09893
09894
09895
09896
09897
09898
09899
09900 cpl_error_code xxx_column_divide(xxx_column *to_column,
09901 xxx_column *from_column)
09902 {
09903
09904 const char *fid = "xxx_column_divide";
09905 int i;
09906 int to_length = xxx_column_get_size(to_column);
09907 int from_length = xxx_column_get_size(from_column);
09908 cpl_type to_type = xxx_column_get_type(to_column);
09909 cpl_type from_type = xxx_column_get_type(from_column);
09910
09911 int *fip;
09912 float *ffp;
09913 double *fdp;
09914 int *tip;
09915 float *tfp;
09916 double *tdp;
09917 int *fnp;
09918 int *tnp;
09919
09920
09921 if (to_column == 0x0 || from_column == 0x0)
09922 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
09923
09924 if ((to_type == CPL_TYPE_STRING) || (from_type == CPL_TYPE_STRING) ||
09925 (to_type & CPL_TYPE_POINTER) || (from_type & CPL_TYPE_POINTER))
09926 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
09927
09928 if (to_length != from_length)
09929 return cpl_error_set(fid, CPL_ERROR_INCOMPATIBLE_INPUT);
09930
09931 if (to_length == 0)
09932 return CPL_ERROR_NONE;
09933
09934 if (from_column->nullcount == from_length)
09935 return xxx_column_fill_invalid(to_column, 0, to_length);
09936
09937
09938
09939
09940
09941
09942
09943 if (from_column->nullcount == 0) {
09944
09945 switch (from_type) {
09946
09947 case CPL_TYPE_INT:
09948 fip = from_column->values->i;
09949 for (i = 0; i < to_length; i++)
09950 if (*fip++ == 0)
09951 xxx_column_set_invalid(to_column, i);
09952 break;
09953
09954 case CPL_TYPE_FLOAT:
09955 ffp = from_column->values->f;
09956 for (i = 0; i < to_length; i++)
09957 if (*ffp++ == 0.0)
09958 xxx_column_set_invalid(to_column, i);
09959 break;
09960
09961 case CPL_TYPE_DOUBLE:
09962 fdp = from_column->values->d;
09963 for (i = 0; i < to_length; i++)
09964 if (*fdp++ == 0.0)
09965 xxx_column_set_invalid(to_column, i);
09966 break;
09967
09968 default:
09969 break;
09970
09971 }
09972 }
09973 else {
09974
09975 fnp = from_column->null;
09976
09977 switch (from_type) {
09978
09979 case CPL_TYPE_INT:
09980 fip = from_column->values->i;
09981 for (i = 0; i < to_length; i++, fip++)
09982 if (*fnp++ == 0)
09983 if (*fip == 0)
09984 xxx_column_set_invalid(to_column, i);
09985 break;
09986
09987 case CPL_TYPE_FLOAT:
09988 ffp = from_column->values->f;
09989 for (i = 0; i < to_length; i++, ffp++)
09990 if (*fnp++ == 0)
09991 if (*ffp == 0.0)
09992 xxx_column_set_invalid(to_column, i);
09993 break;
09994
09995 case CPL_TYPE_DOUBLE:
09996 fdp = from_column->values->d;
09997 for (i = 0; i < to_length; i++, fdp++)
09998 if (*fnp++ == 0)
09999 if (*fdp == 0.0)
10000 xxx_column_set_invalid(to_column, i);
10001 break;
10002
10003 default:
10004 break;
10005
10006 }
10007
10008 }
10009
10010
10011
10012
10013
10014
10015
10016 if (to_column->nullcount == to_length)
10017 return CPL_ERROR_NONE;
10018
10019
10020 fip = from_column->values->i;
10021 ffp = from_column->values->f;
10022 fdp = from_column->values->d;
10023 tip = to_column->values->i;
10024 tfp = to_column->values->f;
10025 tdp = to_column->values->d;
10026
10027 if (to_column->nullcount == 0 && from_column->nullcount == 0) {
10028
10029
10030
10031
10032
10033
10034 switch (to_type) {
10035
10036 case CPL_TYPE_INT:
10037
10038 switch (from_type) {
10039
10040 case CPL_TYPE_INT:
10041 while (to_length--)
10042 *tip++ /= *fip++;
10043 break;
10044
10045 case CPL_TYPE_FLOAT:
10046 while (to_length--)
10047 *tip++ /= *ffp++;
10048 break;
10049
10050 case CPL_TYPE_DOUBLE:
10051 while (to_length--)
10052 *tip++ /= *fdp++;
10053 break;
10054
10055 default:
10056 break;
10057 }
10058 break;
10059
10060 case CPL_TYPE_FLOAT:
10061
10062 switch (from_type) {
10063
10064 case CPL_TYPE_INT:
10065 while (to_length--)
10066 *tfp++ /= (double)*fip++;
10067 break;
10068
10069 case CPL_TYPE_FLOAT:
10070 while (to_length--)
10071 *tfp++ /= (double)*ffp++;
10072 break;
10073
10074 case CPL_TYPE_DOUBLE:
10075 while (to_length--)
10076 *tfp++ /= *fdp++;
10077 break;
10078
10079 default:
10080 break;
10081 }
10082 break;
10083
10084 case CPL_TYPE_DOUBLE:
10085
10086 switch (from_type) {
10087
10088 case CPL_TYPE_INT:
10089 while (to_length--)
10090 *tdp++ /= *fip++;
10091 break;
10092
10093 case CPL_TYPE_FLOAT:
10094 while (to_length--)
10095 *tdp++ /= *ffp++;
10096 break;
10097
10098 case CPL_TYPE_DOUBLE:
10099 while (to_length--)
10100 *tdp++ /= *fdp++;
10101 break;
10102
10103 default:
10104 break;
10105 }
10106 break;
10107
10108 default:
10109 break;
10110 }
10111 }
10112 else {
10113
10114
10115
10116
10117
10118
10119
10120 if (to_column->nullcount == 0 || from_column->nullcount == 0) {
10121
10122
10123
10124
10125
10126
10127
10128 if (from_column->nullcount) {
10129 to_column->null = cpl_calloc(to_length,
10130 sizeof(xxx_column_flag));
10131
10132 i = to_length;
10133 while (i--)
10134 if (from_column->null[i])
10135 to_column->null[i] = 1;
10136
10137 to_column->nullcount = from_column->nullcount;
10138
10139 }
10140 }
10141 else {
10142
10143
10144
10145
10146
10147 i = to_length;
10148 while (i--) {
10149 if (from_column->null[i]) {
10150 if (!to_column->null[i]) {
10151 to_column->null[i] = 1;
10152 to_column->nullcount++;
10153 }
10154 }
10155 }
10156
10157 if (to_column->nullcount == to_length) {
10158
10159
10160
10161
10162
10163
10164
10165 if (to_column->null)
10166 cpl_free(to_column->null);
10167 to_column->null = NULL;
10168 return 0;
10169 }
10170
10171 }
10172
10173
10174
10175
10176
10177
10178
10179 tnp = to_column->null;
10180
10181 switch (to_type) {
10182
10183 case CPL_TYPE_INT:
10184
10185 switch (from_type) {
10186
10187 case CPL_TYPE_INT:
10188 for (i = 0; i < to_length; i++, tip++, fip++, tnp++)
10189 if (*tnp == 0)
10190 *tip /= *fip;
10191 break;
10192
10193 case CPL_TYPE_FLOAT:
10194 for (i = 0; i < to_length; i++, tip++, ffp++, tnp++)
10195 if (*tnp == 0)
10196 *tip /= *ffp;
10197 break;
10198
10199 case CPL_TYPE_DOUBLE:
10200 for (i = 0; i < to_length; i++, tip++, fdp++, tnp++)
10201 if (*tnp == 0)
10202 *tip /= *fdp;
10203 break;
10204
10205 default:
10206 break;
10207 }
10208 break;
10209
10210 case CPL_TYPE_FLOAT:
10211
10212 switch (from_type) {
10213
10214 case CPL_TYPE_INT:
10215 for (i = 0; i < to_length; i++, tfp++, fip++, tnp++)
10216 if (*tnp == 0)
10217 *tfp /= (double)*fip;
10218 break;
10219
10220 case CPL_TYPE_FLOAT:
10221 for (i = 0; i < to_length; i++, tfp++, ffp++, tnp++)
10222 if (*tnp == 0)
10223 *tfp /= (double)*ffp;
10224 break;
10225
10226 case CPL_TYPE_DOUBLE:
10227 for (i = 0; i < to_length; i++, tfp++, fdp++, tnp++)
10228 if (*tnp == 0)
10229 *tfp /= *fdp;
10230 break;
10231
10232 default:
10233 break;
10234 }
10235 break;
10236
10237 case CPL_TYPE_DOUBLE:
10238
10239 switch (from_type) {
10240
10241 case CPL_TYPE_INT:
10242 for (i = 0; i < to_length; i++, tdp++, fip++, tnp++)
10243 if (*tnp == 0)
10244 *tdp /= *fip;
10245 break;
10246
10247 case CPL_TYPE_FLOAT:
10248 for (i = 0; i < to_length; i++, tdp++, ffp++, tnp++)
10249 if (*tnp == 0)
10250 *tdp /= *ffp;
10251 break;
10252
10253 case CPL_TYPE_DOUBLE:
10254 for (i = 0; i < to_length; i++, tdp++, fdp++, tnp++)
10255 if (*tnp == 0)
10256 *tdp /= *fdp;
10257 break;
10258
10259 default:
10260 break;
10261 }
10262 break;
10263
10264 default:
10265 break;
10266 }
10267 }
10268
10269 return CPL_ERROR_NONE;
10270
10271 }
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288 static void xxx_column_exp_int(xxx_column *column, double base)
10289 {
10290
10291 int nullcount = xxx_column_count_invalid(column);
10292 int length = xxx_column_get_size(column);
10293 int *ip = xxx_column_get_data_int(column);
10294 int *np = xxx_column_get_data_invalid(column);
10295 int i;
10296
10297
10298 if (nullcount == length)
10299 return;
10300
10301 if (nullcount == 0) {
10302 for (i = 0; i < length; i++, ip++)
10303 *ip = xxx_tools_ipow(base, *ip);
10304 }
10305 else {
10306 for (i = 0; i < length; i++, ip++, np++)
10307 if (*np == 0)
10308 *ip = xxx_tools_ipow(base, *ip);
10309 }
10310
10311 }
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328 static void xxx_column_exp_float(xxx_column *column, double base)
10329 {
10330
10331 int nullcount = xxx_column_count_invalid(column);
10332 int length = xxx_column_get_size(column);
10333 float *fp = xxx_column_get_data_float(column);
10334 int *np = xxx_column_get_data_invalid(column);
10335 int i;
10336
10337
10338 if (nullcount == length)
10339 return;
10340
10341 if (nullcount == 0) {
10342 for (i = 0; i < length; i++, fp++)
10343 *fp = pow(base, *fp);
10344 }
10345 else {
10346 for (i = 0; i < length; i++, fp++, np++)
10347 if (*np == 0)
10348 *fp = pow(base, *fp);
10349 }
10350
10351 }
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368 static void xxx_column_exp_double(xxx_column *column, double base)
10369 {
10370
10371 int nullcount = xxx_column_count_invalid(column);
10372 int length = xxx_column_get_size(column);
10373 double *dp = xxx_column_get_data_double(column);
10374 int *np = xxx_column_get_data_invalid(column);
10375 int i;
10376
10377
10378 if (nullcount == length)
10379 return;
10380
10381 if (nullcount == 0) {
10382 for (i = 0; i < length; i++, dp++)
10383 *dp = pow(base, *dp);
10384 }
10385 else {
10386 for (i = 0; i < length; i++, dp++, np++)
10387 if (*np == 0)
10388 *dp = pow(base, *dp);
10389 }
10390
10391 }
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408 static void xxx_column_pow_int(xxx_column *column, double exponent)
10409 {
10410
10411 int nullcount = xxx_column_count_invalid(column);
10412 int length = xxx_column_get_size(column);
10413 int *ip = xxx_column_get_data_int(column);
10414 int *np = xxx_column_get_data_invalid(column);
10415 int negative = exponent < 0.0;
10416 int i;
10417
10418
10419 if (nullcount == length)
10420 return;
10421
10422 if (negative)
10423 exponent = -exponent;
10424
10425 if (exponent != 1.0) {
10426 if (nullcount == 0) {
10427 if (negative) {
10428 for (i = 0; i < length; i++, ip++) {
10429 if (*ip > 0)
10430 *ip = floor(1 / pow(*ip, exponent) + 0.5);
10431 else
10432 xxx_column_set_invalid(column, i);
10433 }
10434 }
10435 else {
10436 for (i = 0; i < length; i++, ip++) {
10437 if (*ip >= 0)
10438 *ip = floor(pow(*ip, exponent) + 0.5);
10439 else
10440 xxx_column_set_invalid(column, i);
10441 }
10442 }
10443 }
10444 else {
10445 for (i = 0; i < length; i++, ip++, np++) {
10446 if (negative) {
10447 if (*np == 0) {
10448 if (*ip > 0)
10449 *ip = floor(1 / pow(*ip, exponent) + 0.5);
10450 else
10451 xxx_column_set_invalid(column, i);
10452 }
10453 }
10454 else {
10455 if (*np == 0) {
10456 if (*ip >= 0)
10457 *ip = floor(pow(*ip, exponent) + 0.5);
10458 else
10459 xxx_column_set_invalid(column, i);
10460 }
10461 }
10462 }
10463 }
10464 }
10465 }
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482 static void xxx_column_pow_float(xxx_column *column, double exponent)
10483 {
10484
10485 int nullcount = xxx_column_count_invalid(column);
10486 int length = xxx_column_get_size(column);
10487 float *fp = xxx_column_get_data_float(column);
10488 int *np = xxx_column_get_data_invalid(column);
10489 int negative = exponent < 0.0;
10490 int i;
10491
10492
10493 if (nullcount == length)
10494 return;
10495
10496 if (negative)
10497 exponent = -exponent;
10498
10499 if (exponent != 1.0) {
10500 if (nullcount == 0) {
10501 if (negative) {
10502 for (i = 0; i < length; i++, fp++) {
10503 if (*fp > 0.0)
10504 *fp = 1 / pow(*fp, exponent);
10505 else
10506 xxx_column_set_invalid(column, i);
10507 }
10508 }
10509 else {
10510 for (i = 0; i < length; i++, fp++) {
10511 if (*fp >= 0.0)
10512 *fp = pow(*fp, exponent);
10513 else
10514 xxx_column_set_invalid(column, i);
10515 }
10516 }
10517 }
10518 else {
10519 for (i = 0; i < length; i++, fp++, np++) {
10520 if (negative) {
10521 if (*np == 0) {
10522 if (*fp > 0.0)
10523 *fp = 1 / pow(*fp, exponent);
10524 else
10525 xxx_column_set_invalid(column, i);
10526 }
10527 }
10528 else {
10529 if (*np == 0) {
10530 if (*fp >= 0.0)
10531 *fp = pow(*fp, exponent);
10532 else
10533 xxx_column_set_invalid(column, i);
10534 }
10535 }
10536 }
10537 }
10538 }
10539 }
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556 static void xxx_column_pow_double(xxx_column *column, double exponent)
10557 {
10558
10559 int nullcount = xxx_column_count_invalid(column);
10560 int length = xxx_column_get_size(column);
10561 double *dp = xxx_column_get_data_double(column);
10562 int *np = xxx_column_get_data_invalid(column);
10563 int negative = exponent < 0.0;
10564 int i;
10565
10566
10567 if (nullcount == length)
10568 return;
10569
10570 if (negative)
10571 exponent = -exponent;
10572
10573 if (nullcount == 0) {
10574 if (negative) {
10575 for (i = 0; i < length; i++, dp++) {
10576 if (*dp > 0.0)
10577 *dp = 1 / pow(*dp, exponent);
10578 else
10579 xxx_column_set_invalid(column, i);
10580 }
10581 }
10582 else {
10583 for (i = 0; i < length; i++, dp++) {
10584 if (*dp >= 0.0)
10585 *dp = pow(*dp, exponent);
10586 else
10587 xxx_column_set_invalid(column, i);
10588 }
10589 }
10590 }
10591 else {
10592 for (i = 0; i < length; i++, dp++, np++) {
10593 if (negative) {
10594 if (*np == 0) {
10595 if (*dp > 0.0)
10596 *dp = 1 / pow(*dp, exponent);
10597 else
10598 xxx_column_set_invalid(column, i);
10599 }
10600 }
10601 else {
10602 if (*np == 0) {
10603 if (*dp >= 0.0)
10604 *dp = pow(*dp, exponent);
10605 else
10606 xxx_column_set_invalid(column, i);
10607 }
10608 }
10609 }
10610 }
10611 }
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628 static void xxx_column_log_int(xxx_column *column, double base)
10629 {
10630
10631 int nullcount = xxx_column_count_invalid(column);
10632 int length = xxx_column_get_size(column);
10633 int *ip = xxx_column_get_data_int(column);
10634 int *np = xxx_column_get_data_invalid(column);
10635 int i;
10636 double invlog = 1 / log(base);
10637
10638
10639 if (nullcount == length)
10640 return;
10641
10642 if (nullcount == 0) {
10643 for (i = 0; i < length; i++, ip++) {
10644 if (*ip > 0)
10645 *ip = floor(log(*ip) * invlog + 0.5);
10646 else
10647 xxx_column_set_invalid(column, i);
10648 }
10649 }
10650 else {
10651 for (i = 0; i < length; i++, ip++, np++) {
10652 if (*np == 0) {
10653 if (*ip > 0)
10654 *ip = floor(log(*ip) * invlog + 0.5);
10655 else
10656 xxx_column_set_invalid(column, i);
10657 }
10658 }
10659 }
10660 }
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677 static void xxx_column_log_float(xxx_column *column, double base)
10678 {
10679
10680 int nullcount = xxx_column_count_invalid(column);
10681 int length = xxx_column_get_size(column);
10682 float *fp = xxx_column_get_data_float(column);
10683 int *np = xxx_column_get_data_invalid(column);
10684 int i;
10685 double invlog = 1 / log(base);
10686
10687
10688 if (nullcount == length)
10689 return;
10690
10691 if (nullcount == 0) {
10692 for (i = 0; i < length; i++, fp++) {
10693 if (*fp > 0.0)
10694 *fp = log(*fp) * invlog;
10695 else
10696 xxx_column_set_invalid(column, i);
10697 }
10698 }
10699 else {
10700 for (i = 0; i < length; i++, fp++, np++) {
10701 if (*np == 0) {
10702 if (*fp > 0.0)
10703 *fp = log(*fp) * invlog;
10704 else
10705 xxx_column_set_invalid(column, i);
10706 }
10707 }
10708 }
10709 }
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726 static void xxx_column_log_double(xxx_column *column, double base)
10727 {
10728
10729 int nullcount = xxx_column_count_invalid(column);
10730 int length = xxx_column_get_size(column);
10731 double *dp = xxx_column_get_data_double(column);
10732 int *np = xxx_column_get_data_invalid(column);
10733 int i;
10734 double invlog = 1 / log(base);
10735
10736
10737 if (nullcount == length)
10738 return;
10739
10740 if (nullcount == 0) {
10741 for (i = 0; i < length; i++, dp++) {
10742 if (*dp > 0.0)
10743 *dp = log(*dp) * invlog;
10744 else
10745 xxx_column_set_invalid(column, i);
10746 }
10747 }
10748 else {
10749 for (i = 0; i < length; i++, dp++, np++) {
10750 if (*np == 0) {
10751 if (*dp > 0.0)
10752 *dp = log(*dp) * invlog;
10753 else
10754 xxx_column_set_invalid(column, i);
10755 }
10756 }
10757 }
10758 }
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775 static void xxx_column_add_to_int(xxx_column *column, int value)
10776 {
10777
10778 int nullcount = xxx_column_count_invalid(column);
10779 int length = xxx_column_get_size(column);
10780 int *ip = xxx_column_get_data_int(column);
10781 int *np = xxx_column_get_data_invalid(column);
10782 int i;
10783
10784
10785 if (value == 0)
10786 return;
10787
10788 if (nullcount == length)
10789 return;
10790
10791 if (nullcount == 0)
10792 for (i = 0; i < length; i++)
10793 *ip++ += value;
10794 else
10795 for (i = 0; i < length; i++, ip++, np++)
10796 if (*np == 0)
10797 *ip += value;
10798
10799 }
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816 static void xxx_column_add_to_float(xxx_column *column, double value)
10817 {
10818
10819 int nullcount = xxx_column_count_invalid(column);
10820 int length = xxx_column_get_size(column);
10821 float *fp = xxx_column_get_data_float(column);
10822 int *np = xxx_column_get_data_invalid(column);
10823 int i;
10824
10825
10826 if (value == 0.0)
10827 return;
10828
10829 if (nullcount == length)
10830 return;
10831
10832 if (nullcount == 0)
10833 for (i = 0; i < length; i++)
10834 *fp++ += value;
10835 else
10836 for (i = 0; i < length; i++, fp++, np++)
10837 if (*np == 0)
10838 *fp += value;
10839
10840 }
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857 static void xxx_column_add_to_double(xxx_column *column, double value)
10858 {
10859
10860 int nullcount = xxx_column_count_invalid(column);
10861 int length = xxx_column_get_size(column);
10862 double *dp = xxx_column_get_data_double(column);
10863 int *np = xxx_column_get_data_invalid(column);
10864 int i;
10865
10866
10867 if (value == 0.0)
10868 return;
10869
10870 if (nullcount == length)
10871 return;
10872
10873 if (nullcount == 0)
10874 for (i = 0; i < length; i++)
10875 *dp++ += value;
10876 else
10877 for (i = 0; i < length; i++, dp++, np++)
10878 if (*np == 0)
10879 *dp += value;
10880
10881 }
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898 static void xxx_column_mul_to_double(xxx_column *column, double value)
10899 {
10900
10901 int nullcount = xxx_column_count_invalid(column);
10902 int length = xxx_column_get_size(column);
10903 double *dp = xxx_column_get_data_double(column);
10904 int *np = xxx_column_get_data_invalid(column);
10905 int i;
10906
10907
10908 if (value == 1.0)
10909 return;
10910
10911 if (nullcount == length)
10912 return;
10913
10914 if (nullcount == 0)
10915 for (i = 0; i < length; i++)
10916 *dp++ *= value;
10917 else
10918 for (i = 0; i < length; i++, dp++, np++)
10919 if (*np == 0)
10920 *dp *= value;
10921
10922 }
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939 static void xxx_column_mul_double_to_int(xxx_column *column, double value)
10940 {
10941
10942 int nullcount = xxx_column_count_invalid(column);
10943 int length = xxx_column_get_size(column);
10944 int *ip = xxx_column_get_data_int(column);
10945 int *np = xxx_column_get_data_invalid(column);
10946 int i;
10947
10948
10949 if (value == 1.0)
10950 return;
10951
10952 if (nullcount == length)
10953 return;
10954
10955 if (nullcount == 0)
10956 for (i = 0; i < length; i++)
10957 *ip++ *= value;
10958 else
10959 for (i = 0; i < length; i++, ip++, np++)
10960 if (*np == 0)
10961 *ip *= value;
10962
10963 }
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980 static void xxx_column_mul_double_to_float(xxx_column *column, double value)
10981 {
10982
10983 int nullcount = xxx_column_count_invalid(column);
10984 int length = xxx_column_get_size(column);
10985 float *fp = xxx_column_get_data_float(column);
10986 int *np = xxx_column_get_data_invalid(column);
10987 int i;
10988
10989
10990 if (value == 1.0)
10991 return;
10992
10993 if (nullcount == length)
10994 return;
10995
10996 if (nullcount == 0)
10997 for (i = 0; i < length; i++)
10998 *fp++ *= value;
10999 else
11000 for (i = 0; i < length; i++, fp++, np++)
11001 if (*np == 0)
11002 *fp *= value;
11003
11004 }
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026 cpl_error_code xxx_column_logarithm(xxx_column *column, double base)
11027 {
11028
11029 const char *fid = "xxx_column_logarithm";
11030 cpl_type type = xxx_column_get_type(column);
11031
11032
11033 if (column == 0x0)
11034 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11035
11036 if (base <= 0.0)
11037 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
11038
11039
11040 switch (type) {
11041
11042 case CPL_TYPE_INT:
11043 xxx_column_log_int(column, base);
11044 break;
11045 case CPL_TYPE_FLOAT:
11046 xxx_column_log_float(column, base);
11047 break;
11048 case CPL_TYPE_DOUBLE:
11049 xxx_column_log_double(column, base);
11050 break;
11051 default:
11052 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11053
11054 }
11055
11056 return CPL_ERROR_NONE;
11057
11058 }
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079 cpl_error_code xxx_column_exponential(xxx_column *column, double base)
11080 {
11081
11082 const char *fid = "xxx_column_exponential";
11083 cpl_type type = xxx_column_get_type(column);
11084
11085
11086 if (column == 0x0)
11087 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11088
11089 if (base <= 0.0)
11090 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
11091
11092
11093 switch (type) {
11094
11095 case CPL_TYPE_INT:
11096 xxx_column_exp_int(column, base);
11097 break;
11098 case CPL_TYPE_FLOAT:
11099 xxx_column_exp_float(column, base);
11100 break;
11101 case CPL_TYPE_DOUBLE:
11102 xxx_column_exp_double(column, base);
11103 break;
11104 default:
11105 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11106
11107 }
11108
11109 return CPL_ERROR_NONE;
11110
11111 }
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131 cpl_error_code xxx_column_power(xxx_column *column, double exponent)
11132 {
11133
11134 const char *fid = "xxx_column_power";
11135 cpl_type type = xxx_column_get_type(column);
11136
11137
11138 if (column == 0x0)
11139 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11140
11141
11142 switch (type) {
11143
11144 case CPL_TYPE_INT:
11145 xxx_column_pow_int(column, exponent);
11146 break;
11147 case CPL_TYPE_FLOAT:
11148 xxx_column_pow_float(column, exponent);
11149 break;
11150 case CPL_TYPE_DOUBLE:
11151 xxx_column_pow_double(column, exponent);
11152 break;
11153 default:
11154 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11155
11156 }
11157
11158 return CPL_ERROR_NONE;
11159
11160 }
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179 cpl_error_code xxx_column_add_scalar(xxx_column *column, double value)
11180 {
11181
11182 const char *fid = "xxx_column_add_scalar";
11183 cpl_type type = xxx_column_get_type(column);
11184
11185
11186 if (column == 0x0)
11187 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11188
11189
11190 switch (type) {
11191
11192 case CPL_TYPE_INT:
11193 xxx_column_add_to_int(column, value);
11194 break;
11195 case CPL_TYPE_FLOAT:
11196 xxx_column_add_to_float(column, value);
11197 break;
11198 case CPL_TYPE_DOUBLE:
11199 xxx_column_add_to_double(column, value);
11200 break;
11201 default:
11202 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11203
11204 }
11205
11206 return CPL_ERROR_NONE;
11207
11208 }
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227 cpl_error_code xxx_column_subtract_scalar(xxx_column *column, double value)
11228 {
11229
11230 return xxx_column_add_scalar(column, -value);
11231
11232 }
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251 cpl_error_code xxx_column_multiply_scalar(xxx_column *column, double value)
11252 {
11253
11254 const char *fid = "xxx_column_multiply_scalar";
11255 cpl_type type = xxx_column_get_type(column);
11256
11257
11258 if (column == 0x0)
11259 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11260
11261
11262 switch (type) {
11263
11264 case CPL_TYPE_INT:
11265 xxx_column_mul_double_to_int(column, value);
11266 break;
11267 case CPL_TYPE_FLOAT:
11268 xxx_column_mul_double_to_float(column, value);
11269 break;
11270 case CPL_TYPE_DOUBLE:
11271 xxx_column_mul_to_double(column, value);
11272 break;
11273 default:
11274 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11275
11276 }
11277
11278 return CPL_ERROR_NONE;
11279
11280 }
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300 cpl_error_code xxx_column_divide_scalar(xxx_column *column, double value)
11301 {
11302
11303 const char *fid = "xxx_column_divide_scalar";
11304 cpl_type type = xxx_column_get_type(column);
11305
11306
11307 if (column == 0x0)
11308 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11309
11310
11311 if (value == 0.0)
11312 return cpl_error_set(fid, CPL_ERROR_DIVISION_BY_ZERO);
11313
11314 value = 1 / value;
11315
11316 switch (type) {
11317
11318 case CPL_TYPE_INT:
11319 xxx_column_mul_double_to_int(column, value);
11320 break;
11321 case CPL_TYPE_FLOAT:
11322 xxx_column_mul_double_to_float(column, value);
11323 break;
11324 case CPL_TYPE_DOUBLE:
11325 xxx_column_mul_to_double(column, value);
11326 break;
11327 default:
11328 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11329
11330 }
11331
11332 return CPL_ERROR_NONE;
11333
11334 }
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355 double xxx_column_get_mean(xxx_column *column)
11356 {
11357
11358 const char *fid = "xxx_column_get_mean";
11359 int length = xxx_column_get_size(column);
11360 int nullcount = xxx_column_count_invalid(column);
11361 cpl_type type = xxx_column_get_type(column);
11362 double mean = 0.0;
11363 int count = length - nullcount;
11364 int i;
11365
11366 int *np;
11367 int *ip;
11368 float *fp;
11369 double *dp;
11370
11371
11372 if (column == 0x0) {
11373 cpl_error_set_where(fid);
11374 return 0.0;
11375 }
11376
11377
11378 if (nullcount == length || length == 0) {
11379 cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11380 return 0.0;
11381 }
11382
11383 np = column->null;
11384
11385 switch (type) {
11386
11387 case CPL_TYPE_INT:
11388 ip = column->values->i;
11389 if (nullcount == 0)
11390 for (i = 0; i < length; i++)
11391 mean += *ip++;
11392 else
11393 for (i = 0; i < length; i++, ip++, np++)
11394 if (*np == 0)
11395 mean += *ip;
11396 break;
11397
11398 case CPL_TYPE_FLOAT:
11399 fp = column->values->f;
11400 if (nullcount == 0)
11401 for (i = 0; i < length; i++)
11402 mean += *fp++;
11403 else
11404 for (i = 0; i < length; i++, fp++, np++)
11405 if (*np == 0)
11406 mean += *fp;
11407 break;
11408
11409 case CPL_TYPE_DOUBLE:
11410 dp = column->values->d;
11411 if (nullcount == 0)
11412 for (i = 0; i < length; i++)
11413 mean += *dp++;
11414 else
11415 for (i = 0; i < length; i++, dp++, np++)
11416 if (*np == 0)
11417 mean += *dp;
11418 break;
11419
11420 default:
11421 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11422
11423 }
11424
11425 return (mean / count);
11426
11427 }
11428
11429
11430 double xxx_column_get_stdev(xxx_column *column)
11431 {
11432
11433 const char *fid = "xxx_column_get_stdev";
11434 int length = xxx_column_get_size(column);
11435 int nullcount = xxx_column_count_invalid(column);
11436 cpl_type type = xxx_column_get_type(column);
11437 double stdev = 0.0;
11438 double mean;
11439 int count = length - nullcount;
11440 int i;
11441
11442 int *np;
11443 int *ip;
11444 float *fp;
11445 double *dp;
11446
11447
11448 if (column == 0x0) {
11449 cpl_error_set_where(fid);
11450 return 0.0;
11451 }
11452
11453
11454 if (nullcount == length || length == 0) {
11455 cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11456 return 0.0;
11457 }
11458
11459 if (count == 1)
11460 return 0.0;
11461
11462 mean = xxx_column_get_mean(column);
11463
11464 np = column->null;
11465
11466 switch (type) {
11467
11468 case CPL_TYPE_INT:
11469 ip = column->values->i;
11470 if (nullcount == 0)
11471 for (i = 0; i < length; i++, ip++)
11472 stdev += (*ip - mean) * (*ip - mean);
11473 else
11474 for (i = 0; i < length; i++, ip++, np++)
11475 if (*np == 0)
11476 stdev += (*ip - mean) * (*ip - mean);
11477 break;
11478
11479 case CPL_TYPE_FLOAT:
11480 fp = column->values->f;
11481 if (nullcount == 0)
11482 for (i = 0; i < length; i++, fp++)
11483 stdev += (*fp - mean) * (*fp - mean);
11484 else
11485 for (i = 0; i < length; i++, fp++, np++)
11486 if (*np == 0)
11487 stdev += (*fp - mean) * (*fp - mean);
11488 break;
11489
11490 case CPL_TYPE_DOUBLE:
11491 dp = column->values->d;
11492 if (nullcount == 0)
11493 for (i = 0; i < length; i++, dp++)
11494 stdev += (*dp - mean) * (*dp - mean);
11495 else
11496 for (i = 0; i < length; i++, dp++, np++)
11497 if (*np == 0)
11498 stdev += (*dp - mean) * (*dp - mean);
11499 break;
11500
11501 default:
11502 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11503
11504 }
11505
11506 return sqrt(stdev / (count - 1));
11507
11508 }
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529 double xxx_column_get_max(xxx_column *column)
11530 {
11531
11532 const char *fid = "xxx_column_get_max";
11533 int length = xxx_column_get_size(column);
11534 int nullcount = xxx_column_count_invalid(column);
11535 cpl_type type = xxx_column_get_type(column);
11536 int first = 1;
11537 int *ip;
11538 float *fp;
11539 double *dp;
11540 int *np;
11541 double maximum = 0;
11542 int i;
11543
11544
11545 if (column == 0x0) {
11546 cpl_error_set_where(fid);
11547 return 0.0;
11548 }
11549
11550 if (nullcount == length || length == 0) {
11551 cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11552 return 0.0;
11553 }
11554
11555 np = column->null;
11556
11557 switch (type) {
11558 case CPL_TYPE_INT:
11559 ip = column->values->i;
11560 if (length == 1)
11561 return *ip;
11562 if (nullcount == 0) {
11563 maximum = *ip++;
11564 for (i = 1; i < length; i++, ip++)
11565 if (maximum < *ip)
11566 maximum = *ip;
11567 }
11568 else {
11569 for (i = 0; i < length; i++, ip++, np++) {
11570 if (*np == 0) {
11571 if (first) {
11572 first = 0;
11573 maximum = *ip;
11574 }
11575 else
11576 if (maximum < *ip)
11577 maximum = *ip;
11578 }
11579 }
11580 }
11581 break;
11582 case CPL_TYPE_FLOAT:
11583 fp = column->values->f;
11584 if (length == 1)
11585 return *fp;
11586 if (nullcount == 0) {
11587 maximum = *fp++;
11588 for (i = 1; i < length; i++, fp++)
11589 if (maximum < *fp)
11590 maximum = *fp;
11591 }
11592 else {
11593 for (i = 0; i < length; i++, fp++, np++) {
11594 if (*np == 0) {
11595 if (first) {
11596 first = 0;
11597 maximum = *fp;
11598 }
11599 else
11600 if (maximum < *fp)
11601 maximum = *fp;
11602 }
11603 }
11604 }
11605 break;
11606 case CPL_TYPE_DOUBLE:
11607 dp = column->values->d;
11608 if (length == 1)
11609 return *dp;
11610 if (nullcount == 0) {
11611 maximum = *dp++;
11612 for (i = 1; i < length; i++, dp++)
11613 if (maximum < *dp)
11614 maximum = *dp;
11615 }
11616 else {
11617 for (i = 0; i < length; i++, dp++, np++) {
11618 if (*np == 0) {
11619 if (first) {
11620 first = 0;
11621 maximum = *dp;
11622 }
11623 else
11624 if (maximum < *dp)
11625 maximum = *dp;
11626 }
11627 }
11628 }
11629 break;
11630 default:
11631 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11632 return 0.0;
11633 }
11634
11635 return maximum;
11636
11637 }
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658 double xxx_column_get_min(xxx_column *column)
11659 {
11660
11661 const char *fid = "xxx_column_get_min";
11662 int length = xxx_column_get_size(column);
11663 int nullcount = xxx_column_count_invalid(column);
11664 cpl_type type = xxx_column_get_type(column);
11665 int first = 1;
11666 int *ip;
11667 float *fp;
11668 double *dp;
11669 int *np;
11670 double minimum= 0;
11671 int i;
11672
11673
11674 if (column == 0x0) {
11675 cpl_error_set_where(fid);
11676 return 0.0;
11677 }
11678
11679 if (nullcount == length || length == 0) {
11680 cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11681 return 0.0;
11682 }
11683
11684 np = column->null;
11685
11686 switch (type) {
11687 case CPL_TYPE_INT:
11688 ip = column->values->i;
11689 if (length == 1)
11690 return *ip;
11691 if (nullcount == 0) {
11692 minimum = *ip++;
11693 for (i = 1; i < length; i++, ip++)
11694 if (minimum > *ip)
11695 minimum = *ip;
11696 }
11697 else {
11698 for (i = 0; i < length; i++, ip++, np++) {
11699 if (*np == 0) {
11700 if (first) {
11701 first = 0;
11702 minimum = *ip;
11703 }
11704 else
11705 if (minimum > *ip)
11706 minimum = *ip;
11707 }
11708 }
11709 }
11710 break;
11711 case CPL_TYPE_FLOAT:
11712 fp = column->values->f;
11713 if (length == 1)
11714 return *fp;
11715 if (nullcount == 0) {
11716 minimum = *fp++;
11717 for (i = 1; i < length; i++, fp++)
11718 if (minimum > *fp)
11719 minimum = *fp;
11720 }
11721 else {
11722 for (i = 0; i < length; i++, fp++, np++) {
11723 if (*np == 0) {
11724 if (first) {
11725 first = 0;
11726 minimum = *fp;
11727 }
11728 else
11729 if (minimum > *fp)
11730 minimum = *fp;
11731 }
11732 }
11733 }
11734 break;
11735 case CPL_TYPE_DOUBLE:
11736 dp = column->values->d;
11737 if (length == 1)
11738 return *dp;
11739 if (nullcount == 0) {
11740 minimum = *dp++;
11741 for (i = 1; i < length; i++, dp++)
11742 if (minimum > *dp)
11743 minimum = *dp;
11744 }
11745 else {
11746 for (i = 0; i < length; i++, dp++, np++) {
11747 if (*np == 0) {
11748 if (first) {
11749 first = 0;
11750 minimum = *dp;
11751 }
11752 else
11753 if (minimum > *dp)
11754 minimum = *dp;
11755 }
11756 }
11757 }
11758 break;
11759 default:
11760 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11761 return 0.0;
11762 }
11763
11764 return minimum;
11765
11766 }
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791 cpl_error_code xxx_column_get_maxpos(xxx_column *column, int *indx)
11792 {
11793
11794 const char *fid = "xxx_column_get_maxpos";
11795 int length = xxx_column_get_size(column);
11796 int nullcount = xxx_column_count_invalid(column);
11797 cpl_type type = xxx_column_get_type(column);
11798 int first = 1;
11799 int *ip;
11800 float *fp;
11801 double *dp;
11802 int *np;
11803 double maximum=0;
11804 int i;
11805
11806
11807 if (column == 0x0 || indx == 0x0)
11808 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11809
11810 if (nullcount == length || length == 0)
11811 return cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11812
11813 *indx = 0;
11814
11815 if (length == 1)
11816 return CPL_ERROR_NONE;
11817
11818 np = column->null;
11819
11820 switch (type) {
11821 case CPL_TYPE_INT:
11822 ip = column->values->i;
11823 if (nullcount == 0) {
11824 maximum = *ip++;
11825 for (i = 1; i < length; i++, ip++) {
11826 if (maximum < *ip) {
11827 maximum = *ip;
11828 *indx = i;
11829 }
11830 }
11831 }
11832 else {
11833 for (i = 0; i < length; i++, ip++, np++) {
11834 if (*np == 0) {
11835 if (first) {
11836 first = 0;
11837 maximum = *ip;
11838 *indx = i;
11839 }
11840 else {
11841 if (maximum < *ip) {
11842 maximum = *ip;
11843 *indx = i;
11844 }
11845 }
11846 }
11847 }
11848 }
11849 break;
11850 case CPL_TYPE_FLOAT:
11851 fp = column->values->f;
11852 if (nullcount == 0) {
11853 maximum = *fp++;
11854 for (i = 1; i < length; i++, fp++) {
11855 if (maximum < *fp) {
11856 maximum = *fp;
11857 *indx = i;
11858 }
11859 }
11860 }
11861 else {
11862 for (i = 0; i < length; i++, fp++, np++) {
11863 if (*np == 0) {
11864 if (first) {
11865 first = 0;
11866 maximum = *fp;
11867 *indx = i;
11868 }
11869 else {
11870 if (maximum < *fp) {
11871 maximum = *fp;
11872 *indx = i;
11873 }
11874 }
11875 }
11876 }
11877 }
11878 break;
11879 case CPL_TYPE_DOUBLE:
11880 dp = column->values->d;
11881 if (nullcount == 0) {
11882 maximum = *dp++;
11883 for (i = 1; i < length; i++, dp++) {
11884 if (maximum < *dp) {
11885 maximum = *dp;
11886 *indx = i;
11887 }
11888 }
11889 }
11890 else {
11891 for (i = 0; i < length; i++, dp++, np++) {
11892 if (*np == 0) {
11893 if (first) {
11894 first = 0;
11895 maximum = *dp;
11896 *indx = i;
11897 }
11898 else {
11899 if (maximum < *dp) {
11900 maximum = *dp;
11901 *indx = i;
11902 }
11903 }
11904 }
11905 }
11906 }
11907 break;
11908 default:
11909 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
11910 }
11911
11912 return CPL_ERROR_NONE;
11913
11914 }
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939 cpl_error_code xxx_column_get_minpos(xxx_column *column, int *indx)
11940 {
11941
11942 const char *fid = "xxx_column_get_minpos";
11943 int length = xxx_column_get_size(column);
11944 int nullcount = xxx_column_count_invalid(column);
11945 cpl_type type = xxx_column_get_type(column);
11946 int first = 1;
11947 int *ip;
11948 float *fp;
11949 double *dp;
11950 int *np;
11951 double minimum=0;
11952 int i;
11953
11954
11955 if (column == 0x0 || indx == 0x0)
11956 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
11957
11958 if (nullcount == length || length == 0)
11959 return cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
11960
11961 *indx = 0;
11962
11963 if (length == 1)
11964 return CPL_ERROR_NONE;
11965
11966 np = column->null;
11967
11968 switch (type) {
11969 case CPL_TYPE_INT:
11970 ip = column->values->i;
11971 if (nullcount == 0) {
11972 minimum = *ip++;
11973 for (i = 1; i < length; i++, ip++) {
11974 if (minimum > *ip) {
11975 minimum = *ip;
11976 *indx = i;
11977 }
11978 }
11979 }
11980 else {
11981 for (i = 0; i < length; i++, ip++, np++) {
11982 if (*np == 0) {
11983 if (first) {
11984 first = 0;
11985 minimum = *ip;
11986 *indx = i;
11987 }
11988 else {
11989 if (minimum > *ip) {
11990 minimum = *ip;
11991 *indx = i;
11992 }
11993 }
11994 }
11995 }
11996 }
11997 break;
11998 case CPL_TYPE_FLOAT:
11999 fp = column->values->f;
12000 if (nullcount == 0) {
12001 minimum = *fp++;
12002 for (i = 1; i < length; i++, fp++) {
12003 if (minimum > *fp) {
12004 minimum = *fp;
12005 *indx = i;
12006 }
12007 }
12008 }
12009 else {
12010 for (i = 0; i < length; i++, fp++, np++) {
12011 if (*np == 0) {
12012 if (first) {
12013 first = 0;
12014 minimum = *fp;
12015 *indx = i;
12016 }
12017 else {
12018 if (minimum > *fp) {
12019 minimum = *fp;
12020 *indx = i;
12021 }
12022 }
12023 }
12024 }
12025 }
12026 break;
12027 case CPL_TYPE_DOUBLE:
12028 dp = column->values->d;
12029 if (nullcount == 0) {
12030 minimum = *dp++;
12031 for (i = 1; i < length; i++, dp++) {
12032 if (minimum > *dp) {
12033 minimum = *dp;
12034 *indx = i;
12035 }
12036 }
12037 }
12038 else {
12039 for (i = 0; i < length; i++, dp++, np++) {
12040 if (*np == 0) {
12041 if (first) {
12042 first = 0;
12043 minimum = *dp;
12044 *indx = i;
12045 }
12046 else {
12047 if (minimum > *dp) {
12048 minimum = *dp;
12049 *indx = i;
12050 }
12051 }
12052 }
12053 }
12054 }
12055 break;
12056 default:
12057 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
12058 }
12059
12060 return CPL_ERROR_NONE;
12061
12062 }
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079 static int xxx_column_median_int(xxx_column *column)
12080 {
12081
12082 int length = xxx_column_get_size(column);
12083 int nullcount = xxx_column_count_invalid(column);
12084 int median = 0;
12085 int i, n;
12086 int *np;
12087 int *ip;
12088 int *cip;
12089 int *copybuf;
12090
12091
12092 n = length - nullcount;
12093 cip = copybuf = cpl_malloc(n * sizeof(int));
12094 ip = column->values->i;
12095 np = column->null;
12096
12097 if (nullcount) {
12098 for (i = 0; i < length; i++, np++, ip++) {
12099 if (*np == 0) {
12100 *cip = *ip;
12101 cip++;
12102 }
12103 }
12104 }
12105 else
12106 memcpy(copybuf, ip, length * sizeof(int));
12107
12108 median = xxx_tools_get_median_int(copybuf, n);
12109 cpl_free(copybuf);
12110
12111 return median;
12112
12113 }
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130 static float xxx_column_median_float(xxx_column *column)
12131 {
12132
12133 int length = xxx_column_get_size(column);
12134 int nullcount = xxx_column_count_invalid(column);
12135 float median = 0;
12136 int i, n;
12137 int *np;
12138 float *fp;
12139 float *cfp;
12140 float *copybuf;
12141
12142
12143 n = length - nullcount;
12144 cfp = copybuf = cpl_malloc(n * sizeof(float));
12145 fp = column->values->f;
12146 np = column->null;
12147
12148 if (nullcount) {
12149 for (i = 0; i < length; i++, np++, fp++) {
12150 if (*np == 0) {
12151 *cfp = *fp;
12152 cfp++;
12153 }
12154 }
12155 }
12156 else
12157 memcpy(copybuf, fp, length * sizeof(float));
12158
12159 median = xxx_tools_get_median_float(copybuf, n);
12160 cpl_free(copybuf);
12161
12162 return median;
12163
12164 }
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180 static double xxx_column_median_double(xxx_column *column)
12181 {
12182
12183 int length = xxx_column_get_size(column);
12184 int nullcount = xxx_column_count_invalid(column);
12185 double median = 0;
12186 int i, n;
12187 int *np;
12188 double *dp;
12189 double *cdp;
12190 double *copybuf;
12191
12192
12193 n = length - nullcount;
12194 cdp = copybuf = cpl_malloc(n * sizeof(double));
12195 dp = column->values->d;
12196 np = column->null;
12197
12198 if (nullcount) {
12199 for (i = 0; i < length; i++, np++, dp++) {
12200 if (*np == 0) {
12201 *cdp = *dp;
12202 cdp++;
12203 }
12204 }
12205 }
12206 else
12207 memcpy(copybuf, dp, length * sizeof(double));
12208
12209 median = xxx_tools_get_median_double(copybuf, n);
12210 cpl_free(copybuf);
12211
12212 return median;
12213
12214 }
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233 double xxx_column_get_median(xxx_column *column)
12234 {
12235
12236 const char *fid = "xxx_column_get_median";
12237 cpl_type type = xxx_column_get_type(column);
12238 int length = xxx_column_get_size(column);
12239 int nullcount = xxx_column_count_invalid(column);
12240
12241
12242 if (column == 0x0) {
12243 cpl_error_set_where(fid);
12244 return 0.0;
12245 }
12246
12247 if (nullcount == length || length == 0) {
12248 cpl_error_set(fid, CPL_ERROR_DATA_NOT_FOUND);
12249 return 0.0;
12250 }
12251
12252 switch (type) {
12253 case CPL_TYPE_INT:
12254 return (double)xxx_column_median_int(column);
12255 case CPL_TYPE_FLOAT:
12256 return (double)xxx_column_median_float(column);
12257 case CPL_TYPE_DOUBLE:
12258 return xxx_column_median_double(column);
12259 default:
12260 cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
12261 }
12262
12263 return 0.0;
12264
12265 }
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288 cpl_error_code xxx_column_shift(xxx_column *column, int shift)
12289 {
12290
12291 const char *fid = "xxx_column_shift";
12292 cpl_type type = xxx_column_get_type(column);
12293 int length = xxx_column_get_size(column);
12294 int j;
12295 int status;
12296 int *np1;
12297 int *np2;
12298 int *ip1;
12299 int *ip2;
12300 float *fp1;
12301 float *fp2;
12302 double *dp1;
12303 double *dp2;
12304
12305
12306 if (column == 0x0)
12307 return cpl_error_set(fid, CPL_ERROR_NULL_INPUT);
12308
12309
12310
12311
12312
12313
12314 switch (type) {
12315 case CPL_TYPE_INT:
12316 case CPL_TYPE_FLOAT:
12317 case CPL_TYPE_DOUBLE:
12318 break;
12319 default:
12320 return cpl_error_set(fid, CPL_ERROR_INVALID_TYPE);
12321 }
12322
12323 if (abs(shift) >= length)
12324 return cpl_error_set(fid, CPL_ERROR_ILLEGAL_INPUT);
12325
12326 if (shift == 0)
12327 return CPL_ERROR_NONE;
12328
12329 if (column->nullcount == length)
12330 return CPL_ERROR_NONE;
12331
12332
12333
12334
12335
12336
12337 if (column->nullcount) {
12338 if (shift > 0) {
12339 j = length - shift;
12340 np1 = column->null + length;
12341 np2 = np1 - shift;
12342 while (j--)
12343 *--np1 = *--np2;
12344 }
12345 else {
12346 j = -shift;
12347 np1 = column->null;
12348 np2 = np1 - shift;
12349 while(j++ < length)
12350 *np1++ = *np2++;
12351 }
12352
12353 }
12354
12355
12356
12357
12358
12359
12360 if (shift > 0)
12361 status = xxx_column_fill_invalid(column, 0, shift);
12362 else
12363 status = xxx_column_fill_invalid(column, length + shift, -shift);
12364
12365 if (status)
12366 return status;
12367
12368
12369
12370
12371
12372
12373 switch (type) {
12374
12375 case CPL_TYPE_INT:
12376 if (shift > 0) {
12377 j = length - shift;
12378 ip1 = column->values->i + length;
12379 ip2 = ip1 - shift;
12380 while (j--)
12381 *--ip1 = *--ip2;
12382 }
12383 else {
12384 j = -shift;
12385 ip1 = column->values->i;
12386 ip2 = ip1 - shift;
12387 while(j++ < length)
12388 *ip1++ = *ip2++;
12389 }
12390 break;
12391
12392 case CPL_TYPE_FLOAT:
12393 if (shift > 0) {
12394 j = length - shift;
12395 fp1 = column->values->f + length;
12396 fp2 = fp1 - shift;
12397 while (j--)
12398 *--fp1 = *--fp2;
12399 }
12400 else {
12401 j = -shift;
12402 fp1 = column->values->f;
12403 fp2 = fp1 - shift;
12404 while(j++ < length)
12405 *fp1++ = *fp2++;
12406 }
12407 break;
12408
12409 case CPL_TYPE_DOUBLE:
12410 if (shift > 0) {
12411 j = length - shift;
12412 dp1 = column->values->d + length;
12413 dp2 = dp1 - shift;
12414 while (j--)
12415 *--dp1 = *--dp2;
12416 }
12417 else {
12418 j = -shift;
12419 dp1 = column->values->d;
12420 dp2 = dp1 - shift;
12421 while(j++ < length)
12422 *dp1++ = *dp2++;
12423 }
12424 break;
12425
12426 default:
12427 break;
12428 }
12429
12430 return CPL_ERROR_NONE;
12431
12432 }
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554 cpl_error_code
12555 uves_table_sort_dfsxxxx(cpl_table *table, const uves_propertylist *reflist)
12556 {
12557 return xxx_table_sort((xxx_table *)table, reflist);
12558 }
12559
12560
12561
12562
12563
12564
12570
12571 int
12572 uves_table_and_selected_invalid(cpl_table *t, const char *column)
12573 {
12574 if (cpl_table_get_column_type(t, column) != CPL_TYPE_STRING)
12575 {
12576 return cpl_table_and_selected_invalid(t, column);
12577 }
12578 else
12579 {
12580 int i = 0;
12581 for (i = 0; i < cpl_table_get_nrow(t); i++)
12582 {
12583 if (cpl_table_is_selected(t, i))
12584 {
12585 if (cpl_table_is_valid(t, column, i))
12586 {
12587 cpl_table_unselect_row(t, i);
12588 }
12589
12590 }
12591
12592 }
12593
12594 return cpl_table_count_selected(t);
12595 }
12596 }
12597
12598
12599
12616
12617 int
12618 uves_erase_invalid_table_rows(cpl_table *t, const char *column)
12619 {
12620 int result = 0;
12621
12622 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
12623
12624 if (column == NULL)
12625
12626 {
12627 const char *name;
12628 cpl_table *argument = t;
12629 result = 0;
12630 while ( (name = cpl_table_get_column_name(argument)) != NULL)
12631 {
12632 int n_deleted_rows;
12633
12634 argument = NULL;
12635 n_deleted_rows = uves_erase_invalid_table_rows(t, name);
12636
12637 if (n_deleted_rows > 0)
12638 {
12639 uves_msg_low("%d rows with invalid '%s' removed",
12640 n_deleted_rows, name);
12641 }
12642 result += n_deleted_rows;
12643 }
12644 }
12645 else
12646 {
12647 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
12648 "No such column: %s", column);
12649
12650 check(( cpl_table_select_all(t),
12651 result = uves_table_and_selected_invalid(t, column),
12652 uves_table_erase_selected_dfs02356(t)),
12653 "Error deleting rows");
12654 }
12655
12656 cleanup:
12657 return result;
12658 }
12659
12660
12677
12678 cpl_table *
12679 uves_extract_table_rows(const cpl_table *t, const char *column,
12680 cpl_table_select_operator operator, double value)
12681 {
12682 cpl_table *result = NULL;
12683
12684 assure( t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
12685 assure( cpl_table_has_column(t, column), CPL_ERROR_INCOMPATIBLE_INPUT,
12686 "No such column: %s", column);
12687
12688
12689
12690 check(( result = cpl_table_duplicate(t),
12691
12692 uves_select_table_rows(result, column, operator, value),
12693 cpl_table_not_selected(result),
12694
12695 uves_table_erase_selected_dfs02356(result)),
12696
12697 "Error extracting rows");
12698
12699 passure( cpl_table_count_selected(result) == cpl_table_get_nrow(result),
12700 "%d %d",
12701 cpl_table_count_selected(result), cpl_table_get_nrow(result) );
12702
12703 cleanup:
12704 if (cpl_error_get_code() != CPL_ERROR_NONE)
12705 {
12706 uves_free_table(&result);
12707 }
12708 return result;
12709 }
12710
12711
12723
12724 void
12725 uves_sort_table_1(cpl_table *t, const char *column, bool reverse)
12726 {
12727 uves_propertylist *plist = NULL;
12728
12729 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
12730 assure(cpl_table_has_column(t, column), CPL_ERROR_ILLEGAL_INPUT,
12731 "No column '%s'", column);
12732
12733 check(( plist = uves_propertylist_new(),
12734 uves_propertylist_append_bool(plist, column, reverse)),
12735 "Could not create property list for sorting");
12736
12737 check( uves_table_sort(t, plist), "Could not sort table");
12738
12739 cleanup:
12740 uves_free_propertylist(&plist);
12741 return;
12742 }
12743
12744
12760
12761 void
12762 uves_sort_table_2(cpl_table *t, const char *column1, const char *column2,
12763 bool reverse1, bool reverse2)
12764 {
12765 uves_propertylist *plist = NULL;
12766
12767 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
12768 assure(cpl_table_has_column(t, column1), CPL_ERROR_ILLEGAL_INPUT,
12769 "No column '%s'", column1);
12770 assure(cpl_table_has_column(t, column2), CPL_ERROR_ILLEGAL_INPUT,
12771 "No column '%s'", column2);
12772
12773 check(( plist = uves_propertylist_new(),
12774 uves_propertylist_append_bool(plist, column1, reverse1),
12775 uves_propertylist_append_bool(plist, column2, reverse2)),
12776 "Could not create property list for sorting");
12777 check( uves_table_sort(t, plist), "Could not sort table");
12778
12779 cleanup:
12780 uves_free_propertylist(&plist);
12781 return;
12782 }
12783
12798
12799 void
12800 uves_sort_table_3(cpl_table *t, const char *column1, const char *column2,
12801 const char *column3,
12802 bool reverse1, bool reverse2, bool reverse3)
12803 {
12804 uves_propertylist *plist = NULL;
12805
12806 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
12807 assure(cpl_table_has_column(t, column1), CPL_ERROR_ILLEGAL_INPUT,
12808 "No column '%s'", column1);
12809 assure(cpl_table_has_column(t, column2), CPL_ERROR_ILLEGAL_INPUT,
12810 "No column '%s'", column2);
12811 assure(cpl_table_has_column(t, column3), CPL_ERROR_ILLEGAL_INPUT,
12812 "No column '%s'", column3);
12813
12814 check(( plist = uves_propertylist_new(),
12815 uves_propertylist_append_bool(plist, column1, reverse1),
12816 uves_propertylist_append_bool(plist, column2, reverse2),
12817 uves_propertylist_append_bool(plist, column3, reverse3)),
12818 "Could not create property list for sorting");
12819 check( uves_table_sort(t, plist), "Could not sort table");
12820
12821 cleanup:
12822 uves_free_propertylist(&plist);
12823 return;
12824 }
12825
12826
12831
12832 void uves_free_image(cpl_image **i)
12833 {if(i){cpl_image_delete(*i); *i = NULL;}}
12834
12839
12840 void uves_free_mask(cpl_mask **m)
12841 {if(m){cpl_mask_delete(*m); *m = NULL;}}
12842
12847
12848 void uves_free_imagelist(cpl_imagelist **i)
12849 {if(i){cpl_imagelist_delete(*i); *i = NULL;}}
12850
12851
12856
12857 void uves_free_table(cpl_table **t)
12858 {if(t){cpl_table_delete(*t); *t = NULL;}}
12859
12860
12865
12866 void uves_free_table_const(const cpl_table **t)
12867 {if(t){irplib_table_delete(*t); *t = NULL;}}
12868
12869
12874
12875 void uves_free_propertylist(uves_propertylist **p)
12876 {if(p){uves_propertylist_delete(*p); *p = NULL;}}
12877
12878
12883
12884 void uves_free_propertylist_const(const uves_propertylist **p)
12885 {if(p){uves_propertylist_delete(*p); *p = NULL;}}
12886
12887
12892
12893 void uves_free_property(cpl_property **p)
12894 {if(p){cpl_property_delete(*p); *p = NULL;}}
12895
12900
12901 void uves_free_polynomial(cpl_polynomial **p)
12902 {if(p){cpl_polynomial_delete(*p); *p = NULL;}}
12903
12908
12909 void uves_free_matrix(cpl_matrix **m)
12910 {if(m){cpl_matrix_delete(*m); *m = NULL;}}
12911
12916
12917 void uves_free_parameterlist(cpl_parameterlist **p)
12918 {if(p){cpl_parameterlist_delete(*p); *p = NULL;}}
12919
12924
12925 void uves_free_frameset(cpl_frameset **f)
12926 {if(f){cpl_frameset_delete(*f); *f = NULL;}}
12927
12932
12933 void uves_free_frame(cpl_frame **f)
12934 {if(f){cpl_frame_delete(*f); *f = NULL;}}
12935
12940
12941 void uves_free_bivector(cpl_bivector **b)
12942 {if(b){cpl_bivector_delete(*b); *b = NULL;}}
12943
12948
12949 void uves_free_vector(cpl_vector **v)
12950 {if(v){cpl_vector_delete(*v); *v = NULL;}}
12951
12956
12957 void uves_free_stats(cpl_stats **s)
12958 {if(s){cpl_stats_delete(*s); *s = NULL;}}
12959
12964
12965 void uves_unwrap_vector(cpl_vector **v)
12966 {if(v){cpl_vector_unwrap(*v); *v = NULL;}}
12967
12972
12973 void uves_unwrap_vector_const(const cpl_vector **v)
12974 {if(v){irplib_vector_unwrap_const(*v); *v = NULL;}}
12975
12980
12981 void uves_unwrap_bivector_vectors(cpl_bivector **b)
12982 {if(b){cpl_bivector_unwrap_vectors(*b); *b = NULL;}}
12983
12988
12989 void uves_free_array(cpl_array **a)
12990 {if(a){cpl_array_delete(*a); *a = NULL;}}
12991
12992
12997
12998 void uves_free_int(int **i)
12999 {if(i){cpl_free(*i); *i = NULL;}}
13000
13001
13006
13007 void uves_free_int_const(const int **i)
13008 {if(i){irplib_free(*i); *i = NULL;}}
13009
13014
13015 void uves_free_float(float **f)
13016 {if(f){cpl_free(*f); *f = NULL;}}
13017
13018
13023
13024 void uves_free_double(double **d)
13025 {if(d){cpl_free(*d); *d = NULL;}}
13026
13027
13032
13033 void uves_free_string(char **s)
13034 {if(s){cpl_free(*s); *s = NULL;}}
13035
13040
13041 void uves_free_string_const(const char **s)
13042 {if(s){irplib_free(*s); *s = NULL;}}
13043
13044
13065
13066
13067 static double
13068 get_chisq(int N, int D,
13069 int (*f)(const double x[], const double a[], double *result),
13070 const double *a,
13071 const double *x,
13072 const double *y,
13073 const double *sigma)
13074 {
13075 double chi_sq;
13076 int i = 0;
13077
13078
13079
13080 chi_sq = 0.0;
13081 for (i = 0; i < N; i++)
13082 {
13083 double fx_i;
13084 double residual;
13085 const double *x_i = &(x[0+i*D]);
13086
13087
13088 cpl_ensure( f(x_i,
13089 a,
13090 &fx_i) == 0, CPL_ERROR_ILLEGAL_INPUT, -1.0);
13091
13092
13093 if (sigma == NULL)
13094 {
13095 residual = (fx_i - y[i]);
13096 }
13097 else
13098 {
13099 residual = (fx_i - y[i]) / sigma[i];
13100 }
13101
13102 chi_sq += residual*residual;
13103
13104 }
13105
13106 return chi_sq;
13107 }
13108
13142
13143 static int
13144 get_candidate(const double *a, const int ia[],
13145 int M, int N, int D,
13146 double lambda,
13147 int (*f)(const double x[], const double a[], double *result),
13148 int (*dfda)(const double x[], const double a[], double result[]),
13149 const double *x,
13150 const double *y,
13151 const double *sigma,
13152 double *partials,
13153 cpl_matrix *alpha,
13154 cpl_matrix *beta,
13155 double *a_da)
13156 {
13157 int Mfit = 0;
13158 cpl_matrix *da;
13159 double *alpha_data;
13160 double *beta_data;
13161 double *da_data;
13162 int i, imfit = 0;
13163 int j, jmfit = 0;
13164 int k = 0;
13165
13166
13167
13168 Mfit = cpl_matrix_get_nrow(alpha);
13169
13170 alpha_data = irplib_matrix_get_data(alpha);
13171 beta_data = irplib_matrix_get_data(beta);
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184 cpl_matrix_fill(alpha, 0.0);
13185 cpl_matrix_fill(beta , 0.0);
13186
13187 for (k = 0; k < N; k++)
13188 {
13189 double sm2 = 0.0;
13190 double fx_k = 0.0;
13191 const double *x_k = &(x[0+k*D]);
13192
13193 if (sigma == NULL)
13194 {
13195 sm2 = 1.0;
13196 }
13197 else
13198 {
13199 sm2 = 1.0 / (sigma[k] * sigma[k]);
13200 }
13201
13202
13203 cpl_ensure( f(x_k, a, &fx_k) == 0, CPL_ERROR_ILLEGAL_INPUT, -1);
13204
13205
13206 cpl_ensure( dfda(x_k, a, partials) == 0,
13207 CPL_ERROR_ILLEGAL_INPUT, -1);
13208
13209 for (i = 0, imfit = 0; i < M; i++)
13210 {
13211 if (ia[i] != 0)
13212 {
13213
13214 beta_data[imfit] +=
13215 sm2 * (y[k] - fx_k) * partials[i];
13216
13217
13218
13219 for (j = 0, jmfit = 0; j < i; j++)
13220 {
13221 if (ia[j] != 0)
13222 {
13223 alpha_data[jmfit + imfit*Mfit] +=
13224 sm2 * partials[i] *
13225 partials[j];
13226
13227 jmfit += 1;
13228 }
13229 }
13230
13231
13232 j = i;
13233 jmfit = imfit;
13234
13235 alpha_data[jmfit + imfit*Mfit] +=
13236 sm2 * partials[i] *
13237 partials[j] * (1 + lambda);
13238
13239 imfit += 1;
13240 }
13241 }
13242
13243 assert( imfit == Mfit );
13244 }
13245
13246
13247 for (i = 0, imfit = 0; i < M; i++)
13248 {
13249 if (ia[i] != 0)
13250 {
13251 for (j = i+1, jmfit = imfit+1; j < M; j++)
13252 {
13253 if (ia[j] != 0)
13254 {
13255 alpha_data[jmfit + imfit*Mfit] =
13256 alpha_data[imfit + jmfit*Mfit];
13257
13258 jmfit += 1;
13259 }
13260 }
13261 assert( jmfit == Mfit );
13262
13263 imfit += 1;
13264 }
13265 }
13266 assert( imfit == Mfit );
13267
13268 da = cpl_matrix_solve(alpha, beta);
13269
13270 cpl_ensure(da != NULL, cpl_error_get_code(), -1);
13271
13272
13273 da_data = irplib_matrix_get_data(da);
13274
13275 for (i = 0, imfit = 0; i < M; i++)
13276 {
13277 if (ia[i] != 0)
13278 {
13279 a_da[i] = a[i] + da_data[0 + imfit*1];
13280
13281 imfit += 1;
13282 }
13283 else
13284 {
13285 a_da[i] = a[i];
13286 }
13287 }
13288
13289 assert( imfit == Mfit );
13290
13291 cpl_matrix_delete(da);
13292
13293 return 0;
13294 }
13295