回答:
コミュニティWikiが上位の質問の1つとしてこの質問が繰り返し表示されないことを期待して、別の質問(コメントで述べられている)への回答から改作されました。
線形(時不変)システムによるインパルス応答の「反転」はありません。線形時不変システムの出力は、「反転」インパルス応答ではなく、スケーリングされたバージョンと時間遅延されたバージョンのインパルス応答の合計です。
入力信号をスケーリングされた単位パルス信号の合計に分解します。システムユニットパルス信号に応答し あるインパルス応答またはパルス応答
同様に、単一入力値または は応答 への応答の遅延に注意して。この方法でさらに続行できますが、より表形式に切り替えて、さまざまな出力を時間内に適切に並べることをお勧めします。我々は持っています 、X [ 1 ] (⋯ 、0 、0 、0 、1 、0 、⋯ )= ⋯ 0 、0 、0 、X [ 1 ] 、0 、⋯ 0 、X [ 1 ] H [ 0 ] 、x [ 1 ] h [ 1 ] 、⋯ 、
時間での出力は何ですか?
その後、番目の列を合計して インパルス応答が「ひっくり返る」ように見える、または時間をさかのぼって実行されるため、世代を混乱させる最愛の畳み込み式。しかし、人々が忘れているように思われるのは、代わりに これにより、入力が「反転」または時間的に逆方向に実行されるようになります。言い換えれば、それは人間ですy [ n ]
インパルス応答を逆に使用せずに畳み込みを実行できることを示すC / C ++の例を次に示します。convolve_scatter()
関数を調べると、変数はどこでも無効になりません。これは、各入力サンプルがインパルス応答によって与えられた重みを使用して、メモリ内の複数の出力サンプルに分散(合計)される散乱畳み込みです。出力サンプルを何度も読み書きする必要があるため、これは無駄です。
通常、畳み込みは、次のように行われている収集のように、畳み込みをconvolve_gather()
。この方法では、重みとして逆インパルス応答を使用して、入力サンプルを収集(合計)することにより、各出力サンプルが個別に形成されます。出力サンプルは、これが行われている間、アキュムレータとして使用されるプロセッサのレジスタにあります。これは通常、選択された方法です。フィルター処理されたサンプルごとに1つのメモリ書き込みのみが行われるためです。現在、入力のメモリ読み取りが増えていますが、スキャッタリングメソッドの出力のメモリ読み取りと同数だけです。
#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
フィルターが時変でない限り、散乱法を使用している人を想像することはできません。
これは、ポイントごとの計算に対してのみ「反転」されます。
@Dilipは畳み込み積分/総和が何を表すかを説明しますが、2つの入力関数の1つ(多くの場合h(t)
)が計算目的で反転する理由を説明するために、入力x[n]
およびインパルス応答を持つ離散時間システムを考えますh[n]
:
あなたは可能性があなたの入力機能を取りx[n]
、そして各非ゼロのための*サンプルx[n]
試料からのインパルス応答をスケール計算n
し、タイムシフトまでにh[n]
(因果を想定し、ゼロまでダイスh[n]
)。これは、どちらかのNO「反転」(またはより正確に「時間反転」)を伴わないだろうx[n]
かh[n]
。ただし、最後に、各非ゼロのインパルス応答のこれらのスケーリングされた+シフトされた「エコー」をすべて追加/重ね合わせる必要がありますx[n]
。
x[0]
k
h[n]
x[n]
、ですx[0]h[0]
。次に、k
1 ずつインクリメントするh[n]
と、右の1つのタイムステップにシフトし、時間反転されたh[n]
sの2番目のエントリ(h[1]
)がの上に置かれx[0]
、乗算を待機します。これにより、以前の方法で行われていたのと同じようにx[0]h[1]
、time n=1
に目的の貢献が得られます。x[n]
h[n]
y[n]
インデックスc [n]では、a [n]とb [n]の畳み込みは次のようになります。
「c [n]はm + k = nになるようなすべての積の合計(a [k] b [m])なので、m = n-kまたはk = n-mです。裏返す必要があります。
そもそもなぜ畳み込みがこのように振る舞うのでしょうか?乗算多項式との接続のため。
2つの多項式を乗算すると、係数のある新しい多項式が生成されます。積多項式の係数は、畳み込みの動作を定義します。現在、信号処理では、伝達関数-ラプラス変換またはz変換はこれらの多項式であり、各係数は異なる時間遅延に対応しています。積と被乗数の係数を一致させると、「1つの表現の乗算は変換された表現の畳み込みに対応する」という事実が得られます。
畳み込み中、インパルス応答の「フリップ」はまったく発生する必要がありません...
ただし、位相の変化を防ぎたい場合は、信号をインパルス応答で畳み込み、次にインパルス応答を逆にして再畳み込み、位相効果をキャンセルすることができます。
オフライン処理では、最初の畳み込みの後に信号を簡単に反転させて、同じ結論に達することができます(コメントが示唆しているように)。