National Institute for Environmental Studies

2024年度前期
情報処理演習第8回

2024/05/29
平山 修久（減災連携研究センター）

繰り返し実行：カウンタ制御DOループ
DO i = 10, 1, -2
文の並びi*i
END DO
1.制御変数に初期値が代入される。
2.制御変数が限界値と比較され，次の条件を満たすかどうか調べる
増分値が正の場合は，限界値以下であるかどうか増分値が負の場合は，限界値以上であるかどうか

名古屋大学減災連携研究センター

Disaster Mitigation Research Center, NAGOYA UNIVERSITY

3.条件を満たす場合は，ループ本体と呼ばれる文の並びが実行され，制御変数に増分値が加算されて，ステップ2が繰り返される。そうでない場合は繰り返しが終了する。

12

Tips

Tips

DOループの制御変数は整数型：Integer

IDEOneでは計算時間を15sに延長する。

調べる除数Mの最大値MNの計算は，アカウントを作成

MN = INT(SQRT(REAL(N)))

フラグの使い方素数であると仮定：FP=0割り切れる＝素数でない，FP=1とする
割る数字をすべて調べたのち（DOループ後）FPが0のままであれば，素数，FPが1であれば素数でない。
34

本日の目的配列（1次元配列）
配列の宣言
型宣言文でDIMENSION属性を指定
変数名に直接，配列の形状を指定する。
型, DIMENSION ( [下限 :] 上限 ) :: 配列名のリスト

配列を理解する乱数の発生の仕方を理解する

型 :: 配列名 ( [下限 :] 上限), …
INTEGER, DIMENSION (1 : 100) :: number, mark
REAL :: x, a( -100 : 100 )下限が省略された場合は1とみなされる。
要素の個数 ＝ 上限値 ­ 下限値 + 1
56

配列要素

配列の演算

宣言された配列の1つ1つの要素は単純な変数と同等。

配列要素は，配列名に添え字の値を( )でくくったものを付けて表す。

INTEGER, DIMENSION (1 : 100) :: number, mark
REAL :: x, a( -100 : 100 )mark(1)
number(i)a(-40)

1次元配列の初期値設定には配列定数やDO形反復。
(/ 定数, 定数, … /) [ 定数, 定数, …](/ (データのリスト, DO変数 = 開始値, 限界値) /)INTEGER:: a( 0 : 9 ) = (/0,2,4,6,8,10,12,14,16,18 /)INTEGER:: a( 0 : 9 ) = (/ (n, n=0,18,2) /)INTEGER:: a( 0 : 9 ) = (/ (2*n, n = 0, 9 ) /)7

部分配列

実行文の中で，配列の一部分を，宣言なしで配列として用いることができる。

INTEGER :: a( 1 : 5 ) = (/ 2, 4, 6, 8, 10 /)a( 4 : ) は a( 4 : 5 )と同じで 8,10a( : 3 ) はa( : ) はa( 1 : 3 )と同じで2,4,6a( 1 : 5 )と同じ

a( 1 : 5 : 2 ) は奇数番目の要素からなる配列
a( 5 : 1 : -1 ) は要素を逆順

2,6,1010,8,6,4,2a( 3 : 3 ) は要素 a(3)ではなく，要素数1の配列(/ 6 /)8

配列型添え字

配列代入文
配列要素に，右辺に書かれた同じ形状の配列の配列要素を一括して代入することができる。

