gichebyshev.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031 #include <cxmemory.h>
00032 #include <cxmessages.h>
00033
00034 #include <cpl_matrix.h>
00035
00036 #include "gichebyshev.h"
00037
00038
00047 struct GiChebyshev2D {
00048
00049 cxint xorder;
00050 cxint yorder;
00051
00052 cxdouble ax;
00053 cxdouble bx;
00054 cxdouble ay;
00055 cxdouble by;
00056
00057 cpl_matrix *coeffs;
00058
00059 };
00060
00061
00062 inline static cxdouble
00063 _giraffe_chebyshev2d_eval(const GiChebyshev2D *self, cxdouble x, cxdouble y)
00064 {
00065
00066 cxint i, k;
00067 cxint nx = self->xorder + 1;
00068 cxint ny = self->yorder + 1;
00069
00070 cxdouble xn = (2.0 * x - self->ax - self->bx) / (self->bx - self->ax);
00071 cxdouble yn = (2.0 * y - self->ay - self->by) / (self->by - self->ay);
00072 cxdouble cx0 = 1.0;
00073 cxdouble cx1 = xn;
00074 cxdouble sum = 0.;
00075 cxdouble *_coeffs = cpl_matrix_get_data(self->coeffs);
00076
00077
00078 cx_assert(_coeffs != NULL);
00079
00080 for (i = 0, k = 0; i < nx; i++) {
00081
00082 register cxint j;
00083
00084 register cxdouble cy0 = 1.0;
00085 register cxdouble cy1 = yn;
00086 register cxdouble cx2 = 0.;
00087
00088
00089 if (i < 2) {
00090 cx2 = cx0;
00091 }
00092 else {
00093 cx2 = 2.0 * cx1 * xn - cx0;
00094 }
00095
00096 for (j = 0; j < ny; j++) {
00097
00098 cxdouble cy2 = 0.;
00099
00100 if (j < 2) {
00101 cy2 = cy0;
00102 }
00103 else {
00104 cy2 = 2.0 * cy1 * yn - cy0;
00105 }
00106
00107 sum += cx2 * cy2 * _coeffs[k++];
00108
00109 cy0 = cy1;
00110 cy1 = cy2;
00111
00112 }
00113
00114 cx0 = cx1;
00115 cx1 = cx2;
00116
00117 }
00118
00119 return sum;
00120
00121 }
00122
00123
00124 GiChebyshev2D *
00125 giraffe_chebyshev2d_new(cxint xorder, cxint yorder)
00126 {
00127
00128 GiChebyshev2D *self = cx_calloc(1, sizeof *self);
00129
00130
00131 if (self) {
00132
00133 self->xorder = xorder;
00134 self->yorder = yorder;
00135
00136 self->coeffs = cpl_matrix_new((xorder + 1), (yorder + 1));
00137
00138 if (self->coeffs == NULL) {
00139 giraffe_chebyshev2d_delete(self);
00140 return NULL;
00141 }
00142
00143 }
00144
00145 return self;
00146
00147 }
00148
00149
00150 GiChebyshev2D *
00151 giraffe_chebyshev2d_clone(const GiChebyshev2D *other)
00152 {
00153
00154 GiChebyshev2D *self = NULL;
00155
00156
00157 if (other != NULL) {
00158
00159 self = giraffe_chebyshev2d_new(other->xorder, other->yorder);
00160
00161 self->ax = other->ax;
00162 self->bx = other->bx;
00163 self->ay = other->ay;
00164 self->by = other->by;
00165
00166 self->coeffs = cpl_matrix_duplicate(other->coeffs);
00167
00168 }
00169
00170 return self;
00171
00172 }
00173
00174
00175 void
00176 giraffe_chebyshev2d_delete(GiChebyshev2D *self)
00177 {
00178
00179 if (self) {
00180
00181 if (self->coeffs) {
00182 cpl_matrix_delete(self->coeffs);
00183 self->coeffs = NULL;
00184 }
00185
00186 cx_free(self);
00187
00188 }
00189
00190 return;
00191
00192 }
00193
00194
00195 void giraffe_chebyshev2d_get_order(const GiChebyshev2D *self, cxint *xorder,
00196 cxint *yorder)
00197 {
00198
00199 cx_assert(self != NULL);
00200
00201 if (xorder != NULL) {
00202 *xorder = self->xorder;
00203 }
00204
00205 if (yorder != NULL) {
00206 *yorder = self->yorder;
00207 }
00208
00209 return;
00210
00211 }
00212
00213
00214 void
00215 giraffe_chebyshev2d_get_range(const GiChebyshev2D *self, cxdouble *ax,
00216 cxdouble *bx, cxdouble *ay, cxdouble *by)
00217 {
00218
00219 cx_assert(self != NULL);
00220
00221 if (ax != NULL) {
00222 *ax = self->ax;
00223 }
00224
00225 if (bx != NULL) {
00226 *bx = self->bx;
00227 }
00228
00229 if (ay != NULL) {
00230 *ay = self->ay;
00231 }
00232
00233 if (by != NULL) {
00234 *by = self->by;
00235 }
00236
00237 return;
00238
00239 }
00240
00241
00242 const cpl_matrix *
00243 giraffe_chebyshev2d_coeffs(const GiChebyshev2D *self)
00244 {
00245
00246 cx_assert(self != NULL);
00247
00248 return self->coeffs;
00249
00250 }
00251
00252
00253 cxint
00254 giraffe_chebyshev2d_set(GiChebyshev2D *self, cxdouble ax, cxdouble bx,
00255 cxdouble ay, cxdouble by, cpl_matrix *coeffs)
00256 {
00257
00258 cx_assert(self != NULL);
00259
00260 self->ax = ax;
00261 self->bx = bx;
00262 self->ay = ay;
00263 self->by = by;
00264
00265 if (cpl_matrix_get_nrow(coeffs) <= self->xorder ||
00266 cpl_matrix_get_ncol(coeffs) <= self->yorder) {
00267 return 1;
00268 }
00269 else {
00270
00271 cxint i;
00272
00273 for (i = 0; i <= self->xorder; i++) {
00274
00275 cxint j;
00276
00277 for (j = 0; j <= self->yorder; j++) {
00278
00279 cxdouble c = cpl_matrix_get(coeffs, i, j);
00280
00281 cpl_matrix_set(self->coeffs, i, j, c);
00282
00283 }
00284
00285 }
00286
00287 }
00288
00289 return 0;
00290
00291 }
00292
00293
00294 cxint
00295 giraffe_chebyshev2d_set_coeff(GiChebyshev2D *self, cxint i, cxint j,
00296 cxdouble value)
00297 {
00298
00299 cx_assert(self != NULL);
00300
00301 if (i > self->xorder || j > self->yorder) {
00302 return 1;
00303 }
00304
00305 cpl_matrix_set(self->coeffs, i, j, value);
00306
00307 return 0;
00308
00309 }
00310
00311
00312 cxdouble
00313 giraffe_chebyshev2d_eval(const GiChebyshev2D *self, cxdouble x, cxdouble y)
00314 {
00315
00316 cx_assert(self != NULL);
00317 return _giraffe_chebyshev2d_eval(self, x, y);
00318
00319 }