計算ルーチン: 4つの複素部分行列に区分けされたユニタリ行列の CS 分解

LAPACKサンプルソースコード : 使用ルーチン名:ZUNCSD

ホーム > LAPACKサンプルプログラム目次 > 計算ルーチン > 4つの複素部分行列に区分けされたユニタリ行列の CS 分解

概要

本サンプルはFortran言語によりLAPACKルーチンZUNCSDを利用するサンプルプログラムです。

入力データ

(本ルーチンの詳細はZUNCSD のマニュアルページを参照)

このデータをダウンロード
ZUNCSD Example Program Data

   6        2       4        : m    p    q

 ( -1.3038E-02, -3.2597E-01)
 (  4.2764E-01, -6.2582E-01)
 ( -3.2597E-01,  1.6428E-01)
 (  1.5906E-01, -5.2151E-03)
 ( -1.7210E-01, -1.3027E-02)
 ( -2.6336E-01, -2.4772E-01) : column 1 of unitary matrix X

 ( -1.4039E-01, -2.6167E-01)
 (  8.6298E-02, -3.8174E-02)
 (  3.8163E-01, -1.8219E-01)
 ( -2.8207E-01,  1.9734E-01)
 ( -5.0942E-01, -5.0319E-01)
 ( -1.0861E-01,  2.8474E-01) : column 2 of unitary matrix X

 (  2.5177E-01, -7.9789E-01)
 ( -3.2188E-01,  1.6112E-01)
 (  1.3231E-01, -1.4563E-02)
 (  2.1598E-01,  1.8813E-01)
 (  3.6488E-02,  2.0319E-01)
 (  1.0906E-01, -1.2712E-01) : column 3 of unitary matrix X

 ( -5.0956E-02, -2.1750E-01)
 (  1.1979E-01,  1.6319E-01)
 ( -5.0671E-01,  1.8612E-01)
 ( -4.0163E-01,  2.6787E-01)
 (  1.9271E-01,  1.5574E-01)
 ( -8.8179E-02,  5.6169E-01) : column 4 of unitary matrix X

 ( -4.5947E-02,  1.4052E-04)
 ( -8.0311E-02, -4.3611E-01)
 (  5.9714E-02, -5.8970E-01)
 ( -4.6443E-02,  3.0864E-01)
 (  5.7843E-01, -1.2439E-01)
 (  1.5763E-02,  4.7130E-02) : column 5 of unitary matrix X

 ( -5.2773E-02, -2.2492E-01)
 ( -3.8117E-02, -2.1907E-01)
 ( -1.3850E-01, -9.0941E-02)
 ( -3.7354E-01, -5.5148E-01)
 ( -1.8818E-02, -5.5686E-02)
 (  6.5007E-01,  4.9173E-03) : column 6 of unitary matrix X

出力結果

(本ルーチンの詳細はZUNCSD のマニュアルページを参照)

