【发布时间】:2020-02-04 18:35:22
【问题描述】:
我有一个类似于[Float](repeating: 1.0, count: 42000) 的向量,我想使用 Accelerate 框架计算每个元素的平方根,但不存在与Apple Accelerate Framework scale and normalize a vector 中所述相反的vDSP_vsqrt 函数。我该怎么做?
【问题讨论】:
标签: ios swift accelerate-framework
我有一个类似于[Float](repeating: 1.0, count: 42000) 的向量,我想使用 Accelerate 框架计算每个元素的平方根,但不存在与Apple Accelerate Framework scale and normalize a vector 中所述相反的vDSP_vsqrt 函数。我该怎么做?
【问题讨论】:
标签: ios swift accelerate-framework
vForce Swift 覆盖使语法更简单:
vForce.sqrt(vector: AccelerateBuffer)
看看:https://github.com/apple/swift/blob/master/stdlib/public/Darwin/Accelerate/vForce_Operations.swift
...和...
【讨论】:
看来要调用的正确函数是来自vForce 的vvsqrtf。
以下是the documentation 的用法示例:
var x: [Float] = [100, 10000, 64, 144]
var y = [Float](repeating: 0, count: x.count)
var n = Int32(x.count)
vvsqrtf(&y, &x, &n)
print(y) // [10.0, 100.0, 8.0, 12.0]
请注意,您还可以“就地”计算平方根:
var data = [Float](repeating: 25.0, count: input.count)
let n = Int32(data.count)
vvsqrtf(&data, data, &n)
【讨论】:
我建议制作辅助函数来包装 vvsqrtf,以公开更 Swift 友好的 API:
import Accelerate
extension Array where Element == Float {
func squareRootedElements() -> [Float] {
if self.isEmpty { return [] }
var output = Array(repeating: 0, count: self.count)
var count = Int32(self.count)
vvsqrtf(&output, self, &count)
return output
}
mutating func squareRootElements() {
if self.isEmpty { return }
var count = Int32(self.count)
vvsqrtf(&self, self, &count)
}
}
var squares = stride(from: 0 as Float, through: 10, by: +1).map { $0 * $0 }
print(squares)
print(squares.squareRootedElements())
【讨论】:
vvsqrtf(&output, self, &count)
vvsqrtf 的第一个和第二个参数使用相同的缓冲区,它会就地覆盖吗?
vvsqrtf 所做的事情相同,但复制/粘贴更少