1 #ifndef PURIFY_CONVOLUTION_H
2 #define PURIFY_CONVOLUTION_H
9 inline Vector<T>
zero_pad(
const Vector<T> &input,
const t_int padding);
12 inline Matrix<T>
zero_pad(
const Matrix<T> &input,
const t_int paddingv,
const t_int paddingu);
15 inline Vector<T>
linear_convol_1d(
const Vector<T> &kernelf,
const Vector<T> &kernelg);
18 Matrix<T>
linear_convol_2d(
const Vector<T> &kernelfu,
const Vector<T> &kernelfv,
19 const Matrix<T> &kernelg);
23 const std::function<T(t_int)> &kernelv,
24 const std::function<T(t_int, t_int)> &kernelw,
const t_uint &Jfu,
25 const t_uint &Jfv,
const t_uint &Jgu,
const t_uint &Jgv);
28 inline Vector<T>
zero_pad(
const Vector<T> &input,
const t_int padding) {
29 if (padding < 1)
throw std::runtime_error(
"Padding must be 1 or greater for convolution.");
30 Vector<T> output = Vector<T>::Zero(input.size() + 2 * padding);
31 output.segment(padding, input.size()) = input;
35 inline Matrix<T>
zero_pad(
const Matrix<T> &input,
const t_int paddingv,
const t_int paddingu) {
36 if ((paddingu < 1) or (paddingv < 1))
37 throw std::runtime_error(
"Padding must be 1 or greater for convolution.");
38 Matrix<T> output = Matrix<T>::Zero(input.rows() + 2 * paddingv, input.cols() + 2 * paddingu);
39 output.block(paddingv, paddingu, input.rows(), input.cols()) = input;
43 inline Vector<T>
linear_convol_1d(
const Vector<T> &kernelf,
const Vector<T> &kernelg) {
46 const t_int Jf = kernelf.size();
47 Vector<T> output = Vector<T>::Zero(kernelg.size() - Jf + 1);
48 for (t_int j = 0; j < output.size(); j++)
50 (kernelf.segment(0, Jf).array() * kernelg.segment(output.size() - j - 1, Jf).array()).sum();
56 const Matrix<T> &kernelg) {
58 Matrix<T> buffer = Matrix<T>::Zero(kernelfv.size() + kernelg.rows() - 1, kernelg.cols());
60 for (t_uint i = 0; i < kernelg.cols(); i++)
61 buffer.col(i) = linear_convol_1d<T>(kernelfv, zero_pad<T>(kernelg.col(i), kernelfv.size() - 1));
63 Matrix<T>::Zero(kernelfv.size() + kernelg.rows() - 1, kernelfu.size() + kernelg.cols() - 1);
64 for (t_uint i = 0; i < output.rows(); i++)
65 output.row(i) = linear_convol_1d<T>(kernelfu, zero_pad<T>(buffer.row(i), kernelfu.size() - 1));
71 const std::function<T(t_int)> &kernelv,
72 const std::function<T(t_int, t_int)> &kernelw,
const t_uint &Jfu,
73 const t_uint &Jfv,
const t_uint &Jgu,
const t_uint &Jgv) {
74 Vector<T> kernelfu = Vector<T>::Zero(Jfu);
75 Vector<T> kernelfv = Vector<T>::Zero(Jfv);
76 Matrix<T> kernelg = Matrix<T>::Zero(Jgv, Jgu);
77 for (t_int i = 0; i < kernelg.cols(); i++)
78 for (t_int j = 0; j < kernelg.rows(); j++) kernelg(j, i) = kernelw(j, i);
79 for (t_int i = 0; i < kernelfu.size(); i++) kernelfu(i) = kernelu(i);
80 for (t_int i = 0; i < kernelfv.size(); i++) kernelfv(i) = kernelv(i);
81 return linear_convol_2d<T>(kernelfu, kernelfv, kernelg);
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