全てfortran90のもの。
配列
多次元配列(行列)の初期化
値を入れながら多次元配列を宣言するときは、
A(m,n) = (1次元配列).reshape(shape(A))
とする。配列の中に配列を入れる、という一般的な形での宣言は受け付けてくれない。
さらにここで、悪名高きfortranの多次元配列代入の仕様に注意。reshapeやファイルのreadなどで1次元の数列を多次元配列に初めから代入していく場合、代入される場所は(1,1), (2,1), (3,1)...という順である(普通の言語なら(1,1),(1,2),...となるところ)。例えば
A = (/1,2,3,4,5,6/).reshape(3,2)
を実行すると、結果は
((1,3,5), (2,4,6))
である。
特定行へのアクセス
「ある行をn倍したい」という時など、行の成分をまとめて処理する際は
A(1,:) = A(1,:)*0.5
のような書き方が可能である。
size,shape関数
size(配列, 次元)
で、任意の次元の要素数を取得できる。例えばある2次元配列で、各行に対しループを回したいときは
do i = 1, size(A, 1) (処理) enddo
としよう。次元のオプションをつけないと、全要素数が返ってくるので注意(3x2行列なら"6"が返る)。
shape関数は、配列の次元を一次元配列で返す。sizeが使えればあんまり出番が無さそう。
if文
if (条件 1) then aaa else if (条件 2) then bbb else zzz end if
条件式を( )でくくる。最後のelseにはthenがいらない。 基本的な構文なのにも関わらず、ググった回数は数知れず。
allocate/deallocate
deallocate文は、一度宣言したallocatable配列の長さをリセットできる。再度allocateすれば、配列の長さを前回から変更することも可能。 ループごとに異なる要素数の配列を用意したいときに有用だった。
real(8),allocatable :: matrix(:,:) allocate(matrix(10,15)) ~~~ deallocate(matrix) allocate(matrix(20,30)) ~~~
ファイル名に番号を割り当てて保存
変数の値ごとに別のファイルに計算結果を書き出す際に使ったコード。 文字列の扱いにはあまり強くないfortranは、
- character型は長さを手動で宣言しなければならない。
- char(x) のような構文が使えない。
そのためここでは、
- 十分長い文字列を用意する。
- 目的の数値をcharacter型に代入する。
- trim関数で文字列の余り部分をトリミングする。
という手順を踏んでいる。
real(8) :: x = 1.2d0 integer :: ios character(len=30) :: filename, fullname filenum = int(x*10) write(filename,'(i0)') filenum ! point1: 整数型のfilenumを文字列型のfilenumに書き込み(代入) fullname = trim('result'//trim(filename)//'.txt') ! point2: trim関数で文字列の余白部分をトリミング open(unit=filenum, iostat=ios, file=fullname, action='write', form='formatted', status='replace') if (ios /= 0) then write(*,*) 'Failed to open file', filenum stop end if
名前を指定してファイルを開くサブルーチン
character(len=*) :: name とすることで、任意の長さの文字列を引数に取ることができる。
subroutine open_file_read(filename_strings, filenum_integer) integer :: filenum_integer, fileopen_ios character(len=*),INTENT(IN) :: filename_strings character(len=30) :: filenum_strings write(filenum_strings,'(i0)') filenum_integer !整数を文字列型に変換 open(unit=filenum_integer, iostat=fileopen_ios, file=filename_strings, action='read', form='formatted', status='old')