1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ヒルベルト=シュミット型の内積

Last updated at Posted at 2016-04-11

前置き

行列もベクトル空間の定義を満たすので、ベクトルと見なすことが出来ます。Fortranに慣れていれば、多次元配列はメモリーに1次元に並んでいるだけなので、行列を一本のベクトルと見なすこと有りかなと納得できると思います。

そうなると、行列に内積を考えて、ただのベクトル空間から計量ベクトル空間に進みたい気持ちも湧いてくるというものです。ヒルベルト=シュミット型の内積は、そういう二つの行列の間の内積です。定義は、

<A|B>={\rm Tr}(A^*B)

のようになっています。ここで$A^*$は行列$A$のエルミート共役です。

これは、見かけは面倒ですが、実際は行列$A$の複素共役と行列$B$の対応する各成分の積の和になります。つまり、行列を一次元ベクトルにしたとき、普通のベクトルの内積と一致します。

{\rm Tr}(A^*B)=\sum_{i, j}(\bar{A}_{i,j})({B}_{i,j})

成分で書いてある方が単純ですが、Trace を使って書いてあると結果が基底に依らないことが明白になって、好ましいと思われます。

計算での確認

プログラム

    module m_subs
      implicit none
    contains 
      complex function Hilbert_Schmidt(c, d) 
        complex, intent(in) :: c(:, :), d(:, :)
        Hilbert_Schmidt = trace(matmul(Hermitian_Conjugate(c), d))
      end function Hilbert_Schmidt
     
      function Hermitian_Conjugate(c)
        complex, intent(in) :: c(:, :)
        complex, allocatable :: Hermitian_Conjugate(:, :)
        Hermitian_Conjugate = transpose(conjg(c))
      end function Hermitian_Conjugate  
      
      complex function trace(c)
        complex, intent(in) :: c(:, :)
        integer :: i
        trace = sum( [(c(i, i), i = 1, size(c, 1))] )
      end function trace
    end module m_subs
    
    program HS
      use m_subs
      implicit none
      integer, parameter :: n = 10
      complex :: a(n, n), b(n, n), c, d, e
      complex, allocatable :: s(:), t(:)
      real :: x(n, n), y(n, n)
      call random_seed()
      call random_number(x)
      call random_number(y)
      a = cmplx(x, y)
      call random_number(x)
      call random_number(y)
      b = cmplx(x, y)
      s = reshape(a, [size(a)]) ! 1-dimensional array of size n^2
      t = reshape(b, [size(b)]) ! 1-dimensional array of size n^2
      
      c = Hilbert_Schmidt(a, b) ! Trace(A* B)
      d = sum(conjg(a) * b)     ! sum (A_ij)* (B_ij)
      e = dot_product(s, t)     ! inner-product(A, B) 
      print *, c, d, abs(c - d) / abs(c)
      print *, d, e, abs(d - e) / abs(d)
    end program HS

実行結果

乱数で行列を生成しているので複数回実行してみます。単精度の範囲で結果が一致しているのが分かります。

 (51.86407,-2.380983) (51.86405,-2.380983) 2.9404126E-07
 (51.86405,-2.380983) (51.86405,-2.380983) 0.000000
続行するには何かキーを押してください . . .

 (54.13935,4.021431) (54.13936,4.021432) 2.8161699E-07
 (54.13936,4.021432) (54.13936,4.021432) 0.000000
続行するには何かキーを押してください . . .

 (48.62010,5.180973) (48.62009,5.180972) 7.8624716E-08
 (48.62009,5.180972) (48.62009,5.180972) 0.000000
続行するには何かキーを押してください . . .
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?