FORTRAN W

このエントリーをはてなブックマークに追加
942933:2012/03/03(土) 17:59:25.10
>>939-941
重要な情報,ありがとうございました。
昨日,Amazonで注文したのですが,今,慌ててキャンセルしました。
言われてみれば確かに,表紙には

High Quarity Content by WIKIPEDIA articles!

と書いてあるし,裏表紙にも

Please note that the content of this book primarily consists of
articles available from Wikipedia or other free sources online.

と書いてありました。まったく大損するところでした。
自分のメディア・リテラシーの低さを自覚しました‥‥。
ともあれ,アドバイスして下さり,本当にありがとうございました!
943デフォルトの名無しさん:2012/03/06(火) 20:11:36.89
Windows用の HPFってないんでしょうか?
944デフォルトの名無しさん:2012/03/06(火) 22:28:46.61
はい
945デフォルトの名無しさん:2012/03/06(火) 22:48:57.51
>>943
富士通だったかがHPFをMPIに変換するトランスレータをフリーで供給していた記憶がある。
もしかしたらLinuxだったかもしれない。

あとPGIのFortranCompilerの古いヴァージョンはHPFに対応していた。今のもしているかも。
946943:2012/03/07(水) 17:23:19.93
>>944-945
お答え,ありがとうございました m(_ _)m"
947デフォルトの名無しさん:2012/03/08(木) 00:08:02.12
∬dxdy[0:pi][0:pi]f(x)f(y)*(erf(a|x-y|)/|x-y|)
f(x) = x^2+1
f(y) = sin(x)
の積分をするにはどのようにプログラムすればいいでしょうか?

1, 変数を変換して積分 x-y = r
2, そのまま積分

どちらでやればいいでしょうか?
もしかしてどちらでもできますか?
948デフォルトの名無しさん:2012/03/14(水) 12:35:28.45
フォートラン in 原発?
949デフォルトの名無しさん:2012/03/14(水) 22:46:09.43
電力はFORTRAN。
社会保険庁の年金システムもFORTRAN。 
何年か前にANAがシステム入れ替えで発券機トラブルを起こしたけど、元の問題なく動いていたのはFORTRANだお。
950デフォルトの名無しさん:2012/03/14(水) 23:09:55.88
フォートラン光
951デフォルトの名無しさん:2012/03/14(水) 23:32:06.21
なぜか東八郎がおもいうかんだ
952デフォルトの名無しさん:2012/03/28(水) 23:46:43.47
「n個のデータを大きさの順番に並び替えたときに、同じ値が連続して出現する個数とその組数を出力」したいのですが
並び替えの後、エラトステネスのふるいの要領で求める値を出すプログラムを作ろうとしたところで頭がごちゃごちゃになって挫折しました

初心者が、求める結果の出せるプログラムを書くにはやはり参考書やネットの入門編を1から読んでFORTRANの体系のようなものから学ぶしかないのでしょうか。
自分の今まで作ったものとは全く異なる文章をプログラミングの上級者がプログラムにどうやって変換しているのか、そのプロセスというかコツをもしよければ教えてください。

息抜きがてらの愚痴ですみませんがお願いします
> 初心者が、求める結果の出せるプログラムを書くにはやはり参考書やネットの入門編を1から読んで
> FORTRANの体系のようなものから学ぶしかないのでしょうか。

全然何もしてないなら、それはやるべきだが。
アルゴリズムの勉強と、それをFORTRANで書く勉強とは別だからねー
前者ができていれば、極端な話、後者は泥縄でもいいんだけど
954952:2012/03/29(木) 01:36:02.22
>>953
やはりアルゴリズムの勉強がやや不足してたようで、
そこをはっきりさせてから書くようにしたら何とか出来そうです。

