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