IIINSTRUMENT Pipeline Reference Manual 6.2.5
isaac_fit.c
1/* $Id: isaac_fit.c,v 1.4 2013-03-12 08:06:48 llundin Exp $
2 *
3 * This file is part of the ISAAC Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: llundin $
23 * $Date: 2013-03-12 08:06:48 $
24 * $Revision: 1.4 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*-----------------------------------------------------------------------------
33 Includes
34 -----------------------------------------------------------------------------*/
35
36#include <cpl.h>
37#include <math.h>
38
39#include "isaac_fit.h"
40
41/*----------------------------------------------------------------------------*/
45/*----------------------------------------------------------------------------*/
46
49/*----------------------------------------------------------------------------*/
77/*----------------------------------------------------------------------------*/
79 const cpl_imagelist * ilist,
80 const double * dit,
81 int deg)
82{
83 cpl_imagelist * fitres;
84 const cpl_image * image;
85 int ni, nx, ny;
86
87 double f, f_prod;
88 double * pimad;
89 const float * pi;
90 cpl_matrix * mv;
91 cpl_matrix * mb;
92 cpl_matrix * mx;
93 double * pv;
94 int nsing = 0;
95 int i, j, k;
96
97 /* Check entries */
98 cpl_ensure(ilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
99 cpl_ensure(dit != NULL, CPL_ERROR_NULL_INPUT, NULL);
100 cpl_ensure(deg > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
101
102 ni = cpl_imagelist_get_size(ilist);
103 cpl_ensure(ni >= deg, CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
104
105 image = cpl_imagelist_get_const(ilist, 0);
106
107 nx = cpl_image_get_size_x(image);
108 ny = cpl_image_get_size_y(image);
109
110 /* Allocate deg+1 images to store the results */
111 fitres = cpl_imagelist_new();
112 for (i=0; i < deg+1; i++) {
113 cpl_imagelist_set(fitres, cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
114 i);
115 }
116
117 /* Create matrices */
118 pv = cpl_malloc(ni * deg * sizeof(double));
119 mv = cpl_matrix_wrap(ni, deg, pv);
120
121 /* Fill RHS matrix
122 - mb is _not_ modified */
123 mb = cpl_matrix_wrap(ni, 1, (double*)dit);
124
125 /* Loop on pixels */
126 for (i=0; i < nx*ny; i++) {
127 /* Fill Vandermonde matrix */
128 for (j=0; j < ni; j++) {
129 pi=cpl_image_get_data_float_const(cpl_imagelist_get_const(ilist,j));
130 f_prod = f = (double)pi[i];
131 pv[deg * j] = f;
132 for (k=1; k < deg; k++) {
133 f_prod *= f;
134 pv[deg * j + k] = f_prod;
135 }
136 }
137
138 /* Solve least-squares */
139 /* FIXME: See cpl_polynomial_fit_1d_create() for how to
140 reduce the solve time */
141 mx = cpl_matrix_solve_normal(mv, mb);
142
143 if (mx == NULL) {
144 for (k=0; k < deg+1; k++) {
145 pimad =
146 cpl_image_get_data_double(cpl_imagelist_get(fitres,k));
147 pimad[i] = 0.0;
148 }
149 nsing++;
150 } else {
151 double err, sq_err;
152 const double * px = cpl_matrix_get_data(mx);
153
154 /* Store results */
155 for (k=0; k < deg; k++) {
156 pimad = cpl_image_get_data_double(
157 cpl_imagelist_get(fitres, k));
158 pimad[i] = px[k];
159 }
160
161 /* Goodness of fit */
162 sq_err=0.0;
163 for (j=0; j < ni; j++) {
164 /* Error between model and reality */
165 err = dit[j];
166 /* Computed by model */
167 for (k=0; k < deg; k++)
168 err -= px[k] * pv[deg * j + k];
169 sq_err += err * err;
170 }
171 sq_err /= (double)ni;
172 pimad=cpl_image_get_data_double(cpl_imagelist_get(fitres, deg));
173 pimad[i] = sq_err;
174 cpl_matrix_delete(mx);
175 }
176 }
177
178 cpl_matrix_delete(mv);
179 (void)cpl_matrix_unwrap(mb);
180
181 if (nsing == nx*ny) {
182 cpl_imagelist_delete(fitres);
183 cpl_ensure(0, CPL_ERROR_SINGULAR_MATRIX, NULL);
184 }
185
186 return fitres;
187}
188#undef CPL_OPERATION
189
cpl_imagelist * isaac_imagelist_fit_polynomial(const cpl_imagelist *ilist, const double *dit, int deg)
Compute the non linearity of the detector.
Definition: isaac_fit.c:78