この出力例をダウンロード
 ZUNCSD Example Program Results

     Unitary matrix X
                    1                 2                 3                 4
 1  (-0.0130,-0.3260) (-0.1404,-0.2617) ( 0.2518,-0.7979) (-0.0510,-0.2175)
 2  ( 0.4276,-0.6258) ( 0.0863,-0.0382) (-0.3219, 0.1611) ( 0.1198, 0.1632)
 3  (-0.3260, 0.1643) ( 0.3816,-0.1822) ( 0.1323,-0.0146) (-0.5067, 0.1861)
 4  ( 0.1591,-0.0052) (-0.2821, 0.1973) ( 0.2160, 0.1881) (-0.4016, 0.2679)
 5  (-0.1721,-0.0130) (-0.5094,-0.5032) ( 0.0365, 0.2032) ( 0.1927, 0.1557)
 6  (-0.2634,-0.2477) (-0.1086, 0.2847) ( 0.1091,-0.1271) (-0.0882, 0.5617)
 
                    5                 6
 1  (-0.0459, 0.0001) (-0.0528,-0.2249)
 2  (-0.0803,-0.4361) (-0.0381,-0.2191)
 3  ( 0.0597,-0.5897) (-0.1385,-0.0909)
 4  (-0.0464, 0.3086) (-0.3735,-0.5515)
 5  ( 0.5784,-0.1244) (-0.0188,-0.0557)
 6  ( 0.0158, 0.0471) ( 0.6501, 0.0049)


 Theta Component of CS factorization of X:

     Theta
          1
 1   0.1973
 2   0.5387


 Components of CS factorization of X:

     Theta
          1
 1   0.1973
 2   0.5387


     Recombined matrix X = U * Sigma_p * V^H
                    1                 2                 3                 4
 1  (-0.0130,-0.3260) (-0.1404,-0.2617) ( 0.2518,-0.7979) (-0.0510,-0.2175)
 2  ( 0.4276,-0.6258) ( 0.0863,-0.0382) (-0.3219, 0.1611) ( 0.1198, 0.1632)
 3  (-0.3260, 0.1643) ( 0.3816,-0.1822) ( 0.1323,-0.0146) (-0.5067, 0.1861)
 4  ( 0.1591,-0.0052) (-0.2821, 0.1973) ( 0.2160, 0.1881) (-0.4016, 0.2679)
 5  (-0.1721,-0.0131) (-0.5094,-0.5032) ( 0.0365, 0.2032) ( 0.1927, 0.1557)
 6  (-0.2634,-0.2477) (-0.1086, 0.2847) ( 0.1091,-0.1271) (-0.0882, 0.5617)
 
                    5                 6
 1  (-0.0459, 0.0001) (-0.0528,-0.2249)
 2  (-0.0803,-0.4361) (-0.0381,-0.2191)
 3  ( 0.0597,-0.5897) (-0.1385,-0.0909)
 4  (-0.0464, 0.3086) (-0.3735,-0.5515)
 5  ( 0.5784,-0.1244) (-0.0188,-0.0557)
 6  ( 0.0158, 0.0471) ( 0.6501, 0.0049)

ソースコード

(本ルーチンの詳細はZUNCSD のマニュアルページを参照)

※本サンプルソースコードのご利用手順は「サンプルのコンパイル及び実行方法」をご参照下さい。


このソースコードをダウンロード
    Program zuncsd_example

!     ZUNCSD Example Program Text

!     Copyright 2017, Numerical Algorithms Group Ltd. http://www.nag.com

!     .. Use Statements ..
      Use blas_interfaces, Only: zgemm
      Use lapack_example_aux, Only: nagf_file_print_matrix_complex_gen_comp, &
        nagf_file_print_matrix_real_gen
      Use lapack_interfaces, Only: zuncsd
      Use lapack_precision, Only: dp
!     .. Implicit None Statement ..
      Implicit None
!     .. Parameters ..
      Complex (Kind=dp), Parameter :: one = (1.0_dp, 0.0_dp)
      Complex (Kind=dp), Parameter :: zero = (0.0_dp, 0.0_dp)
      Integer, Parameter :: nin = 5, nout = 6, recombine = 1, reprint = 1
!     .. Local Scalars ..
      Integer :: i, ifail, info, info2, j, ldu, ldu1, ldu2, ldv, ldv1t, ldv2t, &
        ldx, ldx11, ldx12, ldx21, ldx22, lrwork, lwork, m, n11, n12, n21, n22, &
        p, q, r
!     .. Local Arrays ..
      Complex (Kind=dp), Allocatable :: u(:, :), u1(:, :), u2(:, :), v(:, :), &
        v1t(:, :), v2t(:, :), w(:, :), work(:), x(:, :), x11(:, :), x12(:, :), &
        x21(:, :), x22(:, :)
      Complex (Kind=dp) :: wdum(1)
      Real (Kind=dp) :: rwdum(1)
      Real (Kind=dp), Allocatable :: rwork(:), theta(:)
      Integer, Allocatable :: iwork(:)
      Character (1) :: clabs(1), rlabs(1)
