全て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
fullname = trim('result'//trim(filename)//'.txt')
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')