1 #ifndef SOPT_WAVELET_INDIRECT_H
2 #define SOPT_WAVELET_INDIRECT_H
4 #include "sopt/config.h"
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_);
24 assert(coeffs.size() == signal.size());
25 assert(coeffs.size() % 2 == 0);
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);
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);
43 for (
t_uint i = 0; i < signal.rows(); ++i)
44 indirect_transform_impl(coeffs.row(i).transpose(), signal.row(i).transpose(), wavelet);
46 for (
t_uint j = 0; j < signal.cols(); ++j)
47 indirect_transform_impl(coeffs.col(j), signal.col(j), wavelet);
57 template <
typename T0,
typename T1>
59 Eigen::ArrayBase<T0>
const &coeffs, Eigen::ArrayBase<T1> &signal,
t_uint levels,
61 if (levels == 0)
return;
62 assert(coeffs.rows() == signal.rows());
63 assert(coeffs.cols() == signal.cols());
64 assert(coeffs.size() % (1u << levels) == 0);
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);
72 indirect_transform_impl(input, signal, wavelet);
81 template <
typename T0,
typename T1>
83 Eigen::ArrayBase<T0>
const &coeffs_, Eigen::ArrayBase<T1>
const &signal_,
t_uint levels,
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);
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);
102 indirect_transform_impl(input, signal, wavelet);
111 template <
typename T0>
113 WaveletData const &wavelet) -> decltype(copy(coeffs)) {
114 auto result = copy(coeffs);
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.
size_t t_uint
Root of the type hierarchy for unsigned integers.
Holds wavelets coefficients.