Быстрая линейная интерполяция и апсэмплинг - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть поток метрик, которые выбираются неравномерно. Я хочу линейно интерполировать и повышать частоту этих метрик до определенной частоты дискретизации. Я пытался использовать Accelerate Framework и SIMD Framework, но я не совсем уверен, что делать.

Сама проблема заключается в следующем:

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 ​​с помощью какого-либо метода линейной интерполяции.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

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 $0 }

Это выглядит так:

enter image description here

0 голосов
/ 08 ноября 2018

Интерполяция - это широкое поле (см. Википедия: 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)")
    }

В вашем Usecase с чем-то вроде аудиоданных вы должны взглянуть на анализ Фурье.

...