SOPT
Sparse OPTimisation
indirect.h
Go to the documentation of this file.
1 #ifndef SOPT_WAVELET_INDIRECT_H
2 #define SOPT_WAVELET_INDIRECT_H
3 
4 #include "sopt/config.h"
5 #include "sopt/types.h"
8 
9 #include <algorithm> // for std::copy<>
10 
11 // Function inside anonymouns namespace won't appear in library
12 namespace sopt::wavelets {
13 namespace {
18 template <typename T0, typename T1>
19 typename std::enable_if<T1::IsVectorAtCompileTime, void>::type indirect_transform_impl(
20  Eigen::ArrayBase<T0> const &coeffs, Eigen::ArrayBase<T1> const &signal_,
21  WaveletData const &wavelet) {
22  Eigen::ArrayBase<T1> &signal = const_cast<Eigen::ArrayBase<T1> &>(signal_);
23 
24  assert(coeffs.size() == signal.size());
25  assert(coeffs.size() % 2 == 0);
26 
27  up_convolve_sum(signal, coeffs, wavelet.indirect_filter.low_even, wavelet.indirect_filter.low_odd,
28  wavelet.indirect_filter.high_even, wavelet.indirect_filter.high_odd);
29 }
34 template <typename T0, typename T1>
35 typename std::enable_if<not T1::IsVectorAtCompileTime, void>::type indirect_transform_impl(
36  Eigen::ArrayBase<T0> const &coeffs_, Eigen::ArrayBase<T1> const &signal_,
37  WaveletData const &wavelet) {
38  Eigen::ArrayBase<T0> &coeffs = const_cast<Eigen::ArrayBase<T0> &>(coeffs_);
39  Eigen::ArrayBase<T1> &signal = const_cast<Eigen::ArrayBase<T1> &>(signal_);
40  assert(coeffs.rows() == signal.rows() and coeffs.cols() == signal.cols());
41  assert(coeffs.rows() % 2 == 0 and coeffs.cols() % 2 == 0);
42 
43  for (t_uint i = 0; i < signal.rows(); ++i)
44  indirect_transform_impl(coeffs.row(i).transpose(), signal.row(i).transpose(), wavelet);
45  coeffs = signal;
46  for (t_uint j = 0; j < signal.cols(); ++j)
47  indirect_transform_impl(coeffs.col(j), signal.col(j), wavelet);
48 }
49 } // namespace
50 
57 template <typename T0, typename T1>
58 typename std::enable_if<T1::IsVectorAtCompileTime, void>::type indirect_transform(
59  Eigen::ArrayBase<T0> const &coeffs, Eigen::ArrayBase<T1> &signal, t_uint levels,
60  WaveletData const &wavelet) {
61  if (levels == 0) return;
62  assert(coeffs.rows() == signal.rows());
63  assert(coeffs.cols() == signal.cols());
64  assert(coeffs.size() % (1u << levels) == 0);
65 
66  auto input = copy(coeffs);
67  for (t_uint level(levels - 1); level > 0; --level) {
68  auto const N = static_cast<t_uint>(signal.size()) >> level;
69  indirect_transform_impl(input.head(N), signal.head(N), wavelet);
70  input.head(N) = signal.head(N);
71  }
72  indirect_transform_impl(input, signal, wavelet);
73 }
74 
81 template <typename T0, typename T1>
82 typename std::enable_if<not T1::IsVectorAtCompileTime, void>::type indirect_transform(
83  Eigen::ArrayBase<T0> const &coeffs_, Eigen::ArrayBase<T1> const &signal_, t_uint levels,
84  WaveletData const &wavelet) {
85  Eigen::ArrayBase<T0> &coeffs = const_cast<Eigen::ArrayBase<T0> &>(coeffs_);
86  Eigen::ArrayBase<T1> &signal = const_cast<Eigen::ArrayBase<T1> &>(signal_);
87  assert(coeffs.rows() == signal.rows());
88  assert(coeffs.cols() == signal.cols());
89  assert(coeffs.size() % (1u << levels) == 0);
90  if (levels == 0) {
91  signal = coeffs_;
92  return;
93  }
94 
95  auto input = copy(coeffs);
96  for (t_uint level(levels - 1); level > 0; --level) {
97  auto const Nx = static_cast<t_uint>(signal.rows()) >> level;
98  auto const Ny = static_cast<t_uint>(signal.cols()) >> level;
99  indirect_transform_impl(input.topLeftCorner(Nx, Ny), signal.topLeftCorner(Nx, Ny), wavelet);
100  input.topLeftCorner(Nx, Ny) = signal.topLeftCorner(Nx, Ny);
101  }
102  indirect_transform_impl(input, signal, wavelet);
103 }
104 
111 template <typename T0>
112 auto indirect_transform(Eigen::ArrayBase<T0> const &coeffs, t_uint levels,
113  WaveletData const &wavelet) -> decltype(copy(coeffs)) {
114  auto result = copy(coeffs);
115  indirect_transform(coeffs, result, levels, wavelet);
116  return result;
117 }
118 } // namespace sopt::wavelets
119 #endif
constexpr auto N
Definition: wavelets.cc:57
std::enable_if< T1::IsVectorAtCompileTime, void >::type indirect_transform(Eigen::ArrayBase< T0 > const &coeffs, Eigen::ArrayBase< T1 > &signal, t_uint levels, WaveletData const &wavelet)
N-levels 1d indirect transform.
Definition: indirect.h:58
size_t t_uint
Root of the type hierarchy for unsigned integers.
Definition: types.h:15
Holds wavelets coefficients.
Definition: wavelet_data.h:11