1 名前:デフォルトの名無しさん [2006/01/24(火) 09:48:23 ] このスレッドは、他のスレッドでは書き込めない超低レベル、 もしくは質問者自身何が何だが分からない質問を勇気を持って書き込むスレッドです。 FORTRAN使いが優しくコメントを返しますが、 お礼はFORTRANの布教と初心者の救済をお願いします。
230 名前:デフォルトの名無しさん mailto:sage [2006/03/10(金) 22:52:46 ] 欠測のある平均値の求め方を教えてください。 10行ごとの各列の(欠測を除外した)平均値と欠測数を求める問題です。 時間,A,B,C 1,23.5,23.2,22.7 2,24.5,25.2,22.1 3,25.4,24,27.5 4,26.4,,22.4 5,23.5,22.4, と2000行、続きます。
231 名前:デフォルトの名無しさん [2006/03/11(土) 00:02:09 ] >>230 適当なのでもっとうまい方法もあるやも知れぬ。参考までに。 INTEL FORTRAN Ver.9 PROGRAM vipp IMPLICIT NONE INTEGER :: i, j, k REAL :: x(10) i = 0 DO i = i + 1 x = 0.0 READ(9, '(i5, 10F15.5:)', ADVANCE = 'NO', EOR = 98,END = 99) k, (x(j), j = 1, 10) 98 PRINT *, j, ":", SUM(x(1:j)) / REAL(j) END DO 99 PRINT *, "EOF" STOP END PROGRAM vipp 実行結果 C:\Documents and Settings\All Users\Documents\FORTRAN\vip\Debug>vip 3 : 23.13333 3 : 23.93333 3 : 17.63341 3 : 16.26667 3 : 15.30000 EOF
232 名前:231 mailto:sage [2006/03/11(土) 00:09:25 ] >>230 ごめw 列ごとの平均かw 風呂から上がったらまた考えるw
233 名前:230 mailto:sage [2006/03/11(土) 00:25:20 ] >>232 トライ、ありがとうございます。 温度なので、23度あたりになるはずです。 5列分の平均ですが、 A 24.66 , B 23.7 , C 23.675 内部ファイルとLEN 関数をつかって、 うまくできないかとチャレンジ中です。
234 名前:デフォルトの名無しさん [2006/03/11(土) 00:28:05 ] くたばれFORTRAN
235 名前:デフォルトの名無しさん [2006/03/11(土) 00:51:46 ] がんばれFORTRAN
236 名前:231 mailto:sage [2006/03/11(土) 00:52:36 ] >>233 単純に思いつく方法は 1.手抜き方式、0.0が読み取られたときを欠損値とするというやり方 2.内部ファイルに読み込んで、INDEX関数で”,”を区切りとして切り取るやり方 汎用性からみると2かな? 第3の方法を求めて FORMAT文がF95で進化したので、空データの読み取りが検知できないか今調べているw
237 名前:230 mailto:sage [2006/03/11(土) 00:56:23 ] >>233 使用コンパイラ Compaq VFでは、 空白を欠測ではなく0と認識してしまったので、ダメでした。 文字列として読み込んで、^@ の処理を考えます。
238 名前:デフォルトの名無しさん mailto:sage [2006/03/11(土) 01:28:02 ] こんな感じッスかね? program hoge implicit none integer, parameter :: N = 10, NT = 2000 real, parameter :: NG = -1.0E10 real :: A(N), B(N), C(N), t, aa, ab, ac integer :: ka, kb, kc, i, j, ios character(len=80) :: tmp open(unit=11,file="huge.dat",status="OLD",blank="NULL") loop_j: do j = 1, NT/N A = NG; B = NG; C = NG loop_i: do i = 1, N read(unit=11,fmt="(A)",iostat=ios) tmp if (ios < 0) then ! エラー処理は省略... exit loop_j end if read(unit=tmp,fmt=*,iostat=ios) t, A(i), B(i), C(i) end do loop_i ka = count(A <= NG); aa = sum(A, mask=(A > NG)) / (N-ka) kb = count(B <= NG); ab = sum(B, mask=(B > NG)) / (N-kb) kc = count(C <= NG); ac = sum(C, mask=(C > NG)) / (N-kc) print *, "欠測 = ", ka, kb, kc print *, "平均 = ", aa, ab, ac end do loop_j close(11) end program hoge
239 名前:デフォルトの名無しさん mailto:ゲェェ [2006/03/11(土) 01:33:55 ] test
240 名前:230 mailto:sage [2006/03/11(土) 01:56:46 ] >>238 ありがとうございます! 無事に解決できました。 10個とも欠測の時間帯の平均値が NaN と表記されて、 いたれりつくせりです。 count(A <= NG) と mask=(A > NG) がミソですね。 0割になりそうでならないのが少し不思議です。
241 名前:231 [2006/03/11(土) 02:05:07 ] 出遅れたかwwwwwwwwwww PROGRAM vipp IMPLICIT NONE INTEGER :: i, j, k CHARACTER(LEN = 136) :: buff REAL :: a, x(10) = 0.0 INTEGER :: n(10) = 0 DO READ(9, '(a)', END = 99) buff k = INDEX(buff, ',') READ(buff(:k), '(i10)') j buff = buff(k + 1:) DO i = 1, 10 k = INDEX(buff, ',') IF (k == 0 .AND. LEN_TRIM(buff) == 0) EXIT ! end by "," IF (k /= 1) THEN ! k == 1 is missing data : ",," READ(buff, '(F15.0)') a x(i) = x(i) + a n(i) = n(i) + 1 END IF buff = buff(k + 1:) IF (k == 0) EXIT ! end of record END DO END DO 99 PRINT *, "EOF" PRINT *, n PRINT *, x / REAL(n) STOP END PROGRAM vipp >>241
242 名前:231 mailto:sage [2006/03/11(土) 02:06:24 ] C:\Documents and Settings\All Users\Documents\FORTRAN\vip\Debug>vip EOF 5 4 4 0 0 0 0 0 0 0 24.66000 23.70000 23.67500 NaN NaN NaN NaN NaN NaN NaN
243 名前:230 mailto:sage [2006/03/11(土) 02:26:44 ] >>241 わかりやすい注釈までいれていただいて、ありがとうございます。 k = INDEX(buff, ',') buff = buff(k + 1:) LEN_TRIM(buff) == 0 など、文字列処理の強力さはさすがですね。 配列手続といい、文字列処理といい、 f90 の強力さに、あらためて惚れなおしました。
244 名前:230 mailto:sage [2006/03/11(土) 02:38:50 ] >>241 今、調べなおしてみると、 LEN_TRIM 以外は、f77 の機能のようですね。 f77 の文字列処理の先見の明に驚いてしまいます。
245 名前:231 mailto:sage [2006/03/11(土) 02:39:14 ] >>243 場合わけはあまりエレガントでなかった。もう少し冗長でも分かりやすくすべきかも。 buff = buff(k + 1:) これで長さが足りない分に空白が入るかどうか確かめておいた。 ちゃんと空白が入っているようなので、ごみが尻のほうに残ることは無い。 文法書にもそう書いてあった気がするのだが、記憶がアイマイミー。
246 名前:230 mailto:sage [2006/03/11(土) 02:54:36 ] >>245 INDEX を用いた切り分けや、テクニカルな文字列処理の手本 を示していただいただけでも、感謝感激です。 本当にありがとうございました。
247 名前:231 mailto:sage [2006/03/11(土) 03:38:39 ] >>246 喜んでもらえてうれしいお(^ω^)ノシ >>238 も勉強になった。漏れは固定FORMATの愛好者なのでCVS形式はほとんど使ったこと無い。 自由書式の時にCVS形式の空データは読み飛ばすとは知らなかった。0が入ると思っていた。 F77はINDEX関数がとても便利だったが、TRIM関数が無かったせいで初心者時代に苦労した。 ある程度習熟してからは、不定長の文字引数で尻から先頭に向かって空白以外が出るまで 数える関数などを自分で用意できるようになったが、そこに到達するまではかなり時間がかかった。 内部ファイルの使い方も共同研究の外国人の書いたプログラムを読んでいて初めて知った。 それまでこんな便利なものがあるとはまったく知らなかったw 後になって改めて文法書を読むと、文字変数を入力装置にできるとはさりげなく書いてあるのだが、 それがとても便利なものだということはまず分からない。 この辺のノウハウを徒弟制度や口伝に頼っているFORTRAN界の未来は暗いなと思ったりしてw
248 名前:デフォルトの名無しさん [2006/03/11(土) 08:27:30 ] ところでFortranに分割コンパイルっていつ入るんですか?
249 名前:デフォルトの名無しさん mailto:sage [2006/03/11(土) 10:30:55 ] >>248 単純に複数のプログラム単位をコンパイル&リンク出来るという意味でなら FORTRAN IIで副プログラム呼び出しとBinary Symbolic Subroutine Loaderが 使えるようになった1958年から。 複数のプログラム単位のコンパイルを自動化出来るという意味でなら FORTRAN IIモニタの出来た1959年から。 近代的なモジュールの機能が使えるようになったという意味でなら Fortran 90の規格が出来た1991年から。 ということでよろしいかな?
250 名前:デフォルトの名無しさん [2006/03/12(日) 21:48:13 ] 非線形連立代数方程式をとくFORTRANのコードをC++に移植しています。 解の一部がどうしても両プログラムで一致せず、 丸一日かけて色々と試行錯誤したところ、Fortranでreal型を使っていたところ、 c++でdouble型にしてしまっていたことが原因でした。 このような場合、c++への移植の際にもfloat型を使うなどしてもとのコードと精度を合わせた方がよいのでしょうか。 なんとなくより大きな範囲を扱える変数型の方がよさそうな気がするのですが、 移植元が倍精度を使っていないので迷っています。 移植元のコードは1980年頃に書かれたもので、計算時間との兼ね合いから単精度を選択したと捉えたほうがよいでしょうか。 また、計算誤差の発生しないdecimal型があると知りました。 一般に数値計算をする場合はこのような型を使うのでしょうか。 精度が高い代わりに計算速度が遅いと聞きましたので、 一般にはどのような基準で使い分けて折り合いをつけていくのか興味があります。 すみませんが、どなたかご存知の方がいらっしゃいましたらお教えいただけますか。 よろしくお願いいたします。
251 名前:デフォルトの名無しさん [2006/03/12(日) 23:43:23 ] >>250 精度が出てるのを確かめられたならdouble型にすべし。 floatにする必要はないと思う。 C++の組み込み型にdecimalがあるとはきいたことないが、 だた10進数の内部表現ができるってだけで(0.1とかが正確に表せるのかな?) 数値計算自体に誤差が出ないわけではない。はず・・・たぶん
252 名前:デフォルトの名無しさん [2006/03/13(月) 11:13:40 ] ところでFORTRANにリアルタイムイベントハンドラはいつ入るんですか?
253 名前:デフォルトの名無しさん [2006/03/13(月) 13:47:57 ] >>250 1980年代のコードである場合、浮動小数点には今とは違う事情がある。 現在の浮動小数点はIEEEの形式にほぼ統一されているが、かつてはメーカーごとに 実数の内部形式は異なっていた。そのために、同じワード長でも仮数部により多くの ビットを割り当てているものもあれば、指数部により多くのビットを割り当てているもの もあって、機種によって有効桁の範囲が違っていた。 (IBMは仮数部に、CRAYは指数部により多くのビットを割り当てていた。 さらに言えば、NECのACOSのあるシリーズのように1ワード=36bitとか、 CDCのいくつかのシリーズのように1ワード56?bitとかでワード長自体が 違うものもあった。) というわけで、書かれた対象機種が分かれば必要精度に関するヒントになる。 ただ数値演算プロセッサが倍精度で作られている以上 基本的に倍精度にしておくのがよろしいと思う。 まぁSSEで高速化を優先するならまた話は別だが・・・
254 名前:250 [2006/03/13(月) 20:34:42 ] >>251 , 253 ありがとうございます。 頂いたアドバイスに従って とりあえず、倍精度で移植を進めてみようと思います。 >現在の浮動小数点はIEEEの形式にほぼ統一されているが、かつてはメーカーごとに >実数の内部形式は異なっていた。 そういえば、コンピュータの精度に応じてコメントアウトすべしというような注釈のついた関数がありました。 そういうことだったんですね。勉強になります。
255 名前:デフォルトの名無しさん [2006/03/14(火) 01:24:29 ] >>250 DECIMAL型について言えば、あれは商業用の機能で、数値計算的にはあまり 利益がないと思う。特に計算スピードはがくっと落ちるはずである。 専門ではないから正確ではないが、商業の世界では利息で生じた小数点以下の 端数をあるところで切り捨てる(または四捨五入?)する慣例がある。浮動小数 点では2進法を使っている関係で丸め誤差から小数点以下の端数の切り捨てで 10進法の時と微妙なズレが生じ、大量の金額に対して計算すると慣例とのズレ が無視できなくなる。これに対する対策がdecimal型すなわち10進型である。 一般的には、1桁ごとに10進法の数字を1個割り当てて計算するので極めて 計算効率が悪い。1桁につき最低4ビット必要。同じビット数で表される数の 範囲が狭くなってしまう。 (確か8087コプロにもBCD演算機能があったはずだが、固定小数点だったような 気がする。) 数値計算的には、倍精度、倍々精度という方向に行くことはあっても、 10進演算の方向に行くことは特殊な場合を除いてないと思う。 実際FORTRANで10進演算はできないが、利用者からの不満は聞かない。 一方COBOLやPL/Iなどでは10進演算が出来るようになっている。
256 名前:デフォルトの名無しさん [2006/03/14(火) 01:53:35 ] >>254 >そういえば、コンピュータの精度に応じてコメントアウトすべしというような >注釈のついた関数がありました。 昔は精度に関する機種依存性が結構あって移植の問題になっていた。 Fortran90で数値の精度に関する関数が大量に導入されたのは、 この辺でみんな苦労していたからだと思う。ただ90年代に入ってから IEEE形式に集約されて行ったので、ややありがたみが減った。 最近は0割りが発生しても強行突破して計算を続けてくれるので便利だと思う。 投機的実行の為にわざわざIF文で排除したはずの0割りを実行して糸冬了とか 脳の血管切れそうな事態が起きなくなった。 Fortran2003(一部はFortran95の拡張規格)でIEEE754に関する様々な関数が 導入されているので、将来はよりマニアックな要請に対応できるはずである。
257 名前:デフォルトの名無しさん [2006/03/17(金) 01:29:56 ] PROGRAM TEST IMPLICIT REAL*8 (A-H,O-Z) IMPLICIT INTEGER (I-N) * DIMENSION G(50) * WRITE(*,*)'個数(入力数+1)' READ(*,*)N * WRITE(*,*)'整数' DO 10 I = N, 0, -1 READ(*,*)G(I) 10 CONTINUE * DO 500 I = N, 0, -1 WRITE(*,*)I,G(I) 500 CONTINUE * DO 510 J = N, 0, -1 WRITE(*,*)J,G(J) 510 CONTINUE * END これ実行するとG(0)の値がちゃんと出力されないんですが、何故ですか? DO500とDO510で、出力が違う値で出てきてしまいます。 あまりにも簡単すぎる質問で申し訳ないですが、誰か教えてください。
258 名前:257 [2006/03/17(金) 01:31:55 ] frtで実行するとこんなのが出ます。 ↓ jwe0019i-u The program was terminated abnormally with Exception Code EXCEPTION_A CCESS_VIOLATION. error occurs at _MAIN__ line 19 loc 0040108c offset 0000008c _MAIN__ at loc 00401000 called from o.s. error summary (Fortran) error number error level error count jwe0019i u 1 total error count = 1
259 名前:デフォルトの名無しさん mailto:sage [2006/03/17(金) 01:55:44 ] >>257 配列の使い方を復習しましょう。 ttp://www.g.dendai.ac.jp/lecture/fortran/fort07.html
260 名前:257 [2006/03/17(金) 02:28:35 ] >>259 なるほど・・・初歩の初歩ですね。 とてもよくわかりました。 助かりました。ありがとう。
261 名前:デフォルトの名無しさん [2006/03/17(金) 02:29:05 ] >>257 数学科や計算機学科での自然な数は0から始まるのだが、 FORTRANの自然数は1から始まる古典的な自然数体系を取っている。 したがってG(50)と宣言したときはG(1)〜G(50)までの領域が取られており、 G(0)はout of rangeになる。 エラーメッセージにACCESS_VIOLATIONと出ているが、これはは大抵 配列のはみ出しと思っていい。 G(0)がどうしても使いたければG(0:50)という形で宣言すればいいが、 まあ素直に1から始まる配列になれたほうがいいだろう。 エラーメッセージから見る限り富士通のコンパイラを使っていると思うが、 デバッグ用のオプションに配列はみだしをチェックするサブスクリプトチェックの項目が あるだろうから、デバッグ段階ではそれをオンにしておけばはみだしが発生したとき そのソース行を教えてくれる。エラーが取れたら、チェックを外せばよい。
262 名前:259 mailto:sage [2006/03/17(金) 11:56:35 ] >>261 めちゃめちゃ親切に説明して頂いて助かります。 富士通のコンパイラまでわかるなんて、凄いです。 エラーメッセージの意味が理解できなかったので、まだまだでした…精進します。
263 名前:262 mailto:sage [2006/03/17(金) 11:58:40 ] 自分、257でした。 259さん、すみません。
264 名前:http://www.vector.co.jp/soft/win95/util/se072729.html mailto:http://www.microsoft.com/japan/windowsxp/64bit/default.mspx [2006/03/18(土) 19:33:30 ] 64bitに対応したトリップ検索プログラムありますか? TextSS のWindowsXP(Professional)64bit化おながいします もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?
265 名前:デフォルトの名無しさん [2006/03/18(土) 23:10:21 ] この板でも爆撃喰らうんだな。VIPでは日常茶飯事だがw
266 名前:デフォルトの名無しさん [2006/03/26(日) 07:13:26 ] xxxx01.txt xxxx02.txt .... みたいな連番になっているファイルを順番に読み込むようにしたいのですが、 読み込むファイル名の部分をどのような書式にすれば良いのでしょうか? ((文字列+整数)をまとめて文字列として認識する方法が分かりません)
267 名前:デフォルトの名無しさん mailto:sage [2006/03/26(日) 11:30:18 ] >>266 内部ファイルを使うのが一番手っ取り早いだろう。 CHARACTER*10 FNAME INTEGER I DO I = 1, 20 WRITE(FNAME,'(A, I2.2, ''.txt'')') 'xxxx', I OPEN(10, FILE=FNAME, STATUS='OLD') : ファイルの読み込み : CLOSE(10) END DO
268 名前:266 [2006/03/26(日) 20:41:47 ] >>267 どうもありがとうございます。助かります。 申し訳ないですが、もうひとつ質問、 連番になっていなくても、ディレクトリにあるファイル全部を 読み込むような手段はあるでしょうか?
269 名前:デフォルトの名無しさん mailto:sage [2006/03/26(日) 23:22:58 ] >>268 Fortran95 までの標準仕様ではディレクトリの操作や検索は出来ない。 しかし、大抵の処理系にはファイル操作関係の拡張手続きが付いているので それらを使えば可能。 以下は Compaq Visual Fortran での例: use DFLIB implicit none character(len=100) :: dir, files, fname integer(kind=4) :: handle, fnlen type(FILE$INFO) :: info : dir = "D:\DataDir\" files = trim(dir) // "*.txt" handle = FILE$FIRST do fnlen = GETFILEINFOQQ(files, info, handle) if ((handle == FILE$LAST) .or. (handle == FILE$ERROR)) exit fname = trim(dir) // info%NAME open(unit=10, file=fname, status="OLD") : ファイルの読み込み : close(10) end do : 詳しくは処理系のマニュアル等を参照のこと。
270 名前:266 mailto:sage [2006/03/27(月) 20:27:30 ] >>269 どうもありがとうございました。 連番に直してから読み込むことにします。
271 名前:デフォルトの名無しさん mailto:sage [2006/04/05(水) 17:37:56 ] format 文について、教えてください。 配列Aのサイズ変化にあわせて、 format を可変にしたい場合どうすればよいのでしょうか? program main integer, parameter :: NUM=4 real*8 A(NUM) integer n do n=1,NUM A(n)=0.1*n end do ! write (6,'(1x, NUMf5.1)') (A(n),n=1,NUM) ! これはエラー write (6,'(1x, 4f5.1)') (A(n),n=1,NUM) ! これなら通る end
272 名前:デフォルトの名無しさん mailto:sage [2006/04/05(水) 18:08:54 ] write文で DO型並びを使わず愚直に DO文をかく。 write(6, '(1x, $)') do n=1, NUM write(6, '(f5.1, $)') A(n) end do write(6, '(/)') FMT記述子を文字列変数にするという手もあるが、 こちらの方がシンプル。
273 名前:271 mailto:sage [2006/04/05(水) 20:36:03 ] >>272 ありがとうございます。無事にできました。 改行制御編集記述子と斜線編集記述子を組み合わせれば、 できるのですね!
274 名前:デフォルトの名無しさん mailto:sage [2006/04/05(水) 20:58:19 ] 仕様上はFORMAT書式に対応する項目がなくなった時点で書式制御が終了するので 出力する項目に対して多めに指定してやっても良い(ちょっと強引だが) write(6, '(1X, 100F5.1)') (A(n),n=1,NUM) 処理系依存だが、<> でくくった中に整数式を書ける処理系もある。 write(6, '(1X, <NUM>F5.1)') (A(n),n=1,NUM) ついでに、コロン編集記述子を使えば入出力項目がなくなった時点で 以降の書式を無視して終了させられる。 write(6, '(1X, 100(F5.1, :, ", "))') (A(n),n=1,NUM)
275 名前:デフォルトの名無しさん [2006/04/05(水) 21:01:15 ] >>272 $ 指定子ってFortranの規格外でないかい?
276 名前:271 mailto:sage [2006/04/05(水) 21:13:08 ] >>274-275 情報、ありがとうございます。 過大定数の仮代入やコロン編集記述子は、アリですね! <> でくくった中に整数式を書ける処理系 Compaq Visual Fortran ではできました!すごい! 処理系依存はできるだけ避けたいと思っているので、 考えどころですね。 改行制御編集記述子は規格外でしたか! なかなか使い勝手のよさそうな機能なのに。
277 名前:デフォルトの名無しさん mailto:sage [2006/04/06(木) 10:53:52 ] $の代わりにこっちでどうかな? write(*,'(f5.1)',advance='no') A(n)
278 名前:271 mailto:sage [2006/04/06(木) 12:35:24 ] >>277 ありがとうございます。 こちらでもできました! 停留入出力という技もありましたね! F90 の書式仕様の理解は、手を抜いていましたが、 まじめに取り組むべきだと思いました。
279 名前:デフォルトの名無しさん [2006/04/07(金) 19:33:01 ] 教えてください!! 初めて書き込みさせていただきます。 Fortranのプログラムの課題が出ているのですがわからなくて・・・ 簡単な内容なんだと思うのですが、 みなさんのお力貸していただけないでしょうか?? 内容は 配列データa(i) (i=0,Num-1) が与えられたとき、 このデータの平均値および標準偏差を計算するプログラムを書け。 というものです。 お願いします!!
280 名前:デフォルトの名無しさん mailto:sage [2006/04/07(金) 20:31:05 ] >>279 平均値と標準偏差を求める式は知っているな? それをそのまま書けばよい。 avg = sum(a(0:Num-1)) / Num v = sum((avg - a(0:Num-1))**2) / Num s = sqrt(v)
281 名前:デフォルトの名無しさん [2006/04/08(土) 00:17:30 ] >>280 ありがとうございます!! 書いてみます!
282 名前:デフォルトの名無しさん [2006/04/08(土) 00:32:04 ] 学校の課題のこのプログラムが、全体として何が行われているか、どなたか教えてください! お願いします。 real::x,x1,x2,func real::dy,delt=1.e-6 read(*,*) x1,x2 if(func(x1)*func(x2) > 0.0) then write(*,*) 'boo boo' stop end if dy = sqrt(-func(x1)*func(x2)) do while (dy > delt) x=(x1+x2)/2.0 if(func(x1)*func(x) > 0.0) then x1=x else x2=x end if dy = sqrt(-func(x1)*func(x2)) end do x=x1 if(abs(func(x1)) > abs(func(x2))) x=x2 write(*,*) x end
283 名前:デフォルトの名無しさん mailto:sage [2006/04/08(土) 06:52:57 ] >>282 方程式の解、二分法 ttp://www.arch.kumamoto-u.ac.jp/hagane/yamanari/joho3/bisec.html
284 名前:デフォルトの名無しさん [2006/04/08(土) 11:14:08 ] >>283 ありがとうございます! URLとっても参考になりました。 これでやっとレポート書けそうです。 ありがとうございます!!
285 名前:デフォルトの名無しさん [2006/04/08(土) 13:27:05 ] しばらくぶりに・・・・・・宿題もっと持って来い!
286 名前:デフォルトの名無しさん [2006/04/12(水) 09:42:26 ] こんにちわ。 02.dat,05,dat,08,datなどのように、 飛び飛びで01.datから10.datまでの間の番号のついたファイルがあります。 ただし、どの番号のファイルがあって、どの番号が無いのかは 時々刻々と変わります。 このファイルを、01から、10まで、順番にOPENしてREADしたいのですが、 このとき、存在しない番号のファイルをスキップするにはどうしたらよいでしょうか。 status='old'を試しましたが存在しない番号のところで止まってしまいます。 ヒントだけでもよいのでよろしくお願いします。
287 名前:デフォルトの名無しさん [2006/04/12(水) 09:44:56 ] 追記 status無しのただのOPEN文だと、存在しない番号ファイルを 空ファイルで作ってしまいます。これを作らないようにしたいのです。
288 名前:デフォルトの名無しさん mailto:sage [2006/04/12(水) 12:29:36 ] >>286 logical :: exist character(len=80) :: filename do i=1,10 write(filename,'(i2.2,".dat")') i inquire(file=filename,exist=exist) if(exist) then open(io,file=filename,status='old') ! close(io) endif enddo
289 名前:デフォルトの名無しさん mailto:sage [2006/04/12(水) 16:26:44 ] 以下の複素多項式p(z)(zは複素変数)のゼロ点を全て、ニュートン法で求めよ。 (1)p(z)=z**2+4*i (2)p(z)=z**4-2*z**3+2*z**2-2*z+1 お願いします。
290 名前:デフォルトの名無しさん [2006/04/12(水) 22:51:27 ] PROGRAM newton IMPLICIT NONE INTEGER :: i, n REAL :: pi COMPLEX :: z pi = 4.0 * ATAN(1.0) n = 4 !2 DO i = 1, n z = EXP( 2.0 * pi * CMPLX(0.0, REAL(i) / REAL(n)) ) DO IF ( ABS(f(z))**2 < EPSILON(REAL(f(z)))**2 + EPSILON(IMAG(f(z)))**2 ) EXIT z = z - f(z) / df(z) END DO PRINT *, 'finished', z, f(z) END DO STOP CONTAINS COMPLEX FUNCTION f(z) IMPLICIT NONE COMPLEX, INTENT(IN) :: z f = z**4 - 2.0 * z**3 + 2.0 * z**2 - 2.0 * z + (1.0, 0.0) ! f = z**2 + (0.0, 4.0) RETURN END FUNCTION f !---------------------------------- COMPLEX FUNCTION df(z) IMPLICIT NONE COMPLEX, INTENT(IN) :: z df = 4.0 * z**3 - 6.0 * z**2 + 4.0 * z - (2.0, 0.0) ! df = 2.0 * z RETURN END FUNCTION df !---------------------------------- END PROGRAM newton
291 名前:デフォルトの名無しさん [2006/04/12(水) 23:03:46 ] 解 finished (-1.414214,1.414214) (0.0000000E+00,1.3691417E-07) finished (1.414214,-1.414214) (0.0000000E+00,1.3691417E-07) Press any key to continue finished (-7.1054274E-15,1.000000) (-2.8421709E-14,0.0000000E+00) finished (0.9998764,-2.0247151E-11) (0.0000000E+00,1.0012824E-14) finished (1.1924881E-08,-1.000000) (4.7699519E-08,0.0000000E+00) finished (1.000000,1.7484555E-07) (0.0000000E+00,5.6843419E-14) Press any key to continue ふつう、n次代数方程式の初期値は、1のn乗根から出発するのだが、 2番目の問題はそれがすでに解だったりして、newton法を使う前にLOOPから抜けてしまうw 問題設定が悪いw Newton法では微係数が必要なのだが、ここでは手動で微分して関数として与えた。 発展形としては数値微分するもよし、多項式なら機械微分するもよし。 収束判定条件にはEPSILON関数を使ってみた。 あまり真面目に考えてない。
292 名前:デフォルトの名無しさん mailto:sage [2006/04/13(木) 11:35:03 ] どうもありがとうございます。 学校でやってみます。
293 名前:デフォルトの名無しさん [2006/04/13(木) 13:56:30 ] >>288 様 ありがとうございます。 教えていただいたコードをそのままやってみたのですが、 existの中身がファイルのある無しに関わらず常に「F」になって if文の中に入っていきません。原因として何が考えられるでしょうか。 使っているコンパイラはFTN95というやつです。 INQUIREというヒントをいただきましたので、自分でも考えてみます。 ありがとうございました。
294 名前:293 [2006/04/13(木) 14:04:39 ] できました。 ファイルの拡張子指定ミスでした。 大変失礼いたしました。orz
295 名前:デフォルトの名無しさん [2006/04/21(金) 20:32:22 ] あげ
296 名前:デフォルトの名無しさん [2006/05/01(月) 13:36:24 ] そろそろ 宿題持ってこないか?w
297 名前:デフォルトの名無しさん [2006/05/04(木) 01:54:12 ] 質問です。 私のやりたいことは、 file_001.txt file_002.txt file_003.txt ・・・・ とナンバーの振られたファイルを順次読み込んでいくプログラムを作りたいのです。 do文などで何とかならないものでしょうか?
298 名前:デフォルトの名無しさん [2006/05/04(木) 02:08:36 ] >>297 character*12 fname ・・・ do i=1,20 write(fname, '(''file_'', I3.3, ''.txt'')') i open(unit=11, file=fname, status='OLD') ・・・ close(11) end do こんな感じでどうでしょう。
299 名前:297 [2006/05/04(木) 02:27:59 ] できました!ありがとうございます。 ここでwrite文はなにをしてるんでしょうか? fnameの定義ですか?
300 名前:デフォルトの名無しさん mailto:sage [2006/05/04(木) 09:36:38 ] >>299 内部ファイルを使って文字列変数 FNAME に 'file_' + 3桁の整数 + '.txt' を書き込んでいる。 つまり、ループカウンタ I に応じて ファイル名 'file_001.txt' 〜 'file_020.txt' を生成している。 内部ファイルについての詳細は↓やマニュアル等を参照のこと。 ttp://docs.sun.com/source/806-4843/Cp2_io.html
301 名前:デフォルトの名無しさん [2006/05/10(水) 17:17:37 ] Fortran90で直行座標(x,y,z)を極座標(r,θ,Φ)に変換するプログラムを作れ。 って課題が出たのですがわかりません。教えて下さいm(._.)m
302 名前:デフォルトの名無しさん [2006/05/10(水) 19:38:12 ] >>301 「直交座標 極座標」でググればすぐ出て来るだろう、というのは置いといて なんのひねりもなく作ると、 program hoge implicit none real, parameter :: PI = 3.14159265 real :: x, y, z, r, th, ph print *, "x, y, z:" read *, x, y, z r = sqrt(x**2 + y**2 + z**2) th = acos(z / r) ph = atan2(y, x) print *, "r, θ, φ" print "(3F12.3)", r, th*180.0/PI, ph*180.0/PI end program hoge
303 名前:デフォルトの名無しさん [2006/05/16(火) 00:19:31 ] はじめて書き込みます。 大学の先輩にFortranのソースプログラム(?)をもらって、それをインストールしたCOMPAQ VISUAL FORTRANで動かそうとしてます でもコンパイルすると、 Can't open indirect file C:DOCUME~1 みたいなエラー文が出ます。これはどういう事なんでしょうか?
304 名前:デフォルトの名無しさん mailto:sage [2006/05/16(火) 00:32:43 ] >>303 ソースのパスが空白や日本語を含まないようにして(例えば"D:\TEST\HOGE.FOR") 再トライ
305 名前:デフォルトの名無しさん [2006/05/16(火) 16:21:12 ] 303です 304さんありがとうございました エラーなくコンパイルし、実行できました
306 名前:デフォルトの名無しさん [2006/05/16(火) 18:30:45 ] 実行ファイルで条件を入力し、Enterを押すとすぐにウィンドウが消えてしまうのですが、どうしたらいいでしょうか?違うパソコンではそういう状態になりませんでした。
307 名前:デフォルトの名無しさん mailto:sage [2006/05/16(火) 20:40:49 ] >>306 いくら何でも情報少なすぎ。 少なくともどんな環境で実行したか位は書いとかんと、まともの答えてもらえんぞ。 まあとりあえず、プログラムの最後に read * とか pause とか書いとけや。
308 名前:デフォルトの名無しさん [2006/05/16(火) 21:13:52 ] 学校のソフトを使ったので詳しい名前はわかりませんが、fujitsu fortran90 とかいう名前だったと思います。学校のパソコンでファイルを実行したとき は、条件の値を入力したら答えが出て、答えが出た状態でキーボードに 触れるとプログラムウィンドウが閉じていたんですが、自分のパソコン (NEC VALUESTAR Pentium4)で実行したときは条件の値を入力した瞬間 にプログラムウィンドウが閉じてしまいます。307さんのアドバイス通りに 最後にpauseと書いたらウィンドウが勝手に閉じることはなくなりましたが、 それでは根本的に解決していないのでまだ困ってます。
309 名前:デフォルトの名無しさん [2006/05/16(火) 23:43:41 ] >>308 何がしたいのか今一よくわからないんですが… 使っているOSと自分のパソコンに入ってるコンパイラは何ですか? 学校のFujitsu Fortranの開発環境で実行して終了後一時停止していたプログラムを 自分のパソコンでexeファイルをダブルクリックして起動したときでもソースを変更せずに 同じように終了後一時停止するようにしたい。 というのなら>>307 の様にして終了直前にキー入力待ちにして止めるか、 コマンドプロンプトを開いてその上で実行しないと無理ですよ。
310 名前:デフォルトの名無しさん mailto:sage [2006/05/17(水) 00:44:43 ] 初心者ですがフリーのをDLしてやってみたんですが、あるプログラム を実行したら入力させる画面が出て、入力したら答えが出ないで、プログラム が終了してしまいます。どうしたらいいでしょうか?ちなみに正常にコンパイル されています。
311 名前:デフォルトの名無しさん mailto:sage [2006/05/17(水) 00:55:17 ] >>310 >>309
312 名前:306=308 [2006/05/18(木) 22:21:21 ] >>309 >コマンドプロンプトを開いてその上で実行 ありがとうございます、解決しました。
313 名前:デフォルトの名無しさん mailto:sage [2006/05/20(土) 14:54:18 ] m組の変数xと関数f(x)の値を読み込み、x0に対するf(x0)の値をLagrange内挿する 関数副プログラムを作りなさい。また主プログラムを付けて、 次のデーターに対してf(0.525)を内挿してみなさい。 x f(x) 0.0 1.0 0.1 0.90484 0.2 0.81873 0.3 0.74082 0.4 0.67032 0.5 0.60653 0.6 0.54881 1次〜6次の内挿による解の精度も調べなさい。 参考 dimension XI(N),FI(N) RLAGRN=0.0 do 20 I=1,N F=FI(I) do 10 J=1,N if(J.ne.I) P=P*(X-XI(J))/(XI(I)-XI(J)) 10 continue 20 RLAGRN=RLAGRN+P return end 御願いします
314 名前:デフォルトの名無しさん [2006/05/21(日) 21:22:53 ] 放物運動で時刻t、角度θの任意の物体の位置のソースファイル?はあるのですが角度を30度、45度、60度の3通りに ついて計算し、すべての軌跡を出力せよ。との問題に全く手がでません。 ヒントとして配列を用いて3つの角度をプログラム内で定義する。とあるのですがよくわかりません。 どなたか教えて下さい。 お願いします。
315 名前:デフォルトの名無しさん mailto:sage [2006/05/21(日) 21:32:10 ] >>314 元のソースがどんなのか知らんが、「配列を用いて」というところからすると 角度と配列を渡すとその配列に結果を格納するサブルーチンを作って それを3回CALLすればいいんじゃないの?
316 名前:デフォルトの名無しさん [2006/05/21(日) 21:51:35 ] すいません初心者なんでCALLとかわかんないです・・・ テキストには dimension angle(3) data angle/30.,45.,60./ ・・・・・・・ do 20 i=1,3 theta=angle(i)*PI/180. t=0. 10 continue ・・・・・・・ if(y.lt.0.) then go to 20 else go to 10 end if 20 continue close(1) end と書いてあるんですが ・・・・・・ を考える課題なんですけど本当にわかりません。 教えて下さい。
317 名前:デフォルトの名無しさん mailto:sage [2006/05/21(日) 23:00:36 ] >>316 配列って角度の方を配列にしてるのね・・・ まあ、プログラムを見る限り、最初の「・・・・・・・」の部分で ・データファイルをOPEN文で開く 次の「・・・・・・・」の部分で ・角度theta、時間t、などから位置x、yを求める ということなのだろうけど ・初速度や初期位置は既知なのか、自分で決めるのか、ファイルから読み込むのか ・データファイルの書式は? など不明な点があるのでこれ以上は自分でおやりなさい。 いずれにせよ情報を小出しにされたのではエスパーでもない限り「本当にわかりません」。
318 名前:デフォルトの名無しさん [2006/05/21(日) 23:58:11 ] 1からNまでの整数について、次のそれぞれの分類に属する整数の数を数えて表示するプログラムを作成せよ。 ・3の倍数であり、5の倍数でもあるもの ・3の倍数であるが、5の倍数ではないもの ・3の倍数でも5の倍数でもないもの 誰か教えてください。
319 名前:デフォルトの名無しさん mailto:sage [2006/05/22(月) 00:30:10 ] プログラムというか数字の扱いの勉強したら? 高校数学あたり。
320 名前:デフォルトの名無しさん [2006/05/22(月) 01:09:08 ] >>319 ここはどんな質問にもマジレスする擦れです。 宿題も教えまくりますw
321 名前:デフォルトの名無しさん [2006/05/22(月) 01:27:09 ] >>318 FORT77で書いてみたw 英語はうんこw PROGRAM vip WRITE(*, *) ' INPUT N' READ (*, *) N N1 = 0 N2 = 0 N3 = 0 DO I = 1, N M3 = MOD(I, 3) M5 = MOD(I, 5) IF (M3 .EQ. 0 .AND. M5 .EQ. 0) N1 = N1 + 1 IF (M3 .EQ. 0 .AND. M5 .NE. 0) N2 = N2 + 1 IF (M3 .NE. 0 .AND. M5 .NE. 0) N3 = N3 + 1 END DO WRITE (*, *) ' The number of multples of both 3 and of 5', N1 WRITE (*, *) ' The number of multples of 3 but not of 5 ', N2 WRITE (*, *) ' The number of multples not of 3 nor of 5 ', N3 STOP END >>320 専ブラ用インデント
322 名前:デフォルトの名無しさん [2006/05/22(月) 01:35:53 ] >>314 ,316 出された情報だけでは解けない。 初速度が必要だが、それがファイルに入っているのだろうか? 重力常数も必要だがどうするか?(まぁ知ってはいるが、問題が地球とは限らないかもww) もうちょっと情報出せ。 テキストプログラムを見る限り出題者はセンス悪いw このスレで素直な良い手筋を学べ
323 名前:デフォルトの名無しさん [2006/05/22(月) 02:27:10 ] >>313 F90でエラーチェックなしウンコプログラムw PROGRAM Lagrange IMPLICIT NONE INTEGER, PARAMETER :: n = 7 INTEGER :: i REAL :: xin(n), yin(n), x, y OPEN (10, FILE = 'input.dat') DO i = 1, n READ(10, *) xin(i), yin(i) END DO x = 0.525 y = alagran(x, 6, xin, yin) WRITE(*, *) ' x, f(x) =', x, y STOP CONTAINS REAL FUNCTION alagran(x, n, xin, yin) IMPLICIT NONE REAL , INTENT(IN) :: x, xin(:), yin(:) INTEGER, INTENT(IN) :: n REAL :: tmp INTEGER :: i, j alagran = 0.0 DO i = 1, n tmp = yin(i) DO j = 1, n IF (j /= i) tmp = tmp * (x - xin(j)) / (xin(i) - xin(j)) END DO alagran = alagran + tmp END DO END FUNCTION alagran END PROGRAM Lagrange
324 名前:デフォルトの名無しさん [2006/05/22(月) 02:42:50 ] >>323 ごめw まちがい このままだと5次w y = alagran(x, 6, xin, yin) ↓ y = alagran(x, n, xin, yin) でw とりあえず、答えは x, f(x) = 0.5250000 0.591555 のはずw 間違ってても知らんw ほぼ直線に乗っているのでまぁこんな感じ? ラグランジュ法はデータの差分の漸化式で計算するほうが一般的なだが とりあえず参照として出されたサブルーチンと同じく公式どおりに書いた。 1〜6次までの誤差の見積もりのほうは、課題の雰囲気からすれば、まじめな誤差解析は要求して いないだろうから、0.6と0.5・・・・0.0まで逆進する方向でデータを増やしてサブルーチンを呼んだ 結果を書いて何事かムジャムジャ言えばよかろうw
325 名前:デフォルトの名無しさん [2006/05/22(月) 02:47:20 ] >>325 DO i = 1, 6 ! y = alagran(x, n, xin, yin) y = alagran(x, i + 1, xin(7 - i:7), yin(7 - i:7)) WRITE(*, *) ' i, x, f(x) =', i, x, y END DO i, x, f(x) = 1 0.5250000 0.5921000 i, x, f(x) = 2 0.5250000 0.5915309 i, x, f(x) = 3 0.5250000 0.5915560 i, x, f(x) = 4 0.5250000 0.5915547 i, x, f(x) = 5 0.5250000 0.5915551 i, x, f(x) = 6 0.5250000 0.5915558 こんな感じか? 誤差が0.1^Nに比例しているとか書けばいいのだろうか?w ttp://www.library.cornell.edu/nr/bookfpdf/f3-1.pdf この辺でも読みやがれですぅ
326 名前:デフォルトの名無しさん mailto:sage [2006/05/24(水) 00:11:48 ] n個の実数データを配列datに読み込み、読み込んだデータを降順に出力する。 ただし、データを読み込んだ配列の中身は変更せず、別に整数型の配列indexを 用意して、大きい順の並びが dat(index(1)),dat(index(2)),・・・,dat(index(n)) であたえられるようにする。つまり次のような出力命令 do 30 i=1,n write(*,*)dat(index(i)) 30 continue によって、データが降順に出力されるようにせよ。 という課題がでたのですが、fortran77の形で教えていただけませんか? よろしくお願いします<m(__)m>
327 名前:デフォルトの名無しさん [2006/05/24(水) 00:49:46 ] NAGのFortranBuilderの試用版が無料セミナーで配布されるらしい 以下参照 【日時】 5月31日(水)13時30分〜(13時開場) 【場所】 英国大使館 (東京都千代田区一番町1) 【地図】 www.nag-j.co.jp/fbreleasemap.htm 【内容】 1:Fortran Builderのご紹介(Fortran Builder開発者 中野 剛) Fortran Builderの機能、製品コンセプト、事例ご紹介.デモンストレーションなど 2:プログラミング学習とe-Learning (法政大学情報メディア教育研究センター所長 竹内 則雄 教授) プログラミング言語学習用電子ブックと開発環境が連動した体験的なFortran プログラミング学習環境の概要と、対面授業やe-Learningでのその効用について 3: NAGWare f95 and reliable, portable programming (英国NAG NAGWare Fortranコンパイラ開発者、マルコム・コーエン) How to detect errors using NAGWare f95,and how to write portable, reliable programs.Support for features from the latest Fortran standard and plans for future releases. 4: Fortran Builder を使った数値計算 (筑波大学 長谷川 秀彦 助教授) 行列計算パッケージ LAPACK の紹介と Fortran Builder を利用したLAPACK の手軽な使い方について 5:Fortran Builder 体験コーナー・30日トライアル試用版配布・ ノベリティ配布など もちろん無料です。 英国大使館の警備都合上事前にご登録をお願いしております。 下記URLフォームにて参加登録ができます。
328 名前:デフォルトの名無しさん mailto:sage [2006/05/24(水) 01:27:04 ] >>326 特に指定がなかったので解りやすく(?)バブルソートでやってみますた。 parameter (n=10) real dat(n) integer index(n) C do 10 i=1,n read(*,*) dat(i) index(i) = i 10 continue C do 22 i=1,n-1 do 21 j=1,n-i if (dat(index(j)) .lt. dat(index(j+1))) then ntmp = index(j) index(j) = index(j+1) index(j+1) = ntmp end if 21 continue 22 continue C do 30 i=1,n write(*,*) dat(index(i)) 30 continue stop end 処理系によっては配列の宣言部分でエラーになるかも知れないので その時は適時修正のこと。 #F77形式で、って言われるとここが一番難しいかもw
329 名前:デフォルトの名無しさん mailto:sage [2006/05/24(水) 13:00:42 ] >>328 選択法でプログラミングしてもらえませんか?
330 名前:デフォルトの名無しさん mailto:sage [2006/05/24(水) 13:35:10 ] >>329 オレが口をだすべきではないと思うが、苦言を一言。 モノの頼み方を知ってるのか? このスレはフォートランの超初心者向けではあるが、 人生の超初心者(不躾な厨房)向けではないぞ。 質問をするなら、回答者が答えやすいように、できるだけ詳しく書く。 最も簡単な方法は、(要約などせず)出題内容をすべて書く。 直接選択法の解が必要なら、最初から書け。 労を厭わず、回答案を出してもらえたら、 最初の一言は「ありがとうございます」だ。 次に、再要望であったり、回答内容に対する質問だ。