1
2 #define INCLUDE_SMOOTH_POLYD
SmoothPolyD(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)3 void SmoothPolyD(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
4 #include "smoothPolyD.hpp"
5 }
6 //subset having edges
7 #define USE_EDGE
SmoothPolyDWrap(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)8 void SmoothPolyDWrap(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
9 #define EDGE_WRAP
10 #include "smoothPolyD.hpp"
11 #undef EDGE_WRAP
12 }
SmoothPolyDTruncate(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)13 void SmoothPolyDTruncate(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
14 #define EDGE_TRUNCATE
15 #include "smoothPolyD.hpp"
16 #undef EDGE_TRUNCATE
17 }
SmoothPolyDZero(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)18 void SmoothPolyDZero(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
19 #define EDGE_ZERO
20 #include "smoothPolyD.hpp"
21 #undef EDGE_ZERO
22 }
SmoothPolyDMirror(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)23 void SmoothPolyDMirror(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
24 #define EDGE_MIRROR
25 #include "smoothPolyD.hpp"
26 #undef EDGE_MIRROR
27 }
28 #undef USE_EDGE
29 #undef INCLUDE_SMOOTH_POLYD
30
31 #define INCLUDE_SMOOTH_POLYD_NAN
SmoothPolyDNan(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)32 void SmoothPolyDNan(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
33 #include "smoothPolyDnans.hpp"
34 }
35 //subset having edges
36 #define USE_EDGE
SmoothPolyDWrapNan(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)37 void SmoothPolyDWrapNan(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
38 #define EDGE_WRAP
39 #include "smoothPolyDnans.hpp"
40 #undef EDGE_WRAP
41 }
SmoothPolyDTruncateNan(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)42 void SmoothPolyDTruncateNan(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
43 #define EDGE_TRUNCATE
44 #include "smoothPolyDnans.hpp"
45 #undef EDGE_TRUNCATE
46 }
SmoothPolyDZeroNan(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)47 void SmoothPolyDZeroNan(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
48 #define EDGE_ZERO
49 #include "smoothPolyDnans.hpp"
50 #undef EDGE_ZERO
51 }
SmoothPolyDMirrorNan(SMOOTH_Ty * srcIn,SMOOTH_Ty * destIn,const SizeT * datainDim,const int rank,const DLong * width)52 void SmoothPolyDMirrorNan(SMOOTH_Ty* srcIn, SMOOTH_Ty* destIn, const SizeT* datainDim, const int rank, const DLong* width) {
53 #define EDGE_MIRROR
54 #include "smoothPolyDnans.hpp"
55 #undef EDGE_MIRROR
56 }
57 #undef USE_EDGE
58 #undef INCLUDE_SMOOTH_POLYD_NAN
59
60
61 #define INCLUDE_SMOOTH_1D
Smooth1D(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)62 void Smooth1D(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
63 #include "smooth1d.hpp"
64 }
65 //subset having edges
66 #define USE_EDGE
Smooth1DWrap(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)67 void Smooth1DWrap(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
68 #define EDGE_WRAP
69 #include "smooth1d.hpp"
70 #undef EDGE_WRAP
71 }
Smooth1DTruncate(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)72 void Smooth1DTruncate(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
73 #define EDGE_TRUNCATE
74 #include "smooth1d.hpp"
75 #undef EDGE_TRUNCATE
76 }
Smooth1DMirror(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)77 void Smooth1DMirror(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
78 #define EDGE_MIRROR
79 #include "smooth1d.hpp"
80 #undef EDGE_MIRROR
81 }
Smooth1DZero(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)82 void Smooth1DZero(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
83 #define EDGE_ZERO
84 #include "smooth1d.hpp"
85 #undef EDGE_ZERO
86 }
87 #undef USE_EDGE
88 #undef INCLUDE_SMOOTH_1D
89
90 //smooth 1d functions for Nans.
91 #define INCLUDE_SMOOTH_1D_NAN
Smooth1DNan(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)92 void Smooth1DNan(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
93 #include "smooth1dnans.hpp"
94 }
95 //subset having edges
96 #define USE_EDGE
Smooth1DWrapNan(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)97 void Smooth1DWrapNan(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
98 #define EDGE_WRAP
99 #include "smooth1dnans.hpp"
100 #undef EDGE_WRAP
101 }
Smooth1DTruncateNan(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)102 void Smooth1DTruncateNan(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
103 #define EDGE_TRUNCATE
104 #include "smooth1dnans.hpp"
105 #undef EDGE_TRUNCATE
106 }
Smooth1DMirrorNan(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)107 void Smooth1DMirrorNan(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
108 #define EDGE_MIRROR
109 #include "smooth1dnans.hpp"
110 #undef EDGE_MIRROR
111 }
Smooth1DZeroNan(SMOOTH_Ty * data,SMOOTH_Ty * res,SizeT dimx,SizeT w)112 void Smooth1DZeroNan(SMOOTH_Ty* data, SMOOTH_Ty* res, SizeT dimx, SizeT w) {
113 #define EDGE_ZERO
114 #include "smooth1dnans.hpp"
115 #undef EDGE_ZERO
116 }
117 #undef USE_EDGE
118 #undef INCLUDE_SMOOTH_1D_NAN
119
120 //smooth 2d functions.
121 #define INCLUDE_SMOOTH_2D
Smooth2D(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)122 void Smooth2D(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
123 #include "smooth2d.hpp"
124 }
125 //subset having edges
126 #define USE_EDGE
Smooth2DWrap(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)127 void Smooth2DWrap(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
128 #define EDGE_WRAP
129 #include "smooth2d.hpp"
130 #undef EDGE_WRAP
131 }
Smooth2DTruncate(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)132 void Smooth2DTruncate(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
133 #define EDGE_TRUNCATE
134 #include "smooth2d.hpp"
135 #undef EDGE_TRUNCATE
136 }
Smooth2DMirror(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)137 void Smooth2DMirror(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
138 #define EDGE_MIRROR
139 #include "smooth2d.hpp"
140 #undef EDGE_MIRROR
141 }
Smooth2DZero(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)142 void Smooth2DZero(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
143 #define EDGE_ZERO
144 #include "smooth2d.hpp"
145 #undef EDGE_ZERO
146 }
147 #undef USE_EDGE
148 #undef INCLUDE_SMOOTH_2D
149
150 //smooth 2d functions for Nans.
151 #define INCLUDE_SMOOTH_2D_NAN
Smooth2DNan(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)152 void Smooth2DNan(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
153 #include "smooth2dnans.hpp"
154 }
155 //subset having edges
156 #define USE_EDGE
Smooth2DWrapNan(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)157 void Smooth2DWrapNan(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
158 #define EDGE_WRAP
159 #include "smooth2dnans.hpp"
160 #undef EDGE_WRAP
161 }
Smooth2DTruncateNan(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)162 void Smooth2DTruncateNan(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
163 #define EDGE_TRUNCATE
164 #include "smooth2dnans.hpp"
165 #undef EDGE_TRUNCATE
166 }
Smooth2DMirrorNan(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)167 void Smooth2DMirrorNan(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
168 #define EDGE_MIRROR
169 #include "smooth2dnans.hpp"
170 #undef EDGE_MIRROR
171 }
Smooth2DZeroNan(const SMOOTH_Ty * src,SMOOTH_Ty * dest,const SizeT dimx,const SizeT dimy,const DLong * width)172 void Smooth2DZeroNan(const SMOOTH_Ty* src, SMOOTH_Ty* dest, const SizeT dimx, const SizeT dimy, const DLong* width) {
173 #define EDGE_ZERO
174 #include "smooth2dnans.hpp"
175 #undef EDGE_ZERO
176 }
177 #undef USE_EDGE
178 #undef INCLUDE_SMOOTH_2D_NAN
179
180 //Note: Values for ULong types return differently as IDL, but it should be proven that IDL is right...
181 template<>
Smooth(DLong * width,int edgeMode,bool doNan,BaseGDL * missing)182 BaseGDL* Data_<SMOOTH_SP>::Smooth(DLong* width, int edgeMode,
183 bool doNan, BaseGDL* missing)
184 {
185 SMOOTH_Ty missingValue = (*static_cast<Data_*>( missing))[0];
186 SizeT nA = N_Elements();
187
188 SizeT srcRank = this->Rank();
189
190 BaseGDL* data = this;
191 BaseGDL* res = this->Dup();
192
193 SizeT sum = 0;
194 SizeT mydims[srcRank]; //memory of dimensions, done one after the other
195 for (int i = 0; i < srcRank; ++i)
196 {
197 mydims[i] = this->Dim(i);
198 sum += width[i];
199 }
200 if (sum == srcRank) return res;
201
202 DUInt rotate1[srcRank]; //turntable transposition index list
203
204 //doNan only meaningful for real and double (complex are real and double here)
205 doNan=(doNan && (this->Type()==GDL_FLOAT ||this->Type()==GDL_DOUBLE));
206
207 for (int i = 0; i < srcRank-1; ++i) rotate1[i] = i+1; rotate1[srcRank-1]=0; //[1,2,...,0]
208
209 if (doNan) {
210 if (srcRank==1) {
211 SizeT dimx = nA;
212 SizeT w = width[0] / 2;
213 if (edgeMode==0){
214 Smooth1DNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
215 } else if (edgeMode==1) {
216 Smooth1DWrapNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
217 } else if (edgeMode==2) {
218 Smooth1DTruncateNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
219 } else if (edgeMode==3) {
220 Smooth1DZeroNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
221 } else if (edgeMode==4) {
222 Smooth1DMirrorNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
223 }
224 } else if (srcRank==2) {
225 SizeT dimx = data->Dim(0);
226 SizeT dimy = data->Dim(1);
227 if (edgeMode==0){
228 Smooth2DNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
229 } else if (edgeMode==1) {
230 Smooth2DWrapNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
231 } else if (edgeMode==2) {
232 Smooth2DTruncateNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
233 } else if (edgeMode==3) {
234 Smooth2DZeroNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
235 } else if (edgeMode==4) {
236 Smooth2DMirrorNan((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
237 }
238 } else {
239 long rank = data->Rank();
240 SizeT srcDim[MAXRANK];
241 for (int i = 0; i < rank; ++i) srcDim[i] = data->Dim()[i];
242 BaseGDL* dataw = this->Dup();
243 if (edgeMode==0){
244 SmoothPolyDNan((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
245 } else if (edgeMode==1) {
246 SmoothPolyDWrapNan((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
247 } else if (edgeMode==2) {
248 SmoothPolyDTruncateNan((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
249 } else if (edgeMode==3) {
250 SmoothPolyDZeroNan((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
251 } else if (edgeMode==4) {
252 SmoothPolyDMirrorNan((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
253 }
254 GDLDelete(dataw);
255 }
256 //additional loop to replace left Nans by missing, if nans are left anyway
257 if (gdlValid(missingValue)) {
258 SMOOTH_Ty* resty=(SMOOTH_Ty*)res->DataAddr();
259 #pragma omp for
260 for (SizeT i=0; i<nA; ++i) if (!gdlValid(resty[i])) resty[i]=missingValue;
261 }
262 } else {
263 if (srcRank==1) {
264 SizeT dimx = nA;
265 SizeT w = width[0] / 2;
266 if (edgeMode==0){
267 Smooth1D((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
268 } else if (edgeMode==1) {
269 Smooth1DWrap((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
270 } else if (edgeMode==2) {
271 Smooth1DTruncate((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
272 } else if (edgeMode==3) {
273 Smooth1DZero((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
274 } else if (edgeMode==4) {
275 Smooth1DMirror((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, w);
276 }
277 } else if (srcRank==2) {
278 SizeT dimx = data->Dim(0);
279 SizeT dimy = data->Dim(1);
280 if (edgeMode==0){
281 Smooth2D((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
282 } else if (edgeMode==1) {
283 Smooth2DWrap((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
284 } else if (edgeMode==2) {
285 Smooth2DTruncate((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
286 } else if (edgeMode==3) {
287 Smooth2DZero((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
288 } else if (edgeMode==4) {
289 Smooth2DMirror((SMOOTH_Ty*)data->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), dimx, dimy, width);
290 }
291 } else {
292 long rank = data->Rank();
293 SizeT srcDim[MAXRANK];
294 for (int i = 0; i < rank; ++i) srcDim[i] = data->Dim()[i];
295 BaseGDL* dataw = this->Dup();
296 if (edgeMode==0){
297 SmoothPolyD((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
298 } else if (edgeMode==1) {
299 SmoothPolyDWrap((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
300 } else if (edgeMode==2) {
301 SmoothPolyDTruncate((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
302 } else if (edgeMode==3) {
303 SmoothPolyDZero((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
304 } else if (edgeMode==4) {
305 SmoothPolyDMirror((SMOOTH_Ty*)dataw->DataAddr(), (SMOOTH_Ty*)res->DataAddr(), srcDim, rank, width);
306 }
307 GDLDelete(dataw);
308 }
309 }
310 return res;
311 }