くだすれFORTRAN(超初心者用)その4at TECH
くだすれFORTRAN(超初心者用)その4 - 暇つぶし2ch166:デフォルトの名無しさん
09/04/19 14:15:43
>>164
MPI2にそんな機能があったような

167:164
09/04/19 20:21:55
>>165
directアクセスの存在を始めて知りました。
レコード長を把握しておく必要はありますが、効率は良さそうですね。

実際の使い方としては、recl指定子の値をデータの最小サイズで与え、
読みたいレコードの位置を逆算してread文のrec指定子に与える、
という方法で合っていますか?

>>166
なるほど。ということは、Fortranの実装とは別の機能を用いる方法もある、
つまりやり方は色々ある、ということでしょうか。

168:164
09/04/19 20:54:59
>>167の補足ですが
>recl指定子の値をデータの最小サイズで与え、
と言うより、そのファイルを作ったときのwrite文のreclと同じ値をread文のreclに与える、
と言ったほうが適切でしょうね。

あと、使っていて気づいたことなのですが、statusを指定せずにopenしてwriteする場合
 sequential・・・いったん元のファイルを消した上で書き込み
 direct・・・ファイルのレコード位置に対する書き込み
という違いに気をつけないといけませんね。文法的に正確に書けば
 sequential・・・強制的にstatus='replace'
 direct・・・ファイルがあればstatus='old'、なければstatus='new'
でしょうか。

169:デフォルトの名無しさん
09/04/20 17:42:55
ちょっと質問というか確認

ディスクがフラグメンテーションしてる場合、データの分断を許すような
実装だと、ディスクへのアクセスはアドレスのテーブルみたいのを参照
しながらじゃないと原理的にできないよね

フラグメンテーションしててもデータの分断を許さないような実装なら、
ディスクスペースの使用効率は下がるかもしれないけど、テーブル参照が
不要になるからアクセスが速くなるはず・・・だよね?
速度を要するスパコン用のファイルシステムって、そういう実装なのかなぁと想像・・・

170:デフォルトの名無しさん
09/04/20 23:17:11
>>167
ダイレクトアクセス知らなかったのか。
>直接アクセスする
とか書いているから知ってるかとw

昔の映画のコンピュータで磁気テープがグルグル回っているのはダイレクトアクセス
ファイルを読み書きしているんだべなぁ。

171:デフォルトの名無しさん
09/04/21 03:39:52
テープが
今で言う、ディスクとメモリの両方を兼ねてたからね。

ほんのちょっと前にFACOMのやつにテープはめるのをした。
あれ、テープのはしっこを挿入口に近づけると空気で吸い込んでくれるのね。
人間の手で全部とりまわさないといけないのかと思ってたよ。

172:164
09/04/22 15:52:56
>>170
不勉強故、失礼しました。

ところで、磁気テープというのは今も使われているものなのでしょうか?
今、20半ばの院生ですが、テープというのを見たことがありません。

173:デフォルトの名無しさん
09/04/23 01:43:48
fortranで円やら球を離散化?させたい。
円の場合
function X(a)
X=cos(3.14*a/360)
end
function Y(b)
Y=sin(3.14*b/360)
end
こいつを回せば、円をつくることはできる。でもXは小数点の数字になっているよね。
でもやりたいことは、2次元配列を作成して、F(x,y)のx-yのメッシュの中で
円を作成するには、x-yは整数である必要がある。どうすればいいの?
わかる人いますか?
この円・球構造について、拡散方程式やら偏微分方程式を解きたいと思っているんだけど、
こういうことってできますか?

174:デフォルトの名無しさん
09/04/23 03:11:15
すなおに極座標なり円柱座標にするがよろし

175:デフォルトの名無しさん
09/04/23 06:57:36
>>173
メッシュが正方格子でなければならない理由はあるんかいな?
Yesならメッシュを細かくするしかないなぁ・・・

節点座標値が整数でなければならない理由はないと思うょ

176:デフォルトの名無しさん
09/04/23 09:04:46
球や円を特徴的な構造として持つ系にカルテジアンを無理矢理持ち込むのは無理があるにょ
ギザギザがでるし、30度とか45度回転させた初期値境界値で同じ計算すると結果が結構違うにょ。
査読受けたら絶対そこを突っ込まれるにょ。
んで満足いく事例を出せなかったらそこで終わりにょ。
学部生より上なら極座標なり175の言う通り非構造格子にしてきちんとするのがいいにょ。
学部生なら、卒研としてならまあ許されると思うにょ。・・・Fortranと関係なかったにょ。

177:デフォルトの名無しさん
09/04/24 00:48:54
>>173
どうしても直交座標にしたいなら、かなり細かくメッシュを区切って、
計算結果にある値をかけて、整数にするとか。

新しく買ったCorei7で計算させたら、滅茶苦茶速くてびっくりした。
PenMのノートで10分かかる計算が1分で出来て、しかも8個同時に走らせても余裕。

64bitOSを積んだから、というのもあるのかな。

178:デフォルトの名無しさん
09/04/24 05:33:49
>PenMのノートで10分かかる計算が1分で出来て、
まあ、これはそうだろうなあ。

>しかも8個同時に走らせても余裕
へえ。よさそうだね。
余裕、というのは「一個の時のまあ8割くらいのスピードで8個とも動く」くらいなの?

179:デフォルトの名無しさん
09/04/24 16:38:50
>>175 メッシュが正方格子でなければならない理由はあるんかいな?

教官から貰ったコードが正方格子のだったけど、
変更できない、とかかな?
そもそも173のやりたいことがいまいちよくわからない。
Fortranとは関係ないし、ここまでかな

180:デフォルトの名無しさん
09/04/25 00:30:02
>>178
特に並列化をしていない(というよりも、並列化がうまくいかなくて結局諦めた)ものを走らせると
大体16%ぐらいのCPU使用率になるから、
8個ぐらい走らせると100%使い切るようになるからね。
この使用率からすると、たぶんそれぞれ8~9割で動いているといったところかな。

うまいこともっと最適化できないかな・・・。

181:デフォルトの名無しさん
09/04/25 00:40:55
>>180
物理CPUは4個だろうから、よほど例外的な場合でなければ多分4つより大だと帰って遅くなるだろう。

182:デフォルトの名無しさん
09/04/25 14:40:15
178です
>>180
ありがとう。
少なくともOSが認識する使用可能なリソースはフルに使い切れるんだね。
>>181
Xeonの2コアが4つ乗ったマシンでOpenMPを走らせると
きれいに8倍になってくれたけど、これとはまたいろいろ設計が違うんだろうな。


183:デフォルトの名無しさん
09/04/26 01:08:12
>>181
よく考えたらそうだよなあ…
実際時間を計ってみたら、8個計算の時間 / 2 > 4個計算の時間だし。
ただ、実際には数百から数千個計算するし、それぞれ条件が違うから時間もバラバラで、
その待ち時間を埋めるために、まとめて計算するほうが速かったなあ。

プログラム内でうまく並列化をしてフルに使い切れればいいけれど、なかなかうまくいかないんだよな…。
OpenMPをコマンドを入れたら、かなり遅くなったし。

184:デフォルトの名無しさん
09/04/26 11:27:08
>>183
なるほど~。
どちらかというとたくさんある計算をぼんぼん
放り込んでおける、事がメリットなのかもね。
そうなるとqueueの管理の仕方がみそ?

185:デフォルトの名無しさん
09/04/26 13:12:42
>>183
Corei7は、物理4コアをハイパースレッディングで見かけ8コアにしている。
純粋に計算などが重い場合ハイパースレッディングは足を引っ張るだけ。
そのばあいは4スレッドで動かすほうがいい。

MKLのLinpackのBenchmarkをやってみるとどのくらい遅くなるかわかる。
OpenMPのオプションでスレッド数を物理コア数に合わせるようにすると本来の力を発揮する。
あるいはBIOSでハイパースレッディングを切るとかいう手もある。

ただハイパースレッディングが有効な場合もあるので、個別の事情に依る。
自分で試すしかない。

186:デフォルトの名無しさん
09/04/26 15:36:02
MPIなりOpenMPで4並列のジョブを放り込んだばあい、
ちゃんと1プロセス/1CPUにふってくれるのかな?

187:デフォルトの名無しさん
09/04/26 23:50:26
>>186
いや、なんか環境変数にそれなりの指定をしないと、1スレッド1物理プロセッサに
必ず行くとは限らないので遅いまま。
OpenMPのマニュアルの環境変数のところを読めば書いてあったはずだが、
詳しくは忘れたw

188:デフォルトの名無しさん
09/04/27 12:50:57
なるほど・・・。

どちらかというと、dplace や mpirun みたいな並列実行の環境を調えるソフトの
とりあつかう領域だね。dplaceだと
dplace -c1,3,5,7
かな?実機でもってるわけでもないし、いまマニュアルが見れないからわかんねw

HTがあると並列しながら、ふつうの文房具的にPCやWSを使えるわけだから
使い方次第では結構いいかもなあ。

189:デフォルトの名無しさん
09/05/02 11:50:18
冗長な部分があってもいいから現在使っている配列の全てをバイナリに書き出して計算の中断ファイルを
作りたいんですけど、書き出す配列を全部列記する以外に楽な方法ってないでしょうか?

190:デフォルトの名無しさん
09/05/02 19:37:29
>>189
もう一回計算しなおせ!w
データを後生大事に取っておくのは演算コストが高かった時代の名残。

むろん演算量にもよるがw

191:デフォルトの名無しさん
09/05/02 20:33:05
>>189
目的がよく分からないんだけど
コード中の全ての配列をはき出すってこと?

192:デフォルトの名無しさん
09/05/02 22:53:03
>>189
行列がスパースなら,非ゼロ項を書き出すことにすれば,ちょっとはマシな気がする。

193:デフォルトの名無しさん
09/05/03 04:00:14
>>189
配列の全ての成分を書き出せば良いのであれば

integer a(1:10000)
real b(1:100,1:100)

write(10)a,b


とかではダメか?

194:デフォルトの名無しさん
09/05/06 06:16:46
>>190
デバッグとかあるし。
大型計算機とかだと、1計算の時間上限があるからね。
再開するのに必要な情報を全部ファイルとして書き出す選択肢は
持っていた方が良いと思うにょ。
>>193
それがいちばんだね。
書式指定無しでファイルにたたき落とす
違うシステムでは役に立たないけど、メモリの内容をそのままファイルに落とすので
書き込みも読み込み+計算再開も速い。
書式付きもできるけど、めちゃくちゃ遅いし。

195:デフォルトの名無しさん
09/05/08 14:33:24
>>194
デバッグ目的以外で、メモリの中身を全部ダンプする必要性が分からないんだが・・・

今時の計算は反復計算などの単純なループ部が計算のほとんどを占めてて
ループ開始前の前処理なんて全体から見れば知れてるわけで、
次回リスタート用のためにわざわざメモリのスナップショットを取る的な発想は今時ないでしょ。
メモリとストレージの速度差が開く一方の今日じゃなおさら・・・・

196:デフォルトの名無しさん
09/05/09 04:28:25
理由は194が最初に書いてね?
195はあまり大きな計算はしたことがないんだろうな

197:189
09/05/09 15:11:48
遅くなりました。
あー…書き方があいまいですいません、答えてくださった方ありがとうございます。
えと、粒子法的計算なんですけど、191さんがおっしゃっている通りです。
コード中のすべての配列をはきだしたいです。
193さんのやり方は当然わかりますけど、それだとwriteの後に吐き出したい配列を
列記しないといけませんよね。そういうの無しで全配列をばーっと吐き出す方法ないかな、
と思ったわけです。やっぱ使う配列をコツコツ列記するしかないみたいですね。

>>195
非定常計算なんで状況によっては計算途中の段階から少しだけ条件を変えて
計算したいとかあるんですよ。正直にやったら一週間近くかかるので。

198:デフォルトの名無しさん
09/05/09 16:24:49
>>197
質問がひどすぎw

まぁベンダー拡張命令でメモリー全ダンプみたいなことが出来る機種もあった気がするw

199:195
09/05/09 16:47:04
自分には>>189の理由がいまだに分からん・・・(別に分かんなくてもいいけどさ)
たしかに、スパコンでは数日~1週間程度の計算しかしたことない。
大きい計算とは言えんか。

スパコンのジョブってたいてい時間制限が数時間のオーダーだから、
例えば30000ステップ計算したいとしたら3000ステップのジョブを
10回投げるってのが普通だよな。

