概要
Fortran-langコミュニティが主導して開発しているFortraの標準ライブラリstdlibについて紹介します.紹介する内容は,stdlibの現行バージョン0.1.0に基づいています.
本記事では,組込機能の代替・補足として使える機能を紹介します.
- stdlib_error
- stdlib_kinds
- stdlib_io
- stdlib_optval
stdlib_error
stdlib_error
モジュールでは,エラー処理関わる手続を定義しています.モジュール内には,手続が二つ定義されています.
-
check
条件式の結果を調べ,条件が成立していない場合にプログラムを停止する. -
error_stop
プログラムを停止する.
check
check
は,引数に論理値を取り,論理値が.false.
の場合にプログラムを停止します.実用上は,論理値ではなく条件式を渡して条件成立の成否を確認する,assertionに用いられます.
サブルーチンであるため,call check(condition[, msg][, code][, warn])
として呼び出します.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
condition |
logical,intent(in) |
条件式の結果 |
msg |
character(*),intent(in),optional |
出力されるエラーメッセージ.標準値はCheck failed.
|
code |
integer,intent(in),optional |
終了コード.標準値は1
|
warn |
logical,intent(in),optional |
プログラムを終了しない.標準値は.false.
|
使い方
- 引数
condition
が.false.
のとき,Check failed.
を出力し,終了コード1でプログラムを終了する.
call check(condition=.false.)
! Check failed.
! ERROR STOP 1
- 論理値ではなく条件式を渡して条件成立の成否を確認する.
integer :: a = 1
call check(a == 0)
! Check failed.
! ERROR STOP 1
-
a==0
が.false.
のとき,引数msg
に渡した文字列を出力し,終了コード1でプログラムを終了する.
integer :: a = 1
call check(a == 0, msg="error: actual value of a is not equal to expected value 0")
! error: actual value of a is not equal to expected value 0
! ERROR STOP 1
- 条件式が
.false.
のとき,引数msg
に渡した文字列を出力し,終了コード77でプログラムを終了する.
integer :: a = 1
call check(a == 0, "error: actual value of a is not equal to expected value 0", code=77)
! error: actual value of a is not equal to expected value 0
! ERROR STOP 77
- 引数warnに
.true.
を渡すと,プログラムは終了しない.
integer :: a = 1
call check(a == 0, "warning: actual value of a is not equal to expected value 0", warn=.true.)
! warning: actual value of a is not equal to expected value 0
error_stop
error_stop
は,エラーメッセージを表示して,非ゼロの終了コードでプログラムを終了します.Fortran 2018にerror stop
文があり,それと機能は同じです.一方で,Fortran 2008のerror stop
文は定数式を指定できますが,変数を指定できません.error_stop
は,この機能不足を補い,Fortran 2008でも2018でも同じように書けるようにするために導入されています.
call error_stop(msg[, code])
として呼び出します.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
msg |
character(*),intent(in) |
出力されるエラーメッセージ. |
code |
integer,intent(in),optional |
終了コード.標準値は1
|
使い方
- 引数msgに渡した文字列を出力し,非ゼロの終了コードでプログラムを終了する.
call error_stop(msg="Fatal error")
! Fatal error
! ERROR STOP
- 引数に渡した文字列を出力し,終了コード999でプログラムを終了する.
call error_stop("Fatal error", code=999)
! Fatal error
! ERROR: code 999 was specified.
! ERROR STOP
stdlib_kinds
stdlib_kinds
モジュールでは,Fortranのデータ型の種別kindを指定する定数が定義されています.
Fortran 2008で単精度および倍精度のkindを指定するパラメータreal32
およびreal64
が定められました.しかし,単精度のkindをsp
,倍精度をdp
とする習慣があったので,それを踏襲したのだと考えられます.
lk
は論理型変数のkindです.
定義されている定数
-
sp
単精度浮動小数点数のkind(=real32
).selected_real_kind(6)
の戻り値. -
dp
倍精度浮動小数点数のkind(=real64
).selected_real_kind(15)
の戻り値. -
xdp
拡張倍精度浮動小数点数のkind.selected_real_kind(18)
の戻り値.利用できない場合-1
. -
qp
4倍精度浮動小数点数のkind(=real128
).selected_real_kind(33)
の戻り値.利用できない場合-1
. -
lk
論理値のkind.
定義されている定数以外に,iso_fortran_env
モジュールに定義されているint8
, int16
, int32
, int64
が読み込まれ,公開されています.同様に,iso_c_binding
モジュールに定義されているc_bool
も公開されています.
stdlib-fpm
xdp
およびqp
は,cmakeおよびfyppの機能を用いて値が定められます.fpmを用いてビルドする場合,プリプロセスができないため,xdp
, qp
ともに-1
となっています.
!> Extended double precision real numbers
integer, parameter :: xdp = -1
!> Quadruple precision real numbers
integer, parameter :: qp = -1
これらは,selected_real_kind
を用いるように変更した方がよいでしょう.コンパイラが拡張倍精度や4倍精度浮動小数点数をサポートしていなければ,selected_real_kind
は-1
を返します.
!> Extended double precision real numbers
integer, parameter :: xdp = selected_real_kind(18)
!> Quadruple precision real numbers
integer, parameter :: qp = selected_real_kind(33)
stdlib_io
stdlib_io
モジュールでは,入出力の利便性を改善する手続が定義されています.
-
open
ファイルを開き,その装置番号を返す. -
savetxt
2次元配列をテキスト形式でファイルに書き出す. -
loadtxt
2次元配列をテキスト形式でファイルから読み込む.
open
open
関数は,ファイルを開き,その装置番号を返します.
unit_number = open(filename[, mode][, iostat])
として利用します.戻り値unit_number
はinteger
です.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
filename |
character(*),intent(in) |
ファイル名. |
mode |
character(*),intent(in),optional |
ファイルを開くモード.標準はrt
|
iostat |
integer,intent(out),optional |
open 関数のエラー状態.エラーがなければ0 |
モード
モードは,テキストで指定します.
テキスト | モード |
---|---|
"r" |
読み取り専用として開く.(標準) |
"w" |
書き込み用に新規に開く.(既存ファイルの中は消去される) |
"x" |
ファイルを新規作成する.ファイルが既に存在する場合は処理が失敗する. |
"a" |
ファイルを追記するために開く. |
"+" |
ファイル更新(読み取り,書き込み)用に開く |
"b" |
バイナリモードで開く. |
"t" |
テキストモードで開く(標準) |
使い方
integer(int32) :: unit
character(128) :: str
! 書き込み+テキストモードで開く.
unit = open ("example_io.txt", "wt")
close (unit)
! 読み取り+テキストモードで開く
unit = open ("example_io.txt", "rt")
! 書き込みをしようとするとエラー.
! write (unit, '(A)') "append to example_io.txt"
close (unit)
! 追記モードで開く
unit = open ("example_io.txt", "a")
close (unit)
savetxt
サブルーチンsavetxt
は,2次元配列をテキストモードでファイルに書き出します.
call savetxt(filename, array)
として利用します.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
filename |
character(*),intent(in) |
ファイル名. |
array |
integer,dimension(:,:),intent(in) |
出力する2次元配列 |
real,dimension(:,:),intent(in) |
||
complex,dimension(:,:),intent(in) |
使い方
use :: stdlib_math
use :: iso_c_binding
real(real32) :: array(16, 2)
enum, bind(c)
enumerator :: x = 1
enumerator :: f
end enum
! stdlib_mathで定義されているlinspaceを利用してx = [0, 2π]を設定し,sin(x)を計算.
array(:, x) = linspace(0., 2.*acos(-1.), 16)
array(:, f) = sin(array(:, x))
! 2次元配列をテキストモードで出力する.
call savetxt("sin.txt", array)
0.00000000E+00 0.00000000E+00
4.18879032E-01 4.06736642E-01
8.37758064E-01 7.43144870E-01
1.25663710E+00 9.51056540E-01
1.67551613E+00 9.94521916E-01
2.09439516E+00 8.66025388E-01
2.51327419E+00 5.87785184E-01
2.93215322E+00 2.07911611E-01
3.35103226E+00 -2.07911789E-01
3.76991129E+00 -5.87785363E-01
4.18879032E+00 -8.66025448E-01
4.60766935E+00 -9.94521916E-01
5.02654839E+00 -9.51056480E-01
5.44542742E+00 -7.43144751E-01
5.86430645E+00 -4.06736493E-01
6.28318548E+00 1.74845553E-07
loadtxt
サブルーチンloadtxt
は,テキストファイルから2次元配列を読み取ります.
call savetxt(filename, array)
として利用します.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
filename |
character(*),intent(in) |
ファイル名. |
array |
integer,dimension(:,:),allocatable,intent(out) |
読み取ったファイル内容を保持する2次元配列 |
real,dimension(:,:),allocatable,intent(in) |
||
complex,dimension(:,:),allocatable,intent(in) |
使い方
real(real32), allocatable :: array(:, :)
! テキストファイルから2次元配列を読み取る.
call loadtxt("sin.txt", array)
print *, array(:, 1)
print *, array(:, 2)
! 0.00000000 0.418879032 0.837758064 1.25663710 1.67551613 2.09439516 2.51327419 2.93215322 3.35103226 3.76991129 4.18879032 4.60766935 5.02654839 5.44542742 5.86430645 6.28318548
! 0.00000000 0.406736642 0.743144870 0.951056540 0.994521916 0.866025388 0.587785184 0.207911611 -0.207911789 -0.587785363 -0.866025448 -0.994521916 -0.951056480 -0.743144751 -0.406736493 1.74845553E-07
stdlib_optval
stdlib_optval
モジュールでは,optional
引数の取り扱いを改善する手続optval
を定義しています.
optval
optval
は,optional
引数が存在しない場合に標準値を定めるための関数です.
result = optval([x,] default)
として呼び出します.引数はそれぞれ下記の意味があります.
引数名 | 型 | 用途 |
---|---|---|
x |
integer,intent(in),optional |
optional 引数 |
real,intent(in),optional |
||
complex,intent(in),optional |
||
logical,intent(in),optional |
||
character,intent(in),optional |
||
default |
x と同じ |
x が存在しない場合の標準値 |
使い方
- 整数
print *, optval(1, default=0), optval(default=0)
! 1 0
- 単精度実数
print *, optval(1., default=0.), optval(default=0.)
! 1.00000000 0.00000000
- 倍精度実数
print *, optval(1d0, default=0d0), optval(default=0d0)
! 1.0000000000000000 0.0000000000000000
- 論理値
print *, optval(.true., default=.false.), optval(default=.false.)
! T F
- 複素数
print *, optval((1., 2.), default=(0., 0.)), optval(default=(0., 0.))
! (1.00000000,2.00000000) (0.00000000,0.00000000)
- xのn乗根を計算する関数root.nの標準値は2
real(real64) :: x = 64.
print *, root(x), root(x, 3)
! 8.0000000000000000 3.9999999999999996
contains
!| xのn乗根を計算する.
real(real64) function root(x, n)
implicit none
real(real64), intent(in) :: x !! 被開平数
integer(int32), intent(in), optional :: n !! 指数
root = x**(1d0/optval(n, 2)) ! nが無いときは2が使われる
end function root