IIINSTRUMENT Pipeline Reference Manual  6.2.2
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