どうにもこのところ腰が痛い、というか固まったみたいになっていてつらいです。
時々湿布を貼ったりしてしのいではいるのですが。
臀部がかなり重くなってしまっているんですよね。
それに骨盤のすぐ上のあたりの腰ががちがちになっていて。
風邪の方も、熱は無いみたいなのですが、喉は痛いしなんか胃の調子も悪いです。
ううみゅ。
土曜は漫研の連中と飲みに行く予定なんだけどなぁ。でも飲むし。(そんなに飲めないけど。。)
前回にやった初回の分。
かなりおちゃらけた感じが気になったのですが、それなりにシリアスな設定もあるような感じです。
まだ1回目だけじゃ評価できないな。
様子見。(と言いつつ、こういう時は大抵見続けるパターンなんですがね。)
昨日のコードをちょっと修正。
考えてもみれば複数のmoduleに分割する必要なかったですね。
ひとつのパッケージに入ってた方が使いやすいし。
昔は Fortran でサブルーチン同士でデータを共有する手段として COMMON というのがあったのですが、データ記述の順番が決まってるし、共用されているどのタイミングでデータが変更されたかどうかがわかりにくいなどの問題があって、COMMON は推奨されなくなりました。
そのかわりに使われるようになったのが module という手段。
C言語のヘッダーファイルみたいにも見えますが、バイナリー状態になっています。
一番簡単な使い方は module の中に変数を定義して、使う側から use 文でその module 名を指定することで module 内の変数にアクセスする方法で COMMON に似た共有をするというもの。
ただ、この方法では結局、どのタイミングで変数が変化したかを明確にするのは難しいんですよね。そこらへんを完全に明確にするためには関数型の言語を使うしかないのですが、module で構造体だけを定義してデータの実体を module から追い出してしまえばいいのかも、という感じ。module で定義した構造体で変数を定義して、その構造体に対する処理を module 内に定義すると。
module 内では private 宣言で変数を隠蔽し、public 宣言した変数や関数などで外部とのインターフェースをするというわけですね。クラスっぽい使い方なんじゃないかなぁ、とか。
ちゃんと理解できてるわけではないのがあれなんですが。。
! fortran 95 によるオブジェクト指向もどきのつもりサンプル
!
module complex
! 複素数オブジェクトの定義
implicit none
private
public mycomp,mul,cset,cang
! オブジェクト mycomp の本体
type mycomp
real(kind=kind(0.d0))::rp
real(kind=kind(0.d0))::ip
end type mycomp
! 複素数オブジェクト同士の積の定義
contains
function mul(x1,x2)
type(mycomp)::mul
type(mycomp),intent(in):: x1,x2
mul%rp = x1%rp * x2%rp - x1%ip * x2%ip
mul%ip = x1%rp * x2%ip + x2%rp * x1%ip
end function mul
! セッターメソッド
function cset(realpart,imaginalpart)
type(mycomp)::cset
real(kind=kind(0.d0)),intent(in):: realpart,imaginalpart
cset%rp=realpart
cset%ip=imaginalpart
end function cset
! 角度表現
function cang(radius,angle)
type(mycomp)::cang
real(kind=kind(0.d0)),intent(in)::radius,angle ! 角度はラジアン
cang%rp=radius*cos(angle)
cang%ip=radius*sin(angle)
end function cang
end module complex
!****************************
module angleunit
implicit none
private
public dtr,rtd
contains
! 度→ラジアン
function dtr(degree)
real(kind=kind(0.d0))::dtr
real(kind=kind(0.d0)),intent(in)::degree
dtr=cos(-1.d0)/180.d0*degree
end function dtr
! ラジアン→度
function rtd(radian)
real(kind=kind(0.d0))::rtd
real(kind=kind(0.d0)),intent(in)::radian
rtd=180.d0/cos(-1.d0)*radian
end function rtd
end module angleunit
!****************************
program test
! プログラム本体
! module 読み込み
use complex
use angleunit
implicit none
real(kind=kind(0.d0)):: a,b,c,d
type(mycomp):: e,f,g ! インスタンス生成
!
print *,'put four numbers'
read *, a,b,c,d
e=cset(a,b)!複素数オブジェクトeのセット
f=cset(c,d)!複素数オブジェクトfのセット
g=mul(e,f)
print *,'real part:',g%rp,' imaginaly part:',g%ip
print *,'direct compute result:',a*c-b*d,'+',a*d+c*b,'i'
e=cang(a,dtr(b))
print *,'radius=',a,' angle=',b
print *,'real part=',e%rp,' imaginal part=',e%ip
end program test
インスタンスなんて適当に言っていますが、本当のところこれが合ってるのかわかりません。
少なくとも、Fortran的にはもっと直接的にsubroutine を call した方が早いはず。Fortran の処理では速度が命なところもあるからなぁ。
ちなみに、ちゃんとしたオブジェクト指向のコーディングは Fortran 2003 だったか 2008 からできるようになっているようです。もうそこまで行くと未知の領域。
上のコードだって、Fortran 95 とか言ってますが、実際のところ Fortran 90 のレベルぐらいでしか無い気もしますが。
いかんなぁ。
でも、案外と module を使った例とかってあまり見掛けないんですよね。