電子書籍の厳選無料作品が豊富!

fortranの質問です。

integer ix,iy,maxX,maxY
で宣言しており、
do istep=1,100
call B_DIF(☆)
do ix=0,maxX
do iy=0,maxY
B_M(ix,iy)=B_P(ix,iy)
end do
end do
end do
のルーチンで悩んでいます。
B_DIFは
B_P(ix,iy)=K(係数のことです)*B_M(ix,iy)+B_M(ix+1,iy)-B_M(ix-1,iy)
といった感じのサブルーチンです。functionで表していないのは、ややこしい関数があるので、サブルーチンでまとめてメインに返すという手法をとっています。ご了承下さい。

ここで、B_P(☆)の☆には何を入れると適切に動くと思いますか?
☆に
データix,iyを入れるだけで意とするB_P(ix,iy)がでてくるのか、
それとも、ix,iy,B_Mのデータを受け渡すべきか・・

一番の問題は、
B_P(ix,iy)=K(係数のことです)*B_M(ix,iy)+B_M(ix+1,iy)-B_M(ix-1,iy)
にix,iyを送ったとき、B_M(ix+1,iy)などが意図する値を吐いてくれるのかということです。
ix=1,iy=2でB_DIFのルーチンにおいて、
B_P(1,2)=K(係数のことです)*B_M(1,2)+B_M(2,2)-B_M(0,2)
とパソコンが読み取ってくれるのか疑問です。

ちなみに、B_M(1,2)、B_M(2,2)、B_M(0,2)は既知の値です。

頭がこんがらがって、どうすべきかわかりません。
2次元配列の添字の継承・・
よろしくお願いします。

A 回答 (4件)

一応「common ブロックで渡す」と書いたけど, 明らかにそんなことをしない方がいいです. あとでプログラムを見たときに苦しむこ

とが目に見えているので, 素直に引数で渡してください.
    • good
    • 0

「B_P(☆)の☆には何を入れると適切に動くと思いますか」の B_P は B_DIF のことでしょうか? もしそうなら, 「どのような」 (what), 「どのように」 (how) 情報を渡す必要があるのかを決めることになります. まず what については, 必要な情報は K, B_P, B_M, maxX, maxY の 5つでしょうか. それはいいんですが, 次に how の方は, 思い付くのは「引数で渡す」と「common ブロックで渡す」の 2通り. どちらがお好み?


あと, 配列の定義のときは副プログラムなら整合配列 (って言うんだっけ?) が使えるはずですし, メインプログラムでも (Fortran なら) allocatable 属性を付けて定義してから適当な大きさで allocate すればいいはず>#2.
#1, #2 では「Fortran の勉強」と言われてますが, なんとなくこれは「Fortran の勉強」ではすまないような感じがします. もっとはっきりいうと「(言語の問題ではなく) プログラムを組めない」という感じがします.

この回答への補足

>思い付くのは「引数で渡す」と「common ブロックで渡す」の 2通り. どちらがお好み?

引数で渡す方が好きです。ってか前者しかできません。
common ブロックはやり方がわかりません。(テキスト読んでも??な感じでした)覚えたいとは思っているのですが・・とっかかりが無く、習得できそうな気がしません。便利だとは思うんですけどね。

commonを使ったコードあったら教えてもらえると、嬉しいです。
勉強に役立てたいと思います。

補足日時:2008/07/16 16:28
    • good
    • 0

前回の質問からあまり変わっていないようですが、FORTRANの文法は読まれましたか?



●do istep=1,100 のistepはどの計算で使うのですか?

 この値をB_Difの中で使うのであれば渡す必要がありますが、どこにも書かれていません。
(Kの値が istep で変わる場合は istep も渡す必要あり)


●B_DIFF呼び出しの例(未検証) 関連部分のみ記載

注:maxX,maxY の値が定数なら xxxx,yyyy は maxX、maxY の値にする
  変数なら、取り得る最大の値にする


real*8 B_P(xxxx, yyyy)
real*8 B_M(xxxx, yyyy)

・・・

call B_DIF(B_P, B_M, maxX, maxY)

・・・


subroutine B_DIFF(B_P, B_M, ixmax, iymax)

real*8 B_P(xxxx, yyyy)
real*8 B_M(xxxx, yyyy)

do ix=0,ixmax
do iy=0,iymax
B_P(ix,iy)=K * B_M(ix,iy) + B_M(ix+1,iy) - B_M(ix-1,iy)
end do
end do


●xxxx,yyyyが大きすぎてエラーになる場合は、配列の要素毎に渡してください。

 ・二次元配列の要素で計算に必要な値を渡す。
 ・計算結果は1つなのでfunctionが使える

B_P(ix,iy) = B_DIF( B_M(ix,iy), B_M(ix+1,iy), B_M(ix-1,iy) )

・・・

real*8 function B_DIF(a, b, c)

B_DIF = K * a + b - c
return
end

この回答への補足

●do istep=1,100 のistepはどの計算で使うのですか?
すいません、書くの忘れてました。

if (mod(istep,nwrite).eq.0) then
ic=ic+1
って感じで使っています。
nwrite刻みでファイル出力する形をとっています。
nwriteはintegerで定数定義しています。
上記の後に、
isen=ic/1000
ihun=mod((ic/100),10)
iten=mod((ic/10),10)
ione=mod(ic,10)
*
ofile='temp.'//char(48+isen)
&//char(48+ihun)//char(48+iten)//char(48+ione)
write(6,*) ic,ofile
open(16,status='unknown',file=ofile)
が続きます。

補足日時:2008/07/16 16:17
    • good
    • 0

何がしたいのか・・・


subroutineにしてもfunctionにしても、
副関数で定めた引数を渡さないとダメですよ。

>パソコンが読み取ってくれるのか疑問です。
ためしてみました?

おそらくFortranの基礎がまったくわかっていないのが問題です。
勉強しなおしてください。

この回答への補足

試しました。
うまく動作しない!!との事実だけがわかりました。
で、デバック作業してるんですが、、、
正直、B_P(ix+1,iy),B_P(ix,iy)とかを別途、functionで定義して、それとのやり取りをして、メインに返すのがいいのかなと思ったんですが、それだとごちゃごちゃするので、もっとスムーズに組めるのではないかと思って、皆さんに尋ねています。

補足日時:2008/07/16 16:11
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!