粒子法はよく知らないけど、格子点はどんくらいなの?

200:195
09/05/09 16:49:29
あ、粒子法ってメッシュないんだっけか?
粒子数だっけ?

201:デフォルトの名無しさん
09/05/09 16:54:07
背景場を途中から変えた計算をしたいのかな?
普通は計算再開に必要な変数の数(配列の大きさではないよ)って知れてるよね。
粒子法なら、粒子の位置・速度と経過時間くらいか。
あとはiterationのプロセス毎に計算する量や座標系のように
再生成に計算量のかからないものがほとんどだろうから、
それをとっておく必要はないし。
ふつうに193のやり方で落とせばいいんじゃね?たいした手間でもなし。

ところで、ダンプして落としたとして、変数の変更はどういう風に再開時に反映させる
つもりだったんだろうか?

202:デフォルトの名無しさん
09/05/09 16:59:47
>>199
同意。細切れ計算するときに継承すべき情報はあるけど、ダンプする理由はないやね。

ふと、189の「配列全部」は別にダンプではないのでは、と思ったけどオイラの勘違いかな?

203:デフォルトの名無しさん
09/05/09 17:01:58
読み返すと、「ダンプ」を最初に使ったのは195さんだw

204:195
09/05/09 17:17:34
ダンプっていうのは大げさでしたなw
イメージ的に使ってしまった

205:デフォルトの名無しさん
09/05/09 17:55:35
無料のfortran77向けのコンパイラで、高速なものはありますか?
用途はCFDです。
まあ趣味なので大きな計算は必要ないのですが。

206:デフォルトの名無しさん
09/05/09 23:52:54
fortran歴1週間の質問です

論理型を整数型その他に変換できますか?
例えば、いくつかの言語では

(a>b)

等とすると0または1が得られますが
これと同等なことをFORTRANでも行いたいのですが方法がわかりません
無理ならすんなり諦めます

207:デフォルトの名無しさん
09/05/10 00:55:29
>>206
一般的な回答としては、できない。

不可能ではないという意味では、IF THEN ELSE でやれば出来る。

意図しているイメージに一番近いだろうと思われるのは、TRANSFER関数で型変換をすること。
しかし、FORTRANの規格では論理型の内部状態を定義していないので
0/1に投影できるかは運しだい。普通は0/-1が多い(真:ビット全部0と偽:ビット全部1)。

208:デフォルトの名無しさん
09/05/10 01:51:22
>>207
早速ありがとうございます
何となくですができました

209:デフォルトの名無しさん
09/05/10 05:17:13
logical lonlon
real    a, b
a=1.0
b=2.0
lonlon = (a .GT. b)
write(*,'(i3)') lonlon

なるものをつくると、
最後の行で型が合わないと怒られる
0がでてくる
1がでてくる
-1がでてくる、
の4パターンあったw
危険だw

210:デフォルトの名無しさん
09/05/10 21:13:40
g77のよく使う高速化のためのコンパイラオプションを教えてくださいませんか。
それかコンパイラオプションをまとめているサイトないですか?
gccのまとめを見ればよいのでしょうか?

211:デフォルトの名無しさん
09/05/10 21:18:17
>>206
どういう用途?
論理型が用意されてる言語なら、特に理由がない限りそういうマネはやめたほうがいいかと
シェルスクリプトレベルならよくやるけどさ

212:デフォルトの名無しさん
09/05/10 21:34:28
>>210
まずググれ。話はそれからだと思う。

213:デフォルトの名無しさん
09/05/11 01:13:00
でも、コンパイラのドキュメントしっかり読んで全部の仕様を熟知してる人なんて、ほとんどいないよな
こんなオプションあんだ・・・でも何に使うんだろ、ってのばっかだ俺w

214:デフォルトの名無しさん
09/05/11 12:22:05
論理型と整数型の混用は、非常に有用な場合もないではないけど、
基本的にはやるべきでない。

215:デフォルトの名無しさん
09/05/11 20:00:38
ちょっとインチキして
logical:: L(1)
L = (2.0 < 1.0)
write(*,*) count(L)
L = (1.0 < 2.0)
write(*,*) count(L)
とか


216:デフォルトの名無しさん
09/05/11 20:37:43
>>214 バグの元じゃない?

217:デフォルトの名無しさん
09/05/11 20:53:39
>>216
3つの条件abcのうち2つ以上が真なら、という場合に、

a = 条件式
b = 条件式
c = 条件式
if (a + b + c >= 2) ...

とか。Cの場合だけど。

218:デフォルトの名無しさん
09/05/11 21:39:08
後でメンテする時、無駄に手間食うからそういうのやめてくれ~

219:デフォルトの名無しさん
09/05/11 22:35:22
1960年代のおばあちゃんの知恵というかライフハックw風のプログラムだな。

220:デフォルトの名無しさん
09/05/13 02:46:28
>>218
4つの式が近くの行にあればいいけど、すごい離れた所にあるといろいろ嫌だよね

221:デフォルトの名無しさん
09/05/22 20:21:01
LOGON TSS

222:デフォルトの名無しさん
09/05/22 22:46:55
>>221
READY

223:デフォルトの名無しさん
09/05/22 23:18:35
Intel Fortran 10 を使っています。
ifort独自文法のform='binary'でファイルを開いてデータ出力しています。

そのファイルはC言語のファイルフォーマットが公開されているんですが、
unsigned int となっている部分をifortで出力する方法がわかりません。

この部分だけC言語で記述して呼び出す形ならできそうな気がしていますが、
Fortranだけで完結させる方法ってありますか?
アドバイスよろしくお願いします。

224:デフォルトの名無しさん
09/05/23 01:55:11
>>223
32bitのunsighned int?
読み込みのほうはINTEGER*4 でうけて、それをINTEGER*8にTRNASFER関数で
適当な位置にコピーするか、出力サブルーチンを作って負数の場合は
INTEGER*8でUINTの場合の数を求めて出すという方法が考えられる。

225:デフォルトの名無しさん
09/05/23 12:05:07
倍精度の変数宣言だけど、

real(8) a
double precision a

どっちやねん、と思ってた。
先日規格を見たら後者だったので、ウヒー!

今後は全部後者で統一する。行が長くなって、チョトいや。


226:デフォルトの名無しさん
09/05/23 12:13:09
>>225
どっちでもいい。後者は昔風の書き方。
今はむしろ前者が主流だと思う。

227:デフォルトの名無しさん
09/05/23 12:40:28
>>226
うーん、こんなHPもあるからなぁ・・・

 4.1 Fortranのデータ型
 URLリンク(www.nag-j.co.jp)

コードを見られる可能性がある案件は、規格にならった方が
よさそうな気もする。

228:デフォルトの名無しさん
09/05/23 17:17:01
>>227
それは、規格違反ということを意味しているわけではない。
KIND種が規格で決められていないためにベンダー依存になっていることを
問題視しているのだろう。
kd = SELECTED_REAL_KIND(14) とかで、8などの定数べた書きをやめてkdなどに
すれば避けられる。

規格の整合性としては REAL ([KIND =] n) の方が統一的でいいとおもう。
4倍精度が大概のコンパイラでサポートされつつある現状を考えると、REAL(n)の
形式にそろえておいたほうが将来的にものぞましいのではないかと思う。

229:223
09/05/23 20:23:06
>>224
回答ありがとうございます。

詳しくないですが、32bitです。
各bitにどうデータが並んでいて、、、ってのを学ばないと難しそうですね。
ちょっとがんばってみます。


230:デフォルトの名無しさん
09/05/23 20:51:52
>>227
むしろreal*8が普通だと思ってた。double precisionはむしろ非推奨って話も聞いたことあるぞ。
>>227のnagのページは全部鵜呑みにして良いのか甚だ疑問だわ・・・

つーか、この問題の責任は100%規格にあるだろう。規格作ったやつ出てこい!

231:デフォルトの名無しさん
09/05/23 22:29:44
>>228
module xx
 integer, parameter :: kd_re = selected_real_kind(16)
  :

programm yy
 use xx
 real(kd_re) a

みたいな感じかな? 一理あるね。

>>230
JIS X3001-1に
 『DOUBLE PRECISION型指定子は、組込みの
 倍精度実数型のデータ要素を宣言するのに用いる』
とあるから、非推奨ってこともないだろ。


232:デフォルトの名無しさん
09/05/23 22:45:57
詳しくは覚えていないが・・・・

FORTRAN66までは倍精度宣言は DOUBLE PRECISION
だけだったのだが、その後の流れで FORTRAN77では REAL*8
Fortran90でREAL([KIND=]8)の形が出てきて、だんだんと
REAL([KIND=]8)の形に統一しましょうという流れだと思う。


>>230
Fortran90策定の頃は、ベンダー毎にアーキテクチャーも数値フォーマットも
文字コードもバラバラだったのでこのくらいは許してやってくれ。

233:デフォルトの名無しさん
09/05/23 23:03:22
やっぱKIND使った方がお行儀がいいのかなぁ
書き直すのマンドクサイっす

・・・あんま移植性に拘りすぎるのもどうかと思うけどね。どうせみんなインテ(ry

234:デフォルトの名無しさん
09/05/27 00:52:40
FORTRAN77では、いくつかのサブルーチンの間で共通の定数を使うとき
それぞれのサブルーチンで何回も同じ宣言をしなければいけないのですか?

このままだと定数の値を変えるのが非常に面倒なので
一回の宣言で済む方法を知りたいです

235:デフォルトの名無しさん
09/05/27 01:05:33
>>234
定数宣言だけのファイルを1つ作って、各サブルーチンの先頭でINCLUDEする。

FORTRAN77の規格外だが大抵のコンパイラはINCLUDE文に対応している。


236:デフォルトの名無しさん
09/05/27 01:08:13
>>234
PARAMETER文を用いてなら、標準では無いw

COMMON 変数でよければ BLOCK DATA 文で初期化できる。

ベンダー拡張機能を許せば、INCLUDE を使う手もある。

まぁ、横着せずにラインエディターで一括変換すればよろしいw

237:デフォルトの名無しさん
09/05/27 01:10:53
ありがとうございます
とりあえずINCLUDE使ってみます

238:デフォルトの名無しさん
09/05/27 01:11:05
>>234
モジュールでもいいぞ

239:デフォルトの名無しさん
09/05/27 02:04:13
>>238
奴はFORTRAN77と縛りを入れている。

240:デフォルトの名無しさん
09/05/27 13:47:45
>>236
entry文を使えば、何とかならない?


241:デフォルトの名無しさん
09/05/27 14:16:15
とくに理由がない限り、77からはさっさと足を洗った方がよくない?

242:236
09/05/27 23:27:51
>>240
たしかにENTRY文という手もあったな。

COMMONが嫌で、グローバル変数を実現する代わりに使ったことがあったが、
やっぱ変数全部がグローバルになるせいでデバッグが面倒で
よほど特殊な場合意外はやめたほうが良いと思った。

243:デフォルトの名無しさん
09/05/31 15:35:51
みなさまのお力をお借りしたく。
#FAQならすみませんが、ご容赦ください

IVF10.1(11でも)動作したソースを、Linux上のintelに持ち込んでコンパイルしました。
すると、以下のケースに分かれました。
1)あえてコード変換をせずにコンパイル
 コンパイルOKも、当然、表示は滅茶苦茶(要するに2バイト系がだめ)
2)SJIS->UTF8にしてコンパイル
 FORMAT文の箇所でエラー発生、これがどうしても直らない。
 ちなみにエラーメッセージは以下の通りです


244:デフォルトの名無しさん
09/05/31 15:37:35
test.for(14): error #5120: 終了していない文字定数です。
*//' ... ログ出力ファイルを入れて')
--------^
test.for(14): error #5082: 構文エラー、END-OF-STATEMENT が見つかりました、 <FORMAT_ELEMENT> <FORMAT_INTEGER> < ) <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> ... の 1 つを指定してください。
*//' ... ログ出力ファイルを入れて')
----------------------------------------------------------------------------------------^

このソースは、
100 FORMAT(//' *** test を始めます。***',
* //' ... ログ出力ファイルを入れて')
です。

他にも日本語からの問題なのでしょうか、"認識できないトークンを'?'をスキップしました"というエラーもでます。

なおf77でも同様で、この場合には、
Error on line 14: unbalanced quotes; closing quote supplied
Error on line 14: unbalanced parentheses, statement skipped
となります。

お気づきの点があれば、すみませんが、ご指摘ください。
よろしくお願いいたします。

245:デフォルトの名無しさん
09/05/31 16:06:32
>>244
a) kterm上でトライ
b) 使ってる全角文字の中に ' ) あたりの半角と同じ値が混じっている

