vDSP.convolve()
returns an array with length:
values.count - kernel.count
But shouldn't the result array have length:
values.count - kernel.count + 1
I ran the following which prints out the size of the results array with various combinations of values and kernel lengths:
for i in 0 ..< 10 {
let values = Array.init(repeating: 1.0, count: 1000 + i)
for j in 0 ..< 10 {
let kernel = Array.init(repeating: 1.0, count: 100 + j)
let result = vDSP.convolve(values, withKernel: kernel)
print("values[\(values.count)], kernel[\(kernel.count)], result[\(result.count)], result[\(result.count - 1)] = \(result[result.count - 1])")
}
}
As you can see the results array always has length values.count - kernel.count
:
values[1000], kernel[100], result[900], result[899] = 100.0
values[1000], kernel[101], result[899], result[898] = 101.0
values[1000], kernel[102], result[898], result[897] = 102.0
values[1000], kernel[103], result[897], result[896] = 103.0
values[1000], kernel[104], result[896], result[895] = 104.0
values[1000], kernel[105], result[895], result[894] = 105.0
values[1000], kernel[106], result[894], result[893] = 106.0
values[1000], kernel[107], result[893], result[892] = 107.0
values[1000], kernel[108], result[892], result[891] = 108.0
values[1000], kernel[109], result[891], result[890] = 109.0
values[1001], kernel[100], result[901], result[900] = 100.0
values[1001], kernel[101], result[900], result[899] = 101.0
values[1001], kernel[102], result[899], result[898] = 102.0
values[1001], kernel[103], result[898], result[897] = 103.0
values[1001], kernel[104], result[897], result[896] = 104.0
values[1001], kernel[105], result[896], result[895] = 105.0
...
However, the result array should have length values.count - kernel.count + 1
.
For example, if instead of using the returned result array, a result array is passed to vDSP.convolve, with length values.count - kernel.count + 1
the last value has a valid result:
for i in 0 ..< 10 {
let values = Array.init(repeating: 1.0, count: 1000 + i)
for j in 0 ..< 10 {
let kernel = Array.init(repeating: 1.0, count: 100 + j)
var result = Array.init(repeating: 0.0, count: values.count - kernel.count + 1)
vDSP.convolve(values, withKernel: kernel, result: &result)
print("values[\(values.count)], kernel[\(kernel.count)], result[\(result.count)], result[\(result.count - 1)] = \(result[result.count - 1])")
}
}
values[1000], kernel[100], result[901], result[900] = 100.0
values[1000], kernel[101], result[900], result[899] = 101.0
values[1000], kernel[102], result[899], result[898] = 102.0
values[1000], kernel[103], result[898], result[897] = 103.0
values[1000], kernel[104], result[897], result[896] = 104.0
values[1000], kernel[105], result[896], result[895] = 105.0
values[1000], kernel[106], result[895], result[894] = 106.0
values[1000], kernel[107], result[894], result[893] = 107.0
values[1000], kernel[108], result[893], result[892] = 108.0
values[1000], kernel[109], result[892], result[891] = 109.0
values[1001], kernel[100], result[902], result[901] = 100.0
values[1001], kernel[101], result[901], result[900] = 101.0
values[1001], kernel[102], result[900], result[899] = 102.0
values[1001], kernel[103], result[899], result[898] = 103.0
values[1001], kernel[104], result[898], result[897] = 104.0
values[1001], kernel[105], result[897], result[896] = 105.0
If the result array is created with length values.count - kernel.count + 2
then we get the following runtime error:
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
Indicating the extra element in the result array is valid and vDSP.convolve()
is returning a result array which is one element too short.