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