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 }