如何使用 vDSP 集成到 Swift
Posted
技术标签:
【中文标题】如何使用 vDSP 集成到 Swift【英文标题】:How to integrate in Swift using vDSP 【发布时间】:2021-11-14 15:23:53 【问题描述】:我尝试在 Swift 中寻找 SciPy's cumtrapz
function 函数的替代品。我找到了一个名为vDSP_vtrapzD
的东西,但我不知道如何使用它。这是我到目前为止所做的:
import Accelerate
var f1: [Double] = [<some data>]
var tdata: [Double] = [<time vector>]
var output = [Double](unsafeUninitializedCapacity:Int(f1.count), initializingWith: _, _ in)
vDSP_vtrapzD(&f1, 1, &tdata, &output, 1, vDSP_Length(f1.count))
【问题讨论】:
不相关,但我要补充一点:如果您将变量命名为比f1
和 tdata
更有用的名称,则无需编写像 some data
和 time vector
这样的 cmets。您可以将变量命名为 :p
对不起。它在我的计算中更有意义,但我在发布问题时忘记更改它。
【参考方案1】:
您很接近,但您错误地使用了Array.init(unsafeUninitializedCapacity:initializingWith:)
。来自its documentation:
讨论
在闭包内部,将
initializedCount
参数设置为闭包初始化的元素数量。buffer[0..<initializedCount]
范围内的内存必须在闭包执行结束时初始化,buffer[initializedCount...]
范围内的内存必须未初始化。即使initializer
闭包抛出错误,这个后置条件也必须成立。
这个 API 比 Array.init(repeating:count:)
更不安全(但性能更好),它分配一个固定大小的数组,并花时间初始化它的所有内容)。这有两个潜在的缺点:
如果数组的目的是提供一个缓冲区来写入结果,那么在此之前对其进行初始化是多余和浪费的
如果您放入该缓冲区的结果最终大于您的 数组,您需要记住手动“修剪”多余的部分 将其复制到一个新数组中。
Array.init(unsafeUninitializedCapacity:initializingWith:)
对此进行了改进:
您正在使用Array.init(unsafeUninitializedCapacity:initializingWith:)
,就好像它是Array.init(repeating:count:)
。要正确使用它,您可以将初始化逻辑放入 initializer
参数中,如下所示:
let result = Array<Double>(unsafeUninitializedCapacity: f1.count, initializingWith: resultBuffer, count in
assert(f1.count == tdata.count)
vDSP_vtrapzD(
&f1, // Double-precision real input vector.
1, // Address stride for A.
&tdata, // Pointer to double-precision real input scalar: step size.
resultBuffer.baseAddress!, // Double-precision real output vector.
1, // Address stride for C.
vDSP_Length(f1.count) // The number of elements to process.,
)
count = f1.count // This tells Swift how many elements of the buffer to copy into the resultant Array
)
【讨论】:
【参考方案2】:仅供参考,vDSP_vtrapzD
有一个不错的 Swift 版本,您可以在这里看到:https://developer.apple.com/documentation/accelerate/vdsp/integration_functions。返回结果的变体使用unsafeUninitializedCapacity
初始化器。
在相关说明中,Quadrature 还有一个不错的 Swift API:https://developer.apple.com/documentation/accelerate/quadrature-smu
西蒙
【讨论】:
以上是关于如何使用 vDSP 集成到 Swift的主要内容,如果未能解决你的问题,请参考以下文章
将 vDSP.convertElements 与 vDSP.RoundingMode 一起使用