アダマール行列(N = 2^kのときのみ)

StautnerとPucketteが提案したFeedback Delay Networkという人工リバーブがあります。このFDNを実装するときに必要になるものに、N×Nの行列があります。これを行列Gとしたとき、各要素g_{i,j}はディレイラインiからディレイラインjへのフィードバック・ゲインが入っています。この行列はいろいろと選択肢があるのですが、J. Smithによると「アダマール行列も使えるよ」ということでした。

MaxやPureDataでFDNを実装するときにアダマール行列が欲しかったので、Juliaで計算したものを入力して使おうと思いました。ただ、MatlabOctaveにあるようなhadamard関数がJuliaにはなかったので、作りました。参考にしたのはWikipediaに載っていた“他の生成法”MatlabだとN=2k * pでp=1, 12, 20, 28のときの計算ができるけど、とりあえず今回はp=1のときだけ。

"""
    hadamard(n)

Compute the Hadamard matrix of size `n`-by-`n`.
`n` must be a positive integer of power of 2.
"""
function hadamard(n)
  function hadamardF(n)
    if n <= 1
      return [0 1];
    else
      return [zeros(1, 2^(n-1))   ones(1, 2^(n-1))
              hadamardF(n-1)      hadamardF(n-1)];
    end
  end
  
  F = hadamardF(floor(Int, log2(n)));
  FF = F' * F;
  FF[(FF .% 2) .== 1] .= -1;
  FF[(FF .% 2) .== 0] .= 1;
  return map(Int, FF);
end

以下のように使えます。

julia> hadamard(4)
4×4 Array{Int64,2}:
 1   1   1   1
 1  -1   1  -1
 1   1  -1  -1
 1  -1  -1   1

ただ、アダマール行列を計算するプログラムはすでに色々とあります。上記のコードよりもっと高機能なものが以下のリンク先にあるので、それを使うのもよいですね。

nemocas.org

github.com