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
40struct 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
55inline 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
117GiChebyshev2D *
118giraffe_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
143GiChebyshev2D *
144giraffe_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
168void
169giraffe_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
188void 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
207void
208giraffe_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
235const cpl_matrix *
236giraffe_chebyshev2d_coeffs(const GiChebyshev2D *self)
237{
238
239 cx_assert(self != NULL);
240
241 return self->coeffs;
242
243}
244
245
246cxint
247giraffe_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
287cxint
288giraffe_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
305cxdouble
306giraffe_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.18.3.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Jun 4 2025 23:51:55 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004