00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define TYPE_ADD(a) CONCAT2X(a, CPL_TYPE)
00022 #define TYPE_ADD_CONST(a) CONCAT2X(TYPE_ADD(a),const)
00023 #define IMAGE_GET_DATA TYPE_ADD(cpl_image_get_data)
00024
00025
00042
00043 static void
00044 TYPE_ADD(irplib_fit_imagelist_polynomial)(cpl_imagelist * self,
00045 const cpl_matrix * mh,
00046 const cpl_matrix * mv,
00047 const cpl_vector * x_pos,
00048 const cpl_imagelist * values,
00049 const cpl_vector * xpow,
00050 double xnmean, int np, int nc,
00051 cpl_image * fiterror)
00052 {
00053
00054 const cpl_image * value = cpl_imagelist_get_const(values, 0);
00055 const int nx = cpl_image_get_size_x(value);
00056 const int ny = cpl_image_get_size_y(value);
00057
00058 const CPL_TYPE * pi;
00059 double * pdest;
00060 double * px = cpl_malloc(nx * nc * sizeof(double));
00061 double * pbw = cpl_malloc(nx * np * sizeof(double));
00062
00063
00064 cpl_matrix * mx = cpl_matrix_wrap(nx, nc, px);
00065
00066 cpl_matrix * mb = cpl_matrix_wrap(nx, np, pbw);
00067 const cpl_image* image = NULL;
00068 int i, j, k, jj;
00069
00070
00071
00072
00073 for (jj = 0; jj < ny; jj++) {
00074
00075
00076 for (j=0; j < np; j++) {
00077 image = cpl_imagelist_get_const( values, j);
00078 pi = TYPE_ADD_CONST(cpl_image_get_data)
00079 (image);
00080
00081
00082
00083 for (i=0; i < nx; i++) {
00084 pbw[np * i + j] = (double)pi[nx * jj + i];
00085 }
00086 }
00087
00088
00089 irplib_matrix_product_transpose(mx, mb, mv);
00090
00091
00092 irplib_matrix_solve_chol_transpose(mh, mx);
00093
00094 if (xnmean != 0.0) {
00095
00096 for (i=0; i < nx; i++) {
00097 irplib_polynomial_shift_double(px + i * nc, nc, xnmean);
00098 }
00099 }
00100
00101
00102
00103 for (k=0; k < nc; k++) {
00104 pdest = cpl_image_get_data_double(cpl_imagelist_get(self, k));
00105
00106
00107
00108 for (i=0; i < nx; i++) {
00109 pdest[nx * jj + i] = px[nc * i + k];
00110 }
00111 }
00112
00113 if (fiterror != NULL) {
00114 switch (cpl_image_get_type(fiterror)) {
00115 case CPL_TYPE_DOUBLE:
00116 irplib_fit_imagelist_residual_double(fiterror, jj, x_pos,
00117 xpow, mx, mb);
00118 break;
00119 case CPL_TYPE_FLOAT:
00120 irplib_fit_imagelist_residual_float(fiterror, jj, x_pos,
00121 xpow, mx, mb);
00122 break;
00123 case CPL_TYPE_INT:
00124 irplib_fit_imagelist_residual_int(fiterror, jj, x_pos,
00125 xpow, mx, mb);
00126 break;
00127 default:
00128
00129 assert( 0 );
00130 }
00131 }
00132 }
00133 cpl_matrix_delete(mx);
00134 cpl_matrix_delete(mb);
00135
00136 }
00137
00138
00139
00154
00155 static void TYPE_ADD(irplib_fit_imagelist_residual)(cpl_image * self,
00156 int jj,
00157 const cpl_vector * x_pos,
00158 const cpl_vector * xpow,
00159 const cpl_matrix * mx,
00160 const cpl_matrix * mb)
00161 {
00162 double err, sq_err;
00163
00164 int nx = cpl_matrix_get_nrow(mx);
00165 int nc = cpl_matrix_get_ncol(mx);
00166 int np = cpl_vector_get_size(x_pos);
00167
00168
00169 CPL_TYPE * pself = nx * jj + TYPE_ADD(cpl_image_get_data)(self);
00170
00171 const double * pp = cpl_vector_get_data_const(x_pos);
00172
00173
00174 const double * pm = xpow != NULL ? cpl_vector_get_data_const(xpow) : NULL;
00175 const double * px = cpl_matrix_get_data_const(mx);
00176 const double * pb = cpl_matrix_get_data_const(mb);
00177
00178 int i, j, k;
00179
00180
00181 for (i=0; i < nx; i++, pb += np, px += nc) {
00182 sq_err = 0.0;
00183 for (j=0; j < np; j++) {
00184
00185
00186
00187 k = nc;
00188 err = px[--k];
00189
00190 while (k) err = pp[j] * err + px[--k];
00191
00192
00193
00194 if (pm != NULL) {
00195 err = err * pm[j] - pb[j];
00196 } else {
00197 err -= pb[j];
00198 }
00199
00200 sq_err += err * err;
00201 }
00202 pself[i] = (CPL_TYPE)(sq_err/(double)np);
00203 }
00204
00205 }
00206
00207 #undef TYPE_ADD
00208 #undef IMAGE_GET_DATA