19 #ifndef viskores_worklet_waveletcompressor_h
20 #define viskores_worklet_waveletcompressor_h
22 #include <viskores/worklet/wavelets/WaveletDWT.h>
42 template <
typename SignalArrayType,
typename CoeffArrayType>
45 CoeffArrayType& coeffOut,
46 std::vector<viskores::Id>& L)
49 if (nLevels < 0 || nLevels > WaveletBase::GetWaveletMaxLevel(sigInLen))
59 this->
ComputeL(sigInLen, nLevels, L);
68 std::vector<viskores::Id> L1d(3, 0);
71 using OutputValueType =
typename CoeffArrayType::ValueType;
83 cptr = 0 + CLength - tlen - cALen;
86 IdArrayType inputIndices(sigInPtr, 1, len);
87 PermutArrayType input(inputIndices, coeffOut);
89 InterArrayType output;
91 WaveletDWT::DWT1D(input, output, L1d);
94 WaveletBase::DeviceCopyStartX(output, coeffOut, cptr);
98 cALen = WaveletBase::GetApproxLength(cALen);
106 template <
typename CoeffArrayType,
typename SignalArrayType>
109 std::vector<viskores::Id>& L,
110 SignalArrayType& sigOut)
116 std::vector<viskores::Id> L1d(3, 0);
120 using OutValueType =
typename SignalArrayType::ValueType;
132 IdArrayType inputIndices(0, 1, L1d[2]);
133 PermutArrayType input(inputIndices, sigOut);
136 OutArrayBasic output;
138 WaveletDWT::IDWT1D(input, L1d, output);
142 WaveletBase::DeviceCopyStartX(output, sigOut, 0);
145 L1d[1] = L[size_t(i + 1)];
152 template <
typename InArrayType,
typename OutArrayType>
159 OutArrayType& coeffOut,
164 if (nLevels < 0 || nLevels > WaveletBase::GetWaveletMaxLevel(inX) ||
165 nLevels > WaveletBase::GetWaveletMaxLevel(inY) ||
166 nLevels > WaveletBase::GetWaveletMaxLevel(inZ))
180 using OutValueType =
typename OutArrayType::ValueType;
185 sigIn, inX, inY, inZ, 0, 0, 0, currentLenX, currentLenY, currentLenZ, coeffOut, discardSigIn);
190 currentLenX = WaveletBase::GetApproxLength(currentLenX);
191 currentLenY = WaveletBase::GetApproxLength(currentLenY);
192 currentLenZ = WaveletBase::GetApproxLength(currentLenZ);
194 OutBasicArray tempOutput;
196 computationTime += WaveletDWT::DWT3D(
197 coeffOut, inX, inY, inZ, 0, 0, 0, currentLenX, currentLenY, currentLenZ, tempOutput,
false);
200 WaveletBase::DeviceCubeCopyTo(
201 tempOutput, currentLenX, currentLenY, currentLenZ, coeffOut, inX, inY, inZ, 0, 0, 0);
204 return computationTime;
208 template <
typename InArrayType,
typename OutArrayType>
215 OutArrayType& arrOut,
220 if (nLevels < 0 || nLevels > WaveletBase::GetWaveletMaxLevel(inX) ||
221 nLevels > WaveletBase::GetWaveletMaxLevel(inY) ||
222 nLevels > WaveletBase::GetWaveletMaxLevel(inZ))
226 using OutValueType =
typename OutArrayType::ValueType;
230 OutBasicArray outBuffer;
236 else if (discardArrIn)
245 std::vector<viskores::Id> L;
246 this->
ComputeL3(inX, inY, inZ, nLevels, L);
247 std::vector<viskores::Id> L3d(27, 0);
250 for (
size_t i = 0; i < 24; i++)
254 for (
size_t i = 1; i < static_cast<size_t>(nLevels); i++)
256 L3d[24] = L3d[0] + L3d[12];
257 L3d[25] = L3d[1] + L3d[7];
258 L3d[26] = L3d[2] + L3d[5];
260 OutBasicArray tempOutput;
264 WaveletDWT::IDWT3D(outBuffer, inX, inY, inZ, 0, 0, 0, L3d, tempOutput,
false);
267 WaveletBase::DeviceCubeCopyTo(
268 tempOutput, L3d[24], L3d[25], L3d[26], outBuffer, inX, inY, inZ, 0, 0, 0);
274 for (
size_t j = 3; j < 24; j++)
276 L3d[j] = L[21 * i + j];
281 L3d[24] = L3d[0] + L3d[12];
282 L3d[25] = L3d[1] + L3d[7];
283 L3d[26] = L3d[2] + L3d[5];
284 computationTime += WaveletDWT::IDWT3D(outBuffer, inX, inY, inZ, 0, 0, 0, L3d, arrOut,
true);
286 return computationTime;
290 template <
typename InArrayType,
typename OutArrayType>
295 OutArrayType& coeffOut,
296 std::vector<viskores::Id>& L)
300 if (nLevels < 0 || nLevels > WaveletBase::GetWaveletMaxLevel(inX) ||
301 nLevels > WaveletBase::GetWaveletMaxLevel(inY))
317 std::vector<viskores::Id> L2d(10, 0);
320 using OutValueType =
typename OutArrayType::ValueType;
324 computationTime += WaveletDWT::DWT2D(
325 sigIn, currentLenX, currentLenY, 0, 0, currentLenX, currentLenY, coeffOut, L2d);
326 VISKORES_ASSERT(coeffOut.GetNumberOfValues() == currentLenX * currentLenY);
327 currentLenX = WaveletBase::GetApproxLength(currentLenX);
328 currentLenY = WaveletBase::GetApproxLength(currentLenY);
333 OutBasicArray tempOutput;
336 WaveletDWT::DWT2D(coeffOut, inX, inY, 0, 0, currentLenX, currentLenY, tempOutput, L2d);
339 WaveletBase::DeviceRectangleCopyTo(
340 tempOutput, currentLenX, currentLenY, coeffOut, inX, inY, 0, 0);
343 currentLenX = WaveletBase::GetApproxLength(currentLenX);
344 currentLenY = WaveletBase::GetApproxLength(currentLenY);
347 return computationTime;
351 template <
typename InArrayType,
typename OutArrayType>
356 OutArrayType& arrOut,
357 std::vector<viskores::Id>& L)
361 if (nLevels < 0 || nLevels > WaveletBase::GetWaveletMaxLevel(inX) ||
362 nLevels > WaveletBase::GetWaveletMaxLevel(inY))
366 using OutValueType =
typename OutArrayType::ValueType;
370 OutBasicArray outBuffer;
383 std::vector<viskores::Id> L2d(10, 0);
394 for (
size_t i = 1; i < static_cast<size_t>(nLevels); i++)
396 L2d[8] = L2d[0] + L2d[4];
397 L2d[9] = L2d[1] + L2d[3];
399 OutBasicArray tempOutput;
402 computationTime += WaveletDWT::IDWT2D(outBuffer, inX, inY, 0, 0, L2d, tempOutput);
405 WaveletBase::DeviceRectangleCopyTo(tempOutput, L2d[8], L2d[9], outBuffer, inX, inY, 0, 0);
410 L2d[2] = L[6 * i + 2];
411 L2d[3] = L[6 * i + 3];
412 L2d[4] = L[6 * i + 4];
413 L2d[5] = L[6 * i + 5];
414 L2d[6] = L[6 * i + 6];
415 L2d[7] = L[6 * i + 7];
419 L2d[8] = L2d[0] + L2d[4];
420 L2d[9] = L2d[1] + L2d[3];
421 computationTime += WaveletDWT::IDWT2D(outBuffer, inX, inY, 0, 0, L2d, arrOut);
423 return computationTime;
427 template <
typename CoeffArrayType>
433 using ValueType =
typename CoeffArrayType::ValueType;
435 CoeffArrayBasic sortedArray;
438 WaveletBase::DeviceSort(sortedArray);
449 using ThresholdType = viskores::worklet::wavelets::ThresholdWorklet;
450 ThresholdType thresholdWorklet(nthVal);
452 dispatcher.Invoke(coeffIn);
459 template <
typename ArrayType>
462 #define VAL viskores::Float64
463 #define MAKEVAL(a) (static_cast<VAL>(a))
464 VAL VarOrig = WaveletBase::DeviceCalculateVariance(original);
466 using ValueType =
typename ArrayType::ValueType;
468 ArrayBasic errorArray, errorSquare;
471 using DifferencerWorklet = viskores::worklet::wavelets::Differencer;
472 DifferencerWorklet dw;
474 dwDispatcher.Invoke(original, reconstruct, errorArray);
476 using SquareWorklet = viskores::worklet::wavelets::SquareWorklet;
479 swDispatcher.Invoke(errorArray, errorSquare);
481 VAL varErr = WaveletBase::DeviceCalculateVariance(errorArray);
485 snr = VarOrig / varErr;
490 snr = viskores::Infinity64();
491 decibels = viskores::Infinity64();
494 VAL origMax = WaveletBase::DeviceMax(original);
495 VAL origMin = WaveletBase::DeviceMin(original);
496 VAL errorMax = WaveletBase::DeviceMaxAbs(errorArray);
497 VAL range = origMax - origMin;
499 VAL squareSum = WaveletBase::DeviceSum(errorSquare);
502 std::cout <<
"Data range = " << range << std::endl;
503 std::cout <<
"SNR = " << snr << std::endl;
504 std::cout <<
"SNR in decibels = " << decibels << std::endl;
505 std::cout <<
"L-infy norm = " << errorMax
506 <<
", after normalization = " << errorMax / range << std::endl;
507 std::cout <<
"RMSE = " << rmse <<
", after normalization = " << rmse / range
518 size_t nLevels =
static_cast<size_t>(nLev);
519 L.resize(nLevels + 2);
520 L[nLevels + 1] = sigInLen;
521 L[nLevels] = sigInLen;
522 for (
size_t i = nLevels; i > 0; i--)
524 L[i - 1] = WaveletBase::GetApproxLength(L[i]);
525 L[i] = WaveletBase::GetDetailLength(L[i]);
533 std::vector<viskores::Id>& L)
535 size_t nLevels =
static_cast<size_t>(nLev);
536 L.resize(nLevels * 6 + 4);
537 L[nLevels * 6] = inX;
538 L[nLevels * 6 + 1] = inY;
539 L[nLevels * 6 + 2] = inX;
540 L[nLevels * 6 + 3] = inY;
542 for (
size_t i = nLevels; i > 0; i--)
545 L[i * 6 - 6] = WaveletBase::GetApproxLength(L[i * 6 + 0]);
546 L[i * 6 - 5] = WaveletBase::GetApproxLength(L[i * 6 + 1]);
549 L[i * 6 - 4] = WaveletBase::GetApproxLength(L[i * 6 + 0]);
550 L[i * 6 - 3] = WaveletBase::GetDetailLength(L[i * 6 + 1]);
553 L[i * 6 - 2] = WaveletBase::GetDetailLength(L[i * 6 + 0]);
554 L[i * 6 - 1] = WaveletBase::GetApproxLength(L[i * 6 + 1]);
557 L[i * 6 - 0] = WaveletBase::GetDetailLength(L[i * 6 + 0]);
558 L[i * 6 + 1] = WaveletBase::GetDetailLength(L[i * 6 + 1]);
567 std::vector<viskores::Id>& L)
569 size_t n =
static_cast<size_t>(nLev);
570 L.resize(n * 21 + 6);
578 for (
size_t i = n; i > 0; i--)
581 L[i * 21 - 21] = WaveletBase::GetApproxLength(L[i * 21 + 0]);
582 L[i * 21 - 20] = WaveletBase::GetApproxLength(L[i * 21 + 1]);
583 L[i * 21 - 19] = WaveletBase::GetApproxLength(L[i * 21 + 2]);
586 L[i * 21 - 18] = L[i * 21 - 21];
587 L[i * 21 - 17] = L[i * 21 - 20];
588 L[i * 21 - 16] = WaveletBase::GetDetailLength(L[i * 21 + 2]);
591 L[i * 21 - 15] = L[i * 21 - 21];
592 L[i * 21 - 14] = WaveletBase::GetDetailLength(L[i * 21 + 1]);
593 L[i * 21 - 13] = L[i * 21 - 19];
596 L[i * 21 - 12] = L[i * 21 - 21];
597 L[i * 21 - 11] = L[i * 21 - 14];
598 L[i * 21 - 10] = L[i * 21 - 16];
601 L[i * 21 - 9] = WaveletBase::GetDetailLength(L[i * 21 + 0]);
602 L[i * 21 - 8] = L[i * 21 - 20];
603 L[i * 21 - 7] = L[i * 21 - 19];
606 L[i * 21 - 6] = L[i * 21 - 9];
607 L[i * 21 - 5] = L[i * 21 - 20];
608 L[i * 21 - 3] = L[i * 21 - 16];
611 L[i * 21 - 3] = L[i * 21 - 9];
612 L[i * 21 - 2] = L[i * 21 - 14];
613 L[i * 21 - 1] = L[i * 21 - 19];
616 L[i * 21 + 0] = L[i * 21 - 9];
617 L[i * 21 + 1] = L[i * 21 - 14];
618 L[i * 21 + 2] = L[i * 21 - 16];
626 for (
size_t i = 1; i <= size_t(nLevels); i++)
636 for (
size_t i = 1; i <= size_t(nLevels); i++)
638 sum += L[i * 6 - 4] * L[i * 6 - 3];
639 sum += L[i * 6 - 2] * L[i * 6 - 1];
640 sum += L[i * 6 - 0] * L[i * 6 + 1];
651 cALen = WaveletBase::GetApproxLength(cALen);