4 Harwell Boeing形式の読み込みサンプルコード2(複素エルミート行列、反復法)
ここではHarwell Boeing形式の複素エルミート行列ファイル(MXTYPE=CHA)を読み込み、 列方向のインデックスを展開し並べ替えを行った後にnAGルーチンに渡して解くサンプルを示します。 ここで利用するnAGルーチンは F11JSF(複素エルミート反復法ソルバー) です。 F11JSF には列方向のインデックスが圧縮されていない形式で渡す必要がありますのでHarwell Boeing形式のデータを読み込んだ後に、 列方向のインデックスの展開(及び並べ替え)を行い、そして変換後のデータを用いて解を求めます。
4.1 読み込むデータ
読み込むデータは係数行列(Harwell Boeing形式の複素エルミート行列)と右辺ベクトル(テキスト形式)の2つです。
以下にHarwell Boeing形式で上記係数行列を記述した例を示します。 (青い記号は空白を表しています)
係数行列ファイルの例: f11jsf_matrix.hb
右辺ベクトルはN行(N=行列のオーダー。上記例では5)のテキストデータで、 それぞれの行に一つの数値を持つ形式のものです。 上記例の場合以下のようになります。
(8,54) (-10,-92) (25,27) (26,-28) (54,12) (26,-22) (47,65) (71,-57) (60,70)
右辺ベクトルファイルの例: f11jsf_uhen.txt
4.2 サンプルコード
以下にサンプルコードを示します。 以下のサンプルはHarwell Boeing形式の複素エルミート行列を読み込む必要最小限の処理を行っています。 (※実行列、複素非エルミート行列の読み込み等Harwell Boeing形式のすべてに対応してはいませんのでご注意ください)
※以下のサンプルはnAG数値計算ライブラリ(トライアルのご案内 )を利用します。
PROGRAM solve_hermitian
IMPLICIT NONE
CHARACTER filename*256, mxtype*3, ptrfmt*16, indfmt*16, valfmt*20
CHARACTER method*6, precon
INTEGER i, j, k, ifail, nnz, n, nrows, ncols, lwork, maxitn, itn
DOUBLE PRECISION rnorm, omega
COMPLEX (kind(0D0)), ALLOCATABLE :: values(:), rhs(:), x(:), work(:)
DOUBLE PRECISION, ALLOCATABLE :: rdiag(:)
INTEGER, ALLOCATABLE :: iwork_f11zpf(:), iwork(:), istr(:)
INTEGER, ALLOCATABLE :: row_idx(:), compressed_col_idx(:), col_idx(:)
! ---------------------------------------------------------
! Read Harwell Boeing Sparse Matrix File
! ---------------------------------------------------------
PRINT *, 'Enter Harwell Boeing Matrix File Name'
READ *, filename
OPEN (10, FILE=filename, STATUS='old')
READ (10, '(A72,A8)') ! title, key
READ (10, '()') ! Skip 5 I14 format: totcrd, ptrcrd, indcrd, valcrd, rhscrd
READ (10, '(A3,11X,4I14)') mxtype, nrows, ncols, nnz ! ,neltvl
PRINT '(I0, " x ", I0, " (",I0," non-zeros) mxtype is ",A)', nrows, ncols, nnz, mxtype
IF (mxtype(1:1)/='C' .AND. mxtype(1:1)/='c') STOP 'Only complex matrix is accepted...'
IF (mxtype(2:2)/='H' .AND. mxtype(2:2)/='h') STOP 'Only hermitian matrix is accepted...'
n = ncols ! n is the order of the matrix
! Allocate and read coordinates and data (nnz = number of non-zeros)
ALLOCATE (compressed_col_idx(n+1), row_idx(nnz), values(nnz))
READ (10, '(2A16,2A20)') ptrfmt, indfmt, valfmt ! ,rhsfmt
READ (10, ptrfmt)(compressed_col_idx(i), i=1, n+1) ! read compressed column indecies
READ (10, indfmt)(row_idx(i), i=1, nnz) ! read row indecies
READ (10, valfmt)(values(i), i=1, nnz) ! read values
CLOSE (10)
! ---------------------------------------------------------
! Allocate and read RHS
! ---------------------------------------------------------
! open file
PRINT *, 'Enter Vector (txt) File Name'
READ *, filename
ALLOCATE (rhs(n))
OPEN (10, FILE=filename, STATUS='old')
DO i = 1, n
READ (10, *) rhs(i)
END DO
CLOSE (10)
! ---------------------------------------------------------
! Convert CCS to CS(SCS)
! ---------------------------------------------------------
PRINT *, 'Converting to CS(SCS)...'
ALLOCATE (col_idx(nnz))
j = 1
DO i = 1, ncols
k = compressed_col_idx(i+1) - compressed_col_idx(i)
IF (k>0) THEN
col_idx(j:j+k-1) = i
j = j + k
END IF
END DO
! ---------------------------------------------------------
! Sort CS(SCS)
! ---------------------------------------------------------
PRINT *, 'Sorting CS(SCS)...'
ALLOCATE (iwork_f11zpf(n), istr(n+1))
ifail = 0
CALL f11zpf(n, nnz, values, row_idx, col_idx, 'R', 'K', istr, iwork_f11zpf, ifail)
! ---------------------------------------------------------
! Solve Ax = b using f11jsf
! ---------------------------------------------------------
PRINT *, 'Solving...'
lwork = 7*n + 120
ALLOCATE (x(n), rdiag(n), work(lwork), iwork(n+1))
ifail = 0
omega = 1.0D0 ! Omega parameter: only for precon='S', 0.0<=omega<=2.0
maxitn = 30000 ! Maximum number of iteration
precon = 'N' ! Preconditioner: 'N'=none, 'J'=Jacobi, 'S'=SSOR
method = 'CG' ! Method: 'CG'=Conjugate Gradient, 'SYMMLQ'=Lanczos
x = 0D0 ! Set initial approximation to 0
CALL f11jsf(method, precon, n, nnz, values, row_idx, col_idx, omega, rhs, 0D0, maxitn, x, rnorm, &
itn, rdiag, work, lwork, iwork, ifail)
! ---------------------------------------------------------
! Write results
! ---------------------------------------------------------
PRINT *, 'Results: number of iterations =', itn
PRINT '("(",f8.5,", ",f8.5," )")', x
END PROGRAM solve_hermitian
サンプルコード: solve_complex_hermitian.f90
注意点等:
※本サンプルは複素エルミート行列(Harwell Boeing MXTYPE="CHA")のみに対応しています。
※本サンプルで用いるnAGルーチンはSCS形式(圧縮されていないカラム形式)に対応したルーチンですので、
Harwell Boeing形式から読み込まれたcompressed_col_idx(圧縮された列インデックス)はまず圧縮されていない形に変換しています。
("Convert CCS to CS(SCS)"の部分)
そしてその後にnAGルーチンが必要とする順番に並べ替えています。("Sort CS(SCS)"の部分)
※引数詳細等につきましては各ルーチン( f11jsf , f11zpf )のマニュアルページをご参照下さい。
4.3 実行結果例
以下に本サンプルプログラムの実行結果例を示します。
Enter Harwell Boeing Matrix File Name f11jsf_matrix.hb 9 x 9 (23 non-zeros) mxtype is CHA Enter Vector (txt) File Name f11jsf_uhen.txt Converting to CS(SCS)... Sorting CS(SCS)... Solving... Results: number of iterations = 9 ( 1.00000, 9.00000 ) ( 2.00000, -8.00000 ) ( 3.00000, 7.00000 ) ( 4.00000, -6.00000 ) ( 5.00000, 5.00000 ) ( 6.00000, -4.00000 ) ( 7.00000, 3.00000 ) ( 8.00000, -2.00000 ) ( 9.00000, 1.00000 )
ナビゲーション:前へ 上へ 次へ
