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