!     .. Intrinsic Procedures ..
      Intrinsic :: cmplx, cos, min, nint, real, sin
!     .. Executable Statements ..
      Write (nout, *) 'ZUNCSD Example Program Results'
      Write (nout, *)
      Flush (nout)
!     Skip heading in data file
      Read (nin, *)
      Read (nin, *) m, p, q

      r = min(min(p,q), min(m-p,m-q))

      ldx = m
      ldx11 = p
      ldx12 = p
      ldx21 = m - p
      ldx22 = m - p
      ldu = m
      ldu1 = p
      ldu2 = m - p
      ldv = m
      ldv1t = q
      ldv2t = m - q
      Allocate (x(ldx,m), u(ldu,m), v(ldv,m), theta(r), iwork(m), w(ldx,m))
      Allocate (x11(ldx11,q), x12(ldx12,m-q), x21(ldx21,q), x22(ldx22,m-q))
      Allocate (u1(ldu1,p), u2(ldu2,m-p), v1t(ldv1t,q), v2t(ldv2t,m-q))

!     Read (by column) and print unitary X from data file
!      (as, say, generated by a generalized singular value decomposition).

      Do i = 1, m
        Read (nin, *) x(1:m, i)
      End Do

!     Print general complex matrix using matrix printing routine nagf_file_print_matrix_complex_gen_comp.
!     ifail: behaviour on error exit
!            =0 for hard exit, =1 for quiet-soft, =-1 for noisy-soft
      ifail = 0
      Call nagf_file_print_matrix_complex_gen_comp('General', 'N', m, m, x, &
        ldx, 'Bracketed', 'F7.4', '    Unitary matrix X', 'Integer', rlabs, &
        'Integer', clabs, 80, 0, ifail)
      Write (nout, *)

!     Compute the complete CS factorization of X:
!        X11 is stored in X(1:p,   1:q), X12 is stored in X(1:p,   q+1:m)
!        X21 is stored in X(p+1:m, 1:q), X22 is stored in X(p+1:m, q+1:m)
!        U1  is stored in U(1:p,   1:p), U2  is stored in U(p+1:m, p+1:m)
!        V1  is stored in V(1:q,   1:q), V2  is stored in V(q+1:m, q+1:m)
      x11(1:p, 1:q) = x(1:p, 1:q)
      x12(1:p, 1:m-q) = x(1:p, q+1:m)
      x21(1:m-p, 1:q) = x(p+1:m, 1:q)
      x22(1:m-p, 1:m-q) = x(p+1:m, q+1:m)

!     Workspace query first to get length of work array for complete CS
!     factorization routine zuncsd.
      lwork = -1
      lrwork = -1
      Call zuncsd('Yes U1', 'Yes U2', 'Yes V1T', 'Yes V2T', 'Column', &
        'Default', m, p, q, x, ldx, x(1,q+1), ldx, x(p+1,1), ldx, x(p+1,q+1), &
        ldx, theta, u, ldu, u(p+1,p+1), ldu, v, ldv, v(q+1,q+1), ldv, wdum, &
        lwork, rwdum, lrwork, iwork, info)
      lwork = nint(real(wdum(1)))
      lrwork = nint(rwdum(1))
      Allocate (work(lwork), rwork(lrwork))
!     Initialize all of  u, v to zero.
      u(1:m, 1:m) = zero
      v(1:m, 1:m) = zero

