使用 vDSP 去隔行矢量

Deinterlace a vector using vDSP

假设我有一个向量:

let input: [Float] = [1, 2, 3, 4, 5, 6, 7, 8, ...]

我想做的是通过选择每隔一个值来生成 2 个新向量作为输出来消除此向量的交错,如下所示:

[1, 3, 5, 7, ...]
[2, 4, 6, 8, ...]

vDSP 中执行此操作的最佳方法是什么?

这里你想要的工具是vDSP.convert(interleavedComplexVector:toSplitComplexVector:)。不要让“复杂向量”混淆了您。这些是否“复杂”并不重要。 “交错复向量”只是“一系列偶数和奇数值”。而“拆分复数向量”只是“包含偶数列表和赔率列表的结构”。这些有时被解释为实部和虚部,但这种解释与 convert 的工作方式无关(并且通常与这些值在实践中的使用方式无关)。

所以假设 [Float] 像:

let input: [Float] = [1, 2, 3, 4, 5, 6, 7, 8]

还有两个输出列表(“向量”),例如:

var evens: [Float] = Array(repeating: 0, count: input.count / 2)
var odds = evens

您可以这样拆分它们:

evens.withUnsafeMutableBufferPointer { evenPtr in
    odds.withUnsafeMutableBufferPointer { oddPtr in

        var split = DSPSplitComplex(realp: evenPtr.baseAddress!,
                                    imagp: oddPtr.baseAddress!)

        input.withUnsafeBytes {
            vDSP.convert(interleavedComplexVector: Array([=12=].bindMemory(to: DSPComplex.self)),
                         toSplitComplexVector: &split)
        }
    }
}

// At this point, evens and odds are filled in.

这是为了建立 FFT 而特意模仿 Apple's example code

如果您恰好需要以这种方式拆分更多值(尤其是 4 个值),请查看 vImageConvert_ARGBFFFFtoPlanarF 和相关函数。就像“复杂”真的只是意味着“两个浮点数”,“ARGBFFFF”只是意味着“4 个浮点数”。数字只是数字,有时您需要的函数恰好是根据另一个用例命名的。