VTK-m  2.0
WaveletBase.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_worklet_wavelets_waveletbase_h
12 #define vtk_m_worklet_wavelets_waveletbase_h
13 
16 
17 #include <vtkm/Math.h>
18 #include <vtkm/cont/Algorithm.h>
20 
21 namespace vtkm
22 {
23 namespace worklet
24 {
25 
26 namespace wavelets
27 {
28 
29 // Functionalities are similar to MatWaveBase in VAPoR.
31 {
32 public:
33  // Constructor
35  : wname(name)
36  , filter(name)
37  {
38  if (wname == CDF9_7 || wname == BIOR4_4 || wname == CDF5_3 || wname == BIOR2_2)
39  {
40  this->wmode = SYMW; // Default extension mode, see MatWaveBase.cpp
41  }
42  else if (wname == HAAR || wname == BIOR1_1 || wname == CDF8_4 || wname == BIOR3_3)
43  {
44  this->wmode = SYMH;
45  }
46  }
47 
48  // Returns length of approximation coefficients from a decomposition pass.
50  {
51  if (sigInLen % 2 != 0)
52  {
53  return ((sigInLen + 1) / 2);
54  }
55  else
56  {
57  return ((sigInLen) / 2);
58  }
59  }
60 
61  // Returns length of detail coefficients from a decomposition pass
63  {
64  if (sigInLen % 2 != 0)
65  {
66  return ((sigInLen - 1) / 2);
67  }
68  else
69  {
70  return ((sigInLen) / 2);
71  }
72  }
73 
74  // Returns length of coefficients generated in a decomposition pass
76  {
77  return (GetApproxLength(sigInLen) + GetDetailLength(sigInLen));
78  }
80  {
81  return (GetCoeffLength(sigInX) * GetCoeffLength(sigInY));
82  }
84  {
85  return (GetCoeffLength(sigInX) * GetCoeffLength(sigInY) * GetCoeffLength(sigInZ));
86  }
87 
88  // Returns maximum wavelet decomposition level
90  {
91  vtkm::Id filterLen = this->filter.GetFilterLength();
92  vtkm::Id level;
93  this->WaveLengthValidate(sigInLen, filterLen, level);
94  return level;
95  }
96 
97  // perform a device copy. The whole 1st array to a certain start location of the 2nd array
98  template <typename ArrayType1, typename ArrayType2>
99  void DeviceCopyStartX(const ArrayType1& srcArray, ArrayType2& dstArray, vtkm::Id startIdx)
100  {
101  using CopyType = vtkm::worklet::wavelets::CopyWorklet;
102  CopyType cp(startIdx);
104  dispatcher.Invoke(srcArray, dstArray);
105  }
106 
107  // Assign zero value to a certain location of an array
108  template <typename ArrayType>
109  void DeviceAssignZero(ArrayType& array, vtkm::Id index)
110  {
111  using ZeroWorklet = vtkm::worklet::wavelets::AssignZeroWorklet;
112  ZeroWorklet worklet(index);
114  dispatcher.Invoke(array);
115  }
116 
117  // Assign zeros to a certain row to a matrix
118  template <typename ArrayType>
119  void DeviceAssignZero2DRow(ArrayType& array,
120  vtkm::Id dimX,
121  vtkm::Id dimY, // input
122  vtkm::Id rowIdx)
123  {
124  using AssignZero2DType = vtkm::worklet::wavelets::AssignZero2DWorklet;
125  AssignZero2DType zeroWorklet(dimX, dimY, -1, rowIdx);
127  dispatcher.Invoke(array);
128  }
129 
130  // Assign zeros to a certain column to a matrix
131  template <typename ArrayType>
132  void DeviceAssignZero2DColumn(ArrayType& array,
133  vtkm::Id dimX,
134  vtkm::Id dimY, // input
135  vtkm::Id colIdx)
136  {
137  using AssignZero2DType = vtkm::worklet::wavelets::AssignZero2DWorklet;
138  AssignZero2DType zeroWorklet(dimX, dimY, colIdx, -1);
140  dispatcher.Invoke(array);
141  }
142 
143  // Assign zeros to a plane that's perpendicular to the X axis (Left-Right direction)
144  template <typename ArrayType>
145  void DeviceAssignZero3DPlaneX(ArrayType& array, // input array
146  vtkm::Id dimX,
147  vtkm::Id dimY,
148  vtkm::Id dimZ, // dims of input
149  vtkm::Id zeroX) // X idx to set zero
150  {
151  using AssignZero3DType = vtkm::worklet::wavelets::AssignZero3DWorklet;
152  AssignZero3DType zeroWorklet(dimX, dimY, dimZ, zeroX, -1, -1);
154  dispatcher.Invoke(array);
155  }
156 
157  // Assign zeros to a plane that's perpendicular to the Y axis (Top-Down direction)
158  template <typename ArrayType>
159  void DeviceAssignZero3DPlaneY(ArrayType& array, // input array
160  vtkm::Id dimX,
161  vtkm::Id dimY,
162  vtkm::Id dimZ, // dims of input
163  vtkm::Id zeroY) // Y idx to set zero
164  {
165  using AssignZero3DType = vtkm::worklet::wavelets::AssignZero3DWorklet;
166  AssignZero3DType zeroWorklet(dimX, dimY, dimZ, -1, zeroY, -1);
168  dispatcher.Invoke(array);
169  }
170 
171  // Assign zeros to a plane that's perpendicular to the Z axis (Front-Back direction)
172  template <typename ArrayType>
173  void DeviceAssignZero3DPlaneZ(ArrayType& array, // input array
174  vtkm::Id dimX,
175  vtkm::Id dimY,
176  vtkm::Id dimZ, // dims of input
177  vtkm::Id zeroZ) // Y idx to set zero
178  {
179  using AssignZero3DType = vtkm::worklet::wavelets::AssignZero3DWorklet;
180  AssignZero3DType zeroWorklet(dimX, dimY, dimZ, -1, -1, zeroZ);
182  dispatcher.Invoke(array);
183  }
184 
185  // Sort by the absolute value on device
187  {
188  template <typename T>
189  VTKM_EXEC bool operator()(const T& x, const T& y) const
190  {
191  return vtkm::Abs(x) < vtkm::Abs(y);
192  }
193  };
194  template <typename ArrayType>
195  void DeviceSort(ArrayType& array)
196  {
198  }
199 
200  // Reduce to the sum of all values on device
201  template <typename ArrayType>
202  typename ArrayType::ValueType DeviceSum(const ArrayType& array)
203  {
204  return vtkm::cont::Algorithm::Reduce(array, static_cast<typename ArrayType::ValueType>(0.0));
205  }
206 
207  // Helper functors for finding the max and min of an array
208  struct minFunctor
209  {
210  template <typename FieldType>
211  VTKM_EXEC FieldType operator()(const FieldType& x, const FieldType& y) const
212  {
213  return Min(x, y);
214  }
215  };
216  struct maxFunctor
217  {
218  template <typename FieldType>
219  VTKM_EXEC FieldType operator()(const FieldType& x, const FieldType& y) const
220  {
221  return vtkm::Max(x, y);
222  }
223  };
224 
225  // Device Min and Max functions
226  template <typename ArrayType>
227  typename ArrayType::ValueType DeviceMax(const ArrayType& array)
228  {
229  typename ArrayType::ValueType initVal = vtkm::cont::ArrayGetValue(0, array);
230  return vtkm::cont::Algorithm::Reduce(array, initVal, maxFunctor());
231  }
232  template <typename ArrayType>
233  typename ArrayType::ValueType DeviceMin(const ArrayType& array)
234  {
235  typename ArrayType::ValueType initVal = vtkm::cont::ArrayGetValue(0, array);
236  return vtkm::cont::Algorithm::Reduce(array, initVal, minFunctor());
237  }
238 
239  // Max absolute value of an array
241  {
242  template <typename FieldType>
243  VTKM_EXEC FieldType operator()(const FieldType& x, const FieldType& y) const
244  {
245  return vtkm::Max(vtkm::Abs(x), vtkm::Abs(y));
246  }
247  };
248  template <typename ArrayType>
249  typename ArrayType::ValueType DeviceMaxAbs(const ArrayType& array)
250  {
251  typename ArrayType::ValueType initVal = array.ReadPortal().Get(0);
252  return vtkm::cont::Algorithm::Reduce(array, initVal, maxAbsFunctor());
253  }
254 
255  // Calculate variance of an array
256  template <typename ArrayType>
258  {
259  vtkm::Float64 mean = static_cast<vtkm::Float64>(this->DeviceSum(array)) /
260  static_cast<vtkm::Float64>(array.GetNumberOfValues());
261 
263 
264  // Use a worklet
266  SDWorklet sdw(mean);
268  dispatcher.Invoke(array, squaredDeviation);
269 
270  vtkm::Float64 sdMean = this->DeviceSum(squaredDeviation) /
271  static_cast<vtkm::Float64>(squaredDeviation.GetNumberOfValues());
272 
273  return sdMean;
274  }
275 
276  // Copy a small rectangle to a big rectangle
277  template <typename SmallArrayType, typename BigArrayType>
278  void DeviceRectangleCopyTo(const SmallArrayType& smallRect,
279  vtkm::Id smallX,
280  vtkm::Id smallY,
281  BigArrayType& bigRect,
282  vtkm::Id bigX,
283  vtkm::Id bigY,
284  vtkm::Id startX,
285  vtkm::Id startY)
286  {
287  using CopyToWorklet = vtkm::worklet::wavelets::RectangleCopyTo;
288  CopyToWorklet cp(smallX, smallY, bigX, bigY, startX, startY);
290  dispatcher.Invoke(smallRect, bigRect);
291  }
292 
293  // Copy a small cube to a big cube
294  template <typename SmallArrayType, typename BigArrayType>
295  void DeviceCubeCopyTo(const SmallArrayType& smallCube,
296  vtkm::Id smallX,
297  vtkm::Id smallY,
298  vtkm::Id smallZ,
299  BigArrayType& bigCube,
300  vtkm::Id bigX,
301  vtkm::Id bigY,
302  vtkm::Id bigZ,
303  vtkm::Id startX,
304  vtkm::Id startY,
305  vtkm::Id startZ)
306  {
307  using CopyToWorklet = vtkm::worklet::wavelets::CubeCopyTo;
308  CopyToWorklet cp(smallX, smallY, smallZ, bigX, bigY, bigZ, startX, startY, startZ);
310  dispatcher.Invoke(smallCube, bigCube);
311  }
312 
313  template <typename ArrayType>
314  void Print2DArray(const std::string& str, const ArrayType& arr, vtkm::Id dimX)
315  {
316  std::cerr << str << std::endl;
317  auto portal = arr.ReadPortal();
318  for (vtkm::Id i = 0; i < arr.GetNumberOfValues(); i++)
319  {
320  std::cerr << portal.Get(i) << " ";
321  if (i % dimX == dimX - 1)
322  {
323  std::cerr << std::endl;
324  }
325  }
326  }
327 
328 protected:
332 
333  void WaveLengthValidate(vtkm::Id sigInLen, vtkm::Id filterLength, vtkm::Id& level)
334  {
335  if (sigInLen < filterLength)
336  {
337  level = 0;
338  }
339  else
340  {
341  level =
342  static_cast<vtkm::Id>(vtkm::Floor(1.0 +
343  vtkm::Log2(static_cast<vtkm::Float64>(sigInLen) /
344  static_cast<vtkm::Float64>(filterLength))));
345  }
346  }
347 
348 }; // class WaveletBase.
349 
350 } // namespace wavelets
351 
352 } // namespace worklet
353 } // namespace vtkm
354 
355 #endif
vtkm::worklet::wavelets::WaveletBase::DeviceSort
void DeviceSort(ArrayType &array)
Definition: WaveletBase.h:195
vtkm::worklet::wavelets::WaveletBase::GetDetailLength
vtkm::Id GetDetailLength(vtkm::Id sigInLen)
Definition: WaveletBase.h:62
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< vtkm::Float64 >
vtkm::worklet::wavelets::RectangleCopyTo
Definition: WaveletTransforms.h:3585
vtkm::worklet::wavelets::WaveletBase::Print2DArray
void Print2DArray(const std::string &str, const ArrayType &arr, vtkm::Id dimX)
Definition: WaveletBase.h:314
vtkm::worklet::wavelets::BIOR2_2
@ BIOR2_2
Definition: WaveletFilter.h:36
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm::worklet::wavelets::WaveletBase::DeviceCubeCopyTo
void DeviceCubeCopyTo(const SmallArrayType &smallCube, vtkm::Id smallX, vtkm::Id smallY, vtkm::Id smallZ, BigArrayType &bigCube, vtkm::Id bigX, vtkm::Id bigY, vtkm::Id bigZ, vtkm::Id startX, vtkm::Id startY, vtkm::Id startZ)
Definition: WaveletBase.h:295
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::wavelets::WaveletFilter
Definition: WaveletFilter.h:42
vtkm::worklet::wavelets::CubeCopyTo
Definition: WaveletTransforms.h:3639
vtkm::worklet::wavelets::WaveletBase::maxAbsFunctor
Definition: WaveletBase.h:240
vtkm::worklet::wavelets::CDF8_4
@ CDF8_4
Definition: WaveletFilter.h:32
WaveletTransforms.h
vtkm::worklet::wavelets::WaveletBase::maxAbsFunctor::operator()
VTKM_EXEC FieldType operator()(const FieldType &x, const FieldType &y) const
Definition: WaveletBase.h:243
vtkm::worklet::wavelets::WaveletBase::GetCoeffLength
vtkm::Id GetCoeffLength(vtkm::Id sigInLen)
Definition: WaveletBase.h:75
vtkm::worklet::wavelets::WaveletBase
Definition: WaveletBase.h:30
vtkm::worklet::wavelets::AssignZeroWorklet
Definition: WaveletTransforms.h:3450
vtkm::worklet::wavelets::CDF9_7
@ CDF9_7
Definition: WaveletFilter.h:30
vtkm::worklet::wavelets::WaveletBase::SortLessAbsFunctor
Definition: WaveletBase.h:186
vtkm::worklet::wavelets::HAAR
@ HAAR
Definition: WaveletFilter.h:33
vtkm::cont::Algorithm::Sort
static VTKM_CONT void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, Storage > &values)
Definition: Algorithm.h:965
vtkm::worklet::wavelets::AssignZero2DWorklet
Definition: WaveletTransforms.h:3478
vtkm::worklet::wavelets::AssignZero3DWorklet
Definition: WaveletTransforms.h:3526
vtkm::cont::ArrayGetValue
VTKM_CONT T ArrayGetValue(vtkm::Id id, const vtkm::cont::ArrayHandle< T, S > &data)
Obtain a small set of values from an ArrayHandle with minimal device transfers.
Definition: ArrayGetValues.h:264
vtkm::worklet::wavelets::WaveletFilter::GetFilterLength
vtkm::Id GetFilterLength()
Definition: WaveletFilter.h:108
vtkm::worklet::wavelets::WaveletBase::GetCoeffLength3
vtkm::Id GetCoeffLength3(vtkm::Id sigInX, vtkm::Id sigInY, vtkm::Id sigInZ)
Definition: WaveletBase.h:83
vtkm::worklet::wavelets::WaveletBase::DeviceSum
ArrayType::ValueType DeviceSum(const ArrayType &array)
Definition: WaveletBase.h:202
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero3DPlaneY
void DeviceAssignZero3DPlaneY(ArrayType &array, vtkm::Id dimX, vtkm::Id dimY, vtkm::Id dimZ, vtkm::Id zeroY)
Definition: WaveletBase.h:159
vtkm::worklet::wavelets::WaveletBase::DeviceMax
ArrayType::ValueType DeviceMax(const ArrayType &array)
Definition: WaveletBase.h:227
vtkm::Log2
VTKM_EXEC_CONT vtkm::Float32 Log2(vtkm::Float32 x)
Computes the logarithm base 2 of x.
Definition: Math.h:1514
vtkm::Floor
VTKM_EXEC_CONT vtkm::Float32 Floor(vtkm::Float32 x)
Round x to the largest integer value not greater than x.
Definition: Math.h:2204
vtkm::worklet::wavelets::WaveletBase::DeviceRectangleCopyTo
void DeviceRectangleCopyTo(const SmallArrayType &smallRect, vtkm::Id smallX, vtkm::Id smallY, BigArrayType &bigRect, vtkm::Id bigX, vtkm::Id bigY, vtkm::Id startX, vtkm::Id startY)
Definition: WaveletBase.h:278
vtkm::worklet::wavelets::WaveletBase::GetApproxLength
vtkm::Id GetApproxLength(vtkm::Id sigInLen)
Definition: WaveletBase.h:49
vtkm::worklet::DispatcherMapField
Dispatcher for worklets that inherit from WorkletMapField.
Definition: DispatcherMapField.h:25
Math.h
vtkm::worklet::wavelets::WaveletBase::GetCoeffLength2
vtkm::Id GetCoeffLength2(vtkm::Id sigInX, vtkm::Id sigInY)
Definition: WaveletBase.h:79
Algorithm.h
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero2DRow
void DeviceAssignZero2DRow(ArrayType &array, vtkm::Id dimX, vtkm::Id dimY, vtkm::Id rowIdx)
Definition: WaveletBase.h:119
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero
void DeviceAssignZero(ArrayType &array, vtkm::Id index)
Definition: WaveletBase.h:109
vtkm::worklet::wavelets::CDF5_3
@ CDF5_3
Definition: WaveletFilter.h:31
vtkm::worklet::wavelets::SYMH
@ SYMH
Definition: WaveletTransforms.h:28
vtkm::worklet::wavelets::SYMW
@ SYMW
Definition: WaveletTransforms.h:29
vtkm::worklet::wavelets::WaveletBase::DeviceCalculateVariance
vtkm::Float64 DeviceCalculateVariance(ArrayType &array)
Definition: WaveletBase.h:257
vtkm::worklet::wavelets::WaveletBase::wmode
DWTMode wmode
Definition: WaveletBase.h:330
vtkm::worklet::wavelets::DWTMode
DWTMode
Definition: WaveletTransforms.h:26
vtkm::worklet::wavelets::WaveletBase::DeviceMaxAbs
ArrayType::ValueType DeviceMaxAbs(const ArrayType &array)
Definition: WaveletBase.h:249
vtkm::worklet::wavelets::WaveletBase::minFunctor
Definition: WaveletBase.h:208
vtkm::worklet::wavelets::WaveletName
WaveletName
Definition: WaveletFilter.h:28
ArrayGetValues.h
vtkm::worklet::wavelets::WaveletBase::wname
WaveletName wname
Definition: WaveletBase.h:329
vtkm::worklet::wavelets::BIOR3_3
@ BIOR3_3
Definition: WaveletFilter.h:35
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero2DColumn
void DeviceAssignZero2DColumn(ArrayType &array, vtkm::Id dimX, vtkm::Id dimY, vtkm::Id colIdx)
Definition: WaveletBase.h:132
vtkm::worklet::wavelets::WaveletBase::DeviceMin
ArrayType::ValueType DeviceMin(const ArrayType &array)
Definition: WaveletBase.h:233
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero3DPlaneX
void DeviceAssignZero3DPlaneX(ArrayType &array, vtkm::Id dimX, vtkm::Id dimY, vtkm::Id dimZ, vtkm::Id zeroX)
Definition: WaveletBase.h:145
vtkm::worklet::wavelets::WaveletBase::WaveletBase
WaveletBase(WaveletName name)
Definition: WaveletBase.h:34
vtkm::worklet::wavelets::WaveletBase::SortLessAbsFunctor::operator()
VTKM_EXEC bool operator()(const T &x, const T &y) const
Definition: WaveletBase.h:189
vtkm::cont::Algorithm::Reduce
static VTKM_CONT U Reduce(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, U initialValue)
Definition: Algorithm.h:656
vtkm::Float64
double Float64
Definition: Types.h:155
WaveletFilter.h
vtkm::worklet::wavelets::WaveletBase::WaveLengthValidate
void WaveLengthValidate(vtkm::Id sigInLen, vtkm::Id filterLength, vtkm::Id &level)
Definition: WaveletBase.h:333
vtkm::worklet::wavelets::SquaredDeviation
Definition: WaveletTransforms.h:3148
vtkm::worklet::wavelets::BIOR1_1
@ BIOR1_1
Definition: WaveletFilter.h:37
vtkm::worklet::wavelets::WaveletBase::filter
WaveletFilter filter
Definition: WaveletBase.h:331
vtkm::worklet::wavelets::CopyWorklet
Definition: WaveletTransforms.h:3202
vtkm::worklet::wavelets::WaveletBase::minFunctor::operator()
VTKM_EXEC FieldType operator()(const FieldType &x, const FieldType &y) const
Definition: WaveletBase.h:211
vtkm::worklet::wavelets::WaveletBase::maxFunctor
Definition: WaveletBase.h:216
vtkm::worklet::wavelets::WaveletBase::GetWaveletMaxLevel
vtkm::Id GetWaveletMaxLevel(vtkm::Id sigInLen)
Definition: WaveletBase.h:89
vtkm::worklet::wavelets::WaveletBase::DeviceCopyStartX
void DeviceCopyStartX(const ArrayType1 &srcArray, ArrayType2 &dstArray, vtkm::Id startIdx)
Definition: WaveletBase.h:99
vtkm::worklet::wavelets::WaveletBase::DeviceAssignZero3DPlaneZ
void DeviceAssignZero3DPlaneZ(ArrayType &array, vtkm::Id dimX, vtkm::Id dimY, vtkm::Id dimZ, vtkm::Id zeroZ)
Definition: WaveletBase.h:173
vtkm::worklet::wavelets::WaveletBase::maxFunctor::operator()
VTKM_EXEC FieldType operator()(const FieldType &x, const FieldType &y) const
Definition: WaveletBase.h:219
vtkm::worklet::wavelets::BIOR4_4
@ BIOR4_4
Definition: WaveletFilter.h:34