c++ - 如何进行一维 "valid"卷积?

标签 c++ math convolution

<分区>

我正在尝试在 C++ 中以“有效”模式(Matlab 定义)实现一维卷积。

这看起来很简单,但我一直无法找到用 C++(或事实上我可以适应的任何其他语言)执行此操作的代码。如果我的 vector 大小是幂,我可以使用 2D 卷积,但我想找到适用于任何输入和内核的东西。

那么如何在“有效”模式下执行一维卷积,给定大小为 I 的输入 vector 和大小为 K 的内核(输出通常应该是大小为 I - K + 1 的 vector )。

伪代码也被接受。

最佳答案

您可以使用以下实现之一:

全卷积:

template<typename T>
std::vector<T>
conv(std::vector<T> const &f, std::vector<T> const &g) {
  int const nf = f.size();
  int const ng = g.size();
  int const n  = nf + ng - 1;
  std::vector<T> out(n, T());
  for(auto i(0); i < n; ++i) {
    int const jmn = (i >= ng - 1)? i - (ng - 1) : 0;
    int const jmx = (i <  nf - 1)? i            : nf - 1;
    for(auto j(jmn); j <= jmx; ++j) {
      out[i] += (f[j] * g[i - j]);
    }
  }
  return out; 
}

f:第一个序列(一维信号)。

g:第二个序列(一维信号)。

返回大小为 f.size() + g.size() - 1std::vector,也就是离散卷积的结果。柯西积 (f * g) = (g * f)

LIVE DEMO

有效卷积:

template<typename T>
std::vector<T>
conv_valid(std::vector<T> const &f, std::vector<T> const &g) {
  int const nf = f.size();
  int const ng = g.size();
  std::vector<T> const &min_v = (nf < ng)? f : g;
  std::vector<T> const &max_v = (nf < ng)? g : f;
  int const n  = std::max(nf, ng) - std::min(nf, ng) + 1;
  std::vector<T> out(n, T());
  for(auto i(0); i < n; ++i) {
    for(int j(min_v.size() - 1), k(i); j >= 0; --j) {
      out[i] += min_v[j] * max_v[k];
      ++k;
    }
  }
  return out;
}

f:第一个序列(一维信号)。

g:第二个序列(一维信号)。

返回一个 std::vector 大小 std::max(f.size(), g.size()) - std::min(f.size(), g.size()) + 1,这是有效(即没有填充)离散卷积的结果。柯西积 (f * g) = (g * f)

LIVE DEMO

关于c++ - 如何进行一维 "valid"卷积?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24518989/

相关文章:

c++ - Awesomium 1.7RC2 与 VS11

c++ - Sscanf 的问题

android - 不存在这样的 acos 函数

R - 引用替换

python - PyCaffe 输出层用于测试二元分类模型

c++ - 使用指针作为参数调用函数时出错

c++ - 我应该使用 std::shared 指针来传递指针吗?

javascript - MathJax 库在公式中留下滚动条

Swift - 与 Accelerate Framework 的卷积

matlab - 如果 FFT 有很多 0,则寻找卷积核?