GIRAFFE Pipeline Reference Manual

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

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