- 追加された行はこの色です。
- 削除された行はこの色です。
現在作成中です。
既に書いている内容も&color(#ff0000){大幅に変わる};可能性が高いです。
as of 2010-04-28 (&counter;)
// 現在(&lastmod;)作成中です。
// 既に書いている内容も&color(#ff0000){大幅に変わる};可能性が高いので、注意。
-------
#contents
-------
// -------
//#contents
// -------
* 担当教員 [#d810a8d4]
陰山 聡
坪倉 誠
* 演習日 [#e84fbb5c]
- 2010.05.06
- 2010.05.13
//- 2013.05.02 Fortran90/95入門 前半
* 概要と達成目標 [#dcc5c361]
+ 概要
++ why f? (なぜFortran95言語か)
++ f && c (Fotran95とCの同じところ)
++ [演習]Hello, world. コンパイルと実行
++ diff f c (Fotran95とCの違うところ)
++ wonderful f (Fotran95の素晴らしいところ)
++ practical f (Fotran95によるコーディングの実際)
+ 目標
++ この「計算科学演習I」で扱うFotranソースコードが自由に読めること。
++ 2次元拡散方程式を解くコードをFotran95言語の特性を活かして書けるようになること。
//&ref(2013_5_2_f95a_usui.pdf);
* はじめに [#rd9d9a92]
//- 2013.05.09 Fortran90/95入門 後半
// wiki の練習。コメントのテスト。この文字は見えないはず。見えたら異常。
//&ref(2013_5_9_f95b_usui.pdf);
** エディタとコンパイラ [#oae90ba8]
** アンケート [#j36d6593]
Fortran90/95入門 前半(5月9日分)はどうでしたか?1人1回,&color(red){''必ず''};回答して下さい.
- Emacsのmajorモードをf90に設定すると便利(f95モードは用意されていない)
-- ミニバッファでf90-modeと打つ (Esc-x f90-mode)
-- 構文の開始と終了ペアリング入力が簡単。tabキー
-- ^Jで整形改行
難易度
#vote(簡単すぎた(資料読めばわかる。)[][][], ちょうどよかった(C言語を知ってるので、とっつきは悪くなかった。)[][][], 少し難しかった(初めての言語なので、結構戸惑った。)[][][], 難しすぎた(C言語も忘れかけてるのに、新しい言語なんて、ちょっと待って、て言う感じ)[][][])
- scalar上でのコンパイルコマンドは pgf95 またはpgf90
分量
#vote(少ないかも(超簡単! 時間をもてあました)[][][], ちょうどよかった(楽でもなくしんどくもなく。)[][][], 少し多かった(気を抜くと遅れてしまう。忙しいけどなんとかついていける感じ。)[][][], 多すぎ(内容詰めすぎ!。半分くらいしかついていけなかった。)[][][])
- フリーのFortran95コンパイラ
-- gfortran (gnu Fortran): http://gcc.gnu.org/fortran/
-- g95: http://www.g95.org/
* 参考書 [#o122e466]
** Fortran90/95の歴史 [#rd9d9a92]
-「Fortran90/95プログラミング入門」,牛島省著、森北出版
- Fortran90/95 Explained, Second Edition, Michael Metcalf and John Reid, Oxford Univ. Press, 1999
- Fortran 95 Handbook Complete ISO/ANSI Reference J. C. Adams et al., MIT Press, 1997,
- Fortran90 Programming, T. Ellis et al, Addison-Wesley, 1994
- ''FORTRAN''(全部大文字の)という言語は存在しない。
--''Fortran90''や''Fortran95''という言語ならある。
- FORTRAN66。
--1966年に標準化。
- FORTRAN77
--1977年に標準化。
-- if/then/else
-- 広まった
- Fortran90
-- 1991年に標準化。
-- 大幅な改訂
- Fortran95
--F90からのマイナーバージョンアップ
Fortran90はFORTRAN77とは大きく違う。違う言語と考えるべき。
~| f95 - f90 | << | f90 - f77 |
* why Fortran90/95? [#qfc92c34]
** 正しい理由 [#p0256e61]
+ 計算速度が速い
-- スーパーコンピュータは速さが命
-- C/C++でもFortranと同じくらい速いコードは書けるが、遅いコードも書けてしまう。
-- 言語としての自由度の違い。自由度が高いとコンパイラが困る。最適化ができなくなる。
+ 便利
-- 道具(言語)は目的にあったものを
-- 数学的計算にはFortran90/Fotran95が適している
--- '''For'''-mula '''Tran'''-slator
-- 数値計算ライブラリの抱負な蓄積。Legacyなコード。財産。
** 間違った理由 [#o19dac24]
『新しい言語を勉強するのは面倒だ。
FORTRAN77の何の不足もない。これでxx年やってきた。』
・・・Legacyな人間。時代に2010-1977=33年遅れている。
** Fortran90/95に対する偏見 [#u2f56714]
以下全てFORTRAN66/77と誤解している。
- 変数名は6文字までなんでしょう?・・・そんなことはありません。
- ソースコードは全部大文字なんでしょう?・・・そんなことはありません。
- ソースコードは固定形式(7列目から72列目まで)なんでしょう?・・・そんなことはありません。
- 構造体がないんでしょう?・・・あります。普通に使います。
- ポインタがないんでしょう?・・・あります。あまり使う必要はありませんが。
- 再帰呼び出しができなんでしょう?・・・できます。あまり使う機会はありませんが。
- 関数とデータをまとめてひとかたまりにする(クラス化する)ことなんてできないんでしょう?・・・できます。普通にやっています。
- データ/関数の隠蔽(カプセル化)ができないんでしょう?・・・できます。いつもしています。
- 演算子を自分で定義することができなんでしょう?・・・できます。いつもしています。
- 関数や演算子の多重定義ができなんでしょう?・・・できます。いつもしています。
** Fortran90/95は現代のプログラミング言語である。 [#g3040af6]
- スーパーコンピュータ向けの言語としては最先端
- 特に並列計算機には
- 数値演算や計算機シミュレーションには最適な言語
** まだ納得できないない?では例を一つ [#ra937520]
部屋の中の温度場の分布から平均気温を求めよう。
温度場を3次元float配列 f(nx,ny,nz)で表す。3つの整数nx, ny, nzは不定。
平均気温=全ての格子点(i,j,k)上でのfの値を足して格子点の総数で割る
** 【演習】 [#t9110993]
任意サイズの3次元単精度実数(浮動小数点数)配列を受け取り、
その平均値を返す関数をC言語(またはC++言語)で作れ。
- scalar上でのCコンパイラ=cc, gcc
** Fortran90/95ではこう書ける。 [#ube6e027]
わずか4行。
real function mean_value(f)
real, dimension(:,:,:) :: f
mean_value = sum(f) / (size(f,1)*size(f,2)*size(f,3))
end function mean_value
** 数式の表現が簡単な例(複素数) [#ada18727]
$e^{i\pi} = -1$
つまり
#ref(e_i_pi.jpg)
をFortran95で書くと、
complex :: i = (0.0,1.0)
real :: pi = 3.141593
print *,' exp(i*pi) = ', exp(i*pi)
** 例(行列の計算) [#h6f4d481]
行列のかけ算はFortran90/95ではmatmulという組み込み関数を使う。
行列の転置をとる組み込み関数transposeも用意されている。
したがって、行列A(例えば10行10列の2次元配列)の転置と別の行列Bの積を計算しそれを行列Cとする計算、つまり
// C = {}^t\!A\, B
#ref(matmul_a_transpose_b.jpg)
をFortran90/95で書くと、
real, dimension(10,10) :: A, B, C
C = matmul(transpose(A),B)
と一行で書ける。
** 例(級数) [#h6f4d481]
級数
#ref(series_one_forth.jpg)
// \sum_{n=1}^\infty\,\frac{1}{i}\cdot\frac{1}{i+1}\cdot\frac{1}{i+2} = \frac{1}{1}\cdot\frac{1}{2}\cdot\frac{1}{3} + \frac{1}{2}\cdot\frac{1}{3}\cdot\frac{1}{4} + \frac{1}{3}\cdot\frac{1}{4}\cdot\frac{1}{5} + \cdots = \frac{1}{4}
の最初の1000項の和を求めるプログラムも、式をそのまま書けばいい。まさにFormula Translation。
integer, parameter :: nterms = 1000
real, dimension(nterms) :: x, y, z
integer :: i
do i = 1 , nterms
x(i) = 1.0 / i
y(i) = 1.0 / (i+1)
z(i) = 1.0 / (i+2)
end do
print *,'ans = ', sum(x*y*z)
** 例(3次元ベクトル場のエネルギー) [#h2acd79c]
空間中に分布する磁場(3成分のベクトル場)
Bx(100,100,100), By(100,100,100), Bz(100,100,100)
の全磁気エネルギーを計算して出力するには、
print *,' energy = ', sum(Bx**2+By**2+Bz**2)/2
と一行(定義式そのもの)を書けば良い。
* diff f && c : C言語との比較によるFortran90/95入門 [#zf847c1d]
** 定番 hello, worldプログラム [#k5bb5231]
C言語
#include <stdio.h>
main () {
printf("hello, world.\n");
}
Fortran90/95
program hello_world
print *, "hello, world."
end program hello_world
** 【演習】 [#r664bdd2]
+ 計算機「scalar」 で、上のFortran90/95プログラムをエディタで入力し、
ファイル名hello_world.f95として保存せよ。
+ ls -l コマンドでファイルを確認せよ。
+ hello_world.f95 をコンパイルせよ。
-- pgf95 hello_world.f95
- Fortran90/95では標準入出力は組み込まれている(ヘッダファイルをインクルードする必要はない)
- Fortran90/95では print *で標準出力へ。
- 行末にセミコロン不要。
- 文字列はダブルクォーテーションマーク(")で囲む。(C言語と同じ)
- シングルクウォーテーションマーク(')でも同じ意味。(これはC言語と違う)
** 大文字・小文字 [#dfe20c0f]
- Fortran90/95のソースコードではアルファベットの大文字と小文字は区別しない。
-- voltage と Voltage と VOLTAGE は同じ
-- 文字列変数の中では区別される。
** 予約語 [#r3a28ada]
Fortran90/95には予約語が存在しない。
それが変数名かどうかコンパイラが賢く判断してくれる。
if (end==else) if=0
は文法的に問題ない。
** コメント行の書き方 [#l593265a]
C言語
/* この間がコメント */
Fortran90/95
! 一行の中でこの文字以降がコメント( C++やJAVAの//と同じ)
** 型名 [#udeac7be]
| 型 | C (C99)| Fortran90/95 | 補註 |
| 文字 | char | character | |
| 文字列 | char[n+1] | character(len=n) | nは文字長|
| 整数 | int | integer | integer(kind=4)でも可 |
| 実数 | float | real | real(kind=4)でも可 |
| 倍精度実数 | double | real(kind=8) | kindの整数はシステム依存 |
| 「長い」整数 | long | integer(kind=8でも可) | kindの整数はシステム依存 |
| bool | _Bool | logical | 値は .true. または .false. |
| 複素数 | _Complex | complex | |
| 構造体 | struct | type | 詳しくは後述 |
** 定数 [#ha3326c8]
C言語
#define NX 100
Fortran90/95
integer, parameter :: NX = 100
** 配列 [#rb6c9a8a]
*** 1次元配列 [#p525880e]
C言語
int array01[NX];
Fortran90/95
integer, dimension(NX) :: array01
*** 2次元配列 [#xa06a740]
C言語
int array02[NY][NX];
Fortran90/95
integer, dimension(NX,NY) :: array02
*** 3次元配列 [#o2df7a6b]
C言語
int array03[NZ][NY][NX];
Fortran90/95
integer, dimension(NX,NY,NZ) :: array03