与 MATLAB 实现相比,尝试使用 Accelerate 中的 vDSP_conv() 进行卷积时,我得到的结果不一致。在使用此函数计算卷积时,有几篇关于奇怪结果的 StackOverflow 帖子,但据我所知,我正确使用了该框架,并结合了其他 Stack Overflow 帖子的建议。这是我的代码:
public func conv(x: [Float], k: [Float]) -> [Float] {
let resultSize = x.count + k.count - 1
var result = [Float](count: resultSize, repeatedValue: 0)
let kEnd = UnsafePointer<Float>(k).advancedBy(k.count - 1)
let xPad: [Float] = [Float](count: (2*k.count)+1, repeatedValue: 0.0)
let xPadded = x + xPad
vDSP_conv(xPadded, 1, kEnd, -1, &result, 1, vDSP_Length(resultSize), vDSP_Length(k.count))
}
据我所知,我正在按照此处的 Accelerate 框架文档中的说明进行正确的零填充
我定义了两个测试数组A: [Float] = [0, 0, 1, 0, 0]
和B: [float] = [1, 0, 0]
.
在 MATLAB 中,当我运行 时conv(A, B)
,我得到[0, 0, 1, 0, 0, 0, 0]
.
但是,当我运行上面的 vDSP 时,conv()
我得到了[1, 0, 0, 0, 0, 0, 0]
.
我的实施有什么问题?我已经检查了很多次,并查看了我能找到的所有 SO 帖子,但仍然无法解释这种不一致。
除此之外,还有比我这里更有效的方法来对数组进行零填充吗?为了保持x
不可变,我创建了新xPadded
数组,但毫无疑问有一种更有效的方法来执行此填充。
** 编辑 ** 正如 Martin R 所建议的,我k.count -1
在数组的开头和结尾处平均填充,如下所示。
public func conv(x: [Float], k: [Float]) -> [Float] {
let resultSize = x.count + k.count - 1
var result = [Float](count: resultSize, repeatedValue: 0)
let kEnd = UnsafePointer<Float>(k).advancedBy(k.count - 1)
let xPad: [Float] = [Float](count: k.count-1, repeatedValue: 0.0)
let xPadded = xPad + x + xPad
vDSP_conv(xPadded, 1, kEnd, -1, &result, 1, vDSP_Length(resultSize), vDSP_Length(k.count))
return result
}
使用此代码,conv(A, B)
仍然返回 [1, 0, 0, 0, 0, 0, 0]。
我正在调用该函数,如下所示:
let A: [Float] = [0, 0, 1, 0, 0]
let B: [Float] = [1, 0, 0]
let C: [Float] = conv(A, k: B)