1 #include "purify/config.h"
4 #include "catch2/catch_all.hpp"
5 #include "purify/directories.h"
13 const Vector<t_int> signal = Vector<t_int>::Random(3);
14 for (
int i = 1; i < 5; i++) {
16 CHECK(output.size() == signal.size() + 2 * i);
17 for (
int j = 0; j < output.size(); j++) {
18 if (j < i)
CHECK(output(j) == 0);
19 if (j > (i + signal.size()))
CHECK(output(j) == 0);
24 Vector<t_int> tri = Vector<t_int>::Zero(3);
26 Vector<t_int> signal = convol::zero_pad<t_int>(Vector<t_int>::Random(4), tri.size());
28 CHECK(output.size() == signal.size() - tri.size() + 1);
29 for (
int i = 0; i < signal.size() - tri.size() - 1; i++)
30 CHECK(output(i) == tri(0) * signal(output.size() - i - 1) +
31 tri(1) * signal(output.size() - i - 1 + 1) +
32 tri(2) * signal(output.size() - i - 1 + 2));
35 const Vector<t_real> kernelu = Vector<t_real>::Random(3);
36 const Vector<t_real> kernelv = Vector<t_real>::Random(2);
37 const Matrix<t_real> signal = Matrix<t_real>::Random(2, 2);
39 CHECK(output.cols() == signal.cols() + kernelu.size() - 1);
40 CHECK(output.rows() == signal.rows() + kernelv.size() - 1);
41 const Matrix<t_real> test_buff =
42 convol::zero_pad<t_real>(signal, kernelv.size() - 1, kernelu.size() - 1);
44 CHECK(output(0, 0) != output(1, 0));
45 CHECK(output(output.rows() - 1, output.cols() - 1) !=
46 output(output.rows() - 1, output.cols() - 2));
47 for (
int i = 0; i < output.cols(); i++) {
48 for (
int j = 0; j < output.rows(); j++) {
52 (kernelu(0) * test_buff(output.rows() - j - 1, output.cols() - i - 1) +
53 kernelu(1) * test_buff(output.rows() - j - 1, output.cols() - i + 1 - 1) +
54 kernelu(2) * test_buff(output.rows() - j - 1, output.cols() - i - 1 + 2)) -
56 (kernelu(0) * test_buff(output.rows() - 1 - j + 1, output.cols() - i - 1) +
57 kernelu(1) * test_buff(output.rows() - 1 - j + 1, output.cols() - i - 1 + 1) +
59 test_buff(output.rows() - 1 - j + 1, output.cols() - i - 1 + 2))) < 1e-7);
66 SECTION(
"box and delta") {
68 auto convol_kernelu = [=](
const t_int ju) -> t_complex {
return 1.; };
69 auto convol_kernelv = [=](
const t_int jv) -> t_complex {
return 1.; };
70 auto convol_kernelw = [=](
const t_int jv,
const t_int ju) -> t_complex {
71 return ((std::floor(ju - (Jw - 1) * 0.5) == 0) and (std::floor(jv - (Jw - 1) * 0.5) == 0))
75 const Matrix<t_complex> projection_kernel = convol::linear_convol_2d<t_complex>(
76 convol_kernelu, convol_kernelv, convol_kernelw,
static_cast<t_int
>(Ju),
77 static_cast<t_int
>(Jv),
static_cast<t_int
>(Jw),
static_cast<t_int
>(Jw));
78 CAPTURE(projection_kernel);
79 CHECK(projection_kernel.cols() == (Ju + Jw - 1));
80 CHECK(projection_kernel.rows() == (Jv + Jw - 1));
81 CHECK(projection_kernel.block(2, 2, Jv, Ju)
82 .isApprox(Matrix<t_complex>::Constant(Jv, Ju, 1.), 1e-12));
84 SECTION(
"delta and delta") {
86 auto convol_kernelu = [=](
const t_int ju) -> t_complex {
87 return (std::floor(ju - (Ju - 1) * 0.5) == 0) ? 1. : 0.;
89 auto convol_kernelv = [=](
const t_int jv) -> t_complex {
90 return (std::floor(jv - (Jv - 1) * 0.5) == 0) ? 1. : 0.;
92 auto convol_kernelw = [=](
const t_int jv,
const t_int ju) -> t_complex {
93 return ((std::floor(ju - (Jw - 1) * 0.5) == 0) and (std::floor(jv - (Jw - 1) * 0.5) == 0))
97 const Matrix<t_complex> projection_kernel = convol::linear_convol_2d<t_complex>(
98 convol_kernelu, convol_kernelv, convol_kernelw,
static_cast<t_int
>(Ju),
99 static_cast<t_int
>(Jv),
static_cast<t_int
>(Jw),
static_cast<t_int
>(Jw));
100 CAPTURE(projection_kernel);
101 CHECK(projection_kernel.cols() == (Ju + Jw - 1));
102 CHECK(projection_kernel.rows() == (Jv + Jw - 1));
103 CHECK(projection_kernel(4, 3) == 1.);
105 SECTION(
"delta_size_1") {
107 auto convol_kernelu = [=](
const t_int ju) -> t_complex {
108 return (std::floor(ju - (Ju - 1) * 0.5) == 0) ? 1. : 0.;
110 auto convol_kernelv = [=](
const t_int jv) -> t_complex {
111 return (std::floor(jv - (Jv - 1) * 0.5) == 0) ? 1. : 0.;
113 auto convol_kernelw = [=](
const t_int jv,
const t_int ju) -> t_complex {
114 return ((std::floor(ju - (Jw - 1) * 0.5) == 0) and (std::floor(jv - (Jw - 1) * 0.5) == 0))
118 const Matrix<t_complex> projection_kernel = convol::linear_convol_2d<t_complex>(
119 convol_kernelu, convol_kernelv, convol_kernelw,
static_cast<t_int
>(Ju),
120 static_cast<t_int
>(Jv),
static_cast<t_int
>(Jw),
static_cast<t_int
>(Jw));
121 CAPTURE(projection_kernel);
122 CHECK(projection_kernel.cols() == (Ju + Jw - 1));
123 CHECK(projection_kernel.rows() == (Jv + Jw - 1));
124 CHECK(projection_kernel(2, 1) == 1.);
126 SECTION(
"box_and_delta_size_1") {
128 auto convol_kernelu = [=](
const t_int ju) -> t_complex {
return ju * 1.; };
129 auto convol_kernelv = [=](
const t_int jv) -> t_complex {
return jv * 1.; };
130 auto convol_kernelw = [=](
const t_int jv,
const t_int ju) -> t_complex {
131 return ((std::floor(ju - (Jw - 1) * 0.5) == 0) and (std::floor(jv - (Jw - 1) * 0.5) == 0))
135 const Matrix<t_complex> projection_kernel = convol::linear_convol_2d<t_complex>(
136 convol_kernelu, convol_kernelv, convol_kernelw,
static_cast<t_int
>(Ju),
137 static_cast<t_int
>(Jv),
static_cast<t_int
>(Jw),
static_cast<t_int
>(Jw));
138 CAPTURE(projection_kernel);
139 CHECK(projection_kernel.cols() == (Ju + Jw - 1));
140 CHECK(projection_kernel.rows() == (Jv + Jw - 1));
141 for (
int i = 0; i < projection_kernel.cols(); i++) {
142 for (
int j = 0; j < projection_kernel.rows(); j++) {
143 CHECK(std::abs(
static_cast<t_real
>(i * j) - projection_kernel(j, i)) < 1e-12);
#define CHECK(CONDITION, ERROR)
Vector< T > zero_pad(const Vector< T > &input, const t_int padding)
zero pad a vector by a given amount
Matrix< T > linear_convol_2d(const Vector< T > &kernelfu, const Vector< T > &kernelfv, const Matrix< T > &kernelg)
perform linear convolution between two separable kernels and a 2d kernel (vectors)
Vector< T > linear_convol_1d(const Vector< T > &kernelf, const Vector< T > &kernelg)
1d linear convoluiton of entire signal