Що таке алгоритм для повторної вибірки зі змінної швидкості до фіксованої?


27

У мене є датчик, який повідомляє про свої показання часовою позначкою та значенням. Однак він не генерує показань з фіксованою швидкістю.

Мені здається, що дані змінної ставки важко мати справу. Більшість фільтрів очікують фіксовану частоту вибірки. Малювання графіків простіше і з фіксованою частотою вибірки.

Чи існує алгоритм перевпорядкування від змінної частоти вибірки до фіксованої частоти вибірки?


Це перехресний пост від програмістів. Мені сказали, що це краще місце для запитання. programmers.stackexchange.com/questions/193795/…
FigBug

Що визначає, коли датчик повідомить про зчитування? Чи надсилає воно читання лише тоді, коли читання змінюється? Простим підходом було б вибрати "віртуальний інтервал вибірки" (T), який є лише меншим, ніж найкоротший час між згенерованими показаннями. На вході алгоритму зберігайте лише останнє повідомлене читання (CurrentReading). На виході алгоритму повідомляйте CurrentReading як «новий зразок» кожні T секунди, щоб фільтр або служба графіки отримувала показання з постійною швидкістю (кожні T секунди). Не маю уявлення, чи це адекватно у вашому випадку.
користувач2718

Він намагається взяти вибірку кожні 5 мс або 10 мс. Але це завдання з низьким пріоритетом, тому воно може бути пропущеним або затриманим. У мене термін точний до 1 мс. Обробка проводиться на ПК, а не в режимі реального часу, тому повільний алгоритм у порядку, якщо це легше здійснити.
FigBug

1
Ви подивилися на реконструкцію фур'є? Існує перетворення фур'є на основі нерівномірно вибірених даних. Звичайний підхід полягає в перетворенні зображення фур'є назад в рівномірну вибірку часової області.
mbaitoff

3
Чи знаєте ви якісь характеристики основного сигналу, який ви відбираєте? Якщо дані нерівномірно розміщених даних все ще знаходяться на досить високій частоті вибірки порівняно з пропускною здатністю сигналу, що вимірюється, то щось просте, як поліноміальна інтерполяція до рівномірно розташованої часової сітки може спрацювати нормально.
Jason R

Відповіді:


21

Найпростіший підхід - зробити якусь інтерполяцію сплайну, як пропонує Джим Клей (лінійний чи інший). Однак якщо у вас розкіш пакетної обробки, і особливо якщо у вас завищений набір неоднорідних зразків, існує надзвичайно елегантний алгоритм "ідеального відновлення". З чисельних причин це може бути не практично у всіх випадках, але про нього, принаймні, варто знати концептуально. Я вперше про це прочитав у цій статті .

Хитрість полягає в тому, щоб вважати ваш набір неоднорідних зразків таким, що вже був реконструйований з рівномірних зразків за рахунок синпокальної інтерполяції . Дотримуючись позначень у статті:

y(t)=k=1Ny(kT)sin(π(tkT)/T)π(tkT)/T=k=1Ny(kT)sinc(tkTT).

Зауважимо, що це надає набір лінійних рівнянь, по одному для кожного неоднорідного зразка , де невідомі є рівномірно розташованими зразками , наприклад:y ( k T )y(t)y(kT)

[y(t0)y(t1)y(tm)]=[sinc(t0TT)sinc(t02TT)sinc(t0nTT)sinc(t1TT)sinc(t12TT)sinc(t1nTT)sinc(tmTT)sinc(tm2TT)sinc(tmnTT)][y(T)y(2T)y(nT)].

У наведеному рівнянні - кількість невідомих рівномірних зразків, - обернена рівномірна швидкість вибірки, - кількість неоднорідних зразків (яка може бути більше ). Обчислюючи рішення найменших квадратів цієї системи, рівномірні зразки можна реконструювати. Технічно потрібні лише неоднорідних зразків, але залежно від того, наскільки вони "розкидані" в часі, інтерполяційна матриця може бути жахливо обумовлена . У такому випадку зазвичай допомагає використання більше неоднорідних зразків.T m n nnTmnn

Як приклад іграшки, ось порівняння (з використанням numpy ) між вищевказаним методом та інтерполяцією кубічної сплайну на м'яко тремтілій сітці:

