Как использовать линейную интерполяцию из Accelerate - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь линейно интерполировать новые значения из набора данных с помощью платформы Apple Accelerate. Я использовал эту часть документации для реализации своего кода, но я сталкиваюсь с проблемами, когда пытаюсь интерполировать набор значений, меньших 1, дроби.

let values: [CGFloat] = [0.0, 0.019124083, 0.035419375, 0.05232375, 0.06873629, 0.08550575, 0.10209821, 0.11870141, 0.1355003, 0.15223834, 0.16881292, 0.18565933, 0.20213126, 0.21881929, 0.2355565, 0.2522735, 0.26899675, 0.28572345, 0.30233976, 0.3187645, 0.33557975, 0.35221455]
let indices: [CGFloat] = [0.0, 0.00438118, 0.017873764, 0.04094696, 0.07394123, 0.11698151, 0.16987896, 0.23201275, 0.30223083, 0.37879562, 0.45942688, 0.54145336, 0.6220541, 0.6985626, 0.7687006, 0.8307409, 0.88353443, 0.9264679, 0.95935345, 0.98232174, 0.9957142, 1.0]

let numberOfElements = vDSP_Length(100)

var result = [Float](repeating: 0,
                count: Int(numberOfElements))

let stride = vDSP_Stride(1)

var base: Float = 0
var end = Float(values.count)
var control = [Float](repeating: 0,
                      count: Int(numberOfElements))

vDSP_vgenp(values, stride,
           indices, stride,
           &result, stride,
           numberOfElements,
           vDSP_Length(values.count))

print(result)

// [0.0, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455, 0.35221455]


1 Ответ

1 голос
/ 26 мая 2020

Как объяснено в документе, на который имеется ссылка , дробные части индексов определяют интерполяцию между парой значений в массиве значений, начиная с индекса, определенного целой частью.

Точный алгоритм описан как псевдокод в vDSP_vgenp(_:_:_:_:_:_:_:_:):

for (n = 0; n < N; ++n)
    If n <= B[0],  then C[n] = A[0].
    If B[M-1] < n, then C[n] = A[M-1].
    Otherwise:
        Let m be such that B[m] < n <= B[m+1].
        C[n] = A[m] + (A[m+1]-A[m]) * (n-B[m]) / (B[m+1]-B[m]).

Здесь A - массив значений, B - массив индексов и C - массив результатов.

В вашем случае все индексы - <= 1, и поэтому result[n] = values[21] = 0.35221455 для всех n >= 1.

Если намерение состоит в том, чтобы интерполировать значения в интервале [ 0, 100], то индексы должны быть в этом диапазоне. Итак, вы, вероятно, захотите умножить индексы (в диапазоне 0..1) на длину массива результатов:

let numberOfElements = vDSP_Length(100)

let indices: [Float] = [0.0, 0.00438118, ..., 0.9957142, 1.0]
    .map { $0 * Float(numberOfElements) }

Тогда результат будет (Скриншот из Quicklook result.map{ $0 } в Детская площадка):

enter image description here

...