繁体   English   中英

在Swift中使用Accelerate Framework复数支持

[英]Using Accelerate Framework complex number support in Swift

我需要在Swift中使用Accelerate Multiply,Complex Conjugate和Exp执行以下操作。 我已经使用dankogaiComplex Swift代码完成了此操作 ,但是对于我正在做的工作来说太慢了。 我在使用Accelerate框架创建工作版本时遇到了麻烦,希望能够加深我的理解。

SWIFT代码

let frequencyShift = (2 * M_PI * Double(self.centralFrequency) * delays).i / Double(self.samplingFrequencyHertz)
let result = conj(exp(frequencyShift))

delays是大约200k倍的数组,这些行将被称为数百次。 我将它们转换为Swift复杂样式的Complex Number,然后在结果上调用complex exp()和conj()方法。

双精度复数矢量标量乘法。

vDSP_zvzsmlD

共轭

复合矢量共轭 双精度。

vDSP_zvconjD

Accelerate中是否有等效的exp() ,您将如何重组此代码以执行等效的Accelerate'd版本的操作?

在Swift中使用Accelerate的一般原则

我发现第一次尝试将您的代码从使用for循环的幼稚实现转换为映射很有用。 如果您的代码结构适合与地图一起使用,则由于您已经解决了将算法结构化为向量化操作的问题,因此切换加速变得非常容易。

循环映射

let array: [Int] = [1, 2, 3, 4]
let array2 = [Int]()
for value in array {
    array2 = value * 2
}

let array: [Int] = [1, 2, 3, 4]
array.map({ (value: Int) -> Int in
    return value * 2
})

在相等大小的阵列版本上运行

如果发现要枚举两个或更多个相同大小的数组,则上述方法可以将map与enumerate结合使用

let alphas: [Double] = betas.enumerate().map({ (index: Int, beta: Double) -> Double in
    return beta * phis[index]
})

设置阵列以与Accelerate一起使用

使用Accelerate的方法并不总是很明显,特别是UnsafePointerUnsafeMutablePointer语法。 这基本上是不必要的。

var alphaLowers = [Double](count: elementDelays.count, repeatedValue: 0)
vDSP_vmulD(&alphas, 1, &x_ns, 1, &alphaLowers, 1, UInt(elementDelays.count))

因此,Swift允许您创建一个自动的内存管理对象,然后将其与&符号一起传递,从而避免了malloc和free的麻烦。 我之所以这样说是因为它避免尝试将对象包装在此UnsafeMutablePointer<Double>(alphaLowers)

复数

我想做的大多数事情都依赖于涉及复数的运算。 因此,要创建可以在Accelerate中使用的对象,可以尝试以下操作。

var reals = [Double](count: 100, repeatedValue: 0)
var imaginaries = [Double](count: 100, repeatedValue: 0)
var complexNumbers = DSPDoubleSplitComplex(realp: &reals, imagp: &imaginaries)

复杂的exp()

我没有找到与exp相当的Accelerate等效项,但是您可以使用下面使用Complex Swift库说明的Euler方法分解值并对实部和虚部执行必要的操作。

public func exp<T:RealType>(z:Complex<T>) -> Complex<T> {
    let r = T.exp(z.re)
    let a = z.im
    return Complex(r * T.cos(a), r * T.sin(a))
}

我没有找到避免此问题的好方法,因此我实际上不使用Accelerate来执行此步骤。 简单地通过对虚部进行求反即可计算出复共轭。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM