Перегортання імпульсної реакції в згортці


26

Під час згортання сигналу, чому нам потрібно перевертати імпульсну відповідь під час процесу?


5
Остання половина цієї відповіді може допомогти вам зрозуміти.
Діліп Сарват

3
Окрім читання чудової відповіді @ DilipSarwate, це гарна вправа взяти аркуш паперу та графічно обчислити вихід системи LTI шляхом додавання зміщених у часі та масштабованих версій імпульсного відгуку.
Дев

1
Зауважте, що ви можете перевернути будь-який аргумент - результат той самий.
wakjah

Відповіді:


29

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

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

Розбиваємо вхідний сигнал x на суму масштабованих одиничних імпульсних сигналів. Відповідь системи на одиничний імпульсний сигнал , 0, 0, 1, 0, 0, - імпульсна характеристика або імпульсна характеристика

h[0], h[1],, h[n],
і так далі властивість масштабування єдиного вхідного значення x[0]або, якщо ви віддаєте перевагу
x[0](, 0, 0, 1, 0, 0,)= 0, 0, x[0], 0, 0,
створює відповідь
x[0]h[0],  x[0]h[1],,  x[0]h[n],

Аналогічно, значення одного входу або створює x [ 1 ] ( , 0 , 0 , 0 , 1 , 0 , ) = 0 , 0 , 0 , x [ 1 ] , 0 , створює відповідь 0 , х [ 1 ] год [ 0 ] , х [ 1x[1]

x[1](, 0, 0, 0, 1, 0,)= 0, 0, 0, x[1], 0,
Зауважте затримку у відповіді на x [ 1 ] . Ми можемо продовжувати далі в цьому напрямку, але найкраще перейти на більш табличну форму і вчасно показати різні результати, вирівняні належним чином. Маємо час 0 1 2 n n + 1 x [
0,x[1]h[0],  x[1]h[1],,  x[1]h[n1],x[1]h[n]
x[1] Рядки у наведеному вище масиві є точно зменшеними та запізнілими версіями імпульсна відповідь, яка додається до відповідіyна вхідний сигналx. Але якщо ви задасте більш конкретне запитання типу
time012nn+1x[0]x[0]h[0]x[0]h[1]x[0]h[2]x[0]h[n]x[0]h[n+1]x[1]0x[1]h[0]x[1]h[1]x[1]h[n1]x[1]h[n]x[2]00x[2]h[0]x[2]h[n2]x[2]h[n1]x[m]000x[m]h[nm]x[m]h[nm+1]
yx

Який вихід у момент ?n

n

y[n]=x[0]h[n]+x[1]h[n1]+x[2]h[n2]++x[m]h[nm]+=m=0x[m]h[nm],
y[n]=x[n]h[0]+x[n1]h[1]+x[n2]h[2]++x[0]h[n]+=m=0x[nm]h[m],
n

4

Ось приклад C / C ++, який показує, що згортання можна зробити без використання імпульсної відповіді у зворотному напрямку. Якщо ви перевіряєте convolve_scatter()функцію, жодна змінна не заперечується ніде. Це згортання розсіювання, коли кожен вхідний зразок розсіюється (підсумовується) на декілька вихідних зразків у пам'яті, використовуючи ваги, задані імпульсним відгуком. Це марно, оскільки вихідні зразки потрібно буде прочитати та записати кілька разів.

Зазвичай згортання здійснюється як збір згортки, як у convolve_gather(). У цьому способі кожен вихідний зразок формується окремо, шляхом збору (підсумовування) до нього вхідних зразків, із зворотним імпульсним відгуком як вагами. Зразок виводу знаходиться в регістрі процесора, який використовується як акумулятор, поки це робиться. Зазвичай це метод вибору, тому що буде записано лише одну пам'ять на кожен відфільтрований зразок. Зараз існує більше зчитування пам'яті на вході, але лише стільки, скільки було зчитування пам'яті виводу в методі розсіювання.

#include <stdio.h>

const int Nx = 5; 
const int x[Nx] = {1, 0, 0, 0, 2};
const int Ny = 3; 
const int y[Ny] = {1, 2, 3};
const int Nz = Nx+Ny-1;
int z[Nz];

void convolve_scatter() { // z = x conv y
  for (int k = 0; k < Nz; k++) {
    z[k] = 0;
  }
  for (int n = 0; n < Nx; n++) {
    for (int m = 0; m < Ny; m++) {
      z[n+m] += x[n]*y[m]; // No IR reversal
    }
  }
}

void convolve_gather() { // z = x conv y
  for (int k = 0; k < Nz; k++) {
    int accu = 0;
    for (int m = 0; m < Ny; m++) {
      int n = k+m - Ny + 1;
      if (n >= 0 && n < Nx) {
        accu += x[n]*y[Ny-m-1]; // IR reversed here
      }
    }
    z[k] = accu;
  }
}

void print() {
  for (int k = 0; k < Nz; k++) {
    printf("%d ", z[k]);
  }
  printf("\n");
}

int main() {
  convolve_scatter();
  print();
  convolve_gather();
  print();
}

Він складається з послідовностей:

1 0 0 0 2
1 2 3

і використовуючи обидва виходи методу згортки:

1 2 3 0 2 4 6

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


Цікаво! Тож, який я остаточний висновок, мені цікаво побачити
Невдалий вчений

Ваша архітектурна турбота цікава. Враховуючи наявні кеші, інструкції SIMD (SSE, AVX) та багатоядерні архітектури, розсіяний метод здається більш підходящим для паралельних обчислень? Але я не провів детального аналізу, хоча ...
Fat32

@ Fat32 мені ні! Ви маєте на увазі, що накопичення в зборі згортки може стати вузьким місцем з декількома ядрами, що працюють на множення? Це можна пом'якшити, давши кожному ядру свій акумулятор і підсумовуючи їх наприкінці. Я думаю, що цей наклад не буде набагато порівняно з додатковими записами на пам'ять у розсіяній згортці.
Оллі Ніемітало

На самом деле я був більше стурбований , розсіяна ефективностями форми, ніж на збір формі bottleneck.My струму C фільтрацію коду (найбільш ймовірно) у вигляді збору, але коли справа доходить до ASM код я намагаюся писати їх в розширеннях SIMD SSE , які більш підходить до розсипаної форми. Однак я повинен оновити свої тети :-))) IO пам'яті, безумовно, є проблемою порівняно з накопиченням реєстру. І, напевно, мені не вистачає штрафу повторного IO пам'яті ...
Fat32

Хтось знає кращі слова, ніж розсипання та збирання? Я не впевнений, чи вони зарезервовані для ядер з обмеженою згорткою.
Оллі Ніемітало

3

Це лише "перевернуте" для точкового обчислення.

@Dilip пояснює, що являє собою інтеграл / підсумовування згортки, але для пояснення того, чому одна з двох вхідних функцій (часто h(t)) перевернута для цілей обчислення, розглянемо дискретно-часову систему з вхідним x[n]та імпульсним відгуком h[n]:

  • Ви можете взяти свою функцію введення x[n]і для кожного ненульового * зразка x[n]обчислити масштабовану імпульсну відповідь від вибірки nі далі, поки зміщений час не h[n]знизиться до нуля (припускаючи причину h[n]). Це передбачає відсутність "перегортання" (або точніше "зміни часу" жодного x[n]або h[n]. Однак наприкінці вам доведеться додати / накласти всі ці масштабовані + зміщені 'відлуння' імпульсної відповіді для кожного ненульового x[n].

  • x[0]k

    k=x[k]h[nk]
    h[n]x[n], який є x[0]h[0]. Потім приріст kна один зміститься h[n]вправо на один крок часу, таким чином, що h[n]другий запис ( h[1]), повернутий за часом ( ) тепер буде лежати на вершині x[0], чекаючи його множення. Це дасть бажаний внесок x[0]h[1]у часі так n=1само, як це було б зроблено в попередньому методі.

x[n]

x[n]=0
h[n]y[n]

n

@Dilip. Усі n однакові, за винятком 'зрушеного часу h [n]', що означає 'h [nk]', де 'k' є константа, що використовується для перенесення імпульсної відповіді на потрібну точку сигналу x [n ]. тобто: h [n-2] для обчислення відповіді на сигнал при x [2].
abc

3

В індексі c [n] згортка [n] і b [n] така, що:

"c [n] - це підсумок всіх добутків (a [k] b [m]) таким, що m + k = n", тому m = n - k або k = n - m, що означає, що одна з послідовностей доводиться перевертати.

Тепер, чому згортання поводиться саме так? Через його зв’язок з множеннями многочленів.

Помноження двох многочленів призводить до появи нового многочлена з коефіцієнтами. Коефіцієнти многочлена продукту визначають операцію згортки. Тепер, в обробці сигналів, функції передачі - перетворення Лапласа або z-перетворення - це поліноми, кожен з коефіцієнтів яких відповідає різній затримці в часі. Відповідність коефіцієнтів продукту та множників призводить до того, що "множення в одному представленні відповідає згортці в перетвореному поданні".

введіть тут опис зображення


0

Під час згортання взагалі не повинно відбуватися "перевертання" імпульсної реакції ...

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

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


3
y(t)=x(τ)h(tτ)dτh(t)x(t)h(t)=h(t)x(t)

@JasonR Ах, ну! Іноді важко зрозуміти, до чого стикається питання. Іжак, як тільки ти зрозумієш відповідь, яку ти шукав, ти зрозумієш, куди я йшов. Ігноруйте мене поки що!
Learnvst

0

f(τ)g(tτ)dτ
t1+t2=tf(t1)g(t2)dt1dt2
fтgt

Тепер форма ручного розмахування чітко показує симетрію, яка тут задіяна, і жодне "перегортання" не пов'язане. Перетворення цього в належний одновимірний інтеграл вимагає зробити один з двох аргументів фактичною змінною інтеграції. Це або пошук жорсткої симетричної форми, що не передбачає рукоділля. Останнє хитріше. В основному, вам потрібно повернути нормалізацію, створивши щось (при використанні функції / розподілу дельти Дірака), наприклад Якщо потім переставити в один бік, ви отримаєте і від властивості просіювання оператора Dirac t 1 f ( t 1 )

t1,t2f(t1)g(t2)δ(tt1t2)dt1dt2
t 1 f ( t 1 )
t1f(t1)dt1t2g(t2)δ(tt1t2)dt2
t1f(t1)dt1g(tt1)
що є оригінальним інтегралом з трохи перейменуванням.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.