Реконструкція нерівномірних зразків Сінк проти кубічної сплайну

(Код для відтворення вищевказаного сюжету міститься в кінці цієї відповіді)

Все, що було сказано, для якісних, надійних методів, починаючи з чогось в одному з наступних робіт, мабуть, буде більш доречним:

А. Олдрубі та Карлхенц Грохеніг, Неоднорідне відбір проб та реконструкція в інваріантних просторах зсуву , SIAM Rev., 2001, вип . 4, 585–620. ( посилання у форматі PDF ).

К. Гроченіг та Х. Шваб, Швидкі локальні методи реконструкції для неоднорідного відбору проб у просторах , що інвартують зсув , SIAM J. Matrix Anal. Appl., 24 (2003), 899-913.

-

import numpy as np
import pylab as py

import scipy.interpolate as spi
import numpy.random as npr
import numpy.linalg as npl

npr.seed(0)

class Signal(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def plot(self, title):
        self._plot(title)
        py.plot(self.x, self.y ,'bo-')
        py.ylim([-1.8,1.8])
        py.plot(hires.x,hires.y, 'k-', alpha=.5)

    def _plot(self, title):
        py.grid()
        py.title(title)
        py.xlim([0.0,1.0])

    def sinc_resample(self, xnew):
        m,n = (len(self.x), len(xnew))
        T = 1./n
        A = np.zeros((m,n))

        for i in range(0,m):
            A[i,:] = np.sinc((self.x[i] - xnew)/T)

        return Signal(xnew, npl.lstsq(A,self.y)[0])

    def spline_resample(self, xnew):
        s = spi.splrep(self.x, self.y)
        return Signal(xnew, spi.splev(xnew, s))

class Error(Signal):

    def __init__(self, a, b):
        self.x = a.x
        self.y = np.abs(a.y - b.y)

    def plot(self, title):
        self._plot(title)
        py.plot(self.x, self.y, 'bo-')
        py.ylim([0.0,.5])

def grid(n): return np.linspace(0.0,1.0,n)
def sample(f, x): return Signal(x, f(x))

def random_offsets(n, amt=.5):
    return (amt/n) * (npr.random(n) - .5)

def jittered_grid(n, amt=.5):
    return np.sort(grid(n) + random_offsets(n,amt))

def f(x):
    t = np.pi * 2.0 * x
    return np.sin(t) + .5 * np.sin(14.0*t)

n = 30
m = n + 1

# Signals
even   = sample(f, np.r_[1:n+1] / float(n))
uneven = sample(f, jittered_grid(m))
hires  = sample(f, grid(10*n))

sinc   = uneven.sinc_resample(even.x)
spline = uneven.spline_resample(even.x)

sinc_err   = Error(sinc, even)
spline_err = Error(spline, even)

# Plot Labels
sn = lambda x,n: "%sly Sampled (%s points)" % (x,n)
r  = lambda x: "%s Reconstruction" % x
re = lambda x: "%s Error" % r(x)

plots = [
    [even,       sn("Even", n)],
    [uneven,     sn("Uneven", m)],
    [sinc,       r("Sinc")],
    [sinc_err,   re("Sinc")],
    [spline,     r("Cubic Spline")],
    [spline_err, re("Cubic Spline")]
]

for i in range(0,len(plots)):
    py.subplot(3, 2, i+1)
    p = plots[i]
    p[0].plot(p[1])

py.show()

Хороший метод і код. Але для з кількома (наприклад, [0 1 - 3 4 5 - 7 8] T), що, на мою думку, є питанням ОП, чи не є sinc s у матриці всі 0? Звичайно, є способи це виправити, але. tj=jT
denis

Як я розумію, питання ОП стосується зразків, які випадають та / або затримуються. Цей метод в основному є лише завищеною системою рівнянь, тому відкинуті зразки виявляються лише як невідомі (а не як точки даних зі значенням 0). А може, це не те, про що ви питаєте?
datageist

Що станеться, якщо - цілі числа (T = 1)? Скажімо, у нас є точки даних [ ] для , набір ненульових цілих чисел, наприклад {-1 1} або {-2 -1 1 2}; не інтерпольований , незалежно від - чи я щось пропустив? tjj,yjjJy0=0yj
деніс

Якщо показники вибірки точно однакові (з / відсутні точки), то матриця інтерполяції буде рідкою (оскільки кожен вихід залежить лише від одного вводу). Загалом, середня частота вибірки неоднорідних зразків повинна бути більшою, ніж рівномірна норма реконструкції. Іншими словами, вам потрібно буде реконструювати з меншою швидкістю, щоб "заповнити прогалини" (T> 1 для вашого прикладу). Я бачу, але ваш погляд.
datageist

2
Такі відповіді - це чисте золото.
Ахмед Фасіх

6

Це звучить як проблема асинхронного перетворення швидкості вибірки. Для перетворення з однієї частоти вибірки в іншу ми можемо обчислити безперервне представлення сигналу за часом, виконавши синпокалізацію синхронізування, а потім перепробовувати за новою швидкістю вибірки. Те, що ви робите, не сильно відрізняється. Потрібно повторно проаналізувати сигнал, щоб мати фіксований час вибірки.

Сигнал безперервного часу може бути обчислений шляхом обертання кожного зразка функцією sinc. Оскільки функція sinc триває нескінченно, ми використовуємо щось більш практичне, як віконний синк практичної кінцевої довжини. Складна частина полягає в тому, що, оскільки ваші зразки рухаються в часі, для кожного зразка при повторному відборі може знадобитися синхронізація з різним зміщенням фази.

Постійний сигнал часу від вибіркового сигналу:

x(t)=n=x[n]sinc(tnTsTs)

де - ваш зразок часу. У вашому випадку, однак, час вибірки не визначено. Тому я думаю, що вам потрібно замінити його на час вибірки в цьому зразку.Ts

x(t)=n=x[n]sinc(tnTs[n]Ts[n])

Виходячи з цього, ви можете переутворювати сигнал:

y[n]=x(nTns )

де - бажаний час вибірки.Tns

Збираючи все це разом, ви отримуєте:

y[m]=n=x[n]sinc(mTnsnTs[n]Ts[n])

Оскільки це не є причинним або простежуваним, функція sinc може бути замінена функцією кінцевої підтримки та межі підсумовування відповідно відрегульовані.

Нехай ядро ​​(t) являє собою віконний sinc або іншу подібну функцію довжиною 2k тоді:

y[m]=n=kkx[n]kernel(mTnsnTs[n]Ts[n])

Я сподіваюся, що це допомагає ..., але я, можливо, помилився на цьому шляху, і це може бути трохи інтенсивним математикою. Я б рекомендував дослідити конверсію швидкості вибірки для отримання додаткової інформації. Можливо, хтось ще тут може дати краще пояснення чи рішення.


Використання функції sinc для реконструкції безперервної версії сигналу вимагає, щоб зразки були однаково розташовані, тому функція sinc повинна буде адаптуватися до вибіркового інтервалу вибірки. Це може бути досить складно здійснити.
користувач2718

так, це було б не дуже ефективно, як саме тут. Це вимагало б обчислення нових коефіцієнтів ядра для кожного різного часу вибірки. Однак може бути обчислена колекція декількох ядер, і час, квантований до одного з них. Буде досягнуто ефективність щодо помилки квантування.
Яків

Ви також можете попередньо обчислити одну таблицю пошуку синхронізації та інтерполювати між точками цієї таблиці пошуку.
jms

5

Я думаю, що відповідь Якова дуже доцільна.

Більш простий метод, який, мабуть, не дуже хороший з точки зору введення спотворень, - це робити поліноміальну інтерполяцію. Я б використовував або лінійну інтерполяцію (легка, не настільки хороша продуктивність сигналу), або кубічні сплайни (все ще не надто жорсткі, кращі показники сигналу) для отримання зразків у будь-який час, коли ви хочете, з ваших довільних проб часу.


1
Ви відповідаєте, здається, набагато простіше втілити в життя, ніж Якова, тому я пішов із цим першим. Здається, це працює, але я ще не пройшов повний набір тестів.
FigBug

1
@FigBug - Якщо у вас є час, додайте коментар, коли ви остаточне рішення.
користувач2718

2

(Місяць пізніше) є два основні варіанти для будь-якого методу інтерполяції:
1) кількість точок даних, найближчих до відсутньої точки використання, 2 4 6 ... 2) клас базових функцій, які слід використовувати: лінійний, поліном, синус-косинус (Фур'є), кубічно кубічний (B-сплайн або інтерполяційний сплайн), синкоподібний ... (Вибір 0 - чи використовувати чужий метод і код, або робити сам.)Nnear

пряму до точок легко: 2 бали [-1, ], [1, ]: оцінка бали із середнім значенням : середнє загальне : див., наприклад, Числові рецепти стор. 781: підходимо до рядка і оцінюємо . Один і той же спосіб може відповідати квадратикам, кубікам, синусоїнусам.Nnear
y1y1
[ x i , y i ] x i = 0y0(y1+y1)/2
[xi,yi]xi=0
y i [ x i , y i ]y0yi
[xi,yi]
y 0aa+bxy0a

Я розумію, що у вас рівномірно розміщені дані з пропущеними кількома точками, чи правильно?
Наскільки добре працює лінійна інтерполяція для цього випадку?
Що ж, давайте спробуємо cos з = 0,25: 1 0 -1 0 1 0 -1 0 ... 2 сусідів будь-якої точки в середньому до 0, жахливо. 4 сусіди: середній [1 0 (відсутній -1) 0 1] = 1/2, страшний. (Спробуйте цей фільтр із 4-сусідами [-1 3 3 -1] / 4.)f2πftf


Лінійна взаємодія з 4 або 6 або 8 сусідами може працювати досить добре для ваших даних.
Я б запропонував почати з методу, який ви добре розумієте перед тим, як зануритися в сплайни, подібні до синьків ... хоча це теж може бути цікавим.


Ще один, зовсім інший метод - зворотне зважування на відстані . Це легко здійснити (див. Idw-інтерполяція-з-python на SO), працює у 2d 3d і вище, але це важко теоретично проаналізувати.

(Очевидно, що НЕ єдиний метод інтерполяції, можливо, може відповідати зільйонам комбінацій
[сигнал, шум, метрика помилок, тестова функція], які виникають у реальності.
У світі існує більше методів, що мають більше ручок, ніж тестові функції.
Тим не менш галерея методів та тестових функцій можуть бути корисними.)


1

Якщо ви працюєте з matlab, ви можете це зробити, працюючи з таймері.

time  % is your starting vector of time

data % vector of data you want to resample 

data_TS = timeseries(data,time); % define the data as a timeseries 

new_time = time(0):dt:time(end); % new vector of time with fixed dt=1/fs

data_res = resample(data_TS,new_time); % data resampled at constant fs

0

Перш ніж займатись екзотичною обробкою, ви можете спробувати щось таке на кшталт цього (псевдо-код - ніякої інтерполяції, але це можна додати)

TimeStamp[]  //Array of Sensor TimeStamps -NULL terminated – TimeStamp[i] corresponds to Reading[i]
Reading[]      //Array of Sensor Readings       -NULL terminated

AlgorithmOut   //Delimited file of of readings in fixed sample time (5ms) 
CurrentSavedReading = Reading[0]

SampleTime=TimeStamp[0] //ms virtual sample time, 5ms fixed samples

i = 0 // loop index
While(TimeStamp[i] != NULL)
{
   FileWrite (CurrentSavedReading, AlgorithmOut)//write value to file
   SampleTime = SampleTime + 5//ms
   if(SampleTime > TimeStamp[i])
   {
      i++
      CurrentSavedReading = Reading[i]
   }
}

0

Відповідь дагеїста ІМХО правильна, відповідь Якова - ні. Простий спосіб переконатися в тому, що запропонований алгоритм datageist гарантується інтерполяцією через оригінальні зразки (припускаючи нескінченну числову точність), тоді як відповідь Якова не відповідає.

  • Для рівномірного випадку вибірки набір функцій sinc є ортогональним: якщо кожна зміщена функція sinc дискретизується над вхідними зразками, вони утворюють нескінченну матрицю ідентичності. Це тому, що sin (n pi) / (n pi) дорівнює нулю для всіх n, крім n = 0.
  • Однак цю властивість не можна просто екстраполювати на неоднорідний випадок: аналогічний набір функцій sinc, дискретизований над вхідними зразками, дасть нетривіальну матрицю. Отже, внески з навколишніх зразків не будуть нульовими, і реконструкція більше не буде інтерполюватись через вхідні вибірки.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.