7.4 離散的コサイン変換 (DCT : discrete cosine transform )

6.5 アダマール(Hadamard)変換
(1)アダマール変換とは
乗算を使わず加算と減算だけで実行できる直交変換
1896年,素数定理の証明で有名なフランス人
Jacques Salomon Hadamardの名前からこう呼ばれる。
日本では,符号理論の「アダマール変換の発案者として有名。
(注)
「Hadamard」はハダマルドと読みそうだが,
フランス人の名前なので「アダマール」と読もう。
また,アダマール行列は,
ウォルシュ(Walsh)関数を標本化したものとみなすことができるので,
ウォルシュ・アダマール変換(WHT:Walsh Hadamard Transform)と
呼ばれることもある。
(2)変換のためのアダマール行列の定義
以下のように再帰的に定義される。
 H (k ) H (k ) 
H (0)  1, H (k  1)  

 H (k )  H (k )
(例)
H (1)
H (1) 
 H (1) H (1)
H (2)  H (1)  H (1) H (1)  H (1)
 H ( 2)
H (3)  
   H (1) H (1)  H (1)  H (1)
H
(
2
)

H
(
2
)




H
(
1
)

H
(
1
)

H
(
1
)
H
(
1
)


1 1 1 1 1 1 1 1
1  1 1  1 1  1 1  1


1 1  1  1 1 1  1  1


1

1

1
1
1

1

1
1


1 1 1 1  1  1  1  1


1

1
1

1

1
1

1
1


1 1  1  1  1  1 1 1


1

1

1
1

1
1
1

1


(3)符号変化の回数
符号変化の回数が少ない順に並べる行列を使用する。
(例)
1
1

1

1

H (3) 
1

1
1

1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
波形としてCos波の変わりに
矩形波を使っていると考えることができる。
1
 1
1

 1
1

 1
1

 1
