GIRAFFE Pipeline Reference Manual

gimath.c
1 /* $Id$
2  *
3  * This file is part of the GIRAFFE Pipeline
4  * Copyright (C) 2002-2006 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 02110-1301 USA
19  */
20 /*
21  * $Author$
22  * $Date$
23  * $Revision$
24  * $Name$
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30 
31 #include <math.h>
32 
33 #include <cxmemory.h>
34 #include <cxmessages.h>
35 
36 #include "gimath.h"
37 
38 
48 inline static cxdouble
49 _giraffe_chebyshev2d_eval(cxdouble ax, cxdouble bx, cxdouble ay, cxdouble by,
50  const cpl_matrix* coeffs, cxdouble x, cxdouble y)
51 {
52 
53  cxint i, k;
54  cxint xorder;
55  cxint yorder;
56 
57  const cxdouble* _coeffs = NULL;
58 
59  cxdouble x_n = (2.0 * x - ax - bx) / (bx - ax);
60  cxdouble y_n = (2.0 * y - ay - by) / (by - ay);
61  cxdouble cx0 = 1.0;
62  cxdouble cx1 = x_n;
63  cxdouble sum = 0.;
64 
65 
66  cx_assert(coeffs != NULL);
67 
68  xorder = cpl_matrix_get_nrow(coeffs);
69  yorder = cpl_matrix_get_ncol(coeffs);
70 
71  _coeffs = cpl_matrix_get_data_const(coeffs);
72  cx_assert(_coeffs != NULL);
73 
74  for (i = 0, k = 0; i < xorder; i++) {
75 
76  register cxint j;
77 
78  register cxdouble cx2 = 0.;
79  register cxdouble cy0 = 1.0;
80  register cxdouble cy1 = y_n;
81 
82 
83  if (i < 2) {
84  cx2 = cx0;
85  }
86  else {
87  cx2 = 2.0 * cx1 * x_n - cx0;
88  }
89 
90  for (j = 0; j < yorder; j++) {
91 
92  cxdouble cy2 = 0.;
93 
94  if (j < 2) {
95  cy2 = cy0;
96  }
97  else {
98  cy2 = 2.0 * cy1 * y_n - cy0;
99  }
100 
101  sum += cx2 * cy2 * _coeffs[k++];
102 
103  cy0 = cy1;
104  cy1 = cy2;
105 
106  }
107 
108  cx0 = cx1;
109  cx1 = cx2;
110 
111  }
112 
113  return sum;
114 
115 }
116 
117 
118 cxdouble
119 giraffe_interpolate_linear(cxdouble x, cxdouble x_0, cxdouble y_0,
120  cxdouble x_1, cxdouble y_1)
121 {
122 
123  register cxdouble t = (x - x_0) / (x_1 - x_0);
124 
125  return (1. - t) * y_0 + t * y_1;
126 
127 }
128 
129 
144 cpl_matrix *
145 giraffe_chebyshev_base1d(cxdouble start, cxdouble size, cxint order,
146  cpl_matrix *m_x)
147 {
148 
149  register cxint32 i, j, x_nrow, t_ncol;
150 
151  register cxdouble xn, dsize2, d2size;
152 
153  cxdouble *pmx, *pmt;
154 
155  cpl_matrix *m_t = NULL;
156 
157 
158  /*
159  * Preprocessing
160  */
161 
162  dsize2 = size / 2.0;
163  d2size = 2.0 / size;
164 
165  x_nrow = cpl_matrix_get_nrow(m_x);
166 
167  m_t = cpl_matrix_new(order, x_nrow);
168 
169  if (m_t == NULL) {
170  return NULL;
171  }
172 
173  t_ncol = x_nrow;
174 
175  pmx = cpl_matrix_get_data(m_x);
176  pmt = cpl_matrix_get_data(m_t);
177 
178 
179  /*
180  * Processing
181  */
182 
183  for (j = 0; j < t_ncol; j++) {
184 
185  /*
186  * Normalize array between [-1,1]
187  * x[n] = (array[n] - start - size / 2.0) * 2.0 / size;
188  */
189 
190  xn = (pmx[j] - start - dsize2) * d2size;
191 
192  /*
193  * Ones for first column: T[0] = 1.0
194  */
195 
196  pmt[j] = 1.0;
197 
198  if (order < 2) {
199  continue;
200  }
201 
202  /*
203  * X for second column: T[1] = x
204  */
205 
206  pmt[j+t_ncol] = xn;
207 
208  for (i = 2; i < order; i++) {
209 
210  /*
211  * compute Chebyshev coefficients for following columns
212  * with: T[k] = 2 * x * T[k-1] - T[k-2]
213  */
214 
215  pmt[j+i*t_ncol] = 2.0 * xn * pmt[j+(i-1)*t_ncol] -
216  pmt[j+(i-2)*t_ncol];
217 
218  }
219  }
220 
221  return m_t;
222 
223 }
224 
225 
246 cpl_matrix *
247 giraffe_chebyshev_base2d(cxdouble xstart, cxdouble ystart, cxdouble xsize,
248  cxdouble ysize, cxint xorder, cxint yorder,
249  cpl_matrix *m_x, cpl_matrix *m_y)
250 {
251 
252  register cxint32 i, j, k, l;
253 
254  cxint32 x_nrow, y_nrow, /*t_nrow,*/ t_ncol;
255 
256  register cxdouble dxsize2, d2xsize;
257  register cxdouble dysize2, d2ysize;
258  register cxdouble x_n, y_n;
259  register cxdouble bx0, bx1, bx2, by0, by1, by2;
260 
261  cxdouble *pmx, *pmy, *pmt;
262 
263  cpl_matrix *m_t = NULL;
264 
265 
266  /*
267  * Preprocsesing
268  */
269 
270  dxsize2 = xsize / 2.0;
271  d2xsize = 2.0 / xsize;
272  dysize2 = ysize / 2.0;
273  d2ysize = 2.0 / ysize;
274 
275  x_nrow = cpl_matrix_get_nrow(m_x);
276  y_nrow = cpl_matrix_get_nrow(m_y);
277 
278  if (x_nrow != y_nrow) {
279  return NULL;
280  }
281 
282  m_t = cpl_matrix_new(xorder * yorder, x_nrow);
283 
284  if (m_t == NULL) {
285  return NULL;
286  }
287 
288  /*t_nrow = cpl_matrix_get_nrow(m_t);*/
289  t_ncol = cpl_matrix_get_ncol(m_t);
290 
291  pmx = cpl_matrix_get_data(m_x);
292  pmy = cpl_matrix_get_data(m_y);
293  pmt = cpl_matrix_get_data(m_t);
294 
295 
296  /*
297  * Processing
298  */
299 
300  for (j = 0; j < t_ncol; j++) {
301 
302  /*
303  * Normalize array between [-1,1]
304  * x[n] = (array[n] - start - size / 2.0) * 2.0 / size;
305  */
306 
307  x_n = (pmx[j] - xstart - dxsize2) * d2xsize;
308  y_n = (pmy[j] - ystart - dysize2) * d2ysize;
309 
310  bx0 = 1.0;
311  bx1 = x_n;
312 
313  for (l = 0,i = 0; i < xorder; i++) {
314 
315  if (i < 2) {
316  bx2 = bx0;
317  }
318  else {
319  bx2 = 2.0 * bx1 * x_n - bx0;
320  }
321 
322  by0 = 1.0;
323  by1 = y_n;
324 
325  for (k = 0; k < yorder; k++) {
326 
327  if (k < 2) {
328  by2 = by0;
329  }
330  else {
331  by2 = 2.0 * by1 * y_n - by0;
332  }
333 
334  pmt[j + (l++) * t_ncol] = bx2 * by2;
335 
336  by0 = by1;
337  by1 = by2;
338 
339  }
340 
341  bx0 = bx1;
342  bx1 = bx2;
343 
344  }
345  }
346 
347  return m_t;
348 
349 }
350 
351 
370 cpl_matrix *
371 giraffe_chebyshev_base2dt(cxdouble xstart, cxdouble ystart, cxdouble xsize,
372  cxdouble ysize, cxint xorder, cxint yorder,
373  cpl_matrix *m_x, cpl_matrix *m_y)
374 {
375 
376  register cxint32 i, j, k, l;
377 
378  cxint32 x_nrow, y_nrow, t_nrow, t_ncol;
379 
380  register cxdouble dxsize2, d2xsize;
381  register cxdouble dysize2, d2ysize;
382  register cxdouble x_n, y_n;
383  register cxdouble bx0, bx1, bx2, by0, by1, by2;
384 
385  cxdouble *pmx, *pmy, *pmt;
386 
387  cpl_matrix *m_t = NULL;
388 
389 
390  /*
391  * Preprocess
392  */
393 
394  dxsize2 = xsize / 2.0;
395  d2xsize = 2.0 / xsize;
396  dysize2 = ysize / 2.0;
397  d2ysize = 2.0 / ysize;
398 
399  x_nrow = cpl_matrix_get_nrow(m_x);
400  y_nrow = cpl_matrix_get_nrow(m_y);
401 
402  if (x_nrow != y_nrow) {
403  return NULL;
404  }
405 
406  m_t = cpl_matrix_new(x_nrow, xorder * yorder);
407 
408  if (m_t == NULL) {
409  return NULL;
410  }
411 
412  t_nrow = cpl_matrix_get_nrow(m_t);
413  t_ncol = cpl_matrix_get_ncol(m_t);
414 
415  pmx = cpl_matrix_get_data(m_x);
416  pmy = cpl_matrix_get_data(m_y);
417  pmt = cpl_matrix_get_data(m_t);
418 
419 
420  /*
421  * Process
422  */
423 
424  for (j = 0; j < t_nrow; j++) {
425 
426  /*
427  * Normalize array between [-1,1]
428  * x[n] = (array[n] - start - size / 2.0) * 2.0 / size;
429  */
430 
431  x_n = (pmx[j] - xstart - dxsize2) * d2xsize;
432  y_n = (pmy[j] - ystart - dysize2) * d2ysize;
433 
434  bx0 = 1.0;
435  bx1 = x_n;
436 
437  for (l = 0, i = 0; i < xorder; i++) {
438 
439  if (i < 2) {
440  bx2 = bx0;
441  }
442  else {
443  bx2 = 2.0 * bx1 * x_n - bx0;
444  }
445 
446  by0 = 1.0;
447  by1 = y_n;
448 
449  for (k = 0; k < yorder; k++) {
450 
451  if (k < 2) {
452  by2 = by0;
453  }
454  else {
455  by2 = 2.0 * by1 * y_n - by0;
456  }
457 
458  pmt[j * t_ncol + (l++)] = bx2 * by2;
459 
460  by0 = by1;
461  by1 = by2;
462 
463  }
464 
465  bx0 = bx1;
466  bx1 = bx2;
467 
468  }
469  }
470 
471  return m_t;
472 }
473 
474 
489 cpl_matrix *
490 giraffe_chebyshev_fit1d(cxdouble start, cxdouble size, cpl_matrix *m_c,
491  cpl_matrix *m_x)
492 {
493 
494  register cxint32 i, j, jj, order;
495 
496  cxint32 x_nrow, c_nrow, c_ncol, t_nrow, t_ncol;
497 
498  register cxdouble xn;
499  register cxdouble dsize2, d2size;
500  register cxdouble *f0 = NULL;
501  register cxdouble *t0 = NULL;
502  register cxdouble *c0 = NULL;
503 
504  cxdouble *pmc, *pmx, *pmt, *pmf;
505 
506  cpl_matrix *m_t; /* 1D Chabyshev base transposed */
507  cpl_matrix *m_f; /* 1D Chabyshev fit */
508 
509 
510  /*
511  * Preprocess
512  */
513 
514  dsize2 = size / 2.0;
515  d2size = 2.0 / size;
516 
517  c_nrow = cpl_matrix_get_nrow(m_c);
518  c_ncol = cpl_matrix_get_ncol(m_c);
519  x_nrow = cpl_matrix_get_nrow(m_x);
520  order = c_nrow;
521 
522  m_t = cpl_matrix_new(x_nrow, order);
523 
524  if (m_t == NULL) {
525  return NULL;
526  }
527 
528  m_f = cpl_matrix_new(c_nrow, x_nrow);
529 
530  if (m_f == NULL) {
531  cpl_matrix_delete(m_t);
532  return NULL;
533  }
534 
535  t_nrow = cpl_matrix_get_nrow(m_t);
536  t_ncol = cpl_matrix_get_ncol(m_t);
537 
538  pmc = cpl_matrix_get_data(m_c);
539  pmx = cpl_matrix_get_data(m_x);
540  pmt = cpl_matrix_get_data(m_t);
541  pmf = cpl_matrix_get_data(m_f);
542 
543 
544  /*
545  * Process
546  */
547 
548  for (j = 0; j < t_nrow; j++) {
549 
550  /*
551  * Normalize array between [-1,1]
552  * x[n] = (array[n] - start - size / 2.0) * 2.0 / size;
553  */
554 
555  xn = (pmx[j] - start - dsize2) * d2size;
556 
557  /*
558  * Ones for first column: T[0] = 1.0
559  */
560 
561  jj = j * t_ncol;
562 
563  pmt[jj] = 1.0;
564 
565  if (order < 2) {
566  continue;
567  }
568 
569  /*
570  * X for second column: T[1] = x
571  */
572 
573  pmt[jj+1] = xn;
574 
575  for (i = 2; i < order; i++) {
576 
577  /*
578  * Compute Chebyshev coefficients for following columns
579  * with: T[k] = 2 * x * T[k-1] - T[k-2]
580  */
581 
582  pmt[jj + i] = 2.0 * xn * pmt[jj + (i - 1)] - pmt[jj + (i - 2)];
583 
584  }
585  }
586 
587  for (i = 0, f0 = pmf ; i < c_nrow; i++) {
588  for (j = 0, t0 = pmt; j < t_nrow; j++, f0++) {
589  for (jj = 0, *f0 = 0, c0 = pmc + i * c_ncol; jj < c_ncol; jj++) {
590  *f0 += *c0++ * *t0++;
591  }
592  }
593  }
594 
595  cpl_matrix_delete(m_t);
596 
597  return m_f;
598 
599 }
600 
601 
619 cpl_matrix *
620 giraffe_chebyshev_fit2d(cxdouble xstart, cxdouble ystart, cxdouble xsize,
621  cxdouble ysize, const cpl_matrix* m_c,
622  const cpl_matrix* m_x, const cpl_matrix* m_y)
623 {
624 
625  cxint i;
626  cxint nx;
627 
628  const cxdouble* _x = NULL;
629  const cxdouble* _y = NULL;
630 
631  cxdouble bx = xstart + xsize;
632  cxdouble by = ystart + ysize;
633 
634  cpl_matrix *f = NULL;
635 
636 
637  if (m_c == NULL || m_x == NULL || m_y == NULL) {
638  return NULL;
639  }
640 
641  nx = cpl_matrix_get_nrow(m_x);
642 
643  if (nx != cpl_matrix_get_nrow(m_y)) {
644  return NULL;
645  }
646 
647  f = cpl_matrix_new(nx, 1);
648 
649  if (f == NULL) {
650  return NULL;
651  }
652 
653  _x = cpl_matrix_get_data_const(m_x);
654  _y = cpl_matrix_get_data_const(m_y);
655 
656 
657  for (i = 0; i < nx; i++) {
658 
659  cxdouble sum = _giraffe_chebyshev2d_eval(xstart, bx, ystart, by,
660  m_c, _x[i], _y[i]);
661  cpl_matrix_set(f, i, 0, sum);
662 
663  }
664 
665  return f;
666 
667 }
668 
669 
670 #define SWAP(a,b) {swap=(a);(a)=(b);(b)=swap;}
671 
699 cxint
700 giraffe_gauss_jordan(
701  cpl_matrix *mA,
702  cxint n,
703  cpl_matrix *mB,
704  cxint m
705 ) {
706 
707  cxint *indxc, *indxr, *ipiv;
708  register cxint i, icol = 0, irow = 0, j, jj, k, l, ll;
709  register cxdouble big, dum, pivinv, swap;
710 
711  cxdouble *pd_mA = NULL, *pd_mB = NULL;
712  cxint nr_mA, nr_mB;
713 
714  pd_mA = cpl_matrix_get_data(mA);
715  pd_mB = cpl_matrix_get_data(mB);
716  nr_mA = cpl_matrix_get_nrow(mA);
717  nr_mB = cpl_matrix_get_nrow(mB);
718 
719  indxc = (cxint *) cx_calloc(n, sizeof(cxint));
720  indxr = (cxint *) cx_calloc(n, sizeof(cxint));
721  ipiv = (cxint *) cx_calloc(n, sizeof(cxint));
722 
723  for (i = 0; i < n; i++) {
724  /* main loop over the columns to be reduced */
725  big = 0.0;
726  for (j = 0; j < n; j++) {
727  /* outer loop of the search of a pivot element */
728  jj = j * nr_mA;
729  if (ipiv[j] != 1) {
730  for (k = 0; k < n; k++) {
731  if (ipiv[k] == 0) {
732  if (fabs(pd_mA[jj + k]) >= big) {
733  big = fabs(pd_mA[jj + k]);
734  irow = j;
735  icol = k;
736  }
737  } else if (ipiv[k] > 1) {
738  cx_free((cxptr) ipiv);
739  cx_free((cxptr) indxr);
740  cx_free((cxptr) indxc);
741  /* matrix singular 1 */
742  return -1;
743  }
744  }
745  }
746  }
747 
748  /* We now have the pivot, so we interchange rows, if needed, to put
749  * the pivot element on the diagonal. The columns are not physically
750  * interchanged, only relabeled
751  */
752 
753  ++(ipiv[icol]);
754 
755  if (irow != icol) {
756  for (l = 0; l < n; l++) {
757  SWAP(pd_mA[irow * nr_mA + l], pd_mA[icol * nr_mA + l])
758  }
759  for (l = 0; l < m; l++) {
760  SWAP(pd_mB[irow * nr_mB + l], pd_mB[icol * nr_mB + l])
761  }
762  }
763 
764  indxr[i] = irow;
765  indxc[i] = icol;
766 
767  if (pd_mA[icol * nr_mA + icol] == 0.0) {
768  cx_free((cxptr) ipiv);
769  cx_free((cxptr) indxr);
770  cx_free((cxptr) indxc);
771  /* matrix singular 2 */
772  return -2;
773  }
774 
775  /* divide the pivot row by the pivot element */
776  pivinv = 1.0 / pd_mA[icol * nr_mA + icol];
777  pd_mA[icol * nr_mA + icol] = 1.0;
778 
779  for (l = 0; l < n; l++) {
780  pd_mA[icol * nr_mA + l] *= pivinv;
781  }
782 
783  for (l = 0; l < m; l++) {
784  pd_mB[icol * nr_mB + l] *= pivinv;
785  }
786 
787  for (ll = 0; ll < n; ll++) {
788  /* reduce the rows... except for the pivot one */
789  if (ll != icol) {
790  dum = pd_mA[ll * nr_mA + icol];
791  pd_mA[ll * nr_mA + icol] = 0.0;
792 
793  for (l = 0; l < n; l++) {
794  pd_mA[ll * nr_mA + l] -= pd_mA[icol * nr_mA + l] * dum;
795  }
796 
797  for (l = 0; l < m; l++) {
798  pd_mB[ll * nr_mB + l] -= pd_mB[icol * nr_mB + l] * dum;
799  }
800  }
801  }
802  }
803 
804  cx_free((cxptr) ipiv);
805 
806  /* unscramble the solution in view of the column interchanges */
807  for (l = (n-1); l >= 0; l--) {
808  if (indxr[l] != indxc[l]) {
809  for (k = 0; k < n; k++) {
810  SWAP(pd_mA[k * nr_mA + indxr[l]], pd_mA[k * nr_mA + indxc[l]]);
811  }
812  }
813  }
814  cx_free((cxptr)indxr);
815  cx_free((cxptr)indxc);
816 
817  return 0;
818 
819 } /* end of gauss_jordan() */
820 
821 #undef SWAP
822 
849 void
850 giraffe_compute_image_coordinates(
851  cxlong nx,
852  cxlong ny,
853  cpl_matrix *mXi,
854  cpl_matrix *mYi
855 ) {
856 
857  register cxlong i, j, k;
858  register cxdouble *pd_mXi = NULL, *pd_mYi = NULL;
859 
860  if ((mXi != NULL) && (mYi != NULL)) {
861 
862  pd_mXi = cpl_matrix_get_data(mXi);
863  pd_mYi = cpl_matrix_get_data(mYi);
864 
865  for (j = 0; j < nx; j++) {
866  for (k = 0; k < ny; k++) {
867  i = k + j * ny;
868  pd_mXi[i] = (cxdouble) j;
869  pd_mYi[i] = (cxdouble) k;
870  }
871  }
872  } else if (mXi != NULL) {
873 
874  pd_mXi = cpl_matrix_get_data(mXi);
875 
876  for (j = 0; j < nx; j++) {
877  for (k = 0; k < ny; k++) {
878  i = k + j * ny;
879  pd_mXi[i] = (cxdouble) j;
880  }
881  }
882  } else if (mYi != NULL) {
883 
884  pd_mYi = cpl_matrix_get_data(mYi);
885 
886  for (j = 0; j < nx; j++) {
887  for (k = 0; k < ny; k++) {
888  i = k + j * ny;
889  pd_mYi[i] = (cxdouble) k;
890  }
891  }
892  }
893 
894  return;
895 
896 } /* end of giraffe_compute_image_coordinates() */
897 

This file is part of the GIRAFFE Pipeline Reference Manual 2.14.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Mar 11 2015 13:19:41 by doxygen 1.8.9.1 written by Dimitri van Heesch, © 1997-2004