くらいしか思いつかないや。
少なくともf77のケースでのエラーはb の事を言ってるみたいだけど。
英数字以外は使わないのが一番だけどなあ~。どうしても使いたかったら

character*2 zenkaku
read(*,*) zenkaku
write(*,*) ichar(zenkaku(1:1)),ichar(zenaku(2:2))

で全角一文字の対応する半角2文字のアスキーコード数がわかるので、強引に出来そうな気もするけどな。
winだと実際上の3行の部分は動くとおもうけど、linuxだとよくわからんね。
linux + fortran+ 2バイト全角文字 の話題はあまりお話を聞かないからうまく行ったらここにも報告してよ。

246:デフォルトの名無しさん
09/05/31 17:12:19
早速ありがとうございます。ひとつ確認しましたので、ご報告をば。

a)kterm
 Ubuntu9.04にてktermを入れて、確認。
・UTF8はコンパイル時、文字化け?でダメ
・同じくSJISもだめ
・eucではifortでのコンパイルメッセージの出力が化けている(どれでも同じ??)状況でしたが、実行時は日本語出力OK
でした。

 となるとintelFortranのインストールもkterm上から行う方がよかったのか?

 まだすべての確認はできていませんが、うまくいきそうという報告まで。b)も後日、試してみますので結果を報告致します。

247:デフォルトの名無しさん
09/05/31 17:36:04
あ、追加。

うまく表示できているのは、kterm上で、の場合。通常のconsoleでは(当然っちゃぁ当然ですが)化け化けです。

248:デフォルトの名無しさん
09/06/01 08:32:25
おつ~。やっぱりktermがいいのね。

245のbのやつは、対で使われることが多い文字
(ichar()関数の返す値が
' が39、Hexでは27
" が41、Hexでは29
) が93、Hexでは5D
] は34(これはFortranではあまり意味がないか・・)
のようなやつ)が全角に混じってるとダメそうな気がする、という程度の意味で書いてみた。

でも、win版やktermインストだと大丈夫なんだよね。
246さんの意見のとおり、インストール時の設定その他に依存する部分が大きそうな気もするな。

