CR2RE Pipeline Reference Manual 1.6.10
hdrl_cat_statistics.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "hdrl_cat_statistics.h"
21
22#include "hdrl_cat_utils_sort.h"
23
24
25/*---------------------------------------------------------------------------*/
33/*----------------------------------------------------------------------------*/
34
37/* ---------------------------------------------------------------------------*/
50/* ---------------------------------------------------------------------------*/
51cpl_error_code hdrl_median(double xbuf[], cpl_size npt, cpl_size nfilt)
52{
53 if ((nfilt / 2) * 2 == nfilt) {
54 nfilt++;
55 }
56
57 if (npt <= nfilt) {
58 return CPL_ERROR_INCOMPATIBLE_INPUT;
59 }
60
61 cpl_size nfo2p1 = nfilt / 2;
62
63 /* allocate ybuf, array, point */
64 cpl_size nelem = npt + nfilt; /* Max. number of elements req'd */
65 double *ybuf = (double * )cpl_malloc(nelem * sizeof(double ));
66 double *array = (double * )cpl_malloc(nfilt * sizeof(double ));
67 cpl_size *point = (cpl_size *)cpl_malloc(nfilt * sizeof(cpl_size));
68
69 /* set first and last edges equal */
70 cpl_size il = nfilt / 2;
71 cpl_size ilow = (CPL_MAX(3, nfilt / 4) / 2) * 2 + 1;
72
73
74 /* Calculation of xmns */
75 for (cpl_size i = 0; i < ilow; i++) {
76 array[i] = xbuf[i];
77 }
78 sort_array_index(array, ilow, point, HDRL_SORT_CPL_SIZE, CPL_SORT_ASCENDING);
79 double xmns = array[ilow / 2];
80
81
82 /* Calculation of xmnf */
83 for (cpl_size i = 0; i < ilow; i++) {
84 array[i] = xbuf[npt - 1 - i];
85 }
86 sort_array_index(array, ilow, point, HDRL_SORT_CPL_SIZE, CPL_SORT_ASCENDING);
87 double xmnf = array[ilow / 2];
88
89
90 /* reflect edges before filtering */
91 for (cpl_size i = 0; i < il; i++) {
92 ybuf[i] = 2. * xmns - xbuf[il - i - 1 + ilow];
93 ybuf[npt + i + il] = 2. * xmnf - xbuf[npt - i - 1 - ilow];
94 }
95
96 for (cpl_size i = 0; i < npt; i++) {
97 ybuf[i + il] = xbuf[i];
98 }
99
100 /* do median filtering on rest */
101 for (cpl_size i = 0; i < nfilt; i++) {
102 array[i] = ybuf[i];
103 point[i] = i + 1;
104 }
105
106 sort_array_index(array, nfilt, point, HDRL_SORT_CPL_SIZE, CPL_SORT_ASCENDING);
107 xbuf[0] = array[nfo2p1];
108
109 cpl_size jl = nfilt;
110 cpl_size jh = nfilt + npt - 1;
111
112 cpl_size l = 0;
113 for (cpl_size j = jl; j < jh; j++) {
114
115 for (cpl_size i = 0; i < nfilt; i++) {
116 if (point[i] != 1) {
117 point[i]--;
118 } else {
119 point[i] = nfilt;
120 array[i] = ybuf[j];
121 l = i;
122 }
123 }
124
125 cpl_size jj = nfilt;
126 for (cpl_size i = 0; i < nfilt; i++) {
127 if (i != l && array[l] <= array[i]) {
128 jj = i;
129 break;
130 }
131 }
132
133 if (jj - 1 != l) {
134
135 double temp = array[l];
136 cpl_size it = point[l];
137
138 if (jj < l) {
139
140 for (cpl_size i = 0; i < l - jj; i++) {
141 cpl_size ii = l - i - 1;
142 array[ii + 1] = array[ii];
143 point[ii + 1] = point[ii];
144 }
145
146 } else if (jj > l) {
147
148 jj--;
149 if (npt != 0) {
150 for (cpl_size i = 0; i < jj - l; i++) {
151 cpl_size ii = l + i + 1;
152 array[ii - 1] = array[ii];
153 point[ii - 1] = point[ii];
154 }
155 }
156 }
157
158 array[jj] = temp;
159 point[jj] = it;
160 }
161
162 xbuf[j - jl + 1] = array[nfo2p1];
163 }
164
165 /* Free temporary arrays */
166 cpl_free((void *) point);
167 cpl_free((void *) array);
168 cpl_free((void *) ybuf);
169
170 return CPL_ERROR_NONE;
171}
172
cpl_error_code hdrl_median(double xbuf[], cpl_size npt, cpl_size nfilt)
compute median
cpl_error_code sort_array_index(double *a, cpl_size nE, void *b, hdrl_sort_type type, cpl_sort_direction dir)
sort_array_index hdrl function for sort two arrays The alghorithm sort 'a' and in the same way sort t...