SINFONI Pipeline Reference Manual  2.6.0
sinfo_median.c
1 /*
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 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, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 /*---------------------------------------------------------------------------
20 
21  File name : sinfo_median.c
22  Author : N. Devillard
23  Created on : 1998
24  Description : Fast sinfo_median finding routines.
25 
26  *--------------------------------------------------------------------------*/
27 /*
28  $Id: sinfo_median.c,v 1.4 2012-03-02 08:42:20 amodigli Exp $
29  $Author: amodigli $
30  $Date: 2012-03-02 08:42:20 $
31  $Revision: 1.4 $
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37 /*---------------------------------------------------------------------------
38  Includes
39  ---------------------------------------------------------------------------*/
40 #include "sinfo_median.h"
48 /*---------------------------------------------------------------------------
49  Macros
50  ---------------------------------------------------------------------------*/
51 #define median_WIRTH(a,n) sinfo_kth_smallest(a,n,(((n)&1)?((n)/2):(((n)/2)-1)))
52 /*---------------------------------------------------------------------------
53  Function codes
54  ---------------------------------------------------------------------------*/
83 #define PIX_SWAP(a,b) { register pixelvalue t=(a);(a)=(b);(b)=t; }
84 
85 pixelvalue
86 sinfo_kth_smallest(pixelvalue a[], int n, int k)
87 {
88 
89  register int l=0 ;
90  register int m=n-1 ;
91  while (l<m) {
92  register pixelvalue x=a[k] ;
93  register int i=l ;
94  register int j=m ;
95  do {
96  while (a[i]<x) i++ ;
97  while (x<a[j]) j-- ;
98  if (i<=j) {
99  PIX_SWAP(a[i],a[j]) ;
100  i++ ; j-- ;
101  }
102  } while (i<=j) ;
103  if (j<k) l=i ;
104  if (k<i) m=j ;
105  }
106  return a[k] ;
107 }
108 
109 #undef PIX_SWAP
110 
125 #define DBL_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
126 
127 double
128 sinfo_kth_smallest_double(double a[], int n, int k)
129 {
130 
131  register int l=0 ;
132  register int m=n-1 ;
133  while (l<m) {
134  register double x=a[k] ;
135  register int i=l ;
136  register int j=m ;
137  do {
138  while (a[i]<x) i++ ;
139  while (x<a[j]) j-- ;
140  if (i<=j) {
141  DBL_SWAP(a[i],a[j]) ;
142  i++ ; j-- ;
143  }
144  } while (i<=j) ;
145  if (j<k) l=i ;
146  if (k<i) m=j ;
147  }
148  return a[k] ;
149 }
150 
151 #undef DBL_SWAP
152 
153 #define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
154 #define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }
155 
170 pixelvalue
171 sinfo_opt_med3(
172  pixelvalue * p
173 )
174 {
175  PIX_SORT(p[0],p[1]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[0],p[1]) ;
176  return(p[1]) ;
177 }
178 
193 pixelvalue
194 sinfo_opt_med5(
195  pixelvalue * p
196 )
197 {
198  PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ;
199  PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ;
200  PIX_SORT(p[1],p[2]) ; return(p[2]) ;
201 }
202 
217 pixelvalue
218 sinfo_opt_med7(
219  pixelvalue * p
220 )
221 {
222  PIX_SORT(p[0], p[5]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[1], p[6]) ;
223  PIX_SORT(p[2], p[4]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[5]) ;
224  PIX_SORT(p[2], p[6]) ; PIX_SORT(p[2], p[3]) ; PIX_SORT(p[3], p[6]) ;
225  PIX_SORT(p[4], p[5]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[1], p[3]) ;
226  PIX_SORT(p[3], p[4]) ; return (p[3]) ;
227 }
228 
247 pixelvalue
248 sinfo_opt_med9(
249  pixelvalue * p
250 )
251 {
252  PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
253  PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
254  PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
255  PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
256  PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
257  PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
258  PIX_SORT(p[4], p[2]) ; return(p[4]) ;
259 }
260 
279 pixelvalue
280 sinfo_opt_med25(
281  pixelvalue * p
282 )
283 {
284  PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[2], p[4]) ;
285  PIX_SORT(p[2], p[3]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[5], p[7]) ;
286  PIX_SORT(p[5], p[6]) ; PIX_SORT(p[9], p[10]) ; PIX_SORT(p[8], p[10]) ;
287  PIX_SORT(p[8], p[9]) ; PIX_SORT(p[12], p[13]) ; PIX_SORT(p[11], p[13]) ;
288  PIX_SORT(p[11], p[12]) ; PIX_SORT(p[15], p[16]) ; PIX_SORT(p[14], p[16]) ;
289  PIX_SORT(p[14], p[15]) ; PIX_SORT(p[18], p[19]) ; PIX_SORT(p[17], p[19]) ;
290  PIX_SORT(p[17], p[18]) ; PIX_SORT(p[21], p[22]) ; PIX_SORT(p[20], p[22]) ;
291  PIX_SORT(p[20], p[21]) ; PIX_SORT(p[23], p[24]) ; PIX_SORT(p[2], p[5]) ;
292  PIX_SORT(p[3], p[6]) ; PIX_SORT(p[0], p[6]) ; PIX_SORT(p[0], p[3]) ;
293  PIX_SORT(p[4], p[7]) ; PIX_SORT(p[1], p[7]) ; PIX_SORT(p[1], p[4]) ;
294  PIX_SORT(p[11], p[14]) ; PIX_SORT(p[8], p[14]) ; PIX_SORT(p[8], p[11]) ;
295  PIX_SORT(p[12], p[15]) ; PIX_SORT(p[9], p[15]) ; PIX_SORT(p[9], p[12]) ;
296  PIX_SORT(p[13], p[16]) ; PIX_SORT(p[10], p[16]) ; PIX_SORT(p[10], p[13]) ;
297  PIX_SORT(p[20], p[23]) ; PIX_SORT(p[17], p[23]) ; PIX_SORT(p[17], p[20]) ;
298  PIX_SORT(p[21], p[24]) ; PIX_SORT(p[18], p[24]) ; PIX_SORT(p[18], p[21]) ;
299  PIX_SORT(p[19], p[22]) ; PIX_SORT(p[8], p[17]) ; PIX_SORT(p[9], p[18]) ;
300  PIX_SORT(p[0], p[18]) ; PIX_SORT(p[0], p[9]) ; PIX_SORT(p[10], p[19]) ;
301  PIX_SORT(p[1], p[19]) ; PIX_SORT(p[1], p[10]) ; PIX_SORT(p[11], p[20]) ;
302  PIX_SORT(p[2], p[20]) ; PIX_SORT(p[2], p[11]) ; PIX_SORT(p[12], p[21]) ;
303  PIX_SORT(p[3], p[21]) ; PIX_SORT(p[3], p[12]) ; PIX_SORT(p[13], p[22]) ;
304  PIX_SORT(p[4], p[22]) ; PIX_SORT(p[4], p[13]) ; PIX_SORT(p[14], p[23]) ;
305  PIX_SORT(p[5], p[23]) ; PIX_SORT(p[5], p[14]) ; PIX_SORT(p[15], p[24]) ;
306  PIX_SORT(p[6], p[24]) ; PIX_SORT(p[6], p[15]) ; PIX_SORT(p[7], p[16]) ;
307  PIX_SORT(p[7], p[19]) ; PIX_SORT(p[13], p[21]) ; PIX_SORT(p[15], p[23]) ;
308  PIX_SORT(p[7], p[13]) ; PIX_SORT(p[7], p[15]) ; PIX_SORT(p[1], p[9]) ;
309  PIX_SORT(p[3], p[11]) ; PIX_SORT(p[5], p[17]) ; PIX_SORT(p[11], p[17]) ;
310  PIX_SORT(p[9], p[17]) ; PIX_SORT(p[4], p[10]) ; PIX_SORT(p[6], p[12]) ;
311  PIX_SORT(p[7], p[14]) ; PIX_SORT(p[4], p[6]) ; PIX_SORT(p[4], p[7]) ;
312  PIX_SORT(p[12], p[14]) ; PIX_SORT(p[10], p[14]) ; PIX_SORT(p[6], p[7]) ;
313  PIX_SORT(p[10], p[12]) ; PIX_SORT(p[6], p[10]) ; PIX_SORT(p[6], p[17]) ;
314  PIX_SORT(p[12], p[17]) ; PIX_SORT(p[7], p[17]) ; PIX_SORT(p[7], p[10]) ;
315  PIX_SORT(p[12], p[18]) ; PIX_SORT(p[7], p[12]) ; PIX_SORT(p[10], p[18]) ;
316  PIX_SORT(p[12], p[20]) ; PIX_SORT(p[10], p[20]) ; PIX_SORT(p[10], p[12]) ;
317 
318  return (p[12]);
319 }
320 
321 #undef PIX_SORT
322 #undef PIX_SWAP
323 
339 pixelvalue
340 sinfo_median_pixelvalue(pixelvalue * a, int n)
341 {
342  pixelvalue sinfo_median ;
343 
344  switch(n) {
345  case 3:
346  sinfo_median = sinfo_opt_med3(a);
347  break ;
348 
349  case 5:
350  sinfo_median = sinfo_opt_med5(a);
351  break ;
352 
353  case 7:
354  sinfo_median = sinfo_opt_med7(a);
355  break ;
356 
357  case 9:
358  sinfo_median = sinfo_opt_med9(a);
359  break ;
360 
361  case 25:
362  sinfo_median = sinfo_opt_med25(a);
363  break ;
364 
365  default:
366  sinfo_median = median_WIRTH(a,n);
367  break ;
368  }
369  return sinfo_median;
370 }
371