配列名（添え字配列）
INTEGER :: a( -2 : 2 ) = (/ 1,2,3,4,5 /), &b( 1 : 2 ) = (/ 0, 2 /)a(b)(/ 3, 5 /)a( (/ 0, 2 /)とも書くことができる。

INTEGER :: a( 1 : 10 ), b( 1 : 5), c( 1 : 16 ),na = (/ 0,1,2,3,4,5,6,7,8,9 /)a = (/ (n, n = 0, 9 ) /)b = a( 1 : 5 )c( 1 : 10 ) = ac( 12 : 16 ) = a( 6 : 10 )c( 11 ) = 1
b = 0c( 1 : 16 : 2 ) = 1c( 2 : 16 : 2 ) = 0910

配列演算式

ベクトル演算1つ1つの配列要素は，各種の演算において普通の変数と同等に扱ってよい。配列名のままで要素間の演算を一括して書くこともできる。要素の対応は添え字ではなく各配列内での相対位置である。
INTEGER, DIMENSION( 1 : 50 ) :: wa, sa, seki,sho, &even = (/ (2*i, i = 0, 49 ) /), &odd = (/ (2*i+1, i = 0, 49 ) /)wa = even + odd
sa = even - odd
seki = even * odd
syo = even / oddwa( : ) = even( : ) + odd( : )11

INTEGER :: a( 0 : 9 ) = (/ 0,1,2,3,4,5,6,7,8,9 /)のとき

a( 1 : 9 ) = a( 0 : 8 )とDO i = 1, 9a(i) = a(i-1)
END DOは異なる。
DOループで実現するには，別の一時的な待避配列bを用意

INTEGER :: a( 0 : 9 ) = (/ 0,1,2,3,4,5,6,7,8,9 /),&b( 0 : 9 )b = a
DO i = 1, 9a(i) = b(i-1)
END DO12配列の入出力INTEGER :: a( 10 )PRINT `( 10I5 )`, ( a(i), i = 1, 10 )PRINT `( 10I5 )`, a
PRINT `( 5I5 )`, a( 1 : 5 )PRINT `( 10I5 )`, ( a(i), i = 10, 1, -1 )DO i = 1, 10
PRINT `( 10I5 )`, a(i)END DOREAD *, a
READ *, ( a(i), i = 1, 10 )DO i = 1, 10
READ *, a(i)END DO
1314

書式の指定

PRINT 書式識別子, 出力データのリスト
書式は，コンマ「,」または斜線 / で区切って並べたリスト全体を，’()’でくくって構成する。斜線の位置で改行が行われる。w,d,r,nは整数値。
Iw

整数データを文字幅wに右詰め

Fw.d 実数データを文字幅wに右詰め，小数点以下d桁，w>d+1
Ew.d

実数データを10の指数表式，w>d+5

Dw.d

倍精度実数データを10の指数表式，w>d+6

Aw

文字データをw文字幅に右詰めr..

これらの項目の前に反復数を書くことができる。

nX

n桁スキップ。n=1も省略できない。

PRINT ‘( 1X, I3, 2X, 3F10.5)’, k,s,c,p

スペース1桁，3桁の整数が1つ，スペース2桁，10桁の実数（小数点以下5桁）が3つ

PRINT ‘( 1X, I3, 2X, 3F10.5)’, k,s,c,p15

16本日（20240529）の課題（1/2）
ベクトル演算1. ベクトルu = (1.2, 3.5)とv = (4.1, 2.6)の和，差，積，商，内積を求めるプログラムを作成する。
提出物：実行結果のスクリーン画像
和：u + v = (u(1) + v(1), u(2) + v(2))

kadai08̲1.png

差：u − v = (u(1) − v(1), u(2) − v(2))
積：u × v = (u(1) × v(1), u(2) × v(2))
商：u ÷ v = (u(1) ÷ v(1), u(2) ÷ v(2))
内積：u · v = u(1)v(1) + u(2)v(2)乱数計算機で用いることができる乱数は擬似乱数
call random_number(x)変数xに区間[0, 1)の一様乱数が代入される．xは実数型であれば配列でもよい。配列の場合は全ての要素に一様乱数が代入される。

擬似乱数：初期値により決定論的な数列である。初期値を指定する。
implicit none
integer:: nseed, clock
integer, allocatable:: seed(:)
call system_clock(clock)call random_seed(size=nseed)
allocate(seed(nseed))
seed=clock
call random_seed(put=seed)1718

本日（20240529）の課題（2/2）
配列の最大値，最小値最大値，最小値を探索する
アルゴリズム（1/2）

2. 1から100までの整数の一様乱数を配列を用いて20個生成し，その最大値と最小値を求めよ。また，最大値と最小値が何番目の乱数であるのか示せ。なお，最大値，最小値が複数ある場合は最も最初のものでよい。

ただし，組み込み関数 MAX( )，MIN( ) は使わないこと。
提出物：プログラム
実行画面

kadai08̲2.f90
kadai08̲2.png
19

1. 乱数（実数）を発生させる。配列を用いる。

implicit none
integer :: nseed, clock
integer, allocatable:: seed(:)
real :: dum(20)call system_clock(clock)call random_seed(size=nseed)
allocate(seed(nseed))
seed=clock
call random_seed(put=seed)
2. 1から100の乱数（整数）を発生させる。配列を用いる。
call random_number(dum)int(100.0*dum)+1
3. i番目の配列が最大値より大きいか，最小値より小さいか調べる。
20

最大値，最小値を探索する
アルゴリズム（2/2）
4. 最大値nmax，最小値nminを配列の1番目と仮定する。最大値の順番pmax，最小値の順番pminを1とする。
nmax=d(1)pmax=1
nmin=d(1)pmin=15. 配列の2番目以降から，d(i)とnmax，nminと比較する。
6. nmaxより大きい場合には，nmaxとpmaxを更新する。nminより小さい場合には，nminとpminを更新する。
7. すべて比較し終えたら，最大値，最小値を表示する。
21