(4)アダマール変換の定義
次のような行列式として定義される。
X (k )  H (M ) x[n]
逆アダマール変換
1
x ( n)  H ( M ) X [ n]
N
VBAでの記述 ①データ宣言とパルス信号の設定
(色々な信号を設定してみよう)
Private
Private
Private
Private
Private
Private
Const Num = 8
Const PI = 3.12159265358979
X(Num) As Double
Y(Num) As Double
Z(Num) As Double
HMat(8, 8) As Double
Private Sub パルス()
For K = 0 To Num - 1
X(K) = -1
If K >= 3 And K <= 5 Then X(K) = 1
Next
X(Num) = X(0)
End Sub
VBAでの記述 ②結果設定とボタンのCLICKイベントハンドラ
Private Sub 結果設定()
With Worksheets("Sheet3")
.Cells(1, 1) = "No.": .Cells(1, 2) = "X"
.Cells(1, 3) = "Y":
.Cells(1, 4) = "Z"
For K = 0 To Num
.Cells(K + 2, 1) = K:
.Cells(K + 2, 2) = X(K)
.Cells(K + 2, 3) = Y(K): .Cells(K + 2, 4) = Z(K)
Next
End With
End Sub
Sub Sheet3_ボタン1_Click()
パルス
set8HMAT
HT
IHT
結果設定
End Sub
VBAでの記述 ③8行8列のアダマール行列設定(その1)
Private Sub set8HMAT()
For I = 0 To 7
HMat(0, I) = 1
Next
For I = 0 To 7
V = 1
If I >= 4 Then V = -1
HMat(1, I) = V
Next
For I = 0 To 7
V = 1
If I >= 2 And I <= 5 Then V = -1
HMat(2, I) = V
Next
For I = 0 To 7
V = 1
If I = 2 Or I = 3 Or I = 6 Or I = 7 Then V = -1
HMat(3, I) = V
Next
VBAでの記述 ④8行8列のアダマール行列設定(その2)
For I = 0 To 7
V = 1
If I = 1 Or I =
HMat(4, I) = V
Next
For I = 0 To 7
V = 1
If I = 1 Or I =
HMat(5, I) = V
Next
For I = 0 To 7
V = 1
If I = 1 Or I =
HMat(6, I) = V
Next
For I = 0 To 7
V = 1
If (I Mod 2) <>
HMat(7, I) = V
Next
End Sub
2 Or I = 5 Or I = 6 Then V = -1
2 Or I = 4 Or I = 7 Then V = -1
3 Or I = 4 Or I = 6 Then V = -1
0 Then V = -1
VBAでの記述 ⑤アダマール変換と逆アダマール変換
Private Sub HT() 'Hadamard変換
For I = 0 To Num - 1
Y(I) = 0
For J = 0 To Num - 1
Y(I) = Y(I) + HMat(I,J)* X(J)
Next
Next
Y(Num) = Y(0)
End Sub
Private Sub IHT() '逆Hadamard変換
For I = 0 To Num - 1
Z(I) = 0
For J = 0 To Num - 1
Z(I) = Z(I) + HMat(I,J) *Y(J)
Next
Next
Z(Num) = Z(0)
For I = 0 To Num
Z(I) = Z(I) / Num
Next
End Sub
Hmat(I,J)は
-1または1なので
加算と減算に
置き換えることができる。
(5)確認
(6)高速アダマール変換
FFTと同様,時間間引き等による高速HTが可能である。
第1ステップ
第2ステップ
第3ステップ
g[0]
G[0]
g[4]
G[1]
-1
G[2]
g[2]
-1
g[6]
g[1]
g[5]
-1
G[3]
-1
-1
-1
g[3]
-1
g[7]
-1
G[4]
-1
G[5]
-1
-1
G[6]
-1
G[7]
VBAでの記述 ①FHT(その1)
(その他のプログラムはHTと同じ)
Private Sub FHT() 'Hadamard変換)
For i = 0 To Num
Y(i) = X(i)
Next
'ビット逆順の並び替え
For J = 0 To Num - 1
JP = J: JX = 0: k = 1
Do While k < Num
MD = JP Mod 2
JX = JX * 2 + MD
JP = JP \ 2
k = k * 2
Loop
If J < JX Then
temp = Y(J): Y(J) = Y(JX): Y(JX) = temp
End If
Next
VBAでの記述 ②FHT(その2)
'FHTの計算
n_half = Num \ 2: Ne = 1
Do While Ne < Num
符号 = 1
n_half2 = n_half * 2
For JP = 0 To Num - 1 Step n_half2
JX = 0
For J = JP To JP + n_half - 1
jnh = J + n_half
xtmp = 符号 * Y(jnh)
Y(jnh) = Y(J) - xtmp
Y(J) = Y(J) + xtmp
JX = JX + Ne
Next
符号 = -符号
Next
n_half = n_half \ 2
Ne = Ne * 2
Loop
Y(Num) = Y(0)
End Sub
VBAでの記述 ③IFHT(その1)
Private Sub IFHT() '逆Hadamard変換
For i = 0 To Num
Z(i) = Y(i)
Next
'ビット逆順の並び替え
For J = 0 To Num - 1
JP = J: JX = 0: k = 1
Do While k < Num
MD = JP Mod 2
JX = JX * 2 + MD
JP = JP \ 2
k = k * 2
Loop
If J < JX Then
temp = Z(J): Z(J) = Z(JX): Z(JX) = temp
End If
Next
'FHTの計算
n_half = Num \ 2: Ne = 1
Do While Ne < Num
VBAでの記述 ④IFHT(その2)
Do While Ne < Num
符号 = 1
n_half2 = n_half * 2
For JP = 0 To Num - 1 Step n_half2
JX = 0
For J = JP To JP + n_half - 1
jnh = J + n_half
xtmp = 符号 * Z(jnh)
Z(jnh) = Z(J) - xtmp
Z(J) = Z(J) + xtmp
JX = JX + Ne
Next
符号 = -符号
Next
n_half = n_half \ 2
Ne = Ne * 2
Loop
Z(Num) = Z(0)
For i = 0 To Num
Z(i) = Z(i) / Num
Next
End Sub
FHT結果