Mae向きなブログ

Mae向きな情報発信を続けていきたいと思います。

Rubyのソースコードからエルミート行列を調べる

RubyリファレンスマニュアルのMarixクラスを眺めると、Matrix#hermitian? の説明には

行列がエルミートならば真を返します。

とあります。エルミートって習った記憶はあるのですが、どんなものなのか忘れてしまいました。こんなときは線形代数の教科書で調べるなどといった方法があると思うのですが、以前、「pry-docでカジュアルにRubyのソースコードを読む - Qiita」という記事があったことを思い出したので Matrix#hermitian? のソースコードからエルミートを理解してみようと試しにやってみました。

$ pry -rmatrix
[1] pry(main)> show-source Matrix#hermitian?

From: /Users/foo/.rbenv/versions/2.1.0/lib/ruby/2.1.0/matrix.rb @ line 617:
Owner: Matrix
Visibility: public
Number of lines: 6

def hermitian?
  Matrix.Raise ErrDimensionMismatch unless square?
  each_with_index(:upper).all? do |e, row, col|
    e == rows[col][row].conj
  end
end

これを見ると、正方行列(square?)で、行列の対角成分とそれより上側の部分(:upper)全て(all?)を調べたときに、

e == rows[col][row].conj

が成り立つときが、エルミートであるということが分かります。Complex#conjメソッドは、共役複素数を返すメソッドなので、エルミート行列とは、
\left(\begin{array}{cc}-2 & 8-3i \\8+3i & 4 \\\end{array}\right)
のような行列のことなんですね。以下のように実際に試してみると、確かにtrueが返ってきました。

[2] pry(main)> mat = Matrix[[-2, 8-3i],[8+3i,4]]
=> Matrix[[-2, (8-3i)], [(8+3i), 4]]
[3] pry(main)> mat.hermitian?
=> true

ちなみに、Complex#conj のソースコードを調べてみると、以下のように表示されます。虚部の符号を入れ替えている(f_negate)様子が見て取れます。

[4] pry(main)> show-source Complex#conj

From: complex.c (C Method):
Owner: Complex
Visibility: public
Number of lines: 6

static VALUE
nucomp_conj(VALUE self)
{
    get_dat1(self);
    return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}