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結果
© Copyright 2024 ExpyDoc