プログラミングに触れるのはFORTRANが初めてでアルゴリズムを勉強する、という意識がそもそもありませんでした…
(ifやdo文を覚えるだけで後は皆さん自力で何とかしてるものとorz
初歩の初歩ですが自分の躓いている所がはっきりしました、大変助かりました
955デフォルトの名無しさん:2012/04/11(水) 23:14:15.28
グローバル変数が嫌われている理由について、教えてください。
私は研究で流体力学の数値計算をしていますが、
どうもグローバル変数を使っていけない理由がわからないです。

自分で調べたところ、
1,変数名が増えると、重複する可能性が出る。
2,どこで値が変わったのか分からなくなる。
などが理由として挙げられていましたが、
数値計算に限ると、
1に関しては、密度ならrhoとか圧力ならprsとか
物理量に関する名前にすれば、中身がすぐに分かるし
文字制限もないので重複することは滅多にないのでは?と思います。
また、2の場合、基本的に物理量は値が変化するものなので
あまりデバッグの際に気にすることではないのでは?と思います。

私の業界で有名な方のコードを見たところ、
サブルーチンの引数はなく、
全ての変数がグローバル変数になっていたくらいです。
最も、90年代の古いコードなのですが。

時代の流れ的なものなのでしょうか?
956デフォルトの名無しさん:2012/04/12(木) 00:13:13.49
>>955
アルゴリズムとかの研究じゃないなら、計算結果が間違ってないことが
最優先だろうし、何より重要な部分は論文などでまとめてるから、
可読性や再利用のしやすさは二の次なんじゃない?
自分はグローバル変数使うのは定数くらいにするようにしてる
957デフォルトの名無しさん:2012/04/12(木) 01:11:42.78
利点・欠点がわかっていれば
杓子定規に嫌う理由はないと思う
958デフォルトの名無しさん:2012/04/12(木) 01:23:37.97
大域変数を使うなとか、GOTO文を使うなとか言うのは、ワンフレーズプロパガンダだから話半分でいい。
ただ、なんで駄目なのかピンとこないうちは使わないほうが良く、ヤバさを感じ取れるなら使っておk


77までのFORTRANで引数にしないで大域変数にしがちだったのは、構造体がなかったためでもある。

構造体が無いと、深いルーチンでしか使わないパラメータの束を、引き渡すためだけに、
それを使用しない親ルーチンの引数としてだらだら並べないといけなくなって見苦しく面倒になる。
そこで構造体がわりに名前付きCOMMONに固めて渡したりした。

何を引数で渡して、何をCOMMONで渡すかはセンスの問題なので、一定の方針を決めた上で好きにすればいい。
959デフォルトの名無しさん:2012/04/12(木) 01:30:46.57
言語の機能を知るにつれ意外に使わずにすむようになるものでもあって
使わない書き方を工夫してそれに慣れるのも教育的ではあるが
あくまで本業は流体力学だもんね
960デフォルトの名無しさん:2012/04/12(木) 02:08:29.69
小さいプログラムならどっちでもいい。
大きくて複雑になればすべてグローバルだと変数が増え把握管理が人間の手に負えなくなり
開発効率が下がりバグが増え読みにくくなり結局開発に失敗する
いいことなにもない
そういうソフトウェア工学の基本中の基本。
基本中の基本中の基本中の基本。
不味さがわからないなら経験とセンスの問題だから>>958の認識でいいだろう。
961デフォルトの名無しさん:2012/04/12(木) 02:46:18.53
皆様、コメントありがとうございます。
やはり、自分の経験不足なんですかね?

>>956
定数だけで書けるのですか?
例えば自分の場合、基本的な物理量だけでも
15個ほどあります。
それを、サブルーチンの引数にすると、とても長くなってしまい
逆に読みづらくなるんじゃないかと思ってしまいます。

>>960
管理というのは、例えば、ある一部分のサブルーチンを
他の人や未来の自分が入れ替える、といったことでしょうか?
私のボスは、コード全体を把握してないのなら、いじってはいけない
という方針だったのですが、
それはプログラムが小さかったから通用する話なのですかね?
962デフォルトの名無しさん:2012/04/12(木) 03:11:08.30
>>961
変数の管理・把握というのは:
何という名前・型の変数が何個あり、それはどこでどのような使われ、どういった意味の数値を記憶させる変数なのか
と言った、変数の仕様を人間が把握し管理すこと。

プログラムが大きくなりステップ数が何十万何百万となり、変数が半百何千何万となってきたときに、
すべてグローバルだとそれらの把握・管理人の手に負えなくなる。
しあkし真にグローバルであるべき物だけをグローバルにし、ローカルにすべき物はローカルにしておくと、
あるプログラムの一点から見える変数やサブルーチンの数は大幅に減り、人間の手に負えるレベルの複雑さに
できる。それによって大きいソフトウェアがなんとか作れるし、
ソースコードの見やすさ、改良や拡張のしやすさも向上する。

ボスが言う「コード全体を把握してないのなら、いじってはいけない」の真意は直接聞いていないので想像になるが、
良く理解できていないソフトウエアが正しく動いているのであればヘタにいじって
バグ入れたり劣化させるよりも、いじらない方がまだましみたいな意味じゃないかと思うよ。
963デフォルトの名無しさん:2012/04/12(木) 03:15:02.31
プログラムの各部分の意味が変数名だけで(どうにか)分かるのだとしたら
行数などの見た目はどうあれ、小規模で単純なプログラムということになるが

プログラミングじゃなくて数値計算が目的なんだろうしボスが付いてるようだし
現実問題として、規模とプログラミング教育上の問題以外に大域変数を使っていけない理由はない
964デフォルトの名無しさん:2012/04/12(木) 03:17:24.16
ん?全部グローバルにしていいかって意味じゃないよね?
965デフォルトの名無しさん:2012/04/12(木) 03:29:19.03
>>964
話の発端に書かれていたような、全部グローバルはさける「べき」でしょ
でも全部グローバルで差し障りがない規模のプログラム
たとえば数百〜1000行くらいまでなら>>963の言うとおりかもでしょ。
966デフォルトの名無しさん:2012/04/12(木) 03:39:22.93
>>962
既存のコードを拡張する必要があったのですが、
そのときに、コードの最初から最後まで読んで把握しなきゃダメだよ、
と言われたんです。

>>963
確かにそうなんですが、
それゆえに、周りもプログラミング技術自体には無頓着だし、
また、お手本もfortran77で書かれた古いものが多いんです。

ですが、私はまだ院生なので、
将来のことを考えると、もっと新しい技術を取り入れたほうがいいのかな?と思いまして。
(最初はお手本通りに、全てをCOMMONでグローバルにしてたのですが、
そういうのは古いやり方ってのを知りまして・・・
モジュールとか構造体とか使ってみようかな、と。)
967デフォルトの名無しさん:2012/04/12(木) 07:22:01.47
OpenMP 使ってたときは、common で困ることはなかった。
MPI に移行する時、ちょっとというかだいぶ手間取った。
結局、いちど全変数をargument で渡すのにしてから
Module 化。

Module Use ってファイル内の前後関係に
気を使うので、嫌いだ。
968デフォルトの名無しさん:2012/04/12(木) 10:43:43.75
COMMONの注意点だが、規格の上では無名COMMONはSAVE属性が付いているが、名前付きCOMMONはデフォルトではSAVE属性無い。
ただ66以来の歴史的事情でSAVEが付いているように扱われることが多い。
そのうち規格原理主義みたいなのが出てくるとめんどくなる。コンパイラオプションで対応できるようになると思うが。
969955:2012/04/12(木) 19:39:46.64
955です。何度もすみません。
今、書いているプログラムについての情報を書くので、
みなさんならどういう構造にするか、具体的なアドバイスをいただけませんか?

今のプログラムは、100〜200行程度のサブルーチンが10個ほどあります。
メインプログラムには、サブルーチンの呼び出しと簡単なdoループくらいしかなく、
流れが分かるようにしてあります。
サブルーチンは外部副プログラムとして、書いてあり、
順次、継ぎ足していきます。最終的には、今の2、3倍くらいになると思います。

・プログラムの内容は、流体計算で、物理量を時間発展させたい。
・プログラム全体にわたって出てくる物理量は15個程度。
・ファイルがバラバラになるのが嫌なので、一つのファイルに全て書きたい。

で、最初は全部グローバルにしていたのですが、
みなさんの話を聞いて、ローカルも取り入れてみようと思い、
パラメータと基本物理量だけを別ファイルにモジュールとして書いてみました。
ですので、今のプログラムは
プログラム+サブルーチン群と変数宣言のみのモジュール、の2つです。

問題は、変数の宣言についてなのですが
例えば、サブルーチンAからサブルーチンBに変数を引き渡すとき、
宣言を、メインプログラムとAとBの3つに書かなければいけないですよね?
それがとても冗長に感じてしまいます。
また、引数の数も10とか20とかあります。
モジュールにまとめればよいのかもしれませんが、
そのまで大規模なプログラムでもないし、という感じです。

皆さんならどうするか、アドバイスお願いいたします。
970デフォルトの名無しさん:2012/04/12(木) 23:40:39.30
>>969
一から自分で書くわけじゃないなら、見た目が悪くなるから
これまでのは人と同じようにcommonで書く
一から書き直すなら構造体で変数をまとめてcommonなしで書く
971デフォルトの名無しさん:2012/04/13(金) 00:36:58.32
冗長といっても、その外部副プログラムが
大域変数の存在と型とメモリ配置を知るには
書いてくれないと困るわけで。

include 文なり、プリプロセッサが使える環境なら
#include なりで、定義を1ファイルに纏めることはできる。
972デフォルトの名無しさん:2012/04/13(金) 16:13:29.35
お二人とも、アドバイスありがとうございます。

>>970
1から書いています。
昨日、パラメータと基本物理量以外は全てローカルに直すことに成功しました。
あとは、基本物理量をローカルにするだけです。

構造体は使ったことがないのですが、
おっしゃっていることは、このような感じのことでしょうか?
3つの流体変数を時間発展させていくサンプルプログラムです。(若干、端折っています
構造体の要素の代入文のせいで、サブルーチンが
長くなってしまうのは、仕方がないですよね?
まだ、削れるところありますか?
973デフォルトの名無しさん:2012/04/13(金) 16:15:27.76
program main
  implicit none
    type arg
       real(8) :: a(0:n),b(0:n),c(0:n)
    end type arg
  type(arg) :: old,new

  do i = 1, m
    call subevo(old,new)
    old = new
  end do
end program main
subroutine subevo(old,new)
  implicit none
    type arg
     real(8) :: a(0:n),b(0:n),c(0:n)
    end type arg
  type(arg),intent(in) :: old
  type(arg),intent(out) :: new
  old%a(0:n) = rho(0:n)
  old%b(0:n) = vel(0:n)
  old%c(0:n) = ene(0:n)
  ここで計算する
  new%a(0:n) = rho_n(0:n)
  new%b(0:n) = vel_n(0:n)
  new%c(0:n) = ene_n(0:n)
end subroutine subevo
974デフォルトの名無しさん:2012/04/13(金) 16:26:25.60
便乗の筆問だけど、972の例で
new%a new%b new%c
ってメモリ上はどういう順番で格納されるのかな?実装しだい?
つまり new 構造体と
なんか、 new(0:n,3) みたいに添え字で処理(これは型が同じでないと
いけないわけだけど)するのとで
計算のぱふぉーまんすとか変わるのかなぁ、と思った次第。
975デフォルトの名無しさん:2012/04/13(金) 22:45:21.31
>>974
実装次第だな。
Fortran2003で、Cとの相互運用用の命令が導入されてその中に、TYPEのSEQUENTCE属性が導入されて、
これが付いているとメモリー上で宣言順に並べて割り付けられる。
976デフォルトの名無しさん:2012/04/14(土) 01:51:10.69
>>972
サブルーチンもmainと同じファイルに書いているなら
contains使った方がいいかな
977デフォルトの名無しさん:2012/04/14(土) 01:58:19.31
構造体定義も module で持っていける

subevo() 内は old → rho →(計算)→ rho_n → new っぽく見えるけど
サブルーチン内部の配列は無駄じゃないか?

module my_struct
type arg
real(8) :: rho(0:n),vel(0:n),ene(0:n)
end type arg
end module my_struct
program main
use my_struct
implicit none
type(arg) :: old,new
!- 中略 -
end program
subroutine subevo(old,new)
use my_struct
implicit none
type(arg),intent(in) :: old
type(arg),intent(out) :: new
!- 中略 -
end subroutine subevo
978デフォルトの名無しさん:2012/04/14(土) 06:26:26.00
アドバイスありがとうございます。

>>976
わかりました。

>>977
二つ、質問が。

そのmoduleの使い方は、includeと同じだと考えてよいですか?

>subevo() 内は old → rho →(計算)→ rho_n → new っぽく見えるけど
ええと、これは old →(計算 → new のほうがすっきりする、てことであってますかね?
rho_nのほうはなくせるかもしれませんが、
方程式が
new = f(rho,vel,ene)みたいな感じの非線形連立方程式になっているので
右辺に出てくる変数を、arg%rho(0:n)とかarg%vel(0:n)とかで書いていくのは
大変じゃないかな?と思いました。
なので、引数のときは構造体で引き渡して
計算のときは要素にバラしたほうがいいのでは?と。
979デフォルトの名無しさん:2012/04/14(土) 06:32:15.86
すみません
>old%a(0:n) = rho(0:n)
>old%b(0:n) = vel(0:n)
>old%c(0:n) = ene(0:n)
ここ、左辺と右辺が逆でした
980デフォルトの名無しさん:2012/04/15(日) 00:08:24.22
>わかりました。
うーん、わかってもらえなかったみたいだな。
contains使って内部副プログラムとして書けば、oldだのnewだのを引数でやり取りする必要がなくなるんだけど。
981デフォルトの名無しさん:2012/04/15(日) 01:26:55.15
>>978
> include と use module
結果としては同じ

大雑把な言語解釈を言うと include は指定ファイルの"記載"を引用し
use module は module ブロックで記載された"定義"を引用する
ちなみに module を使うとコンパイラーに引数の型一致が保証できる、はず

> サブルーチン内配列
理由があるなら別に構わない

ただ、n が大きいならばそのぶんメモリ消費と
メモリコピーの処理時間が上乗せされると思う
先進的 (Fortran 2003) な手段が使える&使っていいなら
type に procedure を持たせて call old%propagate(new) みたいにするとか
982デフォルトの名無しさん:2012/04/15(日) 01:27:31.54
>>980
containsで引数がいらなくなるのは、
モジュールでグローバル変数化したときだけじゃないんですか?
自分的には、contrainsのメリットは
引数の型をチェックしてくれるってことだと思ってました
983デフォルトの名無しさん:2012/04/15(日) 05:30:24.59
引数型チェックは
Interface ブロックでやってる。

複数やり方があるのは
いうことなんだろうけど、面倒だよね
984デフォルトの名無しさん:2012/04/15(日) 13:55:55.84
981 だが
> type に procedure を持たせて call old%propagate(new) みたいにするとか
これ解決案になってなかったスマン
結局 new%rho = this%rho とか書くから意味ない

内部副プログラムはその親になるプログラムの変数定義を参照できるが
親以外からは呼び出せなかったかな
985955:2012/04/15(日) 22:33:34.13
もうすぐ1000いきますね。
皆さま、長く付き合ってくださりありがとうございます。

色んな機能を教えていただき、まだ全然理解していないのですが
COMMONをINCLUDEして全てをグローバル変数にしていたコードは
・パラメータのみをグローバル変数にし、モジュールで定義
・基本物理量は構造体にまとめる
・intent文をつけて構造体をサブルーチン間で引き渡す
という感じになりました。

containsとinterfaceについては、まだよくわからないので
これから調べてみます。
本当に、いろいろやり方があって
どれが最善なのかは、わかりませんね・・・
メモリ消費のことまでは、まだ頭が回ってないです
(小規模なプログラムなので、まだ大丈夫かな・・・)
986955:2012/04/15(日) 22:55:46.34
すみません、こんなの見つけたんですけど。
>2)親手続き中で使われている変数名,配列名などは内部手続き中でも有効で,共通
>の値を持つ。

>>982は間違ってました
もし、>>980さんのいうように、全てのサブルーチンをcontainsで
main programに入れたら、それって結局
全ての変数をグローバル化するのと同じになりませんかね?
よくわかんなくなってきた・・・
987デフォルトの名無しさん:2012/04/15(日) 23:38:01.86
>>986
そのとおりじゃ。
メインプログラムでのCONTAINSは危険だから止めとけというのが言い伝えじゃ。
ModuleでのCONTAINSと比べて、ループ変数のi,jの類を共有してしまうので危険がいっぱいおっぱい。
988955:2012/04/16(月) 03:38:45.38
>>987
さいきん、ネットにある色んな専門家の資料とか読んで勉強してるんですけど
外部サブプログラムは非推奨、っていう記述を良く見かけるんですよね
理由はよくわかりませんが、引数の受け渡しの際にバグが起きることを
危惧しているのかな?
でも、contrainsを使うと、変数は親子結合してしまうわけですよね
それって、グローバル変数と変わらないような。
人によって言ってることが違くて、わけがわからないっす・・・
989デフォルトの名無しさん:2012/04/16(月) 11:05:15.12
外部サブプログラムというのが何を指しているのか不明だが、たぶんMODULEの中に入っていない野良ルーチンのことだと思う。
これは分割コンパイル時の引数のチェックがなされないのでやめたほうがいい。
メインのPROGRAM中のCONTAINS中のサブプログラムもやめたほうがいい。
それはメインプログラムのローカル変数(DOLOOPのインデックスとか中間変数とか)もグローバルにサブプログラムに共有されて
しまうから。MUDULEの場合、まさかi,jとかtmpとかを共有変数にはしまい。

やや上級者向けだが、最近こういう本が出ている。 Modern Fortran: Style and Usage Norman S. Clerman、 Walter Spector
初級向けは、今は廃れてしまったが、いわゆる Essential Fortran / F と呼ばれるFortran90から過去互換性を捨てた教育用Fortranの
教則本が良かった。Essential Fortran 90 & 95 Loren P. Meissner
買わずともネットで関連の文書が読めた気がするのでその辺を見て見てはいかがか。

わしは大昔にLaheyのELF90を買ってそのマニュアル、(今はPDFしかないが昔は紙版がついてきたので)、それだけ見るようにして勉強した。
ただこれはF90でF95水準ですら無いので今はややおすすめできない。
990955:2012/04/16(月) 16:59:17.19
>>989
>これは分割コンパイル時の引数のチェックがなされないのでやめたほうがいい。
これだけが問題なら、>>983さんのやり方で解決しそうな気がします。
モジュールのなかに入れれば、すっきりしそうです
モジュールのなかぶサブルーチンをcontainsするのは
個人的に好きじゃないです・・・
中身を常に見ておきたいので(ブラックボックス化するのがオブジェクト指向?)

>MUDULEの場合、まさかi,jとかtmpとかを共有変数にはしまい。
え、すみませんw
doloopのintegerを普通に共有変数にしてました

991デフォルトの名無しさん
>>984
>内部副プログラムはその親になるプログラムの変数定義を参照できるが
>親以外からは呼び出せなかったかな

F2008から内部サブプログラムを引数(引関数?)として、別のサブルーチン
等に渡せるようになった。Intelは対応している模様。

しかし寿命が親ルーチンが動いている間なので、ポインターをつけて返り値
(返り関数?)とするとNULLになって死ぬ。

Modern Fortran Explained 20.5.5 p.370