Swift 线性插值和上采样
Swift Linear Interpolation and UpSampling
我有一连串抽样不均的指标。我想将这些指标线性插值并上采样到特定的采样频率。我已经尝试使用 Accelerate Framework 和 SIMD 框架,但我不确定该怎么做。
问题本身如下:
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
let new_times:[Double] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
所以我正在寻找一种通过某种线性插值方法找到 new_values 的方法。
插值是一个广泛的领域(参见维基百科:https://en.wikipedia.org/wiki/Interpolation)
最简单的方法就是这样的线性插值。
class LinearInterpolation {
private var n : Int
private var x : [Double]
private var y : [Double]
init (x: [Double], y: [Double]) {
assert(x.count == y.count)
self.n = x.count-1
self.x = x
self.y = y
}
func Interpolate(t: Double) -> Double {
if t <= x[0] { return y[0] }
for i in 1...n {
if t <= x[i] {
let ans = (t-x[i-1]) * (y[i] - y[i-1]) / (x[i]-x[i-1]) + y[i-1]
return ans
}
}
return y[n]
}
}
用法:
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
let new_times:[Double] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
let ipol = LinearInterpolation(x: original_times, y: original_values)
for t in new_times {
let y = ipol.Interpolate(t: t)
print("t: \(t) y: \(y)")
}
在你的 Uusecase 中有类似音频数据的东西,你应该看看傅里叶分析。
vDSP_vgenpD
会为您完成这项工作。将原始时间和值传递给它,它将用内插值填充一个数组。例如:
import Accelerate
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
var new_values = [Double](repeating: 0,
count: 11)
let stride = vDSP_Stride(1)
vDSP_vgenpD(original_values, stride,
original_times, stride,
&new_values, stride,
vDSP_Length(new_values.count),
vDSP_Length(original_values.count))
您可以获得时间/值元组数组:
let result = new_values.enumerated().map{ return [=11=] }
看起来像:
我有一连串抽样不均的指标。我想将这些指标线性插值并上采样到特定的采样频率。我已经尝试使用 Accelerate Framework 和 SIMD 框架,但我不确定该怎么做。
问题本身如下:
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
let new_times:[Double] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
所以我正在寻找一种通过某种线性插值方法找到 new_values 的方法。
插值是一个广泛的领域(参见维基百科:https://en.wikipedia.org/wiki/Interpolation)
最简单的方法就是这样的线性插值。
class LinearInterpolation {
private var n : Int
private var x : [Double]
private var y : [Double]
init (x: [Double], y: [Double]) {
assert(x.count == y.count)
self.n = x.count-1
self.x = x
self.y = y
}
func Interpolate(t: Double) -> Double {
if t <= x[0] { return y[0] }
for i in 1...n {
if t <= x[i] {
let ans = (t-x[i-1]) * (y[i] - y[i-1]) / (x[i]-x[i-1]) + y[i-1]
return ans
}
}
return y[n]
}
}
用法:
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
let new_times:[Double] = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
let ipol = LinearInterpolation(x: original_times, y: original_values)
for t in new_times {
let y = ipol.Interpolate(t: t)
print("t: \(t) y: \(y)")
}
在你的 Uusecase 中有类似音频数据的东西,你应该看看傅里叶分析。
vDSP_vgenpD
会为您完成这项工作。将原始时间和值传递给它,它将用内插值填充一个数组。例如:
import Accelerate
let original_times:[Double] = [0.0, 2.0, 3.0, 6.0, 10.0]
let original_values: [Double] = [50.0, 20.0, 30.0, 40.0, 10.0]
var new_values = [Double](repeating: 0,
count: 11)
let stride = vDSP_Stride(1)
vDSP_vgenpD(original_values, stride,
original_times, stride,
&new_values, stride,
vDSP_Length(new_values.count),
vDSP_Length(original_values.count))
您可以获得时间/值元组数组:
let result = new_values.enumerated().map{ return [=11=] }
看起来像: