GIRAFFE Pipeline Reference Manual

gichebyshev.c
1 /*
2  * This file is part of the GIRAFFE Pipeline
3  * Copyright (C) 2002-2019 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23 
24 #include <cxmemory.h>
25 #include <cxmessages.h>
26 
27 #include <cpl_matrix.h>
28 
29 #include "gichebyshev.h"
30 
31 
40 struct GiChebyshev2D {
41 
42  cxint xorder;
43  cxint yorder;
44 
45  cxdouble ax;
46  cxdouble bx;
47  cxdouble ay;
48  cxdouble by;
49 
50  cpl_matrix *coeffs;
51 
52 };
53 
54 
55 inline static cxdouble
56 _giraffe_chebyshev2d_eval(const GiChebyshev2D *self, cxdouble x, cxdouble y)
57 {
58 
59  cxint i, k;
60  cxint nx = self->xorder + 1;
61  cxint ny = self->yorder + 1;
62 
63  cxdouble xn = (2.0 * x - self->ax - self->bx) / (self->bx - self->ax);
64  cxdouble yn = (2.0 * y - self->ay - self->by) / (self->by - self->ay);
65  cxdouble cx0 = 1.0;
66  cxdouble cx1 = xn;
67  cxdouble sum = 0.;
68  cxdouble *_coeffs = cpl_matrix_get_data(self->coeffs);
69 
70 
71  cx_assert(_coeffs != NULL);
72 
73  for (i = 0, k = 0; i < nx; i++) {
74 
75  register cxint j;
76 
77  register cxdouble cy0 = 1.0;
78  register cxdouble cy1 = yn;
79  register cxdouble cx2 = 0.;
80 
81 
82  if (i < 2) {
83  cx2 = cx0;
84  }
85  else {
86  cx2 = 2.0 * cx1 * xn - cx0;
87  }
88 
89  for (j = 0; j < ny; j++) {
90 
91  cxdouble cy2 = 0.;
92 
93  if (j < 2) {
94  cy2 = cy0;
95  }
96  else {
97  cy2 = 2.0 * cy1 * yn - cy0;
98  }
99 
100  sum += cx2 * cy2 * _coeffs[k++];
101 
102  cy0 = cy1;
103  cy1 = cy2;
104 
105  }
106 
107  cx0 = cx1;
108  cx1 = cx2;
109 
110  }
111 
112  return sum;
113 
114 }
115 
116 
117 GiChebyshev2D *
118 giraffe_chebyshev2d_new(cxint xorder, cxint yorder)
119 {
120 
121  GiChebyshev2D *self = cx_calloc(1, sizeof *self);
122 
123 
124  if (self) {
125 
126  self->xorder = xorder;
127  self->yorder = yorder;
128 
129  self->coeffs = cpl_matrix_new((xorder + 1), (yorder + 1));
130 
131  if (self->coeffs == NULL) {
132  giraffe_chebyshev2d_delete(self);
133  return NULL;
134  }
135 
136  }
137 
138  return self;
139 
140 }
141 
142 
143 GiChebyshev2D *
144 giraffe_chebyshev2d_clone(const GiChebyshev2D *other)
145 {
146 
147  GiChebyshev2D *self = NULL;
148 
149 
150  if (other != NULL) {
151 
152  self = giraffe_chebyshev2d_new(other->xorder, other->yorder);
153 
154  self->ax = other->ax;
155  self->bx = other->bx;
156  self->ay = other->ay;
157  self->by = other->by;
158 
159  self->coeffs = cpl_matrix_duplicate(other->coeffs);
160 
161  }
162 
163  return self;
164 
165 }
166 
167 
168 void
169 giraffe_chebyshev2d_delete(GiChebyshev2D *self)
170 {
171 
172  if (self) {
173 
174  if (self->coeffs) {
175  cpl_matrix_delete(self->coeffs);
176  self->coeffs = NULL;
177  }
178 
179  cx_free(self);
180 
181  }
182 
183  return;
184 
185 }
186 
187 
188 void giraffe_chebyshev2d_get_order(const GiChebyshev2D *self, cxint *xorder,
189  cxint *yorder)
190 {
191 
192  cx_assert(self != NULL);
193 
194  if (xorder != NULL) {
195  *xorder = self->xorder;
196  }
197 
198  if (yorder != NULL) {
199  *yorder = self->yorder;
200  }
201 
202  return;
203 
204 }
205 
206 
207 void
208 giraffe_chebyshev2d_get_range(const GiChebyshev2D *self, cxdouble *ax,
209  cxdouble *bx, cxdouble *ay, cxdouble *by)
210 {
211 
212  cx_assert(self != NULL);
213 
214  if (ax != NULL) {
215  *ax = self->ax;
216  }
217 
218  if (bx != NULL) {
219  *bx = self->bx;
220  }
221 
222  if (ay != NULL) {
223  *ay = self->ay;
224  }
225 
226  if (by != NULL) {
227  *by = self->by;
228  }
229 
230  return;
231 
232 }
233 
234 
235 const cpl_matrix *
236 giraffe_chebyshev2d_coeffs(const GiChebyshev2D *self)
237 {
238 
239  cx_assert(self != NULL);
240 
241  return self->coeffs;
242 
243 }
244 
245 
246 cxint
247 giraffe_chebyshev2d_set(GiChebyshev2D *self, cxdouble ax, cxdouble bx,
248  cxdouble ay, cxdouble by, cpl_matrix *coeffs)
249 {
250 
251  cx_assert(self != NULL);
252 
253  self->ax = ax;
254  self->bx = bx;
255  self->ay = ay;
256  self->by = by;
257 
258  if (cpl_matrix_get_nrow(coeffs) <= self->xorder ||
259  cpl_matrix_get_ncol(coeffs) <= self->yorder) {
260  return 1;
261  }
262  else {
263 
264  cxint i;
265 
266  for (i = 0; i <= self->xorder; i++) {
267 
268  cxint j;
269 
270  for (j = 0; j <= self->yorder; j++) {
271 
272  cxdouble c = cpl_matrix_get(coeffs, i, j);
273 
274  cpl_matrix_set(self->coeffs, i, j, c);
275 
276  }
277 
278  }
279 
280  }
281 
282  return 0;
283 
284 }
285 
286 
287 cxint
288 giraffe_chebyshev2d_set_coeff(GiChebyshev2D *self, cxint i, cxint j,
289  cxdouble value)
290 {
291 
292  cx_assert(self != NULL);
293 
294  if (i > self->xorder || j > self->yorder) {
295  return 1;
296  }
297 
298  cpl_matrix_set(self->coeffs, i, j, value);
299 
300  return 0;
301 
302 }
303 
304 
305 cxdouble
306 giraffe_chebyshev2d_eval(const GiChebyshev2D *self, cxdouble x, cxdouble y)
307 {
308 
309  cx_assert(self != NULL);
310  return _giraffe_chebyshev2d_eval(self, x, y);
311 
312 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004