在Swift

时间:2016-01-20 10:56:09

标签: swift complex-numbers accelerate-framework

我需要在Swift中使用Accelerate Multiply,Complex Conjugate和Exp执行以下操作。我已经使用Complex Swift code by dankogai完成了这项工作,但这对我正在做的工作来说太慢了。我在使用Accelerate框架创建工作版本时遇到了麻烦,我希望加快理解。

Swift代码

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

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

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

vDSP_zvzsmlD

缀合物

复矢量共轭;双精度。

vDSP_zvconjD

Accelerate中是否有exp()个等效项,您如何重新组织此代码以执行等效的Accelerate&dd版本的操作?

1 个答案:

答案 0 :(得分:0)

使用Accelerate with Swift的一般原则

我发现首先尝试将代码从使用for循环的朴素实现转换为映射是有帮助的。如果您的代码的结构与地图一起使用,那么切换到加速变得非常容易,因为您已经将算法结构化为矢量化操作。

For-loop to map

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
})

在相同大小的数组版本

上运行

如果您发现要枚举两个或更多相同大小的数组,那么上面的内容可以将地图与枚举结合起来

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()

我没有找到exprate的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的情况下执行此步骤。简单地通过否定虚部来计算复共轭。