我试图在Swift中找到函数函数的替代品。我发现了一个叫做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))发布于 2021-11-14 16:17:55
您已经接近了,但是您使用的Array.init(unsafeUninitializedCapacity:initializingWith:)不正确。来自其文件
讨论 在闭包中,将
initializedCount参数设置为由闭包初始化的元素数。范围buffer[0..<initializedCount]中的内存必须在闭包执行结束时初始化,而范围buffer[initializedCount...]中的内存必须未初始化。即使initializer闭包引发错误,这个后置条件也必须保持不变。
这个API对Array.init(repeating:count:)来说是一个更不安全的API(但性能比较好),它分配一个固定大小的数组,并花费时间初始化它的所有内容)。这有两个潜在的缺点:
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
})发布于 2021-11-15 15:26:52
FYI,有一个很好的Swift版本的vDSP_vtrapzD,您可以在这里看到:函数。返回结果的变量使用unsafeUninitializedCapacity初始化器。
在一个相关的注意事项上,还有一个用于求积的很好的Swift:https://developer.apple.com/documentation/accelerate/quadrature-smu
西蒙
发布于 2022-06-20 13:47:08
在过去的一周里,我也一直在努力使用DSP!亚历山大的解决方案是有帮助的。不过,我想补充几点。
vDSP_vtrapzD只允许您针对固定的步骤增量(即标量值)集成一个值数组。该函数不允许为每个增量传递一个变化的时间值。
示例解决方案使我有点困惑,因为它进行了检查,以确保时间数组与数据数组的大小相同。这不是必要的,因为vDSP_vtrapzD函数只使用时间向量中的第一个值。
遗憾的是,vDSP_vtrapzD只将标量作为固定时间分量。在我的经验中,当使用来自传感器的基于时间的数据时,这并不能反映实际情况,这些传感器不以完全相同的增量发送数据。
https://stackoverflow.com/questions/69964423
复制相似问题