SINFONI Pipeline Reference Manual  2.5.2
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  register int i,j,l,m ;
89  register pixelvalue x ;
90 
91  l=0 ; m=n-1 ;
92  while (l<m) {
93  x=a[k] ;
94  i=l ;
95  j=m ;
96  do {
97  while (a[i]<x) i++ ;
98  while (x<a[j]) j-- ;
99  if (i<=j) {
100  PIX_SWAP(a[i],a[j]) ;
101  i++ ; j-- ;
102  }
103  } while (i<=j) ;
104  if (j<k) l=i ;
105  if (k<i) m=j ;
106  }
107  return a[k] ;
108 }
109 
110 #undef PIX_SWAP
111 
126 #define DBL_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
127 
128 double
129 sinfo_kth_smallest_double(double a[], int n, int k)
130 {
131  register int i,j,l,m ;
132  register double x ;
133 
134  l=0 ; m=n-1 ;
135  while (l<m) {
136  x=a[k] ;
137  i=l ;
138  j=m ;
139  do {
140  while (a[i]<x) i++ ;
141  while (x<a[j]) j-- ;
142  if (i<=j) {
143  DBL_SWAP(a[i],a[j]) ;
144  i++ ; j-- ;
145  }
146  } while (i<=j) ;
147  if (j<k) l=i ;
148  if (k<i) m=j ;
149  }
150  return a[k] ;
151 }
152 
153 #undef DBL_SWAP
154 
155 #define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
156 #define PIX_SWAP(a,b) { pixelvalue temp=(a);(a)=(b);(b)=temp; }
157 
172 pixelvalue
173 sinfo_opt_med3(
174  pixelvalue * p
175 )
176 {
177  PIX_SORT(p[0],p[1]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[0],p[1]) ;
178  return(p[1]) ;
179 }
180 
195 pixelvalue
196 sinfo_opt_med5(
197  pixelvalue * p
198 )
199 {
200  PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ;
201  PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ;
202  PIX_SORT(p[1],p[2]) ; return(p[2]) ;
203 }
204 
219 pixelvalue
220 sinfo_opt_med7(
221  pixelvalue * p
222 )
223 {
224  PIX_SORT(p[0], p[5]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[1], p[6]) ;
225  PIX_SORT(p[2], p[4]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[5]) ;
226  PIX_SORT(p[2], p[6]) ; PIX_SORT(p[2], p[3]) ; PIX_SORT(p[3], p[6]) ;
227  PIX_SORT(p[4], p[5]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[1], p[3]) ;
228  PIX_SORT(p[3], p[4]) ; return (p[3]) ;
229 }
230 
249 pixelvalue
250 sinfo_opt_med9(
251  pixelvalue * p
252 )
253 {
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[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
256  PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
257  PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
258  PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
259  PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
260  PIX_SORT(p[4], p[2]) ; return(p[4]) ;
261 }
262 
281 pixelvalue
282 sinfo_opt_med25(
283  pixelvalue * p
284 )
285 {
286  PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[2], p[4]) ;
287  PIX_SORT(p[2], p[3]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[5], p[7]) ;
288  PIX_SORT(p[5], p[6]) ; PIX_SORT(p[9], p[10]) ; PIX_SORT(p[8], p[10]) ;
289  PIX_SORT(p[8], p[9]) ; PIX_SORT(p[12], p[13]) ; PIX_SORT(p[11], p[13]) ;
290  PIX_SORT(p[11], p[12]) ; PIX_SORT(p[15], p[16]) ; PIX_SORT(p[14], p[16]) ;
291  PIX_SORT(p[14], p[15]) ; PIX_SORT(p[18], p[19]) ; PIX_SORT(p[17], p[19]) ;
292  PIX_SORT(p[17], p[18]) ; PIX_SORT(p[21], p[22]) ; PIX_SORT(p[20], p[22]) ;
293  PIX_SORT(p[20], p[21]) ; PIX_SORT(p[23], p[24]) ; PIX_SORT(p[2], p[5]) ;
294  PIX_SORT(p[3], p[6]) ; PIX_SORT(p[0], p[6]) ; PIX_SORT(p[0], p[3]) ;
295  PIX_SORT(p[4], p[7]) ; PIX_SORT(p[1], p[7]) ; PIX_SORT(p[1], p[4]) ;
296  PIX_SORT(p[11], p[14]) ; PIX_SORT(p[8], p[14]) ; PIX_SORT(p[8], p[11]) ;
297  PIX_SORT(p[12], p[15]) ; PIX_SORT(p[9], p[15]) ; PIX_SORT(p[9], p[12]) ;
298  PIX_SORT(p[13], p[16]) ; PIX_SORT(p[10], p[16]) ; PIX_SORT(p[10], p[13]) ;
299  PIX_SORT(p[20], p[23]) ; PIX_SORT(p[17], p[23]) ; PIX_SORT(p[17], p[20]) ;
300  PIX_SORT(p[21], p[24]) ; PIX_SORT(p[18], p[24]) ; PIX_SORT(p[18], p[21]) ;
301  PIX_SORT(p[19], p[22]) ; PIX_SORT(p[8], p[17]) ; PIX_SORT(p[9], p[18]) ;
302  PIX_SORT(p[0], p[18]) ; PIX_SORT(p[0], p[9]) ; PIX_SORT(p[10], p[19]) ;
303  PIX_SORT(p[1], p[19]) ; PIX_SORT(p[1], p[10]) ; PIX_SORT(p[11], p[20]) ;
304  PIX_SORT(p[2], p[20]) ; PIX_SORT(p[2], p[11]) ; PIX_SORT(p[12], p[21]) ;
305  PIX_SORT(p[3], p[21]) ; PIX_SORT(p[3], p[12]) ; PIX_SORT(p[13], p[22]) ;
306  PIX_SORT(p[4], p[22]) ; PIX_SORT(p[4], p[13]) ; PIX_SORT(p[14], p[23]) ;
307  PIX_SORT(p[5], p[23]) ; PIX_SORT(p[5], p[14]) ; PIX_SORT(p[15], p[24]) ;
308  PIX_SORT(p[6], p[24]) ; PIX_SORT(p[6], p[15]) ; PIX_SORT(p[7], p[16]) ;
309  PIX_SORT(p[7], p[19]) ; PIX_SORT(p[13], p[21]) ; PIX_SORT(p[15], p[23]) ;
310  PIX_SORT(p[7], p[13]) ; PIX_SORT(p[7], p[15]) ; PIX_SORT(p[1], p[9]) ;
311  PIX_SORT(p[3], p[11]) ; PIX_SORT(p[5], p[17]) ; PIX_SORT(p[11], p[17]) ;
312  PIX_SORT(p[9], p[17]) ; PIX_SORT(p[4], p[10]) ; PIX_SORT(p[6], p[12]) ;
313  PIX_SORT(p[7], p[14]) ; PIX_SORT(p[4], p[6]) ; PIX_SORT(p[4], p[7]) ;
314  PIX_SORT(p[12], p[14]) ; PIX_SORT(p[10], p[14]) ; PIX_SORT(p[6], p[7]) ;
315  PIX_SORT(p[10], p[12]) ; PIX_SORT(p[6], p[10]) ; PIX_SORT(p[6], p[17]) ;
316  PIX_SORT(p[12], p[17]) ; PIX_SORT(p[7], p[17]) ; PIX_SORT(p[7], p[10]) ;
317  PIX_SORT(p[12], p[18]) ; PIX_SORT(p[7], p[12]) ; PIX_SORT(p[10], p[18]) ;
318  PIX_SORT(p[12], p[20]) ; PIX_SORT(p[10], p[20]) ; PIX_SORT(p[10], p[12]) ;
319 
320  return (p[12]);
321 }
322 
323 #undef PIX_SORT
324 #undef PIX_SWAP
325 
341 pixelvalue
342 sinfo_median_pixelvalue(pixelvalue * a, int n)
343 {
344  pixelvalue sinfo_median ;
345 
346  switch(n) {
347  case 3:
348  sinfo_median = sinfo_opt_med3(a);
349  break ;
350 
351  case 5:
352  sinfo_median = sinfo_opt_med5(a);
353  break ;
354 
355  case 7:
356  sinfo_median = sinfo_opt_med7(a);
357  break ;
358 
359  case 9:
360  sinfo_median = sinfo_opt_med9(a);
361  break ;
362 
363  case 25:
364  sinfo_median = sinfo_opt_med25(a);
365  break ;
366 
367  default:
368  sinfo_median = median_WIRTH(a,n);
369  break ;
370  }
371  return sinfo_median;
372 }
373