ブロック三重対角行列を作成する方法の1つです。いくつかのよく知られている図書館の外に、通常の方法であるがあることはわかりません。これはプログラムですが、関数に変換するためにあなたに任せておきます。
PROGRAM test
USE iso_fortran_env
IMPLICIT NONE
INTEGER :: k ! submatrix size
INTEGER :: n ! number of submatrices along main diagonal
INTEGER :: ix ! loop index
! the submatrices, a (lower diagonal) b (main diagonal) c (upper diagonal)
REAL(real64), DIMENSION(:,:,:), ALLOCATABLE :: amx, bmx, cmx
! the block tridiagonal matrix
REAL(real64), DIMENSION(:,:), ALLOCATABLE :: mat_a
k = 3 ! set these values as you wish
n = 4
ALLOCATE(amx(n-1,k,k), bmx(n,k,k), cmx(n-1,k,k))
ALLOCATE(mat_a(n*k,n*k))
mat_a = 0.0
! populate these as you wish
amx = 1.0
bmx = 2.0
cmx = 3.0
! first the lower diagonal
DO ix = 1,k*(n-1),k
mat_a(ix+k:ix+2*k-1,ix:ix+k-1) = amx(CEILING(REAL(ix)/REAL(k)),:,:)
END DO
! now the main diagonal
DO ix = 1,k*n,k
mat_a(ix:ix+k-1,ix:ix+k-1) = bmx(CEILING(REAL(ix)/REAL(k)),:,:)
END DO
! finally the upper diagonal
DO ix = 1,k*(n-1),k
mat_a(ix:ix+k-1,ix+k:ix+2*k-1) = cmx(CEILING(REAL(ix)/REAL(k)),:,:)
END DO
END PROGRAM test
ここでエラーをチェックすることは一切ありません。私はいくつかのテストを行いました。
1つの明白な選択肢は、同じ繰り返しでamx
、bmx
、cmx
を挿入し、一度だけmat_a
の行をループになりますが、これは、最初と最後の反復のための特別な処理を必要とし、おそらく多くのより複雑になります。パフォーマンスに関しては、いくつかのテストを実行することが重要な場合。
これは密度の高いマトリックスを生成することにも注意してください。行列が非常に大きくなると、対角要素だけを格納するアプローチがより役に立ちます。それは、派生した型と操作に向けて私たちを連れて行きます。それはまったく別の質問です。
このコードはあまり意味がありません。 'ii'と' jj 'で索引付けされたループの中で、 'a_matrix'の同じ要素を最初に' impflux(1,1) '、' impflux(1,2) '、* etc *と繰り返して更新します。あなたが作成しようとしているものの小さな例を私たちに示したなら、私はおそらくよく理解できるでしょう。 –
お返事ありがとうございます。私は偏微分方程式の暗黙の方法を扱っています。これらの方法では、メッシュ内の各点に対して3つの行列(3x3)を作成する必要があります。コードの最初のループはメッシュ内のすべての点を通過します。残りのコードは、A_matrix内の行列impflux(メッシュ内の各点に対して生成された)の正しい配置を処理します。最終的な結果は、A_matrixの主対角線の内側に一連のimpflux行列があることです。 –
理想的な世界は、関数に3つのベクトルa(i、j、nm)、b(i、j、nm)とc(i、j、nm)を渡して、 3つの主対角線を形成するこれらの3つの行列(a、b、c)を有する行列(C)である。 –