技術メモ
This project is maintained by kino-3
Fortran90 の概要メモ 「数値計算のための Fortran90/95 プログラミング 第1版」 3.8節まで
gfortran hoge.f90 fuga.f90 # 依存関係に注意すること
./a.exe # 実行ファイルへのパスを書く
call hoge() ! 複数行のコメントは存在しない
program hoge ! プログラム名は省略してもよい(書いたほうが良い)
implicit none ! 暗黙の変数の型に関する規約を無効にするため, 変数宣言する前に使用する。
integer i ! 宣言文を実行文よりも上に書く
i = 0 ! 代入前の変数は不定値
write(*,*) i
end program hoge
integer counter ! 変数宣言必要
do counter = 1, 100 ! 制御変数(do変数)はかならず整数型変数を用いる。制御変数を省略して `do` のみ書いた場合は無限ループとなる。
! counter は 1, 2, ..., 100
! 内部で制御変数を書き換えてはならない。
! do counter = 1,100,2 -> 1,3,5,...,99
! do counter = 100,1,-2 -> 100,98,96,...,2
enddo
exit
: いわゆるbreak文cycle
: いわゆるcontinue文goto 123
: 文番号(行頭の数字)が123の行に移動する。多重ループなどやむを得ないときに使用。continue
: 何もしない文 (123 continue
のように使う)if (論理式) then
!
else if (論理式) then
!
else
!
endif
real(8) dx, dy
: 8バイトの倍精度実数。数値計算ではこちらを用いる。(real
は4バイトの基本実数)1.5d-1
: 倍精度実数0.15 (0なら0.0d0
とする) (基本実数ならd
ではなくe
)1/2
の計算結果は 0 になる。(整数で不用意に除算をしない)complex(8) e
(1.,1.5)
のようになるinteger :: i, j = 0
: j に初期値0を代入している。::
を型の後に書くべき場合
write()
は2つ引数を取り, 続いて出力対象となる変数などを列挙する。
*
: 標準出力*
: 並び出力a\
: 改行されない。read()
も write()
同様。integer :: ina, inb, iv, is, iost, fi = 10, fo = 11
! 0以上の整数。数字は5,6 は標準入出力なので良くない。
open(fi, file = "inputFilename", action = "read", iostat = is)
! action はオプション(無指定の場合は"readwrite")
! iostat はオプション(openに成功するとisには0が代入される。失敗すると非0が代入される。)
open(fo, file = "outputFilename", position = "append")
! ファイルがあれば上書き。なければ新規作成。
! append は追記するためのオプション
read(fi, *) ina, inb ! 並び出力でファイルを読み込む(入力ファイルに合わせる)
do ! 入力が何行あるかわからん時
read(fi, *, iostat = iost) iv
if (iost < 0) exit ! 代入により終端に達するとiostは負になる。
endif
close(fi)
write(fo,*) "hoge" ! 何回writeを呼び出してもよい。(追記される)
close(fo)
5i6
文字数6文字の整数5個以下。変数が5個より多いときは複数行になる。10e12.4
小数点以下4桁の12文字小数が10個real(8) v(3)
は要素数倍精度実数配列(real(8) v(1:3)
に同じ)integer(8) v(-1:1)
の添え字は -1, 0, 1vi(2) = 7
vi(1:2) = (/ 3, 5 /)
vi(1:3) = 0
, integer :: i(4) = 0
vi(:) = 4
のように上下限は省略可能(u(i), i = 1, 3)
: u(1) u(2) u(3) の並び(/ (i, i = 1, 5, 2) /)
: do型反復。(/ 1, 3, 5 /)
と同じ。dot_product(1次元配列, 1次元配列)
: 内積計算の組み込み関数integer, parameter :: i = 3
のように parameter 属性を持つ変数。実行時に代入不可。implicit none
real(8), allocatable :: u(:), v(:,:)
! この時点で上下限は不明だが, 次元は固定。未割り付けの状態では使用出来ない。
integer i, is
read(*, *) i
allocate (u(i)) ! 複数なら allocate (u(i), v(i,i))
deallocate (u) ! 複数なら allocate (u, v)
allovate (u(-i:i), stat = is) ! 異なる寸法で再割り付け可能。割付が成功するとisに0が代入される。
v(1:5:2)
は v(1) v(3) v(5) を要素とする配列(添字三つ組)
```Fortran
module hoge
implicit none ! 以下 end module 内で有効(プログラム単位ごとに行う)
contains ! containsより前に書いた宣言は全域で有効
! 以下 subroutine と function を書く
subroutine hoge_sub(a, b) ! a, b は仮引数。引数無しの時は括弧も不要。
integer a, b ! 実引数と仮引数で型を一致させる必要がある
integer tmp ! 局所変数で(useしたとしても)このsubroutine内で有効
return ! return が呼び出されるとその時点で subroutine を離脱する
end subroutine hoge_sub ! return が呼び出されないと end subroutine まで
function hoge_func(a, b) result(c)
real, intent(in) :: a,b ! 普通仮引数には intent(in) を与える。
integer c ! resultの要素は必ず単一で intent(out) 不要
end function hoge_func
end module hoge
program fuga use hoge ! module の使用宣言。使用するモジュールは先に定義する。 implicit none ! use はこれより上に書く。以下 end program 内で有効 integer v1, v2 real e1, e2 call hoge_sub(v1, v2) ! subroutineの呼び出し(実引数を参照渡しする) v1 = hoge_func(e1, e2) ! call 不要 end program fuga
#### subroutine の属性
- subroutine の局所変数の save 属性
- `real, save :: i` とすると, subroutine 呼び出し後も変数が保存される。
- `real :: i = 0` のように初期化した場合は自動的に save 属性となる。
- 初期化は 1回目のsubroutine呼び出し時のみ有効で2回目以降は初期化されない。
- 毎回初期化したいなら代入すべし。
- 局所配列にも save 属性を与えることは可能
- subroutine の仮引数の intent 属性
```Fortran
subroutine hoge_sub2(a, b, c)
real, intent(in) :: a, b ! プログラム中で書き換え不可
real, intent(out) :: c ! プログラム中で代入必須(書き換えたいやつ)
subroutine hoge_sub3(a, n)
integer, intent(in) :: n ! 配列の寸法も仮引数として与えて
real, intent(in) :: a(n,n) ! 仮配列定義時に寸法も与える
!
call hoge_sub(mat, mat_n) ! 呼び出し時の実引数 mat は呼び出し時点で形状が自明
subroutine hoge_sub3(a)
real, intent(in) :: a(:,:) ! 次元のみ指定する。各要素数は呼び出しの実引数にあわされる。
! 形状明治仮配列の省略版なのでallocate属性は不要
!
call hoge_sub(mat) ! 呼び出し時の実引数 mat は呼び出し時点で形状が自明
call hoge_sub(mat(2:4,2:4)) ! 部分配列として小行列を引数にすることもできる。
subroutine hoge_sub4(a)
real, allocatable, intent(out) :: a(:,:) ! 仮引数にも allocatable 属性をつける(この時点で形状不明)
integer :: n = 10
allocate (a(n,n))
!
real, allocatable :: a(:,:)
call hoge_sub4(a) ! 呼び出し時の実引数 a は呼び出し時点で未割り付け
real, intent(in) :: a(d:d+n-1,e:e+n-1)
・real, intent(in) :: a(d:,e:)
等で指定する必要がある。subroutine hoge_sub5(n)
integer tmp(n) ! 数値や定数の代わりに仮引数を寸法として与える。
module hoge implicit none contains subroutine fuga use params integer tmp(n) ends subroutine fuga end module hoge
#### 配列を返すモジュール関数
```Fortran
function hoge_func2(v) result(nv)
real(8), intent(in) :: v(:) ! 形状引継ぎ配列
real(8) nv(size(v, 1)) ! 自動割付配列?
nv = 2 * v
end function hoge_func2
module global_params ! use global_params とかで使用宣言する
implicit none
integer, params :: global_i = 1 ! 定数なので書き換え不可能
integer, save :: global_j ! 書き換えて記憶させるやつは save 属性
end module global_params
&
をつける。**
で優先度は乗除より高い。指数は極力整数を用いる。==
, /=
stop "プログラムを停止してこの文字列を出力する"
2.0d0*acos(0.0d0)
またはacos(-1.0d0)
等を用いる。call random_seed
で乱数の初期値を設定して, そのあと call random_number(hoge)
とする。hogeはスカラや配列で, 配列の場合は各要素が[0,1)の数となる。