249:デフォルトの名無しさん
09/06/01 18:51:56
文字化けの件、追試結果(w

 まだf77は試してませんが、どうやら文字コードは確かに影響してるっぽい。
 問題はUTF-8で、どうも旧人なので勝手に2バイトと思い込んでましたが、現在は最大4バイトらしい。
 
 このため、見かけ上、1行内では2バイト換算で70文字程度にしていたものがオバフロしていた模様。
 よってifortでは、-FI -132という固定ながら132文字にしたら通りました。

 いったい何をしていたんだ…わしorz

 ちなみにIVFでUTF8形式でソース保存して、それをWin上でコンパイルしたら妙なゴミが出てました。
 結構コード問題は奥が深そうです。

250:デフォルトの名無しさん
09/06/01 23:28:41
>>249
知ってる人のような気がする......
tt

251:デフォルトの名無しさん
09/06/02 01:58:37
> 問題はUTF-8で、どうも旧人なので勝手に2バイトと思い込んでましたが、現在は最大4バイトらしい。
なか~まw

そっか、UTFだとエディタの見かけより実際のはるかに長いんだね。試しに
vi でてきとうにUTF使ったファイル開いたら、たしかに row 数が多い。
気を付けよう。

252:デフォルトの名無しさん
09/06/02 10:58:03
Intel Fortran の使える KIND を関数呼び出しで見ると、ASCII だけになってたような。
確認してないw

253:デフォルトの名無しさん
09/06/04 23:06:43
モンテカルロ法の計算プログラムを流したら、

FORTRAN I/O ERROR 913: OUT OF FREE SPACE

って出てきて途中で計算が止まったっぽいです。
なにやらメモリー不足とのことですが、どう解決すればいいのでしょうか?

254:デフォルトの名無しさん
09/06/04 23:47:02
>>253
ハードディスクを増設しろ!

255:デフォルトの名無しさん
09/06/05 00:14:43
>>253
I/O エラーだから、メモリーではなくディスクが足りないんだろう。
/tmp とかのスクラッチ領域がパンパンになっている可能性もあるが。

256:デフォルトの名無しさん
09/06/05 01:44:17
うほ

257:デフォルトの名無しさん
09/06/05 18:31:50
いや、I/O処理の最中に何らかのリソースが足りなくなったというメッセージだと思う。

URLリンク(www.uic.edu)
913 OUT OF FREE SPACE

Library cannot allocate an I/O block (from an OPEN statement), parse array (for formats
assembled at run-time), file name string (from OPEN), characters from list-directed read,
ISAM key descriptor, shared COMMON descriptor, variable-format descriptor, or file buffer.
The program may be trying to overwrite a shared memory segment defined by another process.

Allocate more free space in the heap area (see the beginning of this chapter); open fewer
files; use FORMAT statements in place of assembling formats at run time in character arrays;
read fewer characters; user fewer ISAM keys; use fewer shared COMMON areas; use fewer
variable-format expressions; or reduce the maximum size of file records.

258:デフォルトの名無しさん
09/06/06 03:03:47
無書式での読み書きも、そのスペースを食うのかね。

259:デフォルトの名無しさん
09/06/06 20:04:27
fortranの超絶初心者です。
以下のプログラムをexitを使わないで同様の結果を得るには、
どうすればいいのでしょうか?
ご教授願います。fortran90を使っています。

program
real :: r,a
integer :: io !入力結果の状態を表す変数
!
print *, 'CTRl-D を入力すると終了'
!
do while ( .true. )
  read(5,*,IOSTAT=io) r
if(io /= 0 )then
     exit
    endif
   a = 4 *3.141592* r ** 2
   print *, r, a
  end do
!
end program

260:デフォルトの名無しさん
09/06/06 20:16:43
>>259
1.歴史と伝統のGOTO文で抜ける。
2.READ文で END=nnn で抜ける。

だが元のままEXITで抜けるのがもっとも行儀が良いとされる。

261:259
09/06/06 21:28:47
>>260
授業の課題で、exitを使わないで書き上げろという事だったんですが・・・
どうも、ありがとうございました。

262:デフォルトの名無しさん
09/06/08 21:37:33
>>261
>exitを使わないで書き上げろ
exitで抜けるのが一番良いのに、何でこう言ったんでしょ?

263:デフォルトの名無しさん
09/06/08 22:28:50
世に蔓延るGOTO使いまくりのプログラムに慣れさせるため・・・ではないよな、多分。

READ文の指定子の使い方の勉強とかかな。

264:デフォルトの名無しさん
09/06/09 10:49:22
ここはFortranでプログラムを作ってという図々しいお願いはおk?

265:デフォルトの名無しさん
09/06/09 11:41:39
>>264
大丈夫。ただし、初心者にありがちな「エスパーさん、○○作って!」はやめて。
知っている情報をそのまますべて載せるべし。

266:259
09/06/09 16:56:11
>>262さん  >>263さん
どうやら、説明が足りなかったようで、すいません。
今日授業に出たところ、
program
real ::r,a
integer ::io
print *,'CTRL-Dを入力すると終了'
do while (io==0)
if (io==0) then
read (5,*,iostat=io) r
a=4*3.141592*r**2
print *,'半径=',r,'面積=',a
end if
end do
stop
end program
が、答えだそうです。
でもこれを実行すると、CTRL-Dで終了するとき、
前回の計算結果が表示されてしまいます。
またまたすいませんが、何を付け加えればいいのでしょうか?

267:デフォルトの名無しさん
09/06/09 17:09:31
なんかアホらしい授業だけど。
program
real ::r,a
integer ::io
print *,'CTRL-Dを入力すると終了'
do while (io==0)
if (io==0) then
read (5,*,iostat=io) r
if (io==0) then
a=4*3.141592*r**2
print *,'半径=',r,'面積=',a
end if
end if
end do
stop
end program
どう考えてもexitを使うほうが素直だ。


268:デフォルトの名無しさん
09/06/09 17:11:10
ありゃ、間違えた。
program
real ::r,a
integer ::io
print *,'CTRL-Dを入力すると終了'
do while (io==0)
read (5,*,iostat=io) r
if (io==0) then
a=4*3.141592*r**2
print *,'半径=',r,'面積=',a
end if
end do
stop
end program

readをifの外側に出さないといかん。

269:デフォルトの名無しさん
09/06/09 17:20:58
ioの初期化も足りないし。ぐだぐだ。

270:デフォルトの名無しさん
09/06/09 20:24:17
exitの偉大さを実感すると言う狙いなのだろう。

271:デフォルトの名無しさん
09/06/09 20:31:01
蛇足だが >>259
do while ( .true. )

do
だけでおk

まあ、
do while (io==0)
に直させるためにワザと do while にしたのかもしれないが


272:デフォルトの名無しさん
09/06/09 21:52:10
do while (io==0)
if (io==0) then
たまにこういうセンスなさすぎなコード書く人いるよね
他人が書いたコードをメンテするはめになったときに、こういうの見ると何とも言えない溜息がでるわ・・・
たとえバグはないとしても

273:デフォルトの名無しさん
09/06/09 23:17:11
>>272
まぁ待てw
Fortran で WHILE を使おうとするだけでも、きわめて開明的な人物ではないか!

274:デフォルトの名無しさん
09/06/09 23:27:58
> if (io==0) then
これはどこがセンスなさすぎなん?

275:デフォルトの名無しさん
09/06/10 03:23:56
>>272 は「センス」って言葉を使いたかっただけなんだよ。

276:デフォルトの名無しさん
09/06/10 11:45:30
>>274
ループの脱出(継続)分岐条件である io==0 が
WHILE と IF の二箇所で判断されていることを言ってるんだろ。

>>272の態度はむかつかせるだけから、くだすれ的には反省すべき。

277:デフォルトの名無しさん
09/06/10 15:02:05
将来コードをいじったときにそのループをスキップする場合があることを考えて
do while (io .EQ. 0)
みたいなのは意図的に書くことはあるけどね。
というか、>>266 のは変数 io がゼロに初期化されることを
前提にしている時点であまりいい回答では無いように思うけどな。

278:259
09/06/10 16:33:09
>>268さん、>>271さん
どうも、ありがとうございました。
授業はどうもいまいちわかりません(笑)
これからも、ちょくちょく質問させていただきますので、
くだすれの皆さん、よろしくお願いします。

279:デフォルトの名無しさん
09/06/11 23:43:42
Visual Fortranについて質問してもいいですか?(VS2008スレよりもこちらのほうが適切っぽいので・・・)

VBやC#でVS2005を使ってたのですが、Intel コンパイラv11を買って
Visual Fortranを入れてみたところ、Intellisenseが効きません。
Visual Fortranでは使えないということですか?
これだとVSをFortran開発環境とする利点がかなり消えてしまうと思うのですが・・・

280:デフォルトの名無しさん
09/06/12 00:01:40
>>279
使えない。
そういうものがあることを知らなければ気にならないから、いますぐ忘れるんだ!


ただしPolyHedoronがLaheyFortran用のインテリセンスっぽい奴を売っている。
URLリンク(www.lahey.com)

281:デフォルトの名無しさん
09/06/12 00:46:40
>>280
そうですか・・・
計算はLinuxクラスタで走らすけど、開発は使い慣れたWindowsのVSで
っていう人を見たことがあって、それいいなぁと思って入れてみたんですが・・・

Laheyっていうの初めて知りました。intellisenseっぽいポップアップが出てますね。
これやNAGなど他の開発環境で良いのがないか当たってみようかなぁ

ちなみにNAGの↓の比較図ですが、他社製ってやっぱVisual Fortranですかね・・・(苦笑
URLリンク(www.nag-j.co.jp)

282:デフォルトの名無しさん
09/06/12 00:57:25
>>281
PGI Visual Fortran というのもあって、これもVSと統合されているのだが、
確か今は米国内の研究機関に所属していればただで使える。
アメリカの研究機関に知り合いがいれば(略

SalfordというかSilverFrostのFTN95もVSと統合できる。
しかし、PGIもSalfordもインテリセンスは無かったような気がする。
最新状況はしらねw

IntelFortranは今月中にF2003対応度が高まったv11.1で出るらしいので、
あわてずゆっくりしていってね。

283:デフォルトの名無しさん
09/06/12 03:33:59
>>282
色々ありがとうございます。

↓を見みると、SalfordのVS統合はintellisenseみたいなのがあるようです。
URLリンク(www.silverfrost.com)
というかこれ無料っぽくないですか?太っ腹すぎる・・・

PGIも、ざっくり見た感じIntel VFよりは機能が多そうですね。
試用できるようなので試してみます。

しかしIntel VFはせめてキーワード補完くらいあればいいのに・・・
性能第一で見やすさ・作りやすさは二の次ってことなんでしょうか(ある意味硬派?

284:279
09/06/12 21:26:08
さっそく以下の3つを試しました。

Silverfrost FTN95 Express
PGI Visual Fortran
NAG Fortran Builder

SilverfrostとPGIはVS組み込みタイプで、IVFと同じくintellisense等の高度なものはありませんでした。
それ以外も、パッと見特に違いはなさそうで、結局は好みの問題ということになるんでしょうか。
NAGのIDEはVS組み込みではなくオリジナルで、唯一これだけキーワード補完ができましたが、
変数や関数の補完は×でした。

うーん、こうなるとこのままIVFを使い続けたほうがよさそうです・・・

285:279
09/06/12 21:44:13
ググっていたところ、IntelのForumでどんぴしゃなスレを見つけました。
URLリンク(software.intel.com)

皆思うことは同じのようですねw
Steveおじさんも要望をよく理解してくれてるようですが、これまではVS2008への対応で
手一杯だったようです。MSが仕様をコロコロ変えることも妨げの原因だとぼやいてました。

結局、何が根本の原因なのかははっきりと書かれてませんでしたが、IVF以外のVS組込みIDEも
IVFと似たような現状なのを考えると、VS側のほうでAPIみたいな道具を提供してくれないと
Intellisenseのような高度機能は実装できない、ということなのかもしれません。

Steveさんが言うに、C++,C#,VBのVSで備わっていたこれらの機能が「Visual Studio Shell」
で分離されたので、Fortran上にも実装できそう、とのことです。
早くそうなって欲しいところですが、先月のスレへのSteveさんのレスを見る限り、もう少しかかりそうですね・・・
URLリンク(software.intel.com)

286:デフォルトの名無しさん
09/06/13 16:09:35
確かにfortranerの開発って時代遅れな感があるな

287:デフォルトの名無しさん
09/06/14 22:04:16
>>285
スティーブって森の熊さんホモ動画の熊さんの一匹に似てるよね。

288:デフォルトの名無しさん
09/06/15 22:36:44
Fortranの開発環境のヘボさにうんざりしてCに逃げる人も多いんだろうな
ただ、今後のトレンドを考えるとやはりCは…

289:デフォルトの名無しさん
09/06/15 22:46:01
紙テープ・パンチカード・ラインエディター上がりも多いFortran界では、スクリーンエディターで
シンタックス・カラーリングがあるだけでも極楽浄土のけだるい怠けた世界に見えるのさ。

290:デフォルトの名無しさん
09/06/15 23:20:51
これから並列数は増える一方だから、最適化は少しの妥協も許されなくなるんだよな
そうなるとFortran一択しかなくなる…
MSがVisualFortran出してくれれば(^q^)

291:デフォルトの名無しさん
09/06/15 23:30:16
>>290
っ [MS Fortran PowerStation]

292:デフォルトの名無しさん
09/06/16 00:33:41
>>291
そう、それをもう一度頼む!(><)
MSのFortran部隊はどこ行っちまったんだ?

293:デフォルトの名無しさん
09/06/16 00:49:49
>>292
Netscapeがブラウザー戦争を仕掛けたせいで、VC++部隊以外が全部IE開発に
回されたという噂が当時あった。

まぁMSの歴史をたどると、BASICの次に作って売ったのはFORTRANだから
MS Visual FORTRANは原点回帰といえなくもないが、VBすら捨ててしまうMS様は
容赦ないのだw

でも、高い金出してコンパイラ律儀に買ってくれるのはFORTRANユーザーくらい?

294:デフォルトの名無しさん
09/06/16 00:55:45
>>292
MS → DEC → Compaq → Intel

295:デフォルトの名無しさん
09/06/16 13:53:00
>>294
MSからDECに流れたとはしらなんだ
IntelとMSがもっとみっちり連携してくれればいいんだけど、またWintelって非難が起こりそうだな

296:arrayの地獄
09/06/16 22:24:17
時間がかかって仕方ないのだが何とかなりませんか?
ifort 9.1です。

real(8)::x(25,25),y(50,50)
x=なんたら
y=0
y(1:25,1:25)=x(1:25,1:25)
y=cshift(y,12,1)
y=cshift(y,12,2)


特にy=xのところ。
なんでこんなんに時間食う??
(メモリ書き込みに難儀してるのはわかるが、
y全体がキャッシュ上に乗るから、キャッシュで整えてから書けば時間かからんはず・・)

297:デフォルトの名無しさん
09/06/16 22:27:38
>>296
それだけじゃ分からんっつの
時間食うってどれくらい?

298:arrayの地獄
09/06/16 22:46:24
92x49回で数秒のオーダー
@xeon5160? 1core使用
なんかおかしいな・・もうちょっと調べます。

299:デフォルトの名無しさん
09/06/16 22:49:48
ド初心者ですが質問です。コンパイルできたファイルを実行すると
fmt: end of file
apparent state: unit 10 named inp-2.dat
last format: (F9.5)
lately reading sequential formatted external IO
となるのですが何が問題なんでしょうか?プログラムは外部データ(inp-2.dat)から数値を読み最大値を求めるものです
数値は実数です

300:デフォルトの名無しさん
09/06/16 22:56:05
>>296
>y(1:25,1:25)=x(1:25,1:25)

なぜ素直にy=xとしない。 

多分
ALLOCATE(TMP(26,26))
TMP=x
y=TMP
DEALLOCATE(TMP)
のように展開されるから遅いんだろ。

301:デフォルトの名無しさん
09/06/16 22:59:20
>>300
TMP(25,25)だったw 0:25と勘違いしたよ。1:25とか俺的にはあり得ないw

>>299
データ数が足りないように見受けられる。
F9.5に当たるところでデータが足りないか、変数の数が合わないかしてるのでは?

302:296です。
09/06/16 23:06:23
[hoge@xeon prog20]$ cat test.f90
program test
implicit none
integer,parameter::nx=25,ny=50
real(8)::x(nx,nx),y(ny,ny)
integer::i
x=reshape((/1:25*25/),shape(x))
do i=1,100000
call sub1(x,y,nx,ny)
call sub2(x,y,nx,ny)
end do
end program test
subroutine sub1(x,y,nx,ny)
implicit none
real(8)::x(nx,nx),y(ny,ny)
integer::nx,ny
y=0
y(1:nx,1:nx)=x(1:nx,1:nx)
y=cshift(y,12,1)
y=cshift(y,12,2)
end subroutine
subroutine sub2(x,y,nx,ny)
implicit none
real(8)::x(nx,nx),y(nx,nx) !nyでなくnx
integer::nx,ny
y=0
y(1:nx,1:nx)=x(1:nx,1:nx)
y=cshift(y,12,1)
y=cshift(y,12,2)
end subroutine 続く


303:デフォルトの名無しさん
09/06/16 23:07:10
>>301
データ数ですか。それは入力元のファイルの値に問題ありということですか?プログラムは
IMPLICIT REAL(A-H,O-Z)
DIMENSION X(100)
OPEN(UNIT=10,FILE='inp-2.dat',STATUS='old',FORM='FORMATTED')
OPEN(UNIT=11,FILE='list-2.dat',STATUS='UNKNOWN',FORM='FORMATTED')
READ(10,100)N
DO 20 I=1,N
READ(10,200)X(I)
20 CONTINUE
IMAX=0.0
DO 30 I=1,N
IF(X(I).GT.IMAX)MAXN=I
IF(X(I).GT.IMAX)IMAX=X(I)
30 CONTINUE
WRITE(11,300)'MAX=',IMAX,'NO.=',MAXN
100 FORMAT(A5)
200 FORMAT(F9.5)
300 FORMAT(A4,F10.5,A4,I3)
CLOSE(10)
CLOSE(11)
STOP
END
となってます。サンプルプログラムを改変しただけなのでおかしいところが多いと思います。入力ファイルはとりあえず実数を5つ縦に並べてあります

304:296です。
09/06/16 23:07:11
[hoge@xeon prog20]$ ifort test.f90 -p
[hoge@xeon prog20]$ time a.out
real 0m2.359s
user 0m2.357s
sys 0m0.002s
[hoge@xeon prog20]$ gprof -b
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
71.83 1.53 1.53 100000 0.00 0.00 sub1_
28.17 2.13 0.60 100000 0.00 0.00 sub2_
0.00 2.13 0.00 1 0.00 2.13 MAIN__



305:296です。
09/06/16 23:13:31
みにくてすみませんでした。

CPUはcore2の6600 2.4Gでcashe=4Mでした。

yとxの寸法が違うので、y=xにできないはずです。

逆フーリエ変換にかけるとき外を0にしておきたいので、
こんなになっています。
実プログラムでは逆フーリエ変換にかかる時間と
同じくらいの時間がかかって大損しています。


306:296です。
09/06/16 23:18:31
まとめると、
y(1:25,1:25)=x(1:25,1:25)
を100000回実行すると、
real(8)::x(25,25),y(50,50) のとき =>1.53秒かかる。
real(8)::x(25,25),y(25,25) のとき =>0.60秒かかる。
2.5倍もかからんでええやろ
ということです。

307:296です。
09/06/16 23:27:05
>>299
私もできる範囲で手伝い。
100 FORMAT(A5) が気になります。
実際に実行させたらNにどんな値が入るでしょうか?
思っている値かどうかwrite文で確かめるのが吉かと思います。


308:デフォルトの名無しさん
09/06/16 23:32:44
>>307
このままだと実行すらできないんですよね・・・ 
READ(~)N  のあとに
N=5  としてみましたが実行エラーの文は変わりませんでした

309:デフォルトの名無しさん
09/06/16 23:40:27
>>296
corei7のifort 11ですが

$ cat test.f90
integer,parameter::n=25
real(8)::x(n,n),y(2*n,2*n)
x=0
y=1
!y=x
y(1:n,1:n)=x(1:n,1:n)
end

$ time ./a.out
real 0m0.001s
user 0m0.000s
sys 0m0.001s

n=25000だと
real 0m1.974s
user 0m0.754s
sys 0m1.217s

何か環境おかしいんじゃないんでしょうか?他のホストで試したどうっすかね


310:296です。
09/06/16 23:44:15
>>299
適当にinp-2.datに
5
1
12
123
1234
12345
123456
と入れてます。
read(~)Nのあとにwrite(*,*)Nとすれば、ここまでは走りませんか?

これで走らせると、私の場合はN= 538976288と、とんでもないことになってました。
数字を数として読み込みたいのに、文字として読み込んだらまずいですよね、やっぱり。
A5はI5ぐらいかと思いますが、どうでしょう?


311:296です。
09/06/16 23:49:47
>>309
情報ありがとうです。
corei7+ifort 11ですか・・
なるほど。別のマシンで試してみます。

312:デフォルトの名無しさん
09/06/16 23:54:28
>>310
inp-2.datに小数点以下1桁を含んだ実数を適当に5つ入れて、writeしてみたところN=1073741824となってました。
フォーマットをi5にすると実数を受け取れないのでF5.5にしてみたのですが、Nは上記の通りです。何が起こってるんですかね・・・?

313:296です。
09/06/16 23:55:32
>>309
すんません。メインルーチンで
do i=1,100000
と回してますので、timeの結果が直接比較できないです。
すみませんが追加でテストお願いできませんか?

314:デフォルトの名無しさん
09/06/17 00:14:43
>>313
いやメインルーチンとかじゃなくて
>>309でテストすりゃいいじゃん


315:296です。
09/06/17 00:18:42
>>299
Nはデータの個数ですよね。実数じゃまずいのでは?
inp-2.datは
データの個数
データ1
データ2

というような構造じゃありませんか?
少なくとも最初のデータだけは整数かな。
それとIMAXを実数宣言しなきゃいけないようです。

316:デフォルトの名無しさん
09/06/17 00:27:14
>>315
datファイルにデータの個数を入れてなかったんですね・・・やっとわかりました!ありがとうございます。実行できました
プログラム自体はうまくいってないんですが・・・w
実行結果がMAX=0.000・・・、No.=2となっているんでうまくいってないですね

317:296です。
09/06/17 00:33:29
>>314
お世話になってます。
確かにこちらでも結果0秒になりました。

いやしかし、たぶん0.000,0060秒(6マイクロ秒)くらいかかっているのが、
timeコマンドの分解能不足で測れてないだけの様な気がしてますです。
実際は100000x100000回とかもっとぐらい実行するので、何とかしたいです。

>>316
IMAXの方もよろしく。

318:309
09/06/17 00:39:12
>>317
問題点を整理(できればテストコードを用意)して頂ければ協力できますよ
他のマシンもいくつかあります

319:デフォルトの名無しさん
09/06/17 00:53:40
>>317
実数宣言とは何でしょうか?imax=0.0ではダメなんですよね?

320:300
09/06/17 01:02:12
>>305
>yとxの寸法が違うので、y=xにできないはずです。
すまんこw ようつべ見ながらだったので、よく見なかったww

こんなものに時間がかかるも糞もないだろと思ったが、
10^5*10^5回も繰り返すなら気になるかw

部分配列でメモリーが連続していないので、コンパイラのバージョンが古いと
余計なテンポラリを暗黙にとっている可能性が高いと思う。

DO i = 1, 25
y(1:25, i) = x(:, i)
END DO
と、でもすれば早くなるべ。最適化でアンローリングとかもあろうし。

321:296です。
09/06/17 01:07:49
>>318
ありがとうございます!
テストコードを302に書き込みました。これでお願いできたらありがたいです!

問題点のほうは、まとめると、
302のプログラムで
y(1:25,1:25)=x(1:25,1:25)
を100000回実行すると、
real(8)::x(25,25),y(50,50) のとき =>1.53秒かかる。
real(8)::x(25,25),y(25,25) のとき =>0.60秒かかる。
「2.5倍もかからんでええやろ」
ということです。

おわかりいただけたでしょうか?


ifort10.1を試みてみました。XEON5160です。
% time a10.out     :ifort10.1
1.288u 0.000s 0:01.31 97.7%
% time a09.out     :ifort9.1
1.916u 0.004s 0:01.96 97.4%
だいぶ差があるなあ・・というところです。



322:296です。
09/06/17 01:16:14
>>319

real imax
を宣言文のところに追加です。
FORTRANの慣習ではI~Nから始まる変数名は整数変数に使うことになっているので、
imaxのままだと動くけどちょっと減点かな?
imax->xmaxにするほうがいいかも。この場合real xmaxは不要。

>>320
ご指摘ありがとうですです。
さっそく試してみますです!



323:デフォルトの名無しさん
09/06/17 01:21:31
>>322
うまくいきました! なんとなくfortranがわかりはじめてきました!
ありがとうございます

324:デフォルトの名無しさん
09/06/17 01:30:04
初心者は呪文のようにimplicit noneを宣言しておきましょう。

325:309
09/06/17 01:39:38
>>321
こんな感じでした。時間はreal timeです

Corei7 920、ifort 11.0
real(8)::x(25,25),y(50,50)・・・0m0.799s
real(8)::x(25,25),y(25,25)・・・0m0.255s

Xeon5472、ifort 10.1
real(8)::x(25,25),y(50,50)・・・0m0.922s
real(8)::x(25,25),y(25,25)・・・0m0.280s

Opteron2218、pgf90 6.2
real(8)::x(25,25),y(50,50)・・・0m9.821s
real(8)::x(25,25),y(25,25)・・・0m4.372s

>>300さんの指摘通りってことですかね
Opteronが糞遅いのが気になりますが・・・(;^ω^)

326:296です。
09/06/17 01:56:29
>>309様(325)
ありがとうございます!!お手数掛けました。

COREi7万歳というところですか。
320様のご指摘も含めていろいろ検討したいのですが、
今晩はこの辺で失礼します。
(いろいろありがとうございました。また明日頑張ります。)


327:デフォルトの名無しさん
09/06/17 03:05:28
corei7はかなり評判いいよね
opteronを完全に引き離した

328:デフォルトの名無しさん
09/06/17 03:11:03
>>325
OpteronというよりPGIのコンパイラのせいのような気がする。
オプションがどうなってるのかわからんし。
最新版は8.0だし。

でもたしかにi7はなかなかいい。

329:309
09/06/17 13:56:34
>>328
>OpteronというよりPGIのコンパイラのせいのような気がする。
その通りでしたw
>>325のコンパイルは全てオプション指定なしでして、調べたところ
ifortはデフォルトで-O2が、pgf90は-O1がかかるようです。

-O2を付けた場合↓
real(8)::x(25,25),y(50,50)・・・0m1.306s
real(8)::x(25,25),y(25,25)・・・0m0.784s

330:デフォルトの名無しさん
09/06/17 20:36:22
>>301
>1:25とか俺的にはあり得ないw
Cみたいに0から開始ってこと?
Fortranだと1から始めるのが一般的だと思うけど

331:デフォルトの名無しさん
09/06/17 23:16:26
>>330
いや、:だけで済ますとか、それすら書かないと言うこと。

332:デフォルトの名無しさん
09/06/18 18:02:57
>>331
そういうことね

で、実際どれがいいんだろうか。例えば↓の3つでは
① x(1:n) = y(1:n)
② x(:) = y(:)
③ x = y
自分は②が良いと思ってる。①は冗長だし、③は簡潔だけど配列であることが自明じゃないので。
問題はどれが一番速いかなんだけど・・・
↓のサイトでは「並列最適化コンパイラの動作を助け、バグを少なくするため」①が推奨されてるし
URLリンク(www.mri-jma.go.jp)
でも、これって>>300氏の言ってることとは反対だよね。

333:デフォルトの名無しさん
09/06/18 19:19:25

例えば、配列 data1 から data4 があって、次々にsubroutine に引き渡したい場合ですが、

call hoge(data1)
call hoge(data2)
call hoge(data3)
call hoge(data4)

しないで、

do i=1,4
call hoge( )
end do

の様にまとめる事って加能ですか? もし可能ならやり方教えてください。

334:デフォルトの名無しさん
09/06/18 19:22:10

data1 から data4 は既に7次元配列なので、それらをまとめる事はできないです。

335:デフォルトの名無しさん
09/06/18 19:22:23
>>333
普通は配列をdata(n,4)と2次元にして
do i=1,4
call hoge(data(:,i))
enddo

336:デフォルトの名無しさん
09/06/18 19:25:49
>>334
7次元配列ってすごいなw
Fortranの配列って7が限界だったっけ?それなら無理じゃないかな
あきらめれ

337:デフォルトの名無しさん
09/06/18 23:01:17
>>332
新しいコンパイラでは、どれを書いても最適化で同じになるらしいが、
初期のFortran90コンパイラでは、n:nnみたいな指定子が入ると、
テンポラリをとることが多かったみたい。

それは多分一般的には、n:nn:mみたいな不連続の番地をとる可能性があるためだと思う。


>>333
ポインターの配列を、TYPEによって定義しておいて、それに配列を割り付けておいて、
それを引数に置けばいいんじゃないかな?

まぁポインターに割り当てるときに、だらだらとdata1~4を並べないと駄目なので
ゴミの位置が移動するだけだがw

338:337
09/06/19 01:27:21
MODULE m_billy
IMPLICIT NONE
INTEGER, PARAMETER :: nmax = 2
TYPE :: t_billy
INTEGER, POINTER :: mm(:, :, :, :, :, :, :)
END TYPE t_billy
CONTAINS
SUBROUTINE anal(mm)
INTEGER, INTENT(OUT) :: mm(:, :, :, :, :, :, :)
INTEGER :: i1, i2, i3, i4, i5, i6, i7
DO i1 = 1, nmax
DO i2 = 1, nmax
DO i3 = 1, nmax
DO i4 = 1, nmax
DO i5 = 1, nmax
DO i6 = 1, nmax
DO i7 = 1, nmax
mm(i1, i2, i3, i4, i5, i6, i7) = i1 + 10 * (i2 + 10 * (i3 + 10 * (i4 + 10 * (i5 + 10 * (i6 + 10 * i7)))))
END DO
END DO
END DO
END DO
END DO
END DO
END DO
RETURN
END SUBROUTINE anal
END MODULE m_billy

339:337
09/06/19 01:28:03
!====================================================
PROGRAM herrington
USE m_billy
IMPLICIT NONE
INTEGER, TARGET :: data1(nmax, nmax, nmax, nmax, nmax, nmax, nmax), data2(nmax, nmax, nmax, nmax, nmax, nmax, nmax)
INTEGER, TARGET :: data3(nmax, nmax, nmax, nmax, nmax, nmax, nmax), data4(nmax, nmax, nmax, nmax, nmax, nmax, nmax)
TYPE (t_billy) :: kazuya(4)
INTEGER :: i
kazuya(1)%mm => data1
kazuya(2)%mm => data2
kazuya(3)%mm => data3
kazuya(4)%mm => data4
DO i = 1, 4
CALL anal( kazuya(i)%mm )
END DO
print *, data1
STOP
END PROGRAM herrington

340:333
09/06/19 01:58:08

サンクス。でも結構大掛かりだな。。。


real*8 data1(n,n,n,n,n,n,n), data2(n,n,n,n,n,n,n),.......
char*1 cnum
char*5 target

do i = 1, 4
write( cnum, '(i1)' ) i
target = "data" // cnum
call hoge( target )
end do

みたいにできんもんかね。。。 target と data$ は型が違うがな。

341:337
09/06/19 02:24:46
>>340
77の掟破りでよければ、

real*8 data1(n,n,n,n,n,n,n), data2(n,n,n,n,n,n,n), data3(n,n,n,n,n,n,n), data4(n,n,n,n,n,n,n)
real*8 tmp(n**7, 4)
equivalence (tmp(1, 1), data1), (tmp(1, 2), data2), (tmp(1, 3), data3), (tmp(1, 4), data4)
do i = 1, 4
call hoge( tmp(i) )
end do

こんな感じでEUIVALENCEでいけるかな?

342:デフォルトの名無しさん
09/06/19 03:00:32
>>341
call hoge( tmp(1, i) )
の過ち。

ハルヒ新OP糞杉www

343:デフォルトの名無しさん
09/06/19 10:22:30
>>334
本当に7次元いるの? 変数設計を再検討した方がいいんじゃない?
座標3次元+時間で、4次元はざらにあるが。

344:デフォルトの名無しさん
09/06/19 14:06:33
>>343の言うとおり。

変数設計は、アルゴリズム的な自然さ(人間にとっての見やすさ)と速度の
両方の観点から決めるべき。

345:デフォルトの名無しさん
09/06/20 20:01:44
7次元配列の数値計算ってどういう分野で出てくるの?

346:デフォルトの名無しさん
09/06/20 21:51:11
流れぶった切ってすいません。
n×n 次元行列 M と n 次元ベクトルa の積 b = Ma を計算するプログラムを
作っていたのですが、詰まってしまいました。
どこが、おかしいか教えていただけないでしょうか?
program
integer ::i,k,n
integer,parameter ::limit=5
real ::M(1:limit,1:limit),a(1:limit),b(1:limit)
do
print *,'nの値は?'
read *,n
if ((n<=limit).and.(n>=1)) then
exit
end if
end do
!
print *,'行列Mの成分'
do i=1,n
print *,i,'行目?'
read *,(M(i,k),k=1,n)
end do
print *,'ベクトルaの成分'
do k=1,n
read *,a(k)
end do

347:346
09/06/20 21:52:41
!>>346の続き
do i=1,n
do k=1,n
b(0)=0
b(k)=b(k)+M(i,k)*a(k)
end do
end do
print *,'b:'
do k=1,n
print *,b(k)
end do
stop
end program

よろしくお願いします

348:346
09/06/20 21:57:18
たびたびすいません。
上のプログラムはfortran90を使っています。
コンパイルする際は、ifort (プログラム名).f90 -o (プログラム名)
としています。

349:デフォルトの名無しさん
09/06/20 21:59:30
>>346
全く見ていないが、b(0)=0 がおかしい。
b(k)=0.0 でかつ一個DOLOOPの外。

350:デフォルトの名無しさん
09/06/21 10:45:18
ループのところ
do i=1, n
b(i) = 0
do k=1,n
b(i) = b(i) +M(i, k) * a(k)
end do
end do

直接関係ないけど、Mの行と列を入れかえたほうがいいかも。




351:346
09/06/21 18:17:49
>>350さん
ありがとうございました。
うまくいきました!


352:デフォルトの名無しさん
09/06/23 11:08:29
PROGRAM GAUSS_SOLVER
IMPLICIT NONE

REAL,DIMENSION(100,100)::A !行列A(最大100元まで解ける)
REAL,DIMENSION(100)::B,X !右辺Bと解Xのベクトル
INTEGER::N !元数
INTEGER::I,J,K !制御変数

WRITE(*,*)'このプログラムは連立一次方程式AX=Bのい解Xを求めます'
WRITE(*,*)'AandB.TXTの入力フォーマットは次のようです'
WRITE(*,*)'たとえば,3元の連立方程式の場合'
WRITE(*,*)'3 (元数を与えてください)'
WRITE(*,*)'A11 A12 A13 B1 (データは空白やタブで別けてください)'
WRITE(*,*)'A21 A22 A23 B2 (AIJとBIには実数を与えてください)'
WRITE(*,*)'A31 A32 A33 B3'
WRITE(*,*)'解XはX.TXTに出力されます'

OPEN(1,FILE='AandB.TXT')
READ(1,*) N
DO I=1,N
READ(1,*) (A(I,J),J=1,N),B(I)
END DO
CLOSE(1)

DO I=1,N-1
DO J=I+1,N
DO K=I+1,N
A(J,K)=A(J,K)-A(J,I)*A(I,K)/A(I,I)
END DO
B(J)=B(J)-B(I)*A(J,I)/A(I,I)
END DO
END DO

353:デフォルトの名無しさん
09/06/23 11:10:04
DO I=N,1,-1
X(I)=B(I)/A(I,I)
DO J=I+1,N
X(I)=X(I)-A(I,J)*X(J)/A(I,I)
END DO
END DO

OPEN(1,FILE='X.TXT')
DO I=1,N
WRITE(1,*) 'X(',I,')=',X(I)

END DO
CLOSE(1)

STOP
END PROGRAM GAUSS_SOLVER

354:デフォルトの名無しさん
09/06/23 11:20:09
このプログラムをもとにN次行列の逆行列をもとめるプログラムを作るのですが
どうしたらいいかわかりません。教えてくださると助かります。。

355:デフォルトの名無しさん
09/06/24 00:59:41
ガウス・ジョルダン消去法でぐぐれ

ちなみに逆行列を求める時は元の配列に逆行列を
入れる事が出来て効率が良い

356:デフォルトの名無しさん
09/06/24 22:19:20
subroutine gauss_jordan(a,b,flag)
implicit none

integer,parameter::N=3
double precision ::a(N,N),b(N)
integer ipv,i,j
double precision :: inv_pivot,temp
double precision :: big
integer pivot_row,row(N)
integer flag

do ipv=1,N
!コヌツ酖ヘテオコ・ big=0.0
do i=ipv,N
if(abs(a(ipv,i)) > big) then
big = abs(a(ipv,i))
pivot_row = i
endif
enddo

if(abs(big) < 0.0001) then
write(6,*) "A is singular matrix"
flag = 0
return
endif

357:デフォルトの名無しさん
09/06/24 22:20:34

row(ipv) = pivot_row

!ケヤ、ホニ、・リ、ィ
if(ipv .ne. pivot_row) then
do i=1,N
temp = a(i,ipv)
a(i,ipv) = a(i,pivot_row)
a(i,pivot_row) = temp
enddo
temp = b(ipv)
b(ipv) = b(pivot_row)
b(pivot_row) = temp
endif

! ツミウムタョハャ=1(・ヤ・ワ・テ・ネケヤ、ホス靉)
inv_pivot = 1.0/a(ipv,ipv)
a(ipv,ipv) = 1.0

358:デフォルトの名無しさん
09/06/24 22:21:30
do j=1,N
a(j,ipv) = a(j,ipv) * inv_pivot
enddo

b(ipv) = b(ipv) * inv_pivot

! ・ヤ・ワ・テ・ネホ・0(・ヤ・ワ・テ・ネケヤーハウー、ホス靉)
do i=1,N
if(i .ne. ipv) then
temp = a(ipv,i)
a(ipv,i) = 0.0
do j=1,N
a(j,i) = a(j,i) - temp*a(j,ipv)
enddo
b(i) = b(i) - temp*b(ipv)
endif
enddo

359:デフォルトの名無しさん
09/06/24 22:23:23

enddo

! ホホニ、・リ、ィ(オユケヤホ・
do j=N,1,-1
if(j .ne. row(j)) then
do i=1,N
temp = a(j,i)
a(j,i) = a(row(j),i)
a(row(j),i) = temp
enddo
endif
enddo

flag = 1
return
end subroutine

!### TEST MAIN ######
! program MAIN
! implicit none
! integer,parameter::N=3
! double precision :: a(N,N),b(N)
! integer :: flag

360:デフォルトの名無しさん
09/06/24 22:25:41

! a(1,1) = 0.0
! a(2,1) = 1.0
! a(3,1) = 0.0
! a(1,2) = 1.0
! a(2,2) = 0.0
! a(3,2) = 0.0
! a(1,3) = 0.0
! a(2,3) = 0.0
! a(3,3) = 1.0
!
! b(1) = 3.0
! b(2) = 4.0
! b(3) = 5.0

! call gauss_jordan(a,b,flag)
! write(6,*) b(1),b(2),b(3)

! stop
! end program


361:デフォルトの名無しさん
09/06/24 22:27:01
UTF-8か何かで貼ったのか?
文字化けしてて日本語部分読めないぞ

362:デフォルトの名無しさん
09/06/24 22:27:21
これのことですか?長々とすみません

363:デフォルトの名無しさん
09/06/24 22:29:24
ダウンロードしたものをノートパッドで開いてコピペしたんですが。。

364:デフォルトの名無しさん
09/06/24 22:33:53
で、わかったっしょ?ガウスジョルダン消去法を使うと逆行列が
求められるという事が

もちろん行列式が零だと潰れてしまうが

365:デフォルトの名無しさん
09/06/24 22:40:14
半分くらい・・・(汗

366:デフォルトの名無しさん
09/06/24 22:42:15
Cのソースで良いなら

URLリンク(nyan11.ciao.jp)

のINV1.Cが逆行列を実際にガウスジョルダン消去法で解くプログラムだ
これを参考にFORTRANに移植するとよい

367:デフォルトの名無しさん
09/06/24 22:45:03
Intel Fortran v11.1 が出たようだな。
まだ完全ではないようだが、ようやくF2003時代がやってきたw

368:デフォルトの名無しさん
09/06/24 22:49:38
まだ分からないと言われそうなんで一応逃げを打っておく

URLリンク(www.sic.shibaura-it.ac.jp)

ここのPDFをじっくり眺めてくれ
さすがに理解できるだろ

369:デフォルトの名無しさん
09/06/24 22:58:35
去年も逆行列の質問をしていた奴がいたが、さては留年したかw
今年はがんばれ。
質問でうまくおだてて解答ゲットしろw

370:デフォルトの名無しさん
09/06/24 23:05:27
これでも分からないならネットに頼るのはやめて明日本屋に行け
そして線形代数の本を買え

掃き出し法という名前で載っているかもしれないがとにかくそれだ
手で一回3×3程度の行列の逆行列を求めてみればおのずと
プログラムでやっている事も理解できる

371:デフォルトの名無しさん
09/06/24 23:08:37
URLリンク(detail.chiebukuro.yahoo.co.jp)

これとかな

いくらでもネット上にも情報はあるんだけどな

372:デフォルトの名無しさん
09/06/24 23:25:05
数学的なやり方そのものに疑問はないです・・・
ただプログラムできないです・・・ちなみにその去年の人じゃないよ

373:デフォルトの名無しさん
09/06/24 23:33:18
>>372
おk。
疑問点を具体的に書いてくれれば、具体的に答えられるが、
漠然と聞かれると、漠然としか答えられない。

まぁがんばれw

374:デフォルトの名無しさん
09/06/25 04:52:56
最初は誰でも、どこがわからないかわからない状態だよね
まあがんばれw

375:デフォルトの名無しさん
09/06/25 14:49:13
>>372
というか、質問の仕方というものがあるだろう・・・。
いきなりソースコースばしばし貼りまくってから質問内容を言うのは、分かりにくいというか
それ以前のマナーの問題。せめて要点をまとめろよ。

376:デフォルトの名無しさん
09/06/25 15:24:15
いいやん
こっちも動くソースをばしばし貼って、それで終わりにして
質問は一切受け付けませんよという態度を取れば

377:デフォルトの名無しさん
09/06/25 15:52:01
そしたらスレが汚くなるじゃないか。質問者はソースを貼るときは、必要でない限り
・ソース丸ごとではなく、最小限の部位に留める
・変数名を見やすい、もしくは一般的なものに変える

ぐらいはやってくれよと。こんなの常識じゃないかと思うんだが。

378:デフォルトの名無しさん
09/06/25 20:32:26
>>377 それができたら初心者じゃないから、まあ、大目にみようよ

379:デフォルトの名無しさん
09/06/25 22:27:34
>>372ですが今日一日教科書じっくり読み込んでだいたいわかりました
ぐだぐだとプログラムを貼り付けてすいませんでした。。
あと、教えてくれた皆さんありがとうございます

380:デフォルトの名無しさん
09/06/25 23:03:19
>>379
そうかそれはよかったな
君のした努力は決して無駄にならないと思うよ
これから線形代数・微積分学・複素関数論とかいろんな
数学をプログラミングする機会があると思うが、今した努力は
必ず生きてくる

特にFFTのプログラムなんか芸術的だぞ
バタフライ演算って言ってな

381:デフォルトの名無しさん
09/06/25 23:07:12
>>380 
ありがとうございます
読んでる内にどんどん楽しくなってきて、一気に今やってるところまで
読み進めれました。
これからもっとがんばります(`・ω・´)

382:デフォルトの名無しさん
09/06/25 23:20:35
立派なフォートランナーになってくれ^^

383:デフォルトの名無しさん
09/06/25 23:44:58
>>377
おまえの常識なんか初心者はしったこっちゃねーんだよw

384:デフォルトの名無しさん
09/06/27 15:04:27
C
IMPLICIT REAL(A-H,O-Z)
REAL T(100),XZ(100,2)
DATA GRAV,V0,ANGLE/9.8,30.0,45.0/
DATA T0,VINT,TMAX/0.0,0.5,7.5/
PI=ATAN(1.0)*4.0
R=ANGLE*PI/180.0
C
DO 10 I=1,50,1
T(I)=REAL(I-1)*VINT
IF(T(I).GT.TMAX)THEN
STOP
END IF
XZ(I,1)=V0*COS(R)*T(I)
XZ(I,2)=-0.5*GRAV*T(I)**2+V0*SIN(R)*T(I)
10 CONTINUE
S=AREA(T,X,Z,T0,TMAX,R,GRAV)
CALL OUTPUT(T,X,Z,S)
STOP
END


385:デフォルトの名無しさん
09/06/27 15:06:47
C
FUNCTION AREA (T,X,Z,T0,TMAX,R,GRAV)
IMPLICIT REAL(A-H,O-Z)
XMAX=V0*0.5*COS(R)*TMAX
X0=V0*0.5*COS(R)*T0
DO 20 I=1,16
AREA=0.0
DX=(XMAX-X0)/REAL(I)
T=REAL(I-1)*VINT
X1=V0*COS(R)*T
X2=X1+DX
Z1=TAN(R)*X1-0.5*(GRAV/(V0*(COS(R))**2))*X1**2
Z2=TAN(R)*X2-0.5*(GRAV/(V0*(COS(R))**2))*X2**2
AREA=AREA+(Z1+Z2)*DX*0.5
20 CONTINUE
RETURN
END

386:デフォルトの名無しさん
09/06/27 15:09:07
C
SUBROUTINE OUTPUT(T,X,Z,S)
IMPLICIT REAL(A-H,O-Z)
INTEGER NO(100)
REAL T(100),XZ(100,2)
C
OPEN(16,FILE='menseki2.res')
WRITE(16,'(A)')' TIME CX CZ SPACE'
DO 30 I=1,16
WRITE(16,'(F5.1,2F10.2)') T(I),(XZ(I,J),J=1,2)
WRITE(16,'(F10.2)') S
30 CONTINUE
CLOSE(16,STATUS='KEEP')
RETURN
END

物体の投げあげの時間、X座標とZ座標、台形積分の計算をファイルに出力したいのですが、コンパイルしてもファイルが作られません。
ファイルは時間が1次元配列、X座標とZ座標が2次元配列です。
どう改善すればよいのでしょうか

387:デフォルトの名無しさん
09/06/27 15:45:54
>>386
T(I) が TMAX (=7.5) を超えたところでSTOPするようになってるから。

てゆーかぱっと見、変数の使われ方が変だ。
XZ は宣言されてるが X とか Z が突然出てきてるぞ。
IMPLICIT NONEで動くところまで書き直せ。


388:デフォルトの名無しさん
09/06/27 17:50:39
>>384-386
あんた>>352-354か?
ソースを貼るなとは言わんが、まず「○○で困っています。××はどうすればいいでしょうか?ソースは以下の通りです」とか書いてから貼れよ

389:デフォルトの名無しさん
09/06/27 17:57:12
プログラムの書き型が相当古いから別人だろうな。

390:デフォルトの名無しさん
09/06/27 22:05:47
>>387
それ以前に、コンパイルが通らないんだろ。
AREAの引数のTが、スカラー定義なのに配列を渡している。

書き方は古いが、非常にオーソドックスで正当な書き方をしている。
しかし、実際の論理というか中身はかなり??
簡単には直らんw

391:1/2
09/06/27 22:59:57
>>386

IMPLICIT REAL(A-H,O-Z)
REAL T(100),XZ(100,2)
DATA GRAV,V0,ANGLE/9.8,30.0,45.0/
DATA T0,TINT,TMAX/0.0,0.5,7.5/
PI=ATAN(1.0)*4.0
R=ANGLE*PI/180.0
C
C ! IMAX <= 100 no check www
IMAX = INT((TMAX - T0) / TINT) + 1
DO 10 I=1,IMAX
T(I)=T0 + REAL(I-1)*TINT
XZ(I,1)=V0*COS(R)*T(I)
XZ(I,2)=-0.5*GRAV*T(I)**2+V0*SIN(R)*T(I)
10 CONTINUE
S=AREA(IMAX, XZ)
CALL OUTPUT(IMAX, T,XZ,S)
STOP
END
C
FUNCTION AREA(IMAX, XZ)
IMPLICIT REAL(A-H,O-Z)
REAL XZ(100, 2)
AREA=0.0
DO 20 I=1, IMAX - 1
AREA=AREA+( XZ(I,2)+XZ(I+1,2) )*( XZ(I+1,1)-XZ(I,1) )*0.5
20 CONTINUE
RETURN
END

392:2/2
09/06/27 23:02:17
C
SUBROUTINE OUTPUT(IMAX,T,XZ,S)
IMPLICIT REAL(A-H,O-Z)
INTEGER NO(100)
REAL T(100), XZ(100,2)
C
OPEN(16,FILE='menseki2.res')
WRITE(16,'(A)')' TIME CX CZ SPACE'
DO 30 I=1,IMAX
WRITE(16,'(F5.1,2F10.2)') T(I),(XZ(I,J),J=1,2)
30 CONTINUE
WRITE(16,'(A, F10.2)') 'AREA=', S
CLOSE(16,STATUS='KEEP')
RETURN
END

イマイチよく分からんが、こうかな?
とりあえず放物線のようなものは描く。
しかし、地面をつきぬけていくので全積分面積は負になる。
この辺は適宜修正してくれ。

393:名無し
09/07/01 17:03:04
おそらくもう根本的なところから間違っていると思うのですが、間違えている点を教えていただけタラと思います。
あるデータを読みこんで画面に表示させるプログラムなのですがうまくいきません。よろしくお願いします。
implicit none
integer MM,K,X,Y
parameter (MM=500,K=100)
integer year(MM),month(MM),day(MM),sl(K,MM)
character cdummy,CFNAME
X=0
CFNAME='/home/maekawa/numeric/kure.txt/'
open(1,file=CFNAME,status='old')
1010 X=X+1
read(1,10,END=1020)cdummy,year(MM),cdummy,month(MM),
@ cdummy,day(MM),(sl(Y,MM),Y=1,24)
10 format(A5,I2,A1,I2,A1,I2,24(a1,I3))
write(6,*)year(MM),month(MM),day(MM),sl(Y,MM)
goto 1010
1020 close(1)
X=X-1
end


394:名無し
09/07/01 17:03:54
上の続きです。引き続きよろしくお願いします。
コンパイルはできるのですが実行すると
forrtl: Is a directory
forrtl: severe (30): open failure, unit 1, file /
Image PC Routine Line Source
a.out 0809916D Unknown Unknown Unknown
a.out 080986E5 Unknown Unknown Unknown
a.out 0806B758 Unknown Unknown Unknown
a.out 0804C153 Unknown Unknown Unknown
a.out 0804BAB0 Unknown Unknown Unknown
a.out 08052838 Unknown Unknown Unknown
a.out 08049D6C Unknown Unknown Unknown
a.out 08049CC1 Unknown Unknown Unknown
libc.so.6 B7E7A3B0 Unknown Unknown Unknown
a.out 08049C01 Unknown Unknown Unknown
というエラーになります。
質問の仕方も上手ではないので分かりにくい点があるようでしたら申し訳ないのですがその点もご指摘いただけたらと思います。
よろしくお願いします。

395:デフォルトの名無しさん
09/07/01 17:04:57
CFNAME='/home/maekawa/numeric/kure.txt/'

最後の / が余計なのでは?

CFNAME='/home/maekawa/numeric/kure.txt'



396:名無し
09/07/01 17:10:56
ご指摘ありがとうございます。
しかし直して見ましたがエラーは直りませんでした。
どうすればよろしいのでしょうか?

397:デフォルトの名無しさん
09/07/01 17:24:49
さらに
character cdummy,CFNAME

character cdummy,CFNAME*80
にしてみて。


398:名無し
09/07/01 17:33:10
直しました。まだ同じエラーが出ますね…すみません。

399:デフォルトの名無しさん
09/07/01 17:40:46
forrtl: Is a directory
forrtl: severe (30): open failure, unit 1, file /
このメッセージは、open(1,file=CFNAME,status='old')の行で出力されていると思います。

メッセージの最後が "file /" となっていることから、
CFNAMEに格納されているファイル名が、"/" 一文字だけであると判断できます。
メッセージの"Is a Directory" は、 ファイル名として渡された "/"が、
ディレクトリなのでオープンできないことを意味します。


400:名無し
09/07/01 17:49:00
ファイルの場所を確認したら表示されました!ありがとうございます!しかし実行したあと
write(6,*)year(MM),month(MM),day(MM),sl(Y,MM) の「sl(Y,MM)」の部分がずっとゼロで表示されます。
3けたの数字が24個よこに表示されるはずなのですが…

401:デフォルトの名無しさん
09/07/01 17:56:17
write(6,*)year(MM),month(MM),day(MM),sl(Y,MM)

write(6,*)year(MM),month(MM),day(MM),(sl(Y,MM),Y=1,24)
に変えたらどうなりますか?

402:名無し
09/07/01 18:11:57
数字がたくさん表示されるようになりましたがどうやら欲しい値の他に538976300という謎の数字が間に挟まりまくっています。
自分でも調べてみたのですがそのような数字はデータに見当りませんでした。
作った私がいうのもなんですが配列の型宣言あたりでKやYや使っているのが間違いではないかと思うのですが…ここは大丈夫なのでしょうか?

403:デフォルトの名無しさん
09/07/01 18:17:02
次は
@ cdummy,day(MM),(sl(Y,MM),Y=1,24)

@ cdummy,day(MM),(cdummy,sl(Y,MM),Y=1,24)
に変えます。



404:名無し
09/07/01 18:36:59
ほとんど表示されました!ありがとうございます!
表示する量が多すぎて最初の方のデータが表示されないのですが、すべて表示するにはどうすればよいでしょうか?
細かいところまで大変お手数お掛けします…本当に助かります。

405:デフォルトの名無しさん
09/07/01 18:38:52
学校のレポートで4行4列の行列式を計算するプログラムを作れと言われたんですが、
まったくわかりません。
少ない行数でできるらしいのですが、どうか教えてくれませんか?
fortran77を学校では使ってます。

406:デフォルトの名無しさん
09/07/02 01:35:33
>>405
まず、ちみが用いようとしている行列式の公式ないしアルゴリズムを指定してくれ。
いろいろやり方はある。

407:デフォルトの名無しさん
09/07/03 21:13:10
real(8)とrealで計算したときに足りない桁って0で補われるの?それとも動作不定?

408:デフォルトの名無しさん
09/07/03 22:25:02
質問です。
131 'Ashikaga' 65 31 54
101 'Miyoshi' 64 43 62
156 'Chousokabe' 82 58 48
86 'Imagawa' 55 60 72
53 'Houjou' 88 64 73
といったようなデータを読み込んで、
番号  名前  国語  理科  数学  合計 平均


          ~何らかの値~

国語平均  理科平均  数学平均  標準偏差

          ~何らかの値~

といった、表を出力したいのですが
おそらく、最後のprint文がミソだと思うのですがどうしたらいいかわかりません。
以下のプログラムに何を付け加えればいいのでしょうか?
また、どこか間違っている箇所があればご指摘ください。
fortran90を使っています。

409:デフォルトの名無しさん
09/07/03 22:26:38
program
 integer::n,ten(1:3)
 real(8)::sum(1:3),sum2(1:3)
 real(4)::mean(1:3),sd(1:3),heikin
 integer::io
 integer::bango,gokei
 character*14::kamoku(1:3),namae
!
 kamoku(1)='国語'
 kamoku(2)='数学'
 kamoku(3)='理科'
 n=0
 do i=1,3
   sum(i)=0.0D0
   sum2(i)=0.0D0
 end do
!

410:デフォルトの名無しさん
09/07/03 22:29:07
 do
   read(5,*,iostat=io)bango,namae,(kamoku(i),i=1,3)
   if(io/=0)then
    exit
   end if
   n=n+1
   do i=1,3
    sum(i)=sum(i)+ten(i)
    sum2(i)=sum2(i)+ten(i)**2
  end do
 end do
 gokei=ten(1)+ten(2)+ten(3)
 heikin=gokei/3.0
 do i=1,3
   mean(i)=sum(i)/n
   sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n)
 end do
 print *,'人数=',n
 do i=1,3
   print *,'科目',kamoku(i),mean(i),sd(i)
 end do
 stop
end program ex8_1a

よろしくお願いします。

411:デフォルトの名無しさん
09/07/03 23:36:09
>>407
足りない分は、ゴミが入る。
倍精度に定数を与えるときなども注意しなければならない。

412:デフォルトの名無しさん
09/07/03 23:38:29
>>411
thx

413:デフォルトの名無しさん
09/07/04 10:00:10
>>411
ゴミが入るのは、
real(8) a
a=1.0
みたいに倍精度で定義したのに倍精度で代入しなかった場合だね。

宣言の精度が違う場合には407のいう「足りない桁」の部分は
そもそもメモリ上に存在しない。仮にあるとして説明すると、
足りない桁の直前の桁がランダムに切り上げられたり切り下げられたりする、といったところか。

>>408
三好君はもっと出来る子・・・・。

read文でkamoku(1:3)に点数が入ってるけどそのあと使われてないね。
おそらく、
sum(i) = sum(i)+kamoku(i) に変更。
sum2(i) = .... も同様。

goukei=sum(1)+sum(2)+sum(3) に変更。

配列 ten(1:3) はいらなくね?

414:408
09/07/04 11:58:35
>>413
ありがとうございます。プログラムがすっきりしました。

ところで、>>408に書いたように、表みたいに出力したいのですが
以下のプログラムでは読み込んだデータの最後のものが繰り返されてしまいます。
どこがおかしいのでしょうか?

415:デフォルトの名無しさん
09/07/04 11:59:42
program
 integer(8)::n,kamoku(1:3)
 real(8)::sum(1:3),sum2(1:3)
 real(4)::mean(1:3),sd(1:3),heikin
 integer::io
 integer::bango,gokei
 character*14::namae
!
 n=0
 do i=1,3
   sum(i)=0.0D0
   sum2(i)=0.0D0
 end do

416:デフォルトの名無しさん
09/07/04 12:01:37
 do
    read(5,*,iostat=io)bango,namae,(kamoku(i),i=1,3)
   if(io/=0)then
      exit
    end if
    n=n+1
    do i=1,3
      sum(i)=sum(i)+kamoku(i)
      sum2(i)=sum2(i)+kamoku(i)**2
    end do
  end do
  gokei=kamoku(1)+kamoku(2)+kamoku(3)
  heikin=gokei/3.0
  do i=1,3
   mean(i)=sum(i)/n
   sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n)
  end do
  print *,'人数=',n
  do i=1,n
   print *,'名前',namae,'国語',kamoku(1),'数学',kamoku(2),'理科',kamoku(3),'平均',heikin,'合計',gokei
  enddo
  do i=1,3
   print *,'科目平均',mean(i),'標準偏差',sd(i)
  enddo
  stop
end program

417:デフォルトの名無しさん
09/07/04 12:29:05
>>414
データを読み込む時に毎回kamoku(1)~(3)を上書きしてるから

418:デフォルトの名無しさん
09/07/04 12:34:33
gokei の計算、 heikin の計算と
namae, kamoku(1),kamoku(2),kamoku(3),heikin,gokeiの出力は
最初のDOループの内側でやらないとだめでしょ。

419:デフォルトの名無しさん
09/07/04 12:57:31
科目名変数を定義しておいて
character*6::kamokumei(1:3)=(/'国語','数学','理科'/)

データを1行読むごとに、すぐに出力してしまう。
gokei=kamoku(1)+kamoku(2)+kamoku(3)
heikin=gokei/3.0
print *,'名前',namae,(kamokumei(i),kamoku(i),i=1,3),'平均',heikin,'合計',gokei

最後に、科目ごとの平均と標準偏差を出力する。
print *,'人数=',n
do i=1,3
mean(i)=sum(i)/n
sd(i)=sqrt((sum2(i)-(sum(i)**2)/n)/n)
print *,kamokumei(i)//'平均',mean(i),'標準偏差',sd(i)
end do


420:414
09/07/04 15:51:27
>>417さん
アドバイス、ありがとうございました。
>>418さん
なるほど、do文の中にprint文を入れるんですね!
おかげさまでうまくいきました。
>>419さん
別にprint文は最後にまとめなくて良いんですね!
細やかなご指摘、ありがとうございました。

みなさん、本当にありがとうございました!

421:デフォルトの名無しさん
09/07/04 16:43:36
ここの板で質問するのが適当か分からないですが、
FORTRAN使いの方の中にはCとの連携をしている人も
多いと思うのでアドバイス下さい。

FORTRANで作成したサブルーチンを活用し、C++からコール
する形でコードを再利用しようと考えています。
C++からFORTRANを呼び出すのはすぐに出来たのですが、
データの引渡しで困っています。

FORTRAN側ではグローバルな変数を多数(100個以上)宣言
しており、引数としては渡せないのでC++側でも同名の
変数を宣言して共用し、データのアクセスをしようと
目論んでいます。
しかし、FORTRANでexternに相当する宣言の仕方が分からず、
うまく同じ領域を共用できるようになっていません。
具体的にどんなことをすれば良いのかご存知の方がいらっ
しゃいましたら、ぜひご教授願います。
環境は、WindowsでVisualC++とVisual FORTRANを使って
います。
宜しくお願いします。


422:デフォルトの名無しさん
09/07/04 16:47:57
fortran77(g77)(90でもいいけど)で

subroutine foo(nn,letter)
character(len=nn) letter
return
end

とかって出来ないの?
コンパイルでエラーでるんだけど

423:デフォルトの名無しさん
09/07/04 16:58:14
>>421
名前付き COMMON を使います。

424:デフォルトの名無しさん
09/07/04 17:03:03
>>422
gfortran では、エラーなくコンパイルできました。
エラーメッセージを貼ってみたら?

425:デフォルトの名無しさん
09/07/04 17:57:35
>>421
マニュアルにグダグダ書いてあるから読むがよろしい。
いくつか方法がある。
結構めんどい。

Fortran2003のCとの連携ルーチンを使うという手もある。

426:デフォルトの名無しさん
09/07/04 18:00:54
>>424
>>422 ではないけど、g77 でやってみた。

% g77 -c lett.F
lett.F: In subroutine `foo':
lett.F:1:
subroutine foo(nn,letter)
1
lett.F:2: (continued):
character(len=nn) letter
2
Invalid declaration of or reference to symbol `nn' at (2) [initially seen at (1)]

gfortran は問題なかった。そもそも FORTRAN77 の規格ではこんな書き方を許していなかったはず。


427:デフォルトの名無しさん
09/07/04 18:22:42
度々すいません、>>408,414,420です。
前に質問したことは解決したんですが、
今度は書式制御でつまずいてしまいました。
変数等は
integer(8)::n,kamoku(1:3)
real(8)::sum(1:3),sum2(1:3)
real(4)::mean(1:3),sd(1:3),heikin
integer::io
integer::bango,gokei
character*14::namae
character*6::kamokumei(1:3)=(/'国語','数学','理科'/)
で、定義しています。
print "(a2,a14,a2,i7,a2,f7.2,$)",'名前',namae,(kamokumei(i),kamoku(i),i=1,3),'平均',heikin

print "(a2,a2,f7.2,a4,f7.2,$)",kamokumei(i)//'平均',mean(i),'標準偏差',sd(i)
は、どこがおかしいんでしょうか?
書式をこのように書いた場合、エラーが出てうまくいきません。

428:デフォルトの名無しさん
09/07/04 18:34:32
>>422
FORTRAN77しばらく書いてないから忘れちゃったけど、
CHARACTER*(NN) または CHARACTER*(*)でなかったかい?

g77なんてウンココンパイラ使うなよw

429:名無し
09/07/09 16:58:58
まずこのプログラムを見ていただけますか?
implicit none
integer MM,KK,M,K
parameter (MM=100,KK=100)
integer year(MM),month(MM),day(MM),sl(KK,MM)
character cdummy,CFNAME*80
M=0
CFNAME='/home/maekawa/numeric/kure.txt'
open(1,file=CFNAME,status='old')
1010 M=M+1
read(1,10,END=1020)cdummy,year(M),cdummy,month(M),
@ cdummy,day(M),(cdummy,sl(k,M),k=1,24)
10 format(A5,I2,A1,I2,A1,I2,24(a1,I3))
write(6,*)year(M),month(M),day(M),(sl(k,M),k=1,24)
goto 1010
1020 close(1)
M=M-1
end

SLの24の値を平均して一個のデータにして新しい配列を作って代入する、という事をしたいのですがどのようなことを付け加えればよろしいでしょうか。
おかしい質問かもしれませんがよろしくお願いします。

430:デフォルトの名無しさん
09/07/10 09:09:38
えー、そもそもまともに動くはずはないシロモノなんですが、
なぜこういうことが起きるのか教えてください。

A=X+1          (←XとYは未定義)
B=Y+1
Z=1           (暗黙の型宣言)
C=A+B

というような場面でZ=1を入れるかどうかでCの値が変わるんですが。
XとYが未定義なのでどこかめちゃめちゃなアドレスを参照していて、
Zの宣言によって参照するアドレスが変わるとかそんな感じでしょうか?
でも未定義とはいえ既に代入してあるんで結果が変わるのは不思議な気がします…

431:デフォルトの名無しさん
09/07/11 00:57:16
>>430
試してみましたけど、ifort 11.0とgfortran 4.3.2では再現されないですね。
処理系、教えてもらえますか?



432:デフォルトの名無しさん
09/07/11 05:27:22
そういえば似た感じでwrite文のある無しで結果が変わったことがあったな。

アドレス参照して値取り出して・・・は最近のCPUではある程度まとめて出来るだろうけど、
定数の代入とかI/Oみたいに、まとめてしなくても良い or まとめて出来ない処理が
混じるとそこで一度仕切るというかなんか処理が変わるんだろうな・・・と適当な事を書いてみる。
>>430 の Z=1 の代入文を
(なにもしない)continue文に変えてみたらどうなるのだろう?

433:デフォルトの名無しさん
09/07/11 15:27:14
FORTRANでオブジェクト指向ってできますか?

434:デフォルトの名無しさん
09/07/11 17:24:15
>>433
誰かの本にそういう話があったな。誰のだったっけ?

435:デフォルトの名無しさん
09/07/11 18:15:44
>>433
Fortran2003でOOP対応が一通りそろった。

436:デフォルトの名無しさん
09/07/13 20:15:36
皆さん実際、使ってます?>オブジェクト指向
Fortranが使われるような数値計算の分野で、どういう場面で有用なのか
いまいちイメージ沸きません

437:デフォルトの名無しさん
09/07/13 20:24:34
行列とか?

438:デフォルトの名無しさん
09/07/13 23:01:28
>>436
MPIのルーチンとかがC++で書かれていて、引数の型がpolymorphism的に任意に
なっていたりすると、F90のPASCAL的な厳格な型判定では、インターフェースも
書けない。型判定を緩くしようというような消極的な事情もあるようだよ。

439:デフォルトの名無しさん
09/07/14 01:06:44
>>431
遅くなってすいません。OSはXP、intel fortranの11.0+visual studioです。
多分そちらと同じですよね?上のは少し単純化してありますけど、
AとBの右辺がもう少し複雑になってて既知の数で割ったり足したりしてるだけなんで
おかしなことに変わりはないと思いますが…

>>432
continueに変えても値が変わりました…ちなみに
write文のときは何が原因でしたか?

440:デフォルトの名無しさん
09/07/14 01:17:31
>>438
C++はよ消えてなくなれ、ということか。
あれはFortranやCとはあまり親和性が無いから嫌いだ。使うけど。
>>439 後半
原因不明のまま放置w 432でかいたけど
I/O の直前まで、I/O の行、I/O よりうしろ、
でコンパイラが作業を区切るからではないかと推定したw。
自分の時には write文でなくても read文でも同じだったから。

コンパイラにもよるのかもなあ。
同じ経験はDEC Fortranのころからあった気がする。というかIntelのはDECの系譜だろうし。

441:デフォルトの名無しさん
09/07/17 02:00:58
>>436
化学プロセスの設計のときとか
撹拌槽やら蒸留塔やらいろんなクラスを作っておいて
後で自由に組み合わせたりできそうだな。

問題は、うちのボスがオブジェクト指向を理解できない、ということだな…

442:デフォルトの名無しさん
09/07/17 02:17:34
自由に組み合わせる、だけならOOである必要もないけどな。まあ楽だけど。

443:デフォルトの名無しさん
09/07/18 17:26:27
問題解決の方法が、オブジェクト主体で考えるのが自然かそうでないかによると思うけど。
普通の数値計算は、方程式をいかに早く効率良く解くか、というのが主眼だから
オブジェクトなんてものを持ち出す必要性も少ないってことじゃないかと。
計算資源の観点からはむしろマイナスだし>OO

444:デフォルトの名無しさん
09/07/18 22:46:24
10人分の受験番号と1教科の採点結果から、平均と偏差値を求めて、
成績順に並び替えるっていうプログラムを作りたいんだけど、
SUBROUTINEを、
・平均を求めるもの
・偏差値を求めるもの
・成績に並び替えるもの
の3つを作ればいいってこと?
それぞれのサブルーチンの作り方がよく分からないので教えてもらえませんか?
最後の成績はSWAP・・・?

77使ってます

445:デフォルトの名無しさん
09/07/18 23:43:20
>>444

> ・平均を求めるもの
> ・偏差値を求めるもの
> ・成績に並び替えるもの
> の3つを作ればいいってこと?
> それぞれのサブルーチンの作り方がよく分からないので教えてもらえませんか?
> 最後の成績はSWAP・・・?

つまり

・平均値の求め方を知らない
・偏差値の求め方を知らない
・数の大小関係を知らない

ということですね?

FORTRAN 以前の問題なので、中学校あたりの数学からやり直すべきでは?

446:デフォルトの名無しさん
09/07/18 23:50:38
素直に課題ですといえば教えてやらんのに

447:デフォルトの名無しさん
09/07/19 00:30:56
>>445-446
ここはノンケ大歓迎で宿題有りのスレなんだぜ。

448:デフォルトの名無しさん
09/07/19 00:50:34
>>444
並べ替えのf77参考
URLリンク(www.geocities.jp)

F90の参考プログラム
あまり変更なしでf77になる。

平均値と偏差値
URLリンク(ns1.shudo-u.ac.jp)

並べ替え
URLリンク(ns1.shudo-u.ac.jp)



次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch