跳轉到內容

數字訊號處理/離散運算

來自華夏公益教科書

在離散資料集上可以執行許多不同的操作。

假設我們有兩個資料集,A[n] 和 B[n]。我們將定義這兩個集合具有以下值

A[n] = [W X& Y Z]
B[n] = [I J& K L]

離散資料集上的算術運算以逐項方式執行。以下是一些示例

A[n] + B[n] = [(W+I) (X+J)& (Y+K) (Z+L)]

如果零位置沒有對齊(就像我們示例中方便地對齊的那樣),我們需要在加法之前手動對齊零位置。

A[n] - B[n] = [(W-I) (X-J)& (Y-K) (Z-L)]

與加法相同,只是我們減去。

在這種情況下,我們使用“星號”(*) 來表示乘法。實際上,我們應該使用“" 符號來表示乘法。在後面的示例中,我們將使用星號進行其他操作。

A[n] * B[n] = [(W*I) (X*J)& (Y*K) (Z*L)]
A[n] / B[n] = [(W/I) (X/J)& (Y/K) (Z/L)]

儘管我們使用方括號來表示離散資料集,但它們不應該與矩陣混淆。這些不是矩陣,我們不會對這些集合執行矩陣運算。

時間移位

[編輯 | 編輯原始碼]

如果我們對離散資料集進行時間移位,我們實際上是在移動集合的零時間參考點。零點表示“現在”,建立我們對資料的檢視的起點,並且該點的定位通常由我們參與的處理的需要決定。

假設我們具有資料集 F[n],其值如下

F[n] = [1 2 3& 4 5 ]

那麼我們可以將此集合向後移位 1 個數據點,如下所示

F[n-1] = [1 2& 3 4 5]

我們可以以類似的方式將資料向前移位 1 個數據點

F[n+1] = [1 2 3 4& 5]

離散資料值是時間定向的。零點右側的值稱為“未來值”,左側的值稱為“過去值”。當資料集填充在零參考點的兩側時,“未來”和“過去”是相對於零點“現在”的合成術語,並不指當前的物理時間。在這種情況下,資料值已經收集完畢,因此只能來自我們的過去。

重要的是要了解,正在接收資料的可實現的數字系統無法對未來值執行操作。要求未來值才能進行計算是沒有意義的,因為這些系統通常從感測器即時獲取輸入,而未來值根本不存在。

時間反轉

[編輯 | 編輯原始碼]

假設我們有相同的資料集 F[n]

F[n] = [1 2 3& 4 5]

我們可以將資料集反轉,如下所示

F[-n] = [5 4 3& 2 1]

我們保持零點的位置不變,並將所有資料項翻轉過來。從本質上講,我們正在對資料集進行映象,而零點是映象。

此操作可以使用以下 MATLAB 命令執行
conv

在離散時間域中,卷積操作比在連續時間域中容易得多。假設我們有兩個資料集,A[n] 和 B[n]

A[n] = [1& 0 1 2]
B[n] = [2& 2 2 1]

在本節中,我們將使用星號 (*) 來表示卷積;它在這裡不表示“乘法”。我們的卷積函式顯示如下

Y[n] = A[n] * B[n]

它指定我們將卷積值儲存在名為 Y[n] 的集合中。

卷積是透過遵循一系列涉及兩組資料點的步驟來執行的。首先,我們將其中一個數據集進行時間反轉。哪個資料集無關緊要,因此我們可以選擇最簡單的選項

A[n]  = [1& 0 1 2]
B[-n] = [1 2 2 2&]

接下來,我們將資料垂直對齊,以使只有一個數據項重疊

A[n]  ->       [1& 0 1 2]
B[-n] -> [1 2 2 2&]

現在,我們將對兩個集合進行零填充,使它們長度相等,根據需要在空位置中填入零

A[n]  -> [0 0 0 1& 0 1 2]
B[-n] -> [1 2 2 2& 0 0 0]

現在,我們將對每列的內容進行乘法,然後將它們加在一起

A[n]  -> [0 0 0 1& 0 1 2]
B[-n] -> [1 2 2 2& 0 0 0]
Y[m] = 

這將為我們提供第一個資料點:Y[m] = [2]。

接下來,我們需要將 B[-n] 在時間上向前移位一個點,並執行相同的過程:將各列相乘,然後加起來

A[n]    -> [0 0 0 1& 0  1 2]
B[-n-1] ->   [1 2 2  2& 0 0 0]
Y[m+1] = 

重複“時間移位、乘法和加法”步驟,直到不再有資料點重疊。

A[n]    -> [0 0 0 1& 0 1  2]
B[-n-2] ->     [1 2  2 2& 0 0 0]
Y[m+2] = 
A[n]    -> [0 0 0 1& 0 1 2]
B[-n-3] ->       [1  2 2 2& 0 0 0]
Y[m+3] = 
A[n]    -> [0 0 0 1& 0 1 2]
B[-n-4] ->          [1 2 2 2& 0 0 0]
Y[m+4] = 
A[n]  -> [0 0 0 1& 0 1 2]
B[-n] ->            [1 2 2 2& 0 0 0]
Y[m+5] = 
A[n]    -> [0 0 0 1& 0 1 2]
B[-n+6] ->              [1 2 2 2& 0 0 0]
Y[m+6] = 

現在,我們擁有了完整的資料集 Y[m]

Y[m] = [2 2 4 7 6 5 2]

我們擁有了值,但是我們將零點放在哪裡?事實證明,結果的零點出現在兩個運算元的零點在我們移位計算中重疊的位置。結果集變為

Y[n] = [2& 2 4 7 6 5 2]

重要的是要注意,結果集的長度等於未填充運算元長度的總和減 1。或者,如果您願意,結果集的長度與任何一個零填充集相同(因為它們長度相等)。

Matlab/Octave 中的離散運算

[編輯 | 編輯原始碼]

所有這些離散運算都可以在 Matlab 中使用特殊運算子執行。

除法和乘法
Matlab 基於矩陣,因此正常的乘法和除法運算將是矩陣運算,這不是我們在 DSP 中想要做的。要按項進行乘法,我們需要在運算子前面加上一個句點。例如
Y = X .* H  %X times H 
Y = X ./ H  %X divided by H

如果我們忘記了句點,Matlab 將嘗試執行矩陣運算,並提醒您矩陣的維度與運算子不相容。

卷積
可以使用 Matlab 中的 conv 命令執行卷積運算。例如,如果我們要計算 X[n] 和 H[n] 的卷積,我們將使用以下 Matlab 程式碼
Y = conv(X, H);

Y = conv(H, X);

差分微積分

[編輯 | 編輯原始碼]

在處理離散集時,您可能想知道我們究竟如何在離散時間域中執行微積分。實際上,我們應該質疑我們所知的微積分是否可能!事實證明,在離散時間域中,我們可以使用多種技術來逼近微分的微積分運算和積分。我們將這些技術稱為 差分微積分

微分到底是什麼?在連續時間域中,函式的導數是函式在任何給定時間點的斜率。因此,要找到離散時間訊號的導數,我們需要找到離散資料集的斜率。

離散時間域中的資料點可以被視為幾何點,並且我們知道任何兩點都定義一條唯一的直線。然後,我們可以使用代數方程來求解直線的斜率 m

現在,在離散時間域中,f(t) 被取樣並替換為 F[n]。我們還知道,在離散時間中,任何兩個點之間的時間差恰好為 1 個時間單位!考慮到這一點,我們可以將這些值代入上面的公式

或者簡化為

然後我們可以將整個公式向左移動一個點,這樣我們的公式就不需要任何未來值了

導數可以透過從自身中減去時間移動(延遲)版本的函式來找到。

差分演算方程

[edit | edit source]

差分演算方程是算術方程,有幾個關鍵組成部分。讓我們舉個例子

我們可以看到,在這個公式中,X[n-1] 的係數為 2,X[n-2] 的係數為 5。在差分演算中,係數被稱為“抽頭權重”。我們將在後面的關於數字濾波器的章節中瞭解為什麼它們被稱為抽頭權重。

華夏公益教科書