Общие принципы использования Accelerate with Swift
Я считаю полезным сначала попытаться преобразовать ваш код из наивной реализации с использованием циклов for в карты. Если ваш код структурирован для работы с картами, то переключиться на ускорение становится довольно легко, поскольку вы уже занимались структурированием своего алгоритма в векторизованные операции.
Цикл 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
})
Версия для работы с массивами одинакового размера
Если вы обнаружите, что хотите перечислить два или более массива одинакового размера, то приведенное выше может объединить карту с перечислением
let alphas: [Double] = betas.enumerate().map({ (index: Int, beta: Double) -> Double in
return beta * phis[index]
})
Настройка массивов для использования с Accelerate
Способ использования Accelerate не всегда очевиден, особенно синтаксис UnsafePointer
и UnsafeMutablePointer
. Это в принципе не нужно.
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 в Accelerate, но вы можете разбить значения и выполнить необходимую операцию над действительными и мнимыми числами, используя метод Эйлера, показанный ниже, используя библиотеку Complex Swift.
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. Комплексное сопряжение вычисляется просто путем отрицания мнимой части.
person
Cameron Lowell Palmer
schedule
22.01.2016