!     This is how you might pass partitions as sub-matrices
      Call zuncsd('Yes U1', 'Yes U2', 'Yes V1T', 'Yes V2T', 'Column', &
        'Default', m, p, q, x, ldx, x(1,q+1), ldx, x(p+1,1), ldx, x(p+1,q+1), &
        ldx, theta, u, ldu, u(p+1,p+1), ldu, v, ldv, v(q+1,q+1), ldv, work, &
        lwork, rwork, lrwork, iwork, info)
      If (info/=0) Then
        Write (nout, 110) 'Failure in ZUNCSD. info =', info
        Go To 100
      End If

!     Print Theta using real matrix printing routine nagf_file_print_matrix_real_gen
!     Note: U1, U2, V1T, V2T not printed since these may differ by a sign
!     change in columns of U1, U2 and corresponding rows of V1T, V2T.
      Write (nout, 120) 'Theta Component of CS factorization of X:'
      Flush (nout)
      ifail = 0
      Call nagf_file_print_matrix_real_gen('G', 'N', r, 1, theta, r, &
        '    Theta', ifail)
      Write (nout, *)
      Flush (nout)

!     And this is how you might pass partitions as separate matrices.
      Call zuncsd('Yes U1', 'Yes U2', 'Yes V1T', 'Yes V2T', 'Column', &
        'Default', m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, &
        theta, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, work, lwork, rwork, &
        lrwork, iwork, info2)
      If (info/=0) Then
        Write (nout, 110) 'Failure in ZUNCSD. info =', info
        Go To 100
      End If

!     Reprint Theta using matrix printing routine nagf_file_print_matrix_real_gen.
      If (reprint/=0) Then
        Write (nout, 120) 'Components of CS factorization of X:'
        Flush (nout)
        ifail = 0
        Call nagf_file_print_matrix_real_gen('G', 'N', r, 1, theta, r, &
          '    Theta', ifail)
        Write (nout, *)
        Flush (nout)
      End If

      If (recombine/=0) Then
!       Recombining should return the original matrix
!       Assemble Sigma_p into X
        x(1:m, 1:m) = zero
        n11 = min(p, q) - r
        n12 = min(p, m-q) - r
        n21 = min(m-p, q) - r
        n22 = min(m-p, m-q) - r
!       Top Half
        Do j = 1, n11
          x(j, j) = one
        End Do
        Do j = 1, r
          x(j+n11, j+n11) = cmplx(cos(theta(j)), 0.0_dp, kind=dp)
          x(j+n11, j+n11+r+n21+n22) = cmplx(-sin(theta(j)), 0.0_dp, kind=dp)
        End Do
        Do j = 1, n12
          x(j+n11+r, j+n11+r+n21+n22+r) = -one
        End Do
!       Bottom half
        Do j = 1, n22
          x(p+j, q+j) = one
        End Do
        Do j = 1, r
          x(p+n22+j, j+n11) = cmplx(sin(theta(j)), 0.0_dp, kind=dp)
          x(p+n22+j, j+r+n21+n22) = cmplx(cos(theta(j)), 0.0_dp, kind=dp)
        End Do
        Do j = 1, n21
          x(p+n22+r+j, n11+r+j) = one
        End Do
!       multiply U * Sigma_p into w
        Call zgemm('n', 'n', m, m, m, one, u, ldu, x, ldx, zero, w, ldx)
!       form U * Sigma_p * V^T into u
        Call zgemm('n', 'n', m, m, m, one, w, ldx, v, ldv, zero, u, ldu)

!       Print recombined matrix using complex matrix printing routine nagf_file_print_matrix_complex_gen_comp.
        Write (nout, *)
        Flush (nout)
        ifail = 0
        Call nagf_file_print_matrix_complex_gen_comp('General', 'N', m, m, u, &
          ldu, 'Bracketed', 'F7.4', &
          '    Recombined matrix X = U * Sigma_p * V^H', 'Integer', rlabs, &
          'Integer', clabs, 80, 0, ifail)
      End If
100   Continue

110   Format (1X, A, I4)
120   Format (/, 1X, A, /)
    End Program


ご案内
関連情報
Privacy Policy  /  Trademarks