5章:配列
5.2 1次元配列の演算
ここでは1次元配列の演算処理について説明する。
配列演算式はDOループを書く代わりに、部分配列と配列式を使って各要素の間の演算をまとめて書くことができる。
■部分配列
部分配列とは配列の一部であり、それ自体が配列になっている。
部分配列には添字三つ組で指定する方法と、ベクトル添字で指定する方法がある。
・添字三つ組で指定する方法
この方法は、元の全体配列から規則的に配列要素を選択する時に使う。
添字三つ組は、部分配列の下限、上限、およびその間での増分(刻み幅)を表し、以下のように書く。
配列名(下限:上限:増分)
下限を省略した場合は元の配列の下限になる。
上限を省略した場合は元の配列の上限になる。
増分を省略した場合は、増分が1になる。
・ベクトル添字で指定する方法
この方法は、元の全体配列から部分的に配列要素を選択する時に使う。
ベクトル添字とは、全体配列の部分配列を選択する整数値の1次元配列のことである。
選択可能な範囲は宣言された境界の範囲内である。
選択する部分配列は、特定の順序になっている必要はなく、値が重複していてもよい。
ベクトル添字は以下のように書く。
(/式1,式2,・・・/)
式は変数や定数も含む。
(例)
Aが形状(4,8)の2次元配列、Bを形状(2)の1次元配列、Cを形状(3)の1次元配列とし、BとCがそれぞれ以下のような値である場合
B=(/1,4/)
C=(/2,1,1/)
部分配列A(2,B)は、要素A(2,1)とA(2,4)から構成される。
部分配列A(C,2)は、要素A(2,2)、A(1,2)、A(1,2)から構成される。
部分配列A(B,C)は、要素A(1,2)、A(1,1)、A(1,1)、A(4,2)、A(4,1)、A(4,1)から構成される。
- 配列要素が同じ値を2つ以上含むベクトル添字で指定された部分配列のことを
重複部分配列という。
重複部分配列は、代入文の左辺やREAD文の入力項目として使うことはできない。- ベクトル添字で指定した列が空の場合、部分配列の大きさは0になる。
■配列の演算
配列名や部分配列名のままで、要素ごとの演算ができる。
基本的に以下のように書く。
配列名 演算子 配列名
演算式 | 説明 |
---|---|
A+B | An+Bn |
A-B | An-Bn |
A*B | An*Bn |
A/B | An/Bn |
A**B | AnB |
n=1,2,3,・・・,n
■大きさ0の配列の演算
A(3:2)のように添字の下限が上限を超えている配列のことを大きさ0の配列という。配列演算式に大きさ0の配列が含まれている場合、演算式は実行されない。
■配列式と配列の代入
配列式を使うと、DO文などを使わずに配列内のすべての配列要素の演算や論理比較を行うことができる。
2つの配列が形状適合であれば、対応する配列要素ごとに指定された演算を行う。
配列式の代入文の左辺と右辺の配列が形状適合であれば、対応する配列要素ごとに代入が行われる。
(例)配列式のプログラム
INTEGER,DIMENSION(2,5) :: A,B,C
A=2
B=8
C=B-A
END
この場合、
配列Aのすべての要素の値は2になる。
配列Bのすべての要素の値は8になる。
配列Cのすべての要素の値は6になる。
左辺が配列変数である式を配列代入文という。
配列変数に代入される式の値は次のいずれかである必要がある。
- スカラ値
- 配列変数と同じ大きさの配列
(例)
A(3:5)=5.0
配列A(3)、A(4)、A(5)に5.0を代入
A(0:10:5)=1
配列A(0)、A(5)、A(10)に1を代入
A(2:6:2)=(/3,6,9/)
配列A(2)に3、A(4)に6、A(6)に9を代入
C(3:5)=A(2:4)+B(3:5)
C(3)にA(2)+B(3)の値、C(4)にA(3)+B(4)の値、C(5)にA(4)+B(5)の値を代入
■配列組み込み関数
Fortran90には、配列の計算に便利な組み込み関数が多く用意されている。
その代表的なものを以下に示す。
関数 | 説明 |
---|---|
DOT_PRODUCT(A,B) | 2つの一次元配列の内積を計算する |
PRODUCT(A) | 全配列要素の積を求める |
SUM(A) | 全配列要素の和を求める |
MAXVAL(A) | 配列要素の最大値を求める |
MINVAL(A) | 配列要素の最小値を求める |
MAXLOC(A) | 配列中の最大値の位置を求める |
MINLOC(A) | 配列中の最小値の位置を求める |
ALLOCATED(A) | 配列の割り付け状態を調べる |
SIZE(A) | 配列要素の総数を求める |
ALL(A) | 配列要素の値がすべて真の時、真を求める |
ANY(A) | 配列要素の値が1つでも真の時、真を求める |
COUNT(A) | 真の配列要素の個数を求める |
SHAPE(A) | 配列やスカラの形状を求める |
RESHAPE(A) | 配列の再構成を求める |
■配列の入出力
配列へのデータの入出力は配列要素ごとに指定して行う方法以外に、配列全体または部分配列をまとめて指定する方法もある。
配列内のすべてのデータを入出力する場合は、配列名だけを書く。
(例)
READ(*,*) A(2),A(3),A(4),A(5),A(6),A(7),A(8)
は
READ(*,*) (A(X),X=2,8)
と書くことができる
WRITE(*,*) A(1,1),A(1,2),A(2,1),A(2,2)
は
WRITE(*,*) ((A(X,Y),Y=1,2),X=1,2)
と書くことができる
INTEGER A(10),B(2,4)
の場合、配列Aのデータをすべて読み込む時は
READ(*,*) A
配列Bのデータをすべて書き出す時は
WRITE(*,*) B
と書く。
■WHERE文・WHERE構文
配列演算式で配列要素の値によって異なる演算を行う場合、IF文に相当するWHERE文やIF構文に相当するWHERE構文を使って書くことができる。
(IF文の詳細は、3.2.2 IF文を参照。)
WHERE文は以下のように書く。
WHERE (論理配列式) 配列代入文
(例)配列Aのデータが偶数か否かを調べ、奇数の場合は2倍にして偶数にする
WHERE (MOD(A(:),2)/=0) A(:)=A(:)*2
MOD:剰余を求める組み込み関数
WHERE構文は以下のように書く。
WHERE (論理配列式)
ELSEWHERE
END WHERE
ブロック:配列代入文の集まり
(例)配列のデータを調べ、値が正の時は平方根を求め、負の時は0.0を代入する
WHERE(A(:)>0.0)
A(:)=SQRT(A(:))
ELSEWHERE
A(:)=0.0
END WHERE