71 const cpl_imagelist *,
80 const cpl_imagelist *,
89 const cpl_imagelist *,
172 const cpl_imagelist * values,
175 cpl_boolean is_eqdist,
176 cpl_image * fiterror)
179 cpl_imagelist * self = NULL;
185 const cpl_image * value = cpl_imagelist_get_const(values, 0);
189 cpl_error_code error;
192 const int nc = 1 + maxdeg - mindeg;
193 const int np = cpl_vector_get_size(x_pos);
194 const int nx = cpl_image_get_size_x(value);
195 const int ny = cpl_image_get_size_y(value);
197 const cpl_boolean is_eqzero = is_eqdist && mindeg == 0;
202 cpl_ensure(x_pos != NULL, CPL_ERROR_NULL_INPUT, NULL);
203 cpl_ensure(values != NULL, CPL_ERROR_NULL_INPUT, NULL);
205 cpl_ensure(mindeg >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
206 cpl_ensure(maxdeg >= mindeg, CPL_ERROR_ILLEGAL_INPUT, NULL);
210 cpl_ensure(np == cpl_imagelist_get_size(values),
211 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
213 cpl_ensure(cpl_imagelist_is_uniform(values)==0,
214 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
216 if (fiterror != NULL) {
217 cpl_ensure(cpl_image_get_size_x(fiterror) ==
nx &&
218 cpl_image_get_size_y(fiterror) ==
ny,
219 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
225 assert( xhat != NULL );
228 if (is_eqdist && (np & 1)) cpl_vector_set(xhat, np>>1, 0.0);
231 xhat = (cpl_vector*)x_pos;
235 dx = cpl_vector_get_data(xhat);
238 mv = cpl_matrix_wrap(nc, np,
239 cpl_malloc(nc * np *
sizeof(
double)));
242 for (j=0; j < np; j++) {
244 cpl_matrix_set(mv, 0, j, f_prod);
245 for (k=1; k < nc; k++) {
247 cpl_matrix_set(mv, k, j, f_prod);
251 if (xhat != x_pos) cpl_vector_delete(xhat);
267 double * dmh = cpl_matrix_get_data(mh);
269 for (i = 0; i < nc; i++) {
270 for (j = i + 1; j < nc; j += 2) {
271 dmh[nc * i + j] = 0.0;
276 error = cpl_matrix_decomp_chol(mh);
280 cpl_vector * xpow = NULL;
285 self = cpl_imagelist_new();
286 for (i=0; i < nc; i++) {
287 cpl_imagelist_set(self, cpl_image_new(
nx,
ny, CPL_TYPE_DOUBLE),
292 const double * d_pos = cpl_vector_get_data_const(x_pos);
293 double * ppow = cpl_malloc(np *
sizeof(
double));
295 xpow = cpl_vector_wrap(np, ppow);
297 for (i = 0; i < np; i++) {
302 switch (cpl_image_get_type(value)) {
303 case CPL_TYPE_DOUBLE:
305 xpow, -xmean, np, nc,
310 xpow, -xmean, np, nc,
315 xpow, -xmean, np, nc,
323 cpl_vector_unwrap(xpow);
327 cpl_matrix_delete(mh);
328 cpl_matrix_delete(mv);
331 cpl_ensure(!error, error, NULL);
360 result = p & 1 ?
x : 1.0;
365 if (p & 1) result *= pow2;
385 const cpl_matrix * ma,
386 const cpl_matrix * mb)
391 double * ds = cpl_matrix_get_data(self);
392 const double * d1 = cpl_matrix_get_data_const( ma);
393 const double * d2 = cpl_matrix_get_data_const( mb);
396 const int nr = cpl_matrix_get_nrow(ma);
397 const int nc = cpl_matrix_get_nrow(mb);
398 const int nk = cpl_matrix_get_ncol(mb);
402 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
403 cpl_ensure_code(ma != NULL, CPL_ERROR_NULL_INPUT);
404 cpl_ensure_code(mb != NULL, CPL_ERROR_NULL_INPUT);
406 cpl_ensure_code(cpl_matrix_get_ncol(ma) == nk,
407 CPL_ERROR_INCOMPATIBLE_INPUT);
409 if (cpl_matrix_get_nrow(self) != nr || cpl_matrix_get_ncol(self) != nc)
410 cpl_matrix_set_size(self, nr, nc);
412 for (i = 0; i < nr; i++, d1 += nk) {
417 for (j = 0; j < nc; j++, di += nk) {
419 for (k = 0; k < nk; k++) {
420 sum += d1[k] * di[k];
422 ds[nc * i + j] = sum;
426 return CPL_ERROR_NONE;
455 for (j = 0; j <
n-1; j++)
456 for (i = 1; i <
n - j; i++ )
457 coeffs[
n-1-i] += coeffs[
n-i] * u;
478 cpl_vector * xhat = cpl_vector_duplicate(
x);
481 assert( xhat != NULL );
482 assert( pm != NULL );
484 *pm = cpl_vector_get_mean(xhat);
485 cpl_vector_subtract_scalar(xhat, *pm);
522 cpl_matrix * product;
523 const double * ai = cpl_matrix_get_data_const(self);
527 const int m = cpl_matrix_get_nrow(self);
528 const int n = cpl_matrix_get_ncol(self);
532 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
534 bwrite = (
double *) cpl_malloc(
m *
m *
sizeof(
double));
536 product = cpl_matrix_wrap(
m,
m, bwrite);
539 for (i = 0; i <
m; i++, ai +=
n, bwrite +=
m) {
541 for (j = i; j <
m; j++, aj +=
n) {
543 for (k = 0; k <
n; k++) {
544 sum += ai[k] * aj[k];
606 const double * aread;
611 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
612 cpl_ensure_code(rhs != NULL, CPL_ERROR_NULL_INPUT);
614 n = cpl_matrix_get_ncol(self);
616 cpl_ensure_code(cpl_matrix_get_nrow(self) ==
n, CPL_ERROR_ILLEGAL_INPUT);
617 cpl_ensure_code(cpl_matrix_get_ncol(rhs) ==
n, CPL_ERROR_INCOMPATIBLE_INPUT);
619 nrhs = cpl_matrix_get_nrow(rhs);
621 aread = cpl_matrix_get_data_const(self);
624 bk = cpl_matrix_get_data(rhs);
626 for (k=0; k < nrhs; k++, bk +=
n) {
633 for (i = 0; i <
n; i++, ai +=
n) {
635 for (j = 0; j < i; j++) {
636 sub += ai[j] * bk[j];
638 cpl_ensure_code(k > 0 || ai[j] != 0.0, CPL_ERROR_DIVISION_BY_ZERO);
639 bk[j] = (bk[j] - sub) / ai[j];
644 for (i =
n-1; i >= 0; i--) {
646 for (j = i+1; j <
n; j++) {
647 sub -= aread[
n * j + i] * bk[j];
649 bk[i] = sub/aread[
n * i + i];
653 return CPL_ERROR_NONE;
697 const cpl_image * im,
709 cpl_image * extracted ;
712 double u0, ux, uy, uxx, uyy ;
724 cpl_ensure_code(im, CPL_ERROR_NULL_INPUT) ;
726 nx=cpl_image_get_size_x(im);
727 ny=cpl_image_get_size_y(im);
729 cpl_ensure_code(xpos>=1 && xpos<=
nx, CPL_ERROR_ILLEGAL_INPUT);
730 cpl_ensure_code(ypos>=1 && ypos<=
ny, CPL_ERROR_ILLEGAL_INPUT);
733 CPL_ERROR_ILLEGAL_INPUT) ;
747 cpl_ensure_code(extracted, CPL_ERROR_ILLEGAL_INPUT) ;
750 if (5 * cpl_image_count_rejected(extracted) >
751 cpl_image_get_size_x(extracted) * cpl_image_get_size_y(extracted)) {
752 cpl_image_delete(extracted) ;
753 cpl_ensure_code(0, CPL_ERROR_ILLEGAL_INPUT) ;
756 if (cpl_image_get_type(extracted) != CPL_TYPE_DOUBLE) {
758 cpl_image * tmp = extracted;
759 extracted = cpl_image_cast(tmp, CPL_TYPE_DOUBLE);
760 cpl_image_delete(tmp);
761 cpl_ensure_code(extracted, CPL_ERROR_TYPE_MISMATCH);
763 pi = cpl_image_get_data_double(extracted);
766 enx=cpl_image_get_size_x(extracted);
767 eny=cpl_image_get_size_y(extracted);
770 for (j=0 ; j<eny ; j++) {
771 for (i=0 ; i<enx ; i++) {
772 if (!cpl_image_is_rejected(extracted, i+1, j+1)) {
775 ux += (i+1) * pi[pos] ;
776 uy += (j+1) * pi[pos] ;
783 if (u0 == 0 || u0 > ux || ux > u0*enx ||
784 u0 > uy || uy > u0*eny) {
785 cpl_image_delete(extracted) ;
786 cpl_ensure_code(0, CPL_ERROR_ILLEGAL_INPUT) ;
794 for (j=0 ; j<eny ; j++) {
795 for (i=0 ; i<enx ; i++) {
796 if (!cpl_image_is_rejected(extracted, i+1, j+1)) {
798 uxx += ((i+1)-cenx) * ((i+1)-cenx) * pi[pos] ;
799 uyy += ((j+1)-ceny) * ((j+1)-ceny) * pi[pos] ;
803 if (sig_x) *sig_x = sqrt(fabs(uxx/u0)) ;
804 if (sig_y) *sig_y = sqrt(fabs(uyy/u0)) ;
805 if (fwhm_x) *fwhm_x = 2 * sqrt(2 * log(2.0)) * sqrt(fabs(uxx/u0)) ;
806 if (fwhm_y) *fwhm_y = 2 * sqrt(2 * log(2.0)) * sqrt(fabs(uyy/u0)) ;
809 max_val = cpl_image_get(extracted, (
int)cenx, (
int)ceny,
811 cpl_ensure_code(is_rejected >= 0, cpl_error_get_code());
814 cpl_errorstate pstate = cpl_errorstate_get();
815 max_val = cpl_image_get_mean_window(extracted, (
int)cenx,
816 (
int)ceny, (
int)(cenx+1), (
int)(ceny+1)) ;
817 cpl_ensure_code(cpl_errorstate_is_equal(pstate), cpl_error_get_code());
820 cpl_image_delete(extracted) ;
822 if (norm) *norm = max_val*2*CX_PI*sqrt(fabs(uxx/u0))*sqrt(fabs(uyy/u0)) ;
825 if (xcen) *xcen = cenx +
llx - 1 ;
826 if (ycen) *ycen = ceny +
lly - 1 ;
829 return CPL_ERROR_NONE ;
837#define CONCAT(a,b) a ## _ ## b
838#define CONCAT2X(a,b) CONCAT(a,b)
840#define CPL_TYPE double
844#define CPL_TYPE float
static cpl_error_code irplib_matrix_product_transpose(cpl_matrix *, const cpl_matrix *, const cpl_matrix *)
Fill a matrix with the product of A * B'.
static double irplib_tools_ipow(double, int)
Compute x to the power of p.
static cpl_matrix * irplib_matrix_product_normal_create(const cpl_matrix *)
Create and compute A = B * transpose(B)
static void irplib_fit_imagelist_polynomial_float(cpl_imagelist *, const cpl_matrix *, const cpl_matrix *, const cpl_vector *, const cpl_imagelist *, const cpl_vector *, double, int, int, cpl_image *)
static void irplib_fit_imagelist_residual_float(cpl_image *, int, const cpl_vector *, const cpl_vector *, const cpl_matrix *, const cpl_matrix *)
static void irplib_fit_imagelist_polynomial_int(cpl_imagelist *, const cpl_matrix *, const cpl_matrix *, const cpl_vector *, const cpl_imagelist *, const cpl_vector *, double, int, int, cpl_image *)
static cpl_vector * irplib_vector_transform_mean(const cpl_vector *, double *)
Transform: xhat = x - mean(x)
cpl_imagelist * xsh_fit_imagelist_polynomial(const cpl_vector *x_pos, const cpl_imagelist *values, int mindeg, int maxdeg, cpl_boolean is_eqdist, cpl_image *fiterror)
Fit a polynomial to each pixel in a list of images.
static cpl_error_code irplib_matrix_solve_chol_transpose(const cpl_matrix *, cpl_matrix *)
Solve a L*transpose(L)-system with a transposed Right Hand Side.
cpl_error_code xsh_image_find_barycenter(const cpl_image *im, int xpos, int ypos, int size, double *norm, double *xcen, double *ycen, double *sig_x, double *sig_y, double *fwhm_x, double *fwhm_y)
Apply a gaussian fit on an image sub window.
static void irplib_fit_imagelist_polynomial_double(cpl_imagelist *, const cpl_matrix *, const cpl_matrix *, const cpl_vector *, const cpl_imagelist *, const cpl_vector *, double, int, int, cpl_image *)
static void irplib_polynomial_shift_double(double *, int, double)
Given p and u, modify the polynomial to p(x) := p(x+u)
static void irplib_fit_imagelist_residual_double(cpl_image *, int, const cpl_vector *, const cpl_vector *, const cpl_matrix *, const cpl_matrix *)
static void irplib_fit_imagelist_residual_int(cpl_image *, int, const cpl_vector *, const cpl_vector *, const cpl_matrix *, const cpl_matrix *)