PURIFY
Next-generation radio interferometric imaging
convolution.h
Go to the documentation of this file.
1 #ifndef PURIFY_CONVOLUTION_H
2 #define PURIFY_CONVOLUTION_H
3 
4 namespace purify {
5 namespace convol {
6 
8 template <class T>
9 inline Vector<T> zero_pad(const Vector<T> &input, const t_int padding);
11 template <class T>
12 inline Matrix<T> zero_pad(const Matrix<T> &input, const t_int paddingv, const t_int paddingu);
14 template <class T>
15 inline Vector<T> linear_convol_1d(const Vector<T> &kernelf, const Vector<T> &kernelg);
17 template <class T>
18 Matrix<T> linear_convol_2d(const Vector<T> &kernelfu, const Vector<T> &kernelfv,
19  const Matrix<T> &kernelg);
21 template <class T>
22 Matrix<T> linear_convol_2d(const std::function<T(t_int)> &kernelu,
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);
26 
27 template <class T>
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;
32  return output;
33 }
34 template <class T>
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;
40  return output;
41 }
42 template <class T>
43 inline Vector<T> linear_convol_1d(const Vector<T> &kernelf, const Vector<T> &kernelg) {
44  // assumes that Jf has smallest support with kernelf as the filter
45  // assumes that kernelg is zero padded
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++)
49  output(j) =
50  (kernelf.segment(0, Jf).array() * kernelg.segment(output.size() - j - 1, Jf).array()).sum();
51  return output;
52 }
53 
54 template <class T>
55 Matrix<T> linear_convol_2d(const Vector<T> &kernelfu, const Vector<T> &kernelfv,
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));
62  Matrix<T> output =
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));
66  return output;
67 }
69 template <class T>
70 Matrix<T> linear_convol_2d(const std::function<T(t_int)> &kernelu,
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);
82 }
83 
84 } // namespace convol
85 } // namespace purify
86 #endif
Vector< T > zero_pad(const Vector< T > &input, const t_int padding)
zero pad a vector by a given amount
Definition: convolution.h:28
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)
Definition: convolution.h:55
Vector< T > linear_convol_1d(const Vector< T > &kernelf, const Vector< T > &kernelg)
1d linear convoluiton of entire signal
Definition: convolution.h:43