10/03/28 00:47:10
このスレッドは、他のスレッドでは書き込めない超低レベル、
もしくは質問者自身何が何だか分からない質問を勇気を持って書き込むスレッドです。
FORTRAN使いが優しくコメントを返しますが、
お礼はFORTRANの布教と初心者の救済と次期Fortran2008規格でのCOMEFROM文採用をお願いします。
●注意事項
・質問する前にGoogle等の検索サイトで検索しましょう。
・回答者にわかりやすい様に、質問内容はできる限り詳しく書きましょう。
・エラーの場合は起きた状況、環境(OS・コンパイラ・バージョン)、エラーメッセージも詳しく書きましょう。
●前スレ
くだすれFORTRAN(超初心者用)その4
スレリンク(tech板)
くだすれFORTRAN(超初心者用)その3
スレリンク(tech板)
くだすれFORTRAN(超初心者用)その2
スレリンク(tech板)
くだすれFORTRAN(超初心者用)
スレリンク(tech板)
●関連スレ
FORTRAN Ⅳ
スレリンク(tech板)
2:デフォルトの名無しさん
10/03/28 04:40:50
>>1
乙! (≧∀≦)b
3:デフォルトの名無しさん
10/03/28 08:28:13
お前ハイテンションだな
この手の顔文字って結構イタい
4:デフォルトの名無しさん
10/03/28 11:16:57
>>1
おつ
質問です。
integer,parameter::dp=selected_real_kind(20)
a=1._dp
みたいに変数(この例ではdp)で精度を決めてるんだけど、指数部の表現ってどうやるか教えてください。
例えば、0.001を表現する時に倍精度なら1.d-3ってな感じでやってますが、変数を使った場合どうなるでしょう?
今は、1._dp/1e3 という風に表していますが、ちょっと美しくないです。
ご存知の方いらっしゃいましたら、教えていただけませんでしょうか?
5:デフォルトの名無しさん
10/03/28 12:35:22
>>4
1.0e-3_kd
6:デフォルトの名無しさん
10/03/28 15:30:08
>>3
やっぱ今はやりの顔文字はこれだよな (^p^)b
7:デフォルトの名無しさん
10/03/28 19:10:59
●関連スレ【 FORTRAN Ⅳ 】の URL は変更されていますよ~。
スレリンク(tech板)
8:1
10/03/28 21:34:38
>>7
専ブラなんで気づかなかった、すまん。
9:デフォルトの名無しさん
10/03/29 05:06:13
>>8
いえいえ,俺もお気に入りメニューに入れてたんだけど,
なんで新しいレスが来ないのかなと長時間思ってた。
んで,昨日初めて気が付いたw
10:デフォルトの名無しさん
10/04/05 16:19:37
はじめまして、超初心者なので質問させて下さい。
今扱っているデータは1秒ごとに取得した時系列データなのですが
データ取得時に装置の調子が悪くて時々データ抜けが起きてしまっています。
1分ごとに平均値を取りたいのですがデータ抜けのせいで
nを1から10個目までとして平均値を取ってしまうとずれが出てきてしまいます。
ずれを出さないために以下のようにデータを補完したいのですがやりかたが全く判りません。
00:00:04 x4 y4 z4
00:00:05 x5 y5 z5
00:00:06 x6 y6 z6
00:00:10 x7 y7 z7
00:00:11 x8 y8 z8
00:00:12 x9 y9 z9
↓
00:00:04 x4 y4 z4
00:00:05 x5 y5 z5
00:00:06 x6 y6 z6
00:00:07 x7' y7' z7'
00:00:08 x8' y8' z8'
00:00:09 x9' y9' z9'
00:00:10 x7 y7 z7
00:00:11 x8 y8 z8
00:00:12 x9 y9 z9
データの抜けはランダムに起こっています。
フォートランは先生から貰った既存のプログラムを
データにあわせて改造するくらいしかした事がありません、
色々調べたり試したりしてみていますが
もしやりかたが判る方がいらっしゃいましたら教えて頂けると助かりますm(_ _)m
11:デフォルトの名無しさん
10/04/05 17:30:46
>>10
FORTRAN以前の話だけど、補間はそれでいいの?
00:00:04 x4 y4 z4
00:00:05 x5 y5 z5
00:00:06 x6 y6 z6
00:00:07 x6 y6 z6
00:00:08 x6 y6 z6
00:00:09 x6 y6 z6
00:00:10 x7 y7 z7
00:00:11 x8 y8 z8
00:00:12 x9 y9 z9
の方が自然だと思うけど。
12:デフォルトの名無しさん
10/04/05 18:57:27
>>11
10です、前の値で埋める方法も判ればそれはとても嬉しいです、
それもやってみようとしてうまくいきませんでした...
また、前後の値のみだとそれほど信用高いというわけでも無いので
フーリエか最小二乗法で補完出来ればなお良い、という感じです。
3秒くらいの抜けは良い方でデータ取得時の状態が酷いときには
20秒くらい抜けてしまっていたりして、どうしたものかと思い悩んでいます。
13:10
10/04/05 19:02:15
訂正12>それもやってみようとしてうまくいきませんでした...
やってみたけれど、結果で20秒とか30秒とかの間
同じ値がずらりと続いていておかしな事になった時間帯があり
あまりにも無惨だったのでやめた事を思い出しました。
14:デフォルトの名無しさん
10/04/05 22:56:49
>>10
補間なのか補完なのかもよくわからん。
(無いデータを補完しておくのか、抜けたのを内挿するのか)
のちのちのデータ解析にも関わるので、一度指導教官とよく話しあった方がいいぞよ。
詳しいことが分からんからなんとも言えないが、データ読み込み時に、データ補間/補完もできるが、
生データは無加工のままとっておいて、後処理で補完した方がいい気もする。
まぁコメントがつけられるデータ形式なら、補完行にコメントを付けておくこともできるが・・・
15:10
10/04/07 18:42:20
自宅PCが起動しなくなったトラブル&携帯が規制かかってて今まで書き込めませんでした、
すみませんm(_ _)m
>>14
無いデータを補完です、データ抜けでその時間帯のデータが無くなっているので。
生データはちゃんととっておいています、フォートランでデータ加工時に
別名をつけていっているので途中経過も判るようになっています。
先生からは「とりあえず調べてやってみて」と言われまして
色々調べてはいるもののちょっと混乱しているのでこちらに助けを求めに来ました。
もしヒントだけでも教えて頂けるようでしたらお願い致しますm(_ _)m
16:デフォルトの名無しさん
10/04/08 01:09:01
>>15
PROGRAM test
IMPLICIT NONE
INTEGER, PARAMETER :: nmax = 100
REAL :: x(nmax, 3), x1, x2, x3
LOGICAL :: qdata(nmax)
INTEGER :: i, k, k0, kh, km, ks, io, ndata
x = 0.0
qdata = .FALSE.
DO i = 1, nmax
READ(10, '(i2, 1x, i2, 1x, i2, 3F5.0)', IOSTAT = io) kh, km, ks, x1, x2, x3
IF (io == -1) EXIT
IF (i == 1) k0 = 3600 * kh + 60 * km + ks - 1
k = 3600 * kh + 60 * km + ks - k0
x(k, 1) = x1
x(k, 2) = x2
x(k, 3) = x3
qdata(k) = .TRUE.
END DO
ndata = k
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DO i = 1, ndata
IF ( .NOT. qdata(i) ) x(i, :) = x(i - 1, :)
END DO
DO i = 1, ndata
PRINT '(i3, ":", L5, 3(1x, F8.2))', i, qdata(i), x(i, :)
END DO
STOP
END PROGRAM test
17:15
10/04/08 01:14:06
データファイル
00:00:04 1.0 2.0 3.0
00:00:05 4.0 5.0 6.0
00:00:06 7.0 8.0 9.0
00:00:10 10.0 11.0 12.0
00:00:11 13.0 14.0 15.0
00:00:12 16.0 17.0 18.0
実行結果
1: T 1.00 2.00 3.00
2: T 4.00 5.00 6.00
3: T 7.00 8.00 9.00
4: F 7.00 8.00 9.00
5: F 7.00 8.00 9.00
6: F 7.00 8.00 9.00
7: T 10.00 11.00 12.00
8: T 13.00 14.00 15.00
9: T 16.00 17.00 18.00
とりあえず、1秒単位であることを仮定。
読み込むときデータが抜けたら、論理型配列 qdata を .FALSE. にしておいた。
抜けたデータは1個前をコピー。故に連続して抜けた場合は同じのが続く。
こんなんでおk?
18:17
10/04/08 01:27:38
ああごめん>>17は>>16が書いている。名前欄の>>15は間違い。
>>17のデータは2chだと半角スペースがつめられてしまうのであれだが、
実際は空白が入って小数点が揃うように並べてある。
そうでないと読み込みのところのformatがくるってしまう。
データ読み込みとデータ補間は、それぞれサブルーチンにすればすっきりするだろう。
コメント行で切れ目を入れておいた。
スレ汚しすまん。
19:10
10/04/08 07:30:01
昨晩また規制に引っかかってしまって書き込み出来ませんでしたm(_ _)m
>>16,17,18
ありがとうございます、
抜けたところに前のデータを挿入して補完する方法は以前試したのですが
データ落ちが酷いところでは数十秒くらい同じ値が続く事になってしまって
あまり宜しくないという事で、今回別の方法で補完するやり方を探しているところです。
現在は3次スプライン補完という方法があるらしく色々調べているのですが
結構難しくてまだ理解出来ていません(>_<)もう少し頑張ってみます。
20:デフォルトの名無しさん
10/04/08 11:05:39
データ補間してフーリェかけたり平均とったり・・・とか自爆なのを
今でもときどき見るけど、気を付けてね。
走査平均対象の10データ中の有効なものの数でエラーバー決めて解析すればそれでいいと思うけどねぇ。
平均をとる操作と線形あるいは高次補間って同じ事
((非負の係数で)合計が1になる係数をかけて足し算する事に帰着する)だから
とある補間(補完?)した後に平均値をとっても・・・という気はする。
一度、教官に確認した方がいいよ。単なるテストというか簡単な試練を与えられただけなら
それはそれで教育的ともいえるけど・・・危険な香りがする。
21:デフォルトの名無しさん
10/04/08 11:16:55
>>17 抜けたデータは1個前をコピー。故に連続して抜けた場合は同じのが続く。
王道だね。できればかけたデータの後半はその後にくる有効なデータで、なら
たぶんもっといいけど面倒だしね。
if (.NOT. qdata(i)) then のあとに、
j = i
do while ((.NOT. qdata(j) .OR. (j .LE. ndata))
j = j + 1
enddo
ntrue = j
で次の有効なデータの番地がわかるから・・・あれ、これだとntrueは一個ずれるかも。
22:デフォルトの名無しさん
10/04/08 11:17:54
しかも .OR. じゃなかったね・・・
23:デフォルトの名無しさん
10/04/08 11:20:54
スレチだけどexcelのグラフでスムージングをオンにするのはマジでやめて欲しい
妙に滑らかなラインが気持ち悪くて仕方ない
24:デフォルトの名無しさん
10/04/08 11:31:15
最小二乗法かと思ったら移動平均らしいな>Excelのスムージング
ちゃんと理解して使ってる人は少ないと思うがw
25:10
10/04/08 13:31:13
>>20
ご指摘ありがとうございます、うまく説明出来なくて申し訳ないのですが、
全体の解析の結果から数秒~数分単位でグラフにして見たい部分とかが判った時に
予め近似曲線が求まっていれば楽でしょう、という感じで現在に至ります。
なんか、何から何まで良くわからない状態で本当に申し訳ありません・・・
26:10
10/04/08 17:30:07
先生の蔵書の中から参考資料を見つけて頂けました、これを使ってまた少し頑張ってみます。
自分でも至らない点や確認出来た点が多かったのでとても助かりました、色々と助言をありがとうございましたm(_ _)m
また判らない事があったらこちらに駆け込むかもしれませんがその時は宜しくお願いします。
27:デフォルトの名無しさん
10/04/08 19:11:54
>>26
新M1か、四年生かな頑張れー。
28:デフォルトの名無しさん
10/04/08 19:39:57
超初心者なのですが、Intel Visual Fortranを使っていらっしゃる方はいますか?
私にはC言語を白黒画面のコンソール画面でコンパイル&リンクして実行する程度の簡単な経験しかありません。
殆ど統合開発環境を使った事がないのですが、関連ホームページを調べると、魅力的なCPU毎の最適化機能とか、IMSL数値計算ライブラリを使えるようなので興味を持っています。
私が使い始めることになったバージョンは10.1です。
29:デフォルトの名無しさん
10/04/08 23:42:47
すいません。つまらない問題なのですが、
複数ファイルに同一の結果を出力する場合どうすればよいのでしょうか。
open(10,file='A.dat',form='formatted')
open(11,file='B.dat',form='formatted')
write(10,101)int((t2-t1)/60),dble((t2-t1)-int((t2-t1)/60)*60)
write(11,101)int((t2-t1)/60),dble((t2-t1)-int((t2-t1)/60)*60)
みたいな表現をコンパクトにしたいのです。
30:デフォルトの名無しさん
10/04/09 00:03:25
>>29
DO iunit = 10, 11
WRITE(iunt, 101) ....
END DO
31:29
10/04/09 00:34:57
ありがとうございます。
write(10,101)・・・
write(31,101)・・・
write(*,101)・・・
みたいな場合はその方法だと無理ですよね
やはり一行ごとに処理するのが基本なのでしょうか
32:デフォルトの名無しさん
10/04/09 01:05:56
>>31
そう多くないなら1行づつが基本だと思う。
でも一応、
INTEGER.PARAMETER :: iunits(3) = (/10, 31, 6/)
DO i = 1, SIZE(iunits)
WRITE(iunits(i), 101) ....
END DO
とか、あるいは内部サブルーチンにして
CALL wr_info( (/31, 10, 6/) )
......
CONTAINS
SUBROUTINE wr_info(iunits)
INTEGER, INTENT(IN) :: iunits(:)
DO i = 1, SIZE(iunits)
WRITE(iunits(i), 101) ....
END DO
RETURN
END SUBROUTINE wr_info
内部サブルーチンなら、変数は共通。 (/ /) は配列生成子で、これを使えば引数でファイル番号を
並べて指定すればよく、わざわざ配列をメインルーチンで用意する必要がなくなる。
6番は歴史的理由でコンソールになっている(はず)。
33:デフォルトの名無しさん
10/04/09 03:29:41
6番=標準、7番エラー出力・・・だっけ忘れた。
なんかStdoutみたいな明示するキーワードあった気がするけど忘れてもうた。
34:デフォルトの名無しさん
10/04/09 03:33:47
>>24 最小二乗法
でもxもyも観測量なのに普通のxは誤差無し確定値とみなすやつをへーきで使ってたりするけどねぇ。
35:デフォルトの名無しさん
10/04/10 09:07:02
>>24
エクセルなんか使うなよ・・・人文科学かな?
36:デフォルトの名無しさん
10/04/10 13:14:38
環境系の同僚に「このあたりのコーディングはだれか詳しい人に助っ人頼んだ方がいいよ」って言ったら
「いや自分でやるのが大事ですから。シミュレーションはエクセルで私がやります」って言われた
本人は、今いいこといったオレ、見たいな風情なのでなにもいえなかった
37:デフォルトの名無しさん
10/04/10 14:16:13
放っとけ
構うとお前さんに仕事が飛んでくるぞ
38:デフォルトの名無しさん
10/04/12 08:18:32
>>36 「いや自分でやるのが大事ですから。シミュレーションはエクセルで私がやります」
キリッ!
やる夫みたいだw
39:デフォルトの名無しさん
10/04/13 15:30:32
program sample444
real :: x(3),y(3),z(3)
integer :: i
open(1, file="aiueo.txt")
do i=1,3
read(1, *) x(i), y(i), z(i)
print *, x(i), y(i), z(i)
end do
close(1)
end program
上記のコマンドでコンパイルしてプログラムを作成しましたのですが
次のようなエラーが出てしまいます!ファイルの入出力だけがうまく進まず
もうここから全然進みません;
どなたかわかるかたよろしくお願いします;
ちなみにtxtファイルは3×3配列の数値がちゃんと入っています;
traceback: not available, compile with -ftrace=frame or -ftrace=full
Fortran runtime error: End of file
40:デフォルトの名無しさん
10/04/13 20:36:12
>>39
OSとコンパイラの種類
読み込むデータの例も書いた方が良いよ
41:デフォルトの名無しさん
10/04/13 21:08:39
>>40
わかりました。すいません;
んと、windows vistaで、コンパイラはg95です。
読み込むデータはたとえば
25 50 59
34 23 11
45 43 65
とかです。
どうかよろしくお願いします。
42:デフォルトの名無しさん
10/04/14 01:04:24
とっさに思いつく限りでは・・・
元データの最後の改行位置は?
open で status="unknown" を追加してみては?
くらいかなぁ。Good Luck!
43:デフォルトの名無しさん
10/04/14 06:07:06
読み込むデータがInt型なのにrealで読み込もうとしてるのは良くないと思う
確認してないから他にも間違いがあるかもしれないけど
44:デフォルトの名無しさん
10/04/14 11:39:21
>>39 Fortran runtime error: End of file
だから、>>42 のとおりデータの最後の行の右端に改行コードがないんじゃない?
>>43
大事な事だよね。
整数を実数でよんでそのあと整数化すると1小さくなることがあるし。
45:デフォルトの名無しさん
10/04/14 16:52:11
>>42
ふむふむ
改行位置で変わったりするのですか?
テキストにも書いていなかったので少し勉強してみます。
ありがとうございました。
>>43
なるほどー
確かにそのとおりですね;
修正しときます!
ありがとうございました。
>>44
改行コードが何か全くしりませんでした;
元データをただ改行するだけじゃだめなんですか?
もう少し勉強してみます;
ありがとうございました!
46:デフォルトの名無しさん
10/04/14 18:09:47
連投失礼します!
皆さんの助言でなんとかファイル読み込みできるようになりました!
ですが、1列目しかデータが反映されません;
これも改行コードとやらによるものなんでしょうか?
何回もすいません;
47:デフォルトの名無しさん
10/04/15 15:18:39
あまり関係ないかも・・・
Win機上では改行コードが LF/CR かな2つ無いと読めない・・・
ぎゃくにGCCやG95はそれぞれを改行コードとみなしちゃう、とか
・・・今でもあるのかなぁ・・・・?
qkc だっけ、漢字コード変換のソフトがおまけ機能で
改行コードもWin機向けに変えてくれるから、
もし元データがLinux機で作られてたのなら・・・試してちょ。
unix2dos dos2unix っていうのでLinux上でも改行コード変換はできるけど。
48:デフォルトの名無しさん
10/04/19 22:55:45
>>33
キーワードの方は知らんけど、標準エラーは 0 だ。
# 理由は知らんが規制が掛かって暫く
# 書き込めなかった。
49:デフォルトの名無しさん
10/04/20 04:01:32
thanks
50:デフォルトの名無しさん
10/04/21 11:21:26
>>48 理由は知らんが規制が掛かって
そういえば今回は ac.jp ドメインもいくつか規制食らってたなw
51:48
10/04/21 22:42:13
>>50
うち ocn なんだけどね。学校とは縁が切れて、博士号持ちのワープワやってるw
52:デフォルトの名無しさん
10/04/22 01:51:47
そうなんだ。
大学院進んだ人とかポスドクっておかねが多少もらえても雇用統計では「自発的失業者」らしいね。
それを聞いて、博士号取得をくじけた人をしっているけどそれは正解でもあるとおもった。
・・・博士号もち仲間よりw
53:デフォルトの名無しさん
10/04/22 13:08:56
>>51
うお、うちの会社でアルバイト(年300万研究補助)しね?
54:デフォルトの名無しさん
10/04/23 21:36:21
これはひでえなw>自発的失業者
55:デフォルトの名無しさん
10/04/27 20:19:15
!?
大学院進んだ人は普通に「学生」みたいな区分だと思ってた。
ポスドクも任期付/非常勤だからパートと同じような扱いかと・・・(´;ω;`)ブワッ
56:デフォルトの名無しさん
10/04/27 20:19:56
sage忘れたorz
57:デフォルトの名無しさん
10/04/28 15:51:15
泣くんじゃないッ!(´;ω;`)
58:デフォルトの名無しさん
10/04/29 10:52:45
fortran90の勉強はじめましたっ!
fortran77は全然知りません :DD
59:デフォルトの名無しさん
10/04/29 12:08:45
>>58
遺物と向かい合う必要がない限り、知らんで良い。
でも Fortran90 って良書はあるのかな?
色々出てるみたいだけど、倍精度の説明さえロクに
書いていないのは今も謎だ(個人的に)。
60:デフォルトの名無しさん
10/05/02 04:04:51
これから開催される CUDA Fortran のセミナーや講習会,知りませんか?
ググっても3月に東工大のGPUコンピューティング研究会が開催したのしか
検索されてこなくて。
もっと早くチェックしてればよかったなぁ‥‥
61:デフォルトの名無しさん
10/05/10 07:18:31
>>52
生活保護対象にならないようにそういう扱いにするというのは聞いたことがある。
にしてもひどい話ではある・・・(´;ω;`)
>>60
CUDAの試作機とかどっかタダで使えるところないかなぁ・・
62:デフォルトの名無しさん
10/05/10 11:21:13
nvidiaとか本気で流行らせたいんなら、試作機をリモートでいいから無償提供とかやりゃいいのにね
言語なんていかに裾のが広がってくかが大事なのに
63:デフォルトの名無しさん
10/05/10 22:45:53
>>62
? ただで(Cだけど)コンパイラ配ってるし、普通のグラボでも使えるし、Fortranコンパイラにも協力しているしで
十分やってると思うけどね。
64:デフォルトの名無しさん
10/05/11 10:29:26
ぼくのマシンはインテルのへっぽこアクセラレータしかないお・・・でも触ってみたいんだよう、
という人はいると思うんだ。すでに大規模&本格的に使ってる人(おおくないとおもうけど)が、
かるいデバッグ作業するとかなら普通サイズのぐらぼマシンに自分で設定して、でもいいとおもうけど、
将来使うかもという程度の興味出始めな人には
横着なだけかもしれないけどコンパイルと実行環境が整った場所があるとやはりうれしい。
65:デフォルトの名無しさん
10/05/13 15:33:38
最近になって、がっつり数値計算をする必要がでてfortranを
勉強しだしたんですが、要素数が不明の2次元データをファイルから読んで、
その要素分だけallocateしたいのですが、
とりあえず最後まで読んで要素の数を数えてから配列をつくろうかな、と思ったんですけど、
fortranにおいてend of fileの扱いをどうしたらいいのかわからずに困っています
使用OSはvista,コンパイラはg95です。初歩的とは思いますが、よろしくお願いします。
66:デフォルトの名無しさん
10/05/13 15:50:10
open(1,file='data.dat',status='old')
icount = 0
998 continue
read(lun,*,end=999) fjlasdjfkds
icount = icount + 1
goto 998
999 continue
とか、かな。
でもこれ、ファイルの最後の最後が改行コードでおわるか
EOFで終わるか両方無しでいきなり終わるか・・・でいろいろ挙動が変わるかも。
67:デフォルトの名無しさん
10/05/13 16:08:21
fortran 90を使用しています.
二次元配列に初期値をparameterとして代入するにはどのようにしたらよいのでしょうか.
implicit none
integer,parameter :: i(2,2) = (/1,2,3,4/)
だとエラーを吐きます.コンパイラーはPGIです.
宜しくお願いします.
68:デフォルトの名無しさん
10/05/13 16:30:50
>66
マジでありがとうございます!!
とりあえずreadの一個目にファイル変数渡して
できました。改行からのEOFも即EOFも問題なく動きました。
とりあえず、EOFなしのデータは使わない?と思うので。
あと、個人的な好みなのですが、goto文はあまり使いたくないので、
とりあえずdoループで書いたのですけど、endはやはり、
ちょっとぐぐってみたかんじ、ジャンプさせるしかないようにみえるんですが、
exitで抜けさせることはできないのでしょうか?
もしご存知のかたがいらっしゃいましたら、ご教授おねがいします。
なんにせよ、とりあえず進めそうです!66さんありがとうございます。
69:デフォルトの名無しさん
10/05/13 17:48:17
>>67
URLリンク(www.str.ce.akita-u.ac.jp)
70:67
10/05/13 18:08:38
>>69
ありがとうございます.
地道に代入することにします
71:デフォルトの名無しさん
10/05/13 23:22:45
>>68
いまコンパイラないから試してないけど、これで走らないかな。
open(1,file='data.dat',status='old')
icont = 0
do
read(1,*,iostat=io) aaa
if(io /= 0 ) exit
icont = icount + 1
end do
72:デフォルトの名無しさん
10/05/14 00:13:47
>>67
INTEGER, PARAMETER :: n(2, 2) = RESHAPE([1, 2, 3, 4], [2, 2])
[ = (/
] = )]
ただし Fortran2003
73:66
10/05/14 03:18:41
>>71
iostat つかっての方がきれいで良いね。
74:デフォルトの名無しさん
10/05/14 11:24:34
>>73
他のエラーを捉えられなくなるのが難点か。
75:デフォルトの名無しさん
10/05/14 13:25:44
エラー番号って規格で決まってるの?
76:65
10/05/14 15:29:50
レス遅くなって、すみません。
iostatの読み込みで、-1がたったらexitするように書いたら
望むとおりの挙動をしてくれました。
なんとなく勝手がわかってきたきがします。
重ね重ね、ありがとうございます!
77:デフォルトの名無しさん
10/05/14 21:51:12
>>74
大半は決まってない。
EOF=-1 は、まず大丈夫だが、これが規格なのか、慣例なのか分からん。
たしか EOL=-2 だったか。
Fortran2008の次期規格で、この辺の一部の定数が、INTRINSIC定数として定義されるらしい。
78:デフォルトの名無しさん
10/05/14 22:25:30
>>77
EOF=-1は慣例で規格としては決まってない。
だから、EOF=-1と決めつけてプログラムするのは危険。
まぁ、そんな危険はほとんどないが。
79:デフォルトの名無しさん
10/05/15 22:51:39
>>78
EOF=-1 は慣例なのかー。
知らんかったぜ。
80:デフォルトの名無しさん
10/05/17 03:49:59
すみません、質問させて下さい。
数万行ある(x,y)データを600行ごとに値を読んでサブルーチンで計算させて
そのサブルーチンで出て来た値をまた別のサブルーチンで計算させて最後に出て来た結果を
出力ファイルに書き込むようなメインプログラムの作り方がどうにもわかりません。
判るかたがいましたらご教授頂けると助かります。
f77を覚えたてです、まるっきりの初心者で恐縮ですが宜しくお願いします。
81:デフォルトの名無しさん
10/05/17 03:55:24
追記。
数万行のデータのうち始めの600行に対してサブルーチン1、サブルーチン2を実行、その結果を出力ファイルに書き込む
次の600行を同じようにサブルーチン1、2実行、結果を同じ出力ファイルの最後の行から付け足して書き込む
これを入力データの行数分だけ行いたい、という感じです。
82:デフォルトの名無しさん
10/05/17 08:09:42
age
83:80,81
10/05/17 08:16:19
入力データは (f7.0,f9.2) X(I),Y(I) です。
X(I)は0から始まって1,2,3,...600,601,...20000,20001...
という風に1ずつ増えています。
84:デフォルトの名無しさん
10/05/17 16:56:27
おまえらソースコードの管理どうしてる?
85:80,81
10/05/17 17:20:37
open(10,file=infile)
open(20,file=outfile)
N=600
30 continue
DO 20 I=N,N+6001
DO 20 I=0,N+1
20 READ(10,*) X(I),Y(I)
CALL SUB1(X,Y,G,H,N,MP)
DO 40 I=N,N+600
40 WRITE(20,*) X(I),Y(I),G(I),H(I)
WRITE(6,*) X(I),Y(I),G(I),H(I)
N=N+600
goto 30
close (20)
close (10)
STOP
サブルーチンを一つだけにして結果をファイルに出力させてみました。
上記のようにしてみたのですが、どうしてもうまく600行毎に計算できません。
もし判るかたがいらっしゃいましたら助言を頂けると助かります。
86:80,81
10/05/17 17:22:19
DO 20 I=N,N+6001
DO 20 I=0,N+1
訂正
DO 20 I=N,N+601
87:デフォルトの名無しさん
10/05/17 17:56:32
>>84
脳内
88:デフォルトの名無しさん
10/05/18 02:50:34
ぬるぽ
89:デフォルトの名無しさん
10/05/18 17:27:11
ガッ
90:デフォルトの名無しさん
10/05/18 23:50:40
>>85
すくなくとも
N=1
DO 20 I = N, N + 600
もう一個のDO 20 は要らない。
91:デフォルトの名無しさん
10/05/19 02:05:24
>>90
ぬるぽいんたーえくせぷしょん
92:デフォルトの名無しさん
10/05/19 11:38:21
>>91
FORTRAN スレなんだから、ABEND だろ!
93:80
10/05/19 16:10:18
>>90
すみません、色々試していてコメントアウトしたところとかを載せてしまっていたので
86で訂正しています。ややこしくて申し訳有りません。
今のところサブルーチン2つまわすやりかたのほうで下のような感じにしています。
N=0
30 continue
DO 20 I=N,N+601
20 READ(10,*) X(I),Y(I)
CALL SUB1(X,Y,G,H,N,MP)
DO 40 I=N,N+600
40 WRITE(20,*) X(I),Y(I),G(I),H(I)
HH=1
DO 30 I=N,N+600
XX=X(N)+HH*I
YY=SUB2(G,H,X,Y,XX,N,MP)
KH=0
DO 50 K=N,N+600
IF(ABS(X(K)-XX).LE,1.d0) THEN
GOTO 50
ENDIF
50 CONTINUE
WRITE(20,fmt)XX,YY
30 CONTINUE
N=N+600
goto 30
94:80
10/05/19 16:12:46
>>80続き(改行が多すぎるのでエラーになってしまったので)
PARAMETER (MP=36000, NW=600)
DIMENSION X(0:MP),Y(0:MP),G(0:MP),H(0:MP)としています、
MPはデータの行数で、ファイル毎に少し違うのですが最大行数を入れてあります。
600行を読み込んで、SUB1とSUB2を計算させて、ファイルに書き出して次の600行をまた・・・
という感じで操作させたいのですが、何故かおそらく始めの600行のSUB1で出て来るHやGを使って
次の600行以降が計算されているような変な結果になってしまいまして。
始めの600行に関しては結果として正しい値が出て来ているのでサブルーチン部分には問題は無いと思います。
本当にすみませんがよろしくお願いします。
95:80
10/05/19 16:15:46
あわわわまた間違えていました!!!30 CONTINUEが2回ありますが
>>93の頭の30 continueは15 continueの間違いで、最後のgoto 30がgoto 15になります!!!
ほんとうに申し訳有りません。。。
96:デフォルトの名無しさん
10/05/19 16:47:43
どうもGOTO文やDO..CONTINUE文で混乱しているようだけど,
まだFORTRANを覚え立てなら,わざわざ古い書き方で覚えずに,
Fortran90形式のDO..END DO構文で慣れた方がいいんではないかい?
特にGOTO文を使うのは間違いを誘発しやすいから,使わないようにするのが世界的な流れだし.
97:デフォルトの名無しさん
10/05/19 17:05:53
ところでend doとendoはどっちが望ましいの?
個人的にenddoの方が一語にまとまってて好きだけど
98:80
10/05/19 17:35:55
>>90
そうなんですか、理解していませんでした(>_<)
f77とf90だとかなり違うのでしょうか?
例えば参考にしているサイト陣がf90だったりf77だったりそれぞれ違っていたと思うのですが、
取り混ぜてしまっていたらまともなコードにはならない・・・という考えで合っていますか?
教科書は今までf77のものを使っていたので、なんにしてもf90のものを探してみます。
99:デフォルトの名無しさん
10/05/19 18:49:19
(>_<) …
100:デフォルトの名無しさん
10/05/19 19:29:53
良いこと思いついた
焚書坑儒して77を滅ぼそう
101:デフォルトの名無しさん
10/05/19 23:16:55
>>94
色々、妙な点が多いプログラムではあるので、可能性は色々あるが、
サブルーチン側でX(1)~X(600)までで計算してるんで内科医?
そもそも、古い数値がいらないなら、600個の配列に毎回書き換えて読み込めばいいし、
サブルーチン側でも600個を受け取って、1~600までの要素で計算すれば良い。
全要素を引渡しているようだが、必要なのかな?
>>100
77もいいとこあるんだよ。
102:デフォルトの名無しさん
10/05/20 01:00:59
大学のPCのOSがLinuxでfortranを学び始めました。
家でも練習みたいのをしたのですが、windows vistaでもできるのでしょうか。
例えばメモ帳に書いて、フリーのコンパイラでコンパイルするというのを想定しているのですがこれは無理なんですか。
103:デフォルトの名無しさん
10/05/20 01:05:07
>>102
知らないから僕ではなく他の人に聞いてみてよ
104:デフォルトの名無しさん
10/05/20 01:55:37
>>102
スレリンク(tech板:2-3番)
105:デフォルトの名無しさん
10/05/20 02:26:22
>>104
そのスレの3つ目は・・・・w
106:デフォルトの名無しさん
10/05/20 03:20:19
>>102
これが所謂ゆとりというものなのか
107:80
10/05/20 03:55:52
>>101
助言ありがとうございます、毎回書き換えてみる方法を色々試してみました。
下のようにメインプログラムを書き換えてみたのですが、
READ(10,*) X(0),Y(0)
do N=1,NW,MP
DO I=1,MP
READ(10,*,err=99) X(I),Y(I)
end do
CALL SUB1(X,Y,G,H,N,MP)
DO I=0,INT(X(MP-1)-X(0))
XX=X(0)+real(I)
K=1
do while ((X(K-1)-XX)*(X(K)-XX) > 0.0d0)
K=K+1
end do
YY=SUB2(G,H,X,Y,XX,K,MP)
WRITE(20,2100) XX,YY
end do
X(0) = X(MP)
Y(0) = Y(MP)
end do
close (20)
close (10)
STOP
108:デフォルトの名無しさん
10/05/20 04:01:02
まぁまぁw
Win機だと gfortran が一番かな?
タダだし、Linux版その他あってWin機でテストしたコードをよそに持っていっても
規格やら互換の問題がとても少ない・・・とおもう。OpenMPも使えるし。
コマンドプロンプト内の処理しかなく、Linuxコンソールと基本同じ使い勝手。
インスト(といってもファイルを展開するだけなのだが)楽チン。環境変数設定はめんどいw
109:80
10/05/20 04:02:28
107続き
最後のほうのデータが抜けてしまって、現在はどうしたものかと悩んでいます。
取り敢えずサブルーチンのDIMENSIONの設定とかをもう少し見直してみます。
110:102
10/05/20 04:47:12
>>108
すいません。。PCは大学入るまで使うことが少なくてよくわからなかったのです。
とりあえずいわれたものをダウンロードしてみます。ありがとごいました
111:デフォルトの名無しさん
10/05/20 05:04:02
>>110
g95だがこのへんとか
URLリンク(d.hatena.ne.jp)
あと最近の本だとこれがわかりやすい。
URLリンク(www.amazon.co.jp)
112:108
10/05/20 07:46:36
タダのFortranコンパイラを、と訊かれると
自分が使っている&インストール簡単だった、というそれだけの理由でgfortranを
人にはいつも薦めてるけど・・・じつはg95との違いをよく知らないのよねw
ぐぬーライセンスとか内部のオトナの事情はさておき、1ユーザーとしてみると何が違うのかな?
113:デフォルトの名無しさん
10/05/20 08:03:21
gfortranでは装置番号を環境変数で指定できない
114:デフォルトの名無しさん
10/05/20 10:25:59
>>85,>>92 → >>107
同じ人が書いたとは思えない!初心者でも1日でこんなに上達するんだな。
>最後のほうのデータが抜けてしまって
表現があいまいすぎて意味分からん。もしかして女の子?
助言を求めているなら、具体的に書かないとなんとも言いようがない。
115:デフォルトの名無しさん
10/05/20 10:27:19
× >>85,>>92 → >>107
○ >>85,>>93 → >>107
116:デフォルトの名無しさん
10/05/20 15:16:53
あえて77で書いてる人っているの?
117:デフォルトの名無しさん
10/05/20 15:43:03
ifortマンセー
118:80,85,93,107
10/05/20 19:25:09
>>114
わかりにくくて申し訳有りません(>_<)データは30000行入っていて欲しかったのですが
どうやら最後のほうや途中がデータ計測の時に抜けてしまったようでした。
抜け自体はそれほど多く無いので線形補間というのをすれば問題は無いそうです。
計算式は渡されて、どうやるかはまだ良く判っていませんが、調べてみます。
>もしかして女の子?
はい、最近分野変えで物理系の研究室に転入してきたばかりなのですが
今まではプログラミングには縁もゆかりもありませんでした。
>107は昨晩学校を徘徊して他の研究室に残っていた先輩からもアドバイスを貰いました。
>93については先輩曰く「動くようなプログラムには見えないぞ」との事で
つまるところ>>96と同じような指摘を受けたりなんだりして、手直ししてみました。
自分ではまだまだ勉強が浅いので次に違うプログラムを作る時には
また色々戸惑うだろうなぁとは思っています。
これからまたしっかり勉強します、ありがとうございました。
119:デフォルトの名無しさん
10/05/20 19:30:16
すいません。学校の課題でy=(x+1)(x-3)=0でNEWTON法を使い、収束判定が0.0000001で終わるプログラムを
「READ」「WRITE」「if」「GO TO」「SUBROUTIN」「DIMENSION]だけ使って作るんですけど・・・
SUBROUTINEとDIMENTIONが全く分かりません。誰か教えてください。
120:デフォルトの名無しさん
10/05/20 22:22:05
>>118
匿名掲示板だから思い切って聞きますが、処女ですか?
121:デフォルトの名無しさん
10/05/20 22:38:22
>>120
横レスですが違います
122:デフォルトの名無しさん
10/05/20 22:57:36
>>120
他人ですが・・・うるさーい(>_<)
123:デフォルトの名無しさん
10/05/21 00:27:38
\ / .::::::::::::::::::::::::;;:;;::,ッ、:::::: ) く ホ す
\ l ,ッィrj,rf'"'"'" lミ::::::: く れ モ ま
Y ,!ミ::::::: ヽ な 以 な
`ヽ、 | くミ:::::::: ノ い 外 い
|、__ ャー--_ニゞ `i::::,rく か は
``''ー- ゝ、'l  ゙̄´彑,ヾ }::;! ,ヘ.) ! 帰
゙ソ """"´` 〉 L_ っ
/ i , /| て r
≡=- 〈´ ,,.._ i 't-'゙ | ,へ ,r┘
,、yx=''" `ー{゙ _, -、 ; l レ' ヽr、⌒ヽ'
゙、`--─゙ /! `、
_,,、- ゙、 ー'' / ; `、
-''"_,,、-''" ゙、 /;;' ,' / 、\
-''" / `ー─''ぐ;;;;' ,' ノ
// / ヾ_、=ニ゙
124:デフォルトの名無しさん
10/05/21 01:01:32
本当に誰か助けてください(TAT)
流れは
xを読み込む
↓
y1=(x+1)(x-3)とy2=2x-2のy1、y2をそれぞれ算出
↓
H=y1/y2を算出
↓
Hが0.0000001より小さいか判別
↓
小さかったらHを出力して終了、大きかったらx-H=Aを算出
↓
Aをxに代入して0.0000001より小さくなるまで繰り返し計算する
こんな感じのプログラムを作りたいんですが・・・全然分からなくてできません・・・
誰か本当に助けたください
125:デフォルトの名無しさん
10/05/21 01:31:01
>>124
ガンガレ!
126:デフォルトの名無しさん
10/05/21 01:51:09
>>90あたりからの流れ好きだよ俺は
127:デフォルトの名無しさん
10/05/21 02:12:18
>>124
エラーチェック無し、暴走考慮せず、記述通りで無駄あり、Fortran90だ。
PROGRAM unko
IMPLICIT NONE
REAL :: x, y1, y2, a, h
x = 0.0
DO
y1 = (x + 1.0) * (x - 3.0)
y2 = 2.0 * x - 2.0
h = y1 / y2
IF (ABS(h) < 1.0e-7) EXIT
a = x - h
x = a
END DO
WRITE(*, *) 'result=', h, ': x=', x
STOP
END PROGRAM unko
実行結果
result= 0.0000000E+00 : x= -1.000000
128:127
10/05/21 02:17:54
>>124
プログラム出しておいてなんだが、たぶん問題が間違ってるか、問題を写し間違っているか、
質問者が問題を理解しそこねている。
この問題だと、単にy1のゼロ点近傍に近づいたときに終了し、y2の条件があまり意味を持たない。
あまりにイミフw
129:127
10/05/21 02:20:07
>>124
ごめんw >>119でNewton法で質問していたのか。Newton法なら意味わかる。
前レスは忘れろwww
130:デフォルトの名無しさん
10/05/21 02:29:43
>>119
>「READ」「WRITE」「if」「GO TO」「SUBROUTIN」「DIMENSION]だけ使って作る
これは出題者がこうしろと言ってるの?
131:デフォルトの名無しさん
10/05/21 02:41:32
>>129
ありがとうございます。そして悲しいことにFORTRANは77なんです(TAT)
>>130
そうなんです(汗)
講義で教えられてないのを使うと大目玉をくらうんです。
132:デフォルトの名無しさん
10/05/21 02:53:31
>>118
よく解らんが、不等間隔のデータを読み込んで、等間隔のデータに補間して出力したいのかな。
> do while ((X(K-1)-XX)*(X(K)-XX) > 0.0d0)
この条件式の書き方は昔風で今は流行らない。素直にIF文にした方がいい。
こんな感じの事をしたいのかもしれない。
PROGRAM unko
PARAMETER (MP = 600)
DIMENSION x(0:MP), y(0:MP)
READ(10,*) X(0),Y(0)
DO N = 1, 999999
DO I = 1,MP
READ(10,*,err=99) X(I),Y(I)
END DO
CALL SUB1(X,Y,G,H,MP)
K = 1
DO I = 0, INT( X(MP - 1) - X(0) )
XX = X(0) + REAL(I)
IF ( ( X(K-1) < XX ) .AND. ( XX <= X(K) ) ) THEN
YY = SUB2(G,H,X,Y,XX,K,MP)
WRITE(20,'(2F15.7)') XX,YY
ELSE
K = K + 1
END IF
END DO
X(0) = X(MP)
Y(0) = Y(MP)
END DO
99 CONTINUE
STOP
END
133:デフォルトの名無しさん
10/05/21 03:18:18
>>131
77なら77と最初から言え・・・といいつつ本来の質問を見ていなかった朕。
一応、昔風に芋臭く書いてみた。DIMENSIONをどう使ったらいいのか分からん。
微分もプログラム的にやることにしてみた。ちょっと無理っぽいw あと、ABSを使った。
PROGRAM main
WRITE(6, *) 'INPUT START VALUE ='
READ(5, *) a
1 x = a
CALL newton(x, h)
a = x - h
IF (ABS(h) .GT. 0.0000001) GOTO 1
WRITE(6, *) 'h=', h, ' x=', x
END
SUBROUTINE newton(x, h)
DIMENSION c(2)
c(1) = -1.0
c(2) = 3.0
y1 = (x - c(1)) * (x - c(2)) ! f = (x + 1)(x - 3)
y2 = (x - c(1)) + (x - c(2)) ! df/dx = 1(x - 3) + (x + 1)1
h = y1 / y2
RETURN
END
実行例1
INPUT START VALUE =
5.0
h= 0.0000000E+00 x= 3.000000
実行例2
INPUT START VALUE =
-3.0
h= 0.0000000E+00 x= -1.000000
134:デフォルトの名無しさん
10/05/21 03:43:09
>>133
ありがとうございます。(T∀T)
やっぱりDIMENSIONは無理やり使わないと使えないですよね(汗)
ちょっと疑問になったんですが、ABSのところをそのまんまhにしてもエラーが
おきたりしないですか?
135:デフォルトの名無しさん
10/05/21 06:37:05
>>134
エラーは発生しない。
それとお礼を言われる程のことはしていない。
136:デフォルトの名無しさん
10/05/21 11:08:52
>>135
嘘教えんなよwww誰だよw
>>134
hが負になる時の事を考えると、ABSが必要。
どうしてもABSを使いたくないなら、
IF (h < -0.0000001) GOTO 1
IF (h > 0.0000001) GOTO 1
とし給へ。
137:デフォルトの名無しさん
10/05/21 19:16:24
>>136
>嘘教えんなよwww誰だよw
>エラーは発生しない。
これは嘘ではないと思うが。
>それとお礼を言われる程のことはしていない。
それともこっちが嘘と言っているの?
138:デフォルトの名無しさん
10/05/21 20:34:30
プログラマーって短気が多いんだなぁw
139:デフォルトの名無しさん
10/05/22 00:06:23
>>137
キモイです.....(>_<)
140:デフォルトの名無しさん
10/05/22 02:28:39
>>136
いやエラーは出ないだろ。
141:80,107,118
10/05/22 05:49:11
>>132
これは書き方が判りやすくて助かります!おっしゃる通りのようなプログラムです、
どうやら抜け落ちたデータの補間もこれで出来るらしい?です。
107に書いたやりかたで取り敢えず動くのでやってみたのですが
50000行くらいの大きなデータだと、結果が出るまでもの凄く時間が掛かってしまいました。
変なところにバッファしてるんじゃないの?と言われたのですが良く判らず
10000ずつ計算させて切り貼りしています。どうしたものかと悩んでいます。
> do while ((X(K-1)-XX)*(X(K)-XX) > 0.0d0)
先輩が教えてくれたのですが、イマイチ意味が判っていませんでした、
普通にIFでやっても良いんですね、ありがとうございます。
142:デフォルトの名無しさん
10/05/22 09:48:31
>>141
計算機でやる分には、時間がかかってもそのままやらせればいいと思う。
手で切り貼りする作業時間を含めれば、結局トータルでの時間は、計算機でやった方が早いのでは?
時間がかかる原因は、色々ある。
しかしプログラムのどの部分に時間を取られているのか分からないとなんと見えない。
細切れのI/Oが多いと時間はかかる。だが、50000行くらいなら、600行づつ読んでもそれほどでもないような。
元のプログラムだと、毎回最初のデータから条件を満たす位置を探し始めているが、
Xが単調に増加しているのなら、前回の位置から探し始めれば早く適切な場所が見つかると思う。
この辺に、時間がかかっている気がしなくもない。
143:141
10/05/22 16:30:49
>>142
一桁間違えていました!(>_<)500000行くらいのデータです。
数時間の測定だと100000行以内くらいで済むので5~6分で計算出来るんですが
200000行くらいだと20~30分くらい掛かってしまいます。
500000行くらいのデータをやろうとしたら数時間掛かってしまっていました。
Xは単調増加なので前回の位置から探すというやりかたをちょっと考えてみます、
ありがとうございます。
144:デフォルトの名無しさん
10/05/22 19:13:23
>>143
N=
1 * 10**5, 5. .6min 5 / 1^2 = 5
2 * 10**5, 20.. 30min 20 / 2^2 = 5
5 * 10**5, 60..180min ~125/ 5^2 = 5
計算時間が要素数の自乗で増えているが、処理内容から言ってそうなるはずのものではない。
計算回数が自乗になりそうな所を探せば解決する気がする。
データを毎回頭から探すような部分はnC_2~O(n^2)だから、可能性は高い。
あと、それとは別に、今デバッグモードで実行しているなら、リリースモードで実行することにより
2~10倍くらいはやくなる可能性はある。その辺はコンパイラに依るので先輩などに聞いてみるとよいかな。
145:デフォルトの名無しさん
10/05/22 21:37:39
>Xは単調増加なので前回の位置から探すというやりかたをちょっと考えてみます、
>>142が言っている「元のプログラム」って>>85や>>93のことではないの?
>>107も>>132も,すでに前回の位置からREADするようになっているでしょ.
146:デフォルトの名無しさん
10/05/22 22:09:28
>>143ちょっとまて!
>>107でやってみたって言ってるけど,SUB1の引数にNが入るのっておかしくないか?
>>107バージョン CALL SUB1(X,Y,G,H,N,MP)
>>132バージョン CALL SUB1(X,Y,G,H,MP)
データの補間がしたいと言うことから推察するに,スプライン補間かな?(SUB1は行列を解いてる?)
5番目の引数が配列のサイズを渡しているんだとすれば,>>107ではNに相当大きな配列サイズが指定されて,
無意味なメモリ領域を読み取ってそのまま解いているんじゃないか?
SUB2ではその無意味な計算結果は使われないから,それで正常な結果が得られたとしても納得できそう.
ちょっと行き過ぎた推測かも知れないけど...
いちど,サブルーチンの引数を確認してみては?
147:142
10/05/23 17:10:04
>>146
毎回最初からと言っているのは、READではなくて、補間位置を決める、2つのデータに挟まれている位置を
求める部分の話。
>>107での2重DO-LOOP構造では、DO内でK=1にしているので毎回X(0)から探し始めている
DO I=0,INT(X(MP-1)-X(0))
XX=X(0)+real(I)
K=1
do while ((X(K-1)-XX)*(X(K)-XX) > 0.0d0)
K=K+1
end do
..YY=SUB2(G,H,X,Y,XX,K,MP)
end do
..
end do
一応>>132では(Xの単調増加を仮定して)外に出してある。
>>146
読み込んだデータを延々と配列にため込んでいるので、毎回現在のポインタ位置のような意味でNを渡す
必要があるのではないかと思う。
148:デフォルトの名無しさん
10/05/23 19:34:40
必要があるといいですね
149:デフォルトの名無しさん
10/05/23 19:59:51
前半は納得した.
後半「読み込んだデータを延々と配列にため込んでいるので、」というのは違うと思う.
どちらも0:MPの配列を使い回してる.
>>107の抜粋
READ(10,*) X(0),Y(0)
do N=1,NW,MP
DO I=1,MP
READ(10,*,err=99) X(I),Y(I)
end do
CALL SUB1(X,Y,G,H,N,MP)
...(略)...
X(0) = X(MP)
Y(0) = Y(MP)
end do
>>132の抜粋
READ(10,*) X(0),Y(0)
DO N = 1, 999999
DO I = 1,MP
READ(10,*,err=99) X(I),Y(I)
END DO
CALL SUB1(X,Y,G,H,MP)
...(略)...
X(0) = X(MP)
Y(0) = Y(MP)
END DO
どちらにしてもサブルーチンの中身が分からないと,X,Yの配列を使い回すのが正しいのかすら推測の域を出ないな.
質問者のレベルから考えると,引数の意味を把握しているか自体が心配.
(このスレ,勉強になるなぁ)
150:142
10/05/23 22:24:25
>>149
おk把握した。
古い方のプログラムと混乱していた。
古い方は、データをため込んでいるので、現在位置をサブルーチンに渡す必要があるから、
Nを渡していると理解していた。
とすると>>107では、Nの値が狂っているなw N=1で固定しなきゃないかな?w
151:141
10/05/24 02:20:17
>>144->>150
今理解するのにちょっと時間が掛かっています(>_<)皆様有り難うございますm(_ _)m
>>146さんの言う通りサブルーチンの中身はスプライン補間になっていました。
SUB1で行列を解いていて、SUB2で間隔1毎の値を計算している?感じです。
引数の意味はまだ良く理解出来ていません、SUB1のNがおかしいのでしょうか?
もう少しいぢくってみます。。。
152:デフォルトの名無しさん
10/05/24 12:47:55
>>151
メール欄に sage と書き込んで、スレが上のほうに上がらないようにした方がいいですよ。
スレが上に上がると、通りすがりの冷かしが面白半分なレスを書き込んでくる確率が上がるので(^^
153:デフォルトの名無しさん
10/06/06 02:50:01
i==2 ? x = 0 : x = 2
みたいなのは無理なんですか?
154:デフォルトの名無しさん
10/06/06 03:15:10
>>153
x=2; IF (i==2) x=0
155:デフォルトの名無しさん
10/06/06 22:26:58
>>154
なるほどサンクスです
でもやっぱ?使えた方が見やすいですね
156:デフォルトの名無しさん
10/06/07 13:55:06
>>153
これって何の言語ですか?
157:デフォルトの名無しさん
10/06/07 18:05:16
>>156
Ruby java
158:デフォルトの名無しさん
10/06/08 00:01:45
>>156
おしっこC言語。3項演算子。
しかし、昔風の書き方の気が・・・
最近はFortranでもCでも、もっとわかりやすく書くように指導されているはずだが・・・
159:デフォルトの名無しさん
10/06/08 02:05:16
配列の仮引数に、スカラーの実変数をsize=1の配列として渡すのって、
どうやればいいの?
下の例だと、rank mismatchでcompile通んないし、
reshape(s,1)もダメって言われた。
一回、別の配列に値をコピーするしかないのかな?
Program test
integer s
s = 1
call inc(1,s)
print *, s
Contains
Subroutine inc(n, a)
implicit none
integer, intent(in) :: n
integer, intent(inout) :: a(n)
integer i
do i = 1,n
a(i) = a(i) + 1
end do
End subroutine inc
End program test
160:デフォルトの名無しさん
10/06/08 03:16:01
>>159
INTENT(IN) 属性なら、
call inc(1,[s]) ないし call inc(1, (/s/))
でいけるが、INTENT(OUT)で値が返る場合はダメだなあ。
161:デフォルトの名無しさん
10/06/08 11:42:43
integer s(1)
とサイズが1を明示すれば通るけど(intel のやつ)・・・それじゃダメなんだよねぇ・・・・
思いつきで(邪道とされるw)equivalence 使って
Program test
integer sdummy(1)
integer s
equivalence(sdummy, s)
s = 1
call inc(1,sdummy)
・・・・・
でも通るけど・・・意味ねぇなw
162:デフォルトの名無しさん
10/06/08 11:44:40
あ、始めて気づいたけど、
integer s(1)
s=1
って通るんだね。コンパイラにも寄るんだろうけど。
163:デフォルトの名無しさん
10/06/08 12:46:57
>>162
たぶんそれ、F90の配列初期化の一括代入になってるだとおもう。
164:デフォルトの名無しさん
10/06/08 12:50:56
ありがとう。
そっか普段77で書いてるから不慣れというかまったく気付かなかった。
たまに90で書くし初期化で使うのに・・・
Intel (たぶん余所のも) のはF77固定書式で書いても、
その事をコンパイルオプションで明示しないと、
F90の機能をちょっとなら混ぜても
文法が干渉しない限りは有効とみなすんだよね。
・・・危ないような気もする。
165:159
10/06/08 19:06:53
>>160
その場合でも結局、一時的な配列に値をコピーしてから渡すって意味になってるんだよ。
>>164
FORTRAN77なら型チェックなんかないし、
配列にスカラー変数を渡すのは正しい操作なんだよね。
内部的にはメモリアドレスを渡してるだけなんだから。
>>161のequivalenceは、今回のprogram文では意味ないけど、
変数sがサブルーチンの仮引数のときに、
無用なコピーを作らず渡せる唯一の方法かもしれない。
166:デフォルトの名無しさん
10/06/08 23:43:04
>>165
素直にテンポラリを間にかますのが一番いいと思うけどさw
EQUIVALENCE ありなら、なんでもアリだなw
POINTERという手はどうだ?
Cとの互換POINTERを使えば、RANKとかのチェックは逃れられる。
Program test
USE, INTRINSIC :: iso_c_binding
IMPLICIT NONE
integer :: s
s = 1
call inc(1, c_loc(s))
Contains
Subroutine inc(n, p)
implicit none
integer, intent(in) :: n
TYPE(C_PTR), intent(in) :: p
integer :: a(n)
integer i
CALL C_F_POINTER(p, a)
do i = 1,n
a(i) = a(i) + 1
end do
End subroutine inc
End program test
167:デフォルトの名無しさん
10/06/09 13:23:31
>>159みたいなことは御法度なんじゃないの?
そのために90以降いろいろと拡張されたわけでしょ?
168:デフォルトの名無しさん
10/06/09 22:00:59
質問です。
LAPACKを使うプログラムなんですが、
Intelのコンパイラだとコンパイル出来るのですが、
gfortranだとSyntax errorが出てしまいます。
こういうことってプログラムに間違いが無くても起こりますか?
169:デフォルトの名無しさん
10/06/09 22:23:27
>>168
起こる。
170:デフォルトの名無しさん
10/06/09 22:49:25
>>167
そうなんだけど、その辺は70年代的Pascalマンセー的な発想で、型チェックギチギチにしたら
確かにエラーは減ったが、窮屈で困ってしまったというのが、80年代以降というか。
実際、Fortran的にはF95でELEMENTAL型の副プログラムが定義出来るようになって、
スカラーで副プログラムを定義しておけばRANKによらずに配列引数が取れるようになっている。
アルゴリズム部分とデータ構造を、もっと独立したユルユルの関係にしたいというか。
171:デフォルトの名無しさん
10/06/09 22:57:12
>>169
そうですかー…
ありがとうございます
172:デフォルトの名無しさん
10/06/10 04:24:29
>>168
その LAPACK はだれがどのコンパイラでコンパイルしたの?
173:デフォルトの名無しさん
10/06/10 13:10:28
>>170
気持ちは分かるなぁ・・・
この辺の善し悪しは開発の規模にもよるんだろうな
174:デフォルトの名無しさん
10/06/10 14:47:46
>>172
LAPACKはLinuxのパッケージ管理ソフトで入れたんですが、
だからたぶんgccでコンパイルされたものだと思います。
175:デフォルトの名無しさん
10/06/14 19:39:21
Fortranerの中には数値計算な業界の人も多いと思うけど、ぶっちゃけ聞きますが飯食えてますか?
ニッチでそこそこやっていけてるのか、それとも潰しのきかない悲しい境遇なのか
176:デフォルトの名無しさん
10/06/14 21:57:26
受験者数と受験者の受験番号と点数が分かっている。
10
17 73
5 64
22 67
6 66
7 90
42 88
9 74
11 79
2 63
13 72
(1行目は受験者数、2行目以降の左は受験番号、右は点数)
以上のデータdata.txtを読み込み、以下に示す結果をresult.txtに出力するようなプログラムを作成せよなお、この試験では59点以下はD、60点以上69点以下はC、70点以上79点以下はB、80点以上はAと判定することにする。
----------------------------------------------
受験者 x人
A x人
B x人
C x人
D x人
平均点 x
標準偏差 x
中央値 x
順位 受験番号 点数 成績
1 25 85 A
2 41 82 A
(以下省略)
----------------------------------------------
・xには数字が入る。
・中央値はMOD関数を用いること。
以上の問題が分かりません。誰かよろしくお願いします。
177:デフォルトの名無しさん
10/06/15 19:18:06
e^x,sinx,logxのテーラー展開を求めるプログラムを教えてもらいたいのですが…
e^xはできたので、これを参考に教えてください!
subroutine expotn (x)
c
real Tn, ans, err
integer n
c
EPS = 1.0e-6
n = 0
Tn = 1.0
ans = Tn
write(6,10) x
10 format('EXP(', f10.5, ') ')
50 if( abs(Tn) .gt. EPS) then
n = n + 1
Tn = Tn * x / n
ans = ans + Tn
err = ans - exp(x)
write(6,11) n, ans, err
11 format(I3,' exp(X) = ',f12.7,' err = ',f15.10)
go to 50
end if
write(6,*) ' Exp( ',x,' )= ',ans
return
end
c
178:デフォルトの名無しさん
10/06/19 00:40:28
MinGWにくっついていたG95コンパイラを用いて、
Fortran77のソースコードをコンパイルしようとすると
以下のようなエラーが出ます。
コンパイルするときのコマンドは以下のとおりです。
>g95 F:\Direct_vs_Ewald.f -freal-loops
問題のソースコードは以下の部分です。
volume=a(1)*(b(2)*c(3)-b(3)*c(2))-a(2)*(b(1)*c(3)-b(3)*c(1))
& +a(3)*(b(1)*c(2)-b(2)*c(1))
この処理の部分で&の下に1が出現します。
Error: Unclassifiable statement at (1)
なぜ、このようなエラーが出るのかわかりませんでした。
()の閉じ忘れは確認したところありませんでした。
&記号が二つの文をひとつにする働きがあることは調べたら出てきましたが、
G95コンパイラにはこのような機能は無いということでしょうか?
179:178
10/06/19 02:02:52
すみません。いったん寝ます
180:デフォルトの名無しさん
10/06/19 02:19:08
>>177
SIN(x) = x - x^3 / 3! + x^5 / 5! - x^7 / 7! +.....
subroutine sinetn(x)
c
real Tn, ans, err
integer n
c
EPS = 1.0e-6
n = 0
Tn = x
ans = Tn
write(6,10) x
10 format('SIN(', f10.5, ') ')
50 if( abs(Tn) .gt. EPS) then
n = n + 1
Tn = - Tn * x**2 / ( (2 * n + 1) * 2 * n )
ans = ans + Tn
err = ans - sin(x)
write(6,11) n, ans, err
11 format(I3,' Sin(X) = ',f12.7,' err = ',f15.10)
go to 50
end if
write(6,*) ' Sin( ',x,' )= ',ans
return
end
c
181:デフォルトの名無しさん
10/06/19 02:24:33
>>177
LOG(1 + x) = x - x^2 / 2 + x^3 / 3 - x^4 / 4 +......
収束半径が小さいので注意。一般の範囲でやりたいなら、LOGの性質を使って範囲を調整汁。
subroutine logtn(x)
c
real Tn, ans, err
integer n
c
EPS = 1.0e-6
n = 1
Tn = x - 1.0
ans = Tn
write(6,10) x
10 format('Log(', f10.5, ') ')
50 if( abs(Tn) .gt. EPS) then
n = n + 1
Tn = - Tn * ( x - 1.0 )
ans = ans + Tn / n
err = ans - log(x)
write(6,11) n, ans, err
11 format(I3,' Log(X) = ',f12.7,' err = ',f15.10)
go to 50
end if
write(6,*) ' Log(',x,' )= ',ans
return
end
c
182:デフォルトの名無しさん
10/06/19 03:07:25
>>178
g95で試してみたが、6カラム目に&がくれば問題なくコンパイルできた。
FORTRAN77の継続行指定は6カラム目に無いと駄目。
ずれると、
Error: Unclassifiable statement at (1)
が出る。
エラー行と数字の1が出ているはずで、それがエラー位置を指しているので、よく見よ。
ちなみに、Fortran90では&は継続行を意味するが、1行目の尻に書く。
詳しくはマニュアルを読んでくれ。
純粋なFORTRAN77では&は規格外の文字なので本来は使っていけない。
(今となっては余り気にしないが。)
183:178
10/06/19 08:06:20
>182
ありがとうございます。
Tabでインデントしていたので気づきませんでした。
半角スペース5個をつけた後、&をつけるようにしたら、そのエラーは消えました。
Warning (121): COMMON block 'coor' is 1600004 bytes at (1) and 160004 bytes at (
2)
というエラーは出ましたが、-wオプションをつけることでなんとかコンパイルはできるようになりました
184:デフォルトの名無しさん
10/06/19 14:10:25
ファイルをdirect accessで読む場合、
open (10,file='hoge.dat',access='direct',recl=4)
read(10,rec=10000) j
みたいに欲しい場所をすぐ読めますが、sequentialで同じようなことは可能でしょうか?
今まではこんな風に不要な部分は破棄していたんですが、効率が悪いと思いまして。
open (10,file='hoge.dat',access='sequential')
do i=1,9999
read(10) jtmp
enddo
read(10) j
185:デフォルトの名無しさん
10/06/19 16:37:37
>>184
末尾だったらOPEN時に指定出来るが、任意位置には行けない。
というか行きようが無い。
直接型はレコード長が全要素で共通だから特定の位置までのバイト数がわかるが、
レコード長が不定長の逐次型では原理的に知り得ない。
ところで読み飛ばすときjtmpに読み込まなくても空READだけでおk。
あと後ろに近いなら、尻から始めてBACKSPACEで逆行する技もある。
それが負荷を減らすかどうか知らんwwwww
186:デフォルトの名無しさん
10/06/19 18:14:42
>>185
やっぱり不可能ですか。
将来ウンTBのデータを扱う時代になったら、データハンドリングはどうなるんでしょうね。
ファイルはダイレクトアクセス、データ構造はレコード長まで完全に把握するというのが
一般的になるんでしょうかね・・・
187:デフォルトの名無しさん
10/06/19 23:07:40
>>176
受験者 10 人
A 2 人
B 3 人
C 4 人
D 1 人
平均点 68.00000
標準偏差 19.24578
中央値 69.50000
順位 受験番号 点数 成績
1 7 90 A
2 42 88 A
3 11 79 B
4 9 74 B
5 13 72 B
6 22 67 C
7 6 66 C
8 5 64 C
9 2 63 C
10 10 17 D
188:1/3
10/06/19 23:08:59
PROGRAM test
PARAMETER(nmax = 999)
INTEGER id(nmax, 2), idistr(4)
CHARACTER grade
OPEN(10, FILE = 'data.txt' , STATUS = 'old' )
OPEN( 9, FILE = 'result.txt', STATUS = 'unknown')
DO 10 i = 1, nmax
READ(10, *, END = 99) id(i, 1), id(i, 2)
10 CONTINUE
STOP 'error: too many data! increase nmax'
99 ndata = i - 1
sum = 0.0
DO 20 i = 1, ndata
sum = sum + id(i, 2)
20 CONTINUE
ave = sum / ndata
sum = 0.0
DO 30 i = 1, ndata
sum = sum + (id(i, 2) - ave)**2
30 CONTINUE
rms = SQRT(sum / ndata)
CALL sort(nmax, ndata, id)
DO 40 i = 1, 4
idistr(i) = 0
40 CONTINUE
189:2/3
10/06/19 23:09:40
DO 50 i = 1, ndata
IF ( grade( id(i, 2) ) .EQ. 'A') idistr(1) = idistr(1) + 1
IF ( grade( id(i, 2) ) .EQ. 'B') idistr(2) = idistr(2) + 1
IF ( grade( id(i, 2) ) .EQ. 'C') idistr(3) = idistr(3) + 1
IF ( grade( id(i, 2) ) .EQ. 'D') idistr(4) = idistr(4) + 1
50 CONTINUE
IF (MOD(ndata, 2) .EQ. 1) THEN
xmean = id(ndata / 2 + 1, 2)
ELSE
xmean = ( id(ndata / 2, 2) + id(ndata / 2 + 1, 2) ) / 2.0
ENDIF
WRITE(9, *) '受験者 ', ndata, '人'
WRITE(9, *) 'A ', idistr(1), '人'
WRITE(9, *) 'B ', idistr(2), '人'
WRITE(9, *) 'C ', idistr(3), '人'
WRITE(9, *) 'D ', idistr(4), '人'
WRITE(9, *) '平均点 ', ave
WRITE(9, *) '標準偏差', rms
WRITE(9, *) '中央値', xmean
WRITE(9, *) '順位 受験番号 点数 成績'
DO i = 1, ndata
WRITE(9, '(i5, 2i11, a5)') i, id(i, 1), id(i, 2), grade(id(i, 2))
END DO
STOP
END
C
190:3/3
10/06/19 23:12:50
SUBROUTINE sort(nmax, n, in)
INTEGER in(nmax, 2)
DO 10 i = 1, n
DO 20 j = 1, n
IF ( in(j, 2) .LT. in(i, 2) ) THEN
itmp1 = in(i, 1)
itmp2 = in(i, 2)
in(i, 1) = in(j, 1)
in(i, 2) = in(j, 2)
in(j, 1) = itmp1
in(j, 2) = itmp2
END IF
20 CONTINUE
10 CONTINUE
RETURN
END
FUNCTION grade(k)
CHARACTER grade
IF (k .GE. 80) THEN
grade = 'A'
ELSE IF (k .GE. 70) THEN
grade = 'B'
ELSE IF (k .GE. 60) THEN
grade = 'C'
ELSE
grade = 'D'
END IF
RETURN
END
考えなしに書いた。なんなん(・∀・)!?
191:デフォルトの名無しさん
10/06/20 02:12:48
残差の二乗和を計算するときの精度と実行速度について悩んでます。
速度よりは精度の方を優先したいのですが、
以下の3つのソースで、最もバランスの良いものはどれでしょう?
xとaはそれぞれ倍精度実数として、
1.
(x-a)**2
2.
(x-a)*(x-a)
3.
(x-a)*(x+a)
よろしくお願いします。
192:デフォルトの名無しさん
10/06/20 06:21:47
指数部が整数の時は同じ掛け算をする(はず)。というわけで精度&実行速度の点で、ぼほ1=2と思ってよろし。
でもたとえば、a=1.0 でデータxを3要素で値が(1e-6,1,1e6)とすると、
第3要素のおかげで他の2項の寄与が消えちゃう。
ので、x^2 + 2ax + a^2
の3項にわけで個別に和をとって最後に足す、という事をすると
2ax の部分が残る分マシ。参照値 a とデータ x の分布次第だね。
x が a と同じオーダーなら気にすることは無い。
3は、 x*x - a*a の方が一般には精度という点で推奨される
同じく参照値 a と比べたときの x の値の分布次第、でもあるが
速度については積の演算はCPU毎にコストが違うので、どちらが良いかは一概にはいえない。
193:デフォルトの名無しさん
10/06/20 17:31:29
>>181
ちょっとまた質問です。
例えば、x-1.0=tと自分で置いたら
Tn = x - 1.0 → Tn = t
write(6,10) x → write(6,10) t
Tn = - Tn * ( x - 1.0 ) ← Tn = - Tn * t
とおいて、より簡単なプログラムにしてもいいですか?
なるべくなら、式が簡単なほうが分かりやすいですし。
194:デフォルトの名無しさん
10/06/20 23:29:03
>>193
それでもよい。
なお、そのテイラー展開の収束半径は、|x|<1のはずなので、その範囲から外れるような値も
計算できるようにしたいなら、LOG(X*10^N)=LOG(X)+N*LOG(10) などの公式を使って
スケールしてやる必要がある。
195:デフォルトの名無しさん
10/06/21 00:13:24
仮にt=1.5の計算をするときには範囲のプログラムとして>>194のようなプログラムを施すということでよろしいのでしょうか?
196:デフォルトの名無しさん
10/06/21 00:16:37
>>195
もう一個スケール処理するサブルーチンを書いて、それがテイラー展開のサブルーチンを呼べばいいんでないかい?
サブルーチンからサブルーチンを呼ぶ。
197:デフォルトの名無しさん
10/06/21 00:30:26
>>196
つまりは例として出ているLOG(X*10^N)=LOG(X)+N*LOG(10)という関数のサブルーチンをlog(x)の範囲のところに呼ぶというわけですか?
198:デフォルトの名無しさん
10/06/23 16:56:50
こんにちは。sinxのテーラーのプログラムを以下のように書きましたが、うまくいきません…
おそらく、何か足りないのでしょうが…教えてください。
プログラム(1/2)
program sinTelor
c
real x
integer which
c
c begin
c EPS = 1.0e-5
write(6,*) 'Taylor Expansion of mathematical function'
write(6,*) ' .Sine function'
read (5,*) which
end
199:デフォルトの名無しさん
10/06/23 16:57:33
プログラム(2/2)
c
subroutine sine (x)
c begin
real Tn, ans, err
integer n, nstop
c
nstop=30
EPS = 1.0e-6
n =1
Tn = x
ans = Tn
write(6,10) x
write(6,*) ' sin(x)= ',sin(x)
10 format('SIN(', f10.5, ') ')
50 if( abs(Tn) .gt. EPS .and. n .lt. nstop) then
n = n + 1
Tn = - Tn * x **2 / ( (2 * n -1) *( 2 * n-2 ))
ans = ans + Tn
err = ans - sin(x)
write(6,11) n, ans, err
11 format(I3,' sin(X) = ',f12.7,' err = ',f15.10)
go to 50
end if
write(6,*) ' sin( ',x,' )= ',ans
return
end
return
end
200:デフォルトの名無しさん
10/06/23 18:28:09
>>198>>199
それは君が馬鹿だからです
201:デフォルトの名無しさん
10/06/24 02:44:17
>>198
まずこの 綴りの間違いを何とかしろ!w
program sinTelor
CALL sine( which )
を書け。サブルーチンを呼び出さずに何をする気だw
兄貴がサブを呼ぶと覚エロ!
202:デフォルトの名無しさん
10/06/24 09:49:15
>兄貴がサブを呼ぶ
解説プリーズ
203:デフォルトの名無しさん
10/06/25 10:09:02
すみません(汗)
FORTRAN77で、Gauss-Jordan法のプログラムを
「READ」「WRITE」「GO TO]「IF]「SUBROUTINE」
「DIMENSION」を使って作りたいんですが・・・
全く分りません。誰か教えてください!
204:デフォルトの名無しさん
10/06/25 23:49:59
>>203
図書館行ってアルゴリズム集から完コピ。マジオススメ
205:デフォルトの名無しさん
10/06/26 00:03:12
>>203
誰か、F77で掃き出し法のサブルーチン作ってテンプレに書いておけよ。
206:デフォルトの名無しさん
10/06/26 00:58:47
>>203
goto は使うな!
207:デフォルトの名無しさん
10/06/26 02:12:04
>>206
それ70年代の話www
208:デフォルトの名無しさん
10/06/26 12:17:22
>>207
え!?
209:デフォルトの名無しさん
10/06/26 14:07:24
>>203
dimensionも使うな!
210:デフォルトの名無しさん
10/06/26 23:12:28
微笑ましいよね。
きっと課題に「xxx」「yyy」を使え、と明示してあるんだろうね。
211:デフォルトの名無しさん
10/06/27 10:00:36
77でgotoを使わないのは、結構苦しいと思うが。
212:デフォルトの名無しさん
10/06/27 11:19:38
全く無しはしんどいよね。最小限にはすべきだけど。
do while
があれば goto を使う機会が激減する・・・と書こうとしたけど、
お題の203さんの課題では do は入ってないね・・。
if goto の組み合わせで何とかしろ、ということなのか。
これはこれでしんどいw
213:デフォルトの名無しさん
10/06/27 12:44:34
>>203
まじめにアドバイス
Fortranがわからないの?Gauss-Jordan法がわからないの?
「知らない数値解法」で「知らない言語」で書け、
という課題が悩ましいのは自分もそうだったのでわかるけど
丸投げだとあまり回答もらえないですよ。
前者なら、どの程度の基礎的なプログラムなら書けるのかを提示して
どの部分を調べたらよいかをアドバイスもらい、
後者なら、ネットで調べたり、その解法のどの部分のプログラム化が?なのかを提示
したほうがいいと思います。
正直、その解法で、何を解きたいのかよくわからないし。
214:デフォルトの名無しさん
10/06/27 14:11:37
>>213
放っておいてあげれば良いと思うよ。
215:デフォルトの名無しさん
10/07/02 13:45:32
A~Zまでの文字のデータを1つ1つファイルにしておき
小文字で入力された文字列をファイルから読み込んで
大文字で表示するにはどのようにすれば良いのでしょうか?
入力された文字をそれぞれのファイルから
読み込む方法がよくわかりません。お願いします。 F90
216:デフォルトの名無しさん
10/07/02 16:33:26
質問があいまい&意味不明...
ファイル内に記述された特定の文字だけを大文字に変換したいのかな?
もしそうなら、Fortranではなくawkやperlを使った方が断然楽だよ。
いちおう、ファイルを読み込むのも、入力文字を読み込むのもREADを使う。
217:デフォルトの名無しさん
10/07/03 00:07:10
>>215
完全イミフ。
日本語でおk
218:デフォルトの名無しさん
10/07/03 00:08:49
表示ができるようになったのですが、ファイルの行数を明示しないと
End Of Line になってしまうのですが、そこで
integer io を宣言して行末を発見して読み込みを止めさせようとしたが
うまくできないのです
なお data614.txt は株価のデータで
価格(整数),年,月,日
にしてあります。
program hyoujisurudake2
implicit none
integer :: i
integer :: io=0
integer :: xprice,xyear,xmonth,xday
!*4を*8にしたりして試していたけどできなくて、こうしたらできた
open(10,file='data614.txt',status='old')
i = 0
do
!だめだ read(10,iostat=io) ,xprice, xyear, xmonth, xday
read(10,*) ,xprice, xyear, xmonth, xday
! if(io <= -1 ) exit
if(i>=3406) exit
i=i+1
!2 print* , i,xprice
print* , i, xprice, xyear, xmonth, xday
end do
close(10)
stop
end
219:デフォルトの名無しさん
10/07/03 00:34:57
多分続けて投稿です
上記の株価データですが本当はこうなっているんです
これ
年/月/日,株価
具体的には
1999/12/31,12345
2000/1/1,23456
2000/1/2,23456
てな具合ですがここで大きな問題がある それは
読み込むときに「,」切りはいいとして
「/」での切り方がわからない・・・
fortran だと何文字をどこそこに格納して とかいうのはとくいですが
パーサーが無い? ので「,」で切ってから「/」で切るという処理は
どうやるのでしょうか
220:デフォルトの名無しさん
10/07/03 01:10:19
>>218
IOSTATがうまくいかないのは、Fortmat書式を抜いているから。
>>219
INDEX関数使えば出来る。
221:デフォルトの名無しさん
10/07/03 01:44:30
>>219
program hyoujisurudake2
implicit none
integer :: i, io, ip1, ip2, ip3
CHARACTER(LEN = 80) :: text
integer :: iprice, iyear, imonth, iday
open(10,file='data614.txt',status='old')
i = 0
do
read(10, '(a)', iostat = io) text
if(io <= -1 ) exit
i=i+1
ip1 = INDEX(text, '/')
ip2 = INDEX(text, '/', BACK = .TRUE.)
ip3 = INDEX(text, ',')
READ(text( 1:ip1 - 1), *) iyear
READ(text(ip1 + 1:ip2 - 1), *) imonth
READ(text(ip2 + 1:ip3 - 1), *) iday
READ(text(ip3 + 1: ), *) iprice
print * , i, iprice, iyear, imonth, iday
end do
close(10)
stop
end
1 12345 1999 12 31
2 23456 2000 1 1
3 23456 2000 1 2
続行するには何かキーを押してください . . .
この入力データで問題となるのは、FORTRANの書式指定無しの場合、スラッシュ『/』は改行を意味する制御文字に
なっている点だ。これを知らないと、何故か入力がなされなくて、地獄へ落ちる!
222:デフォルトの名無しさん
10/07/03 16:10:31
>>203
gotoは1関数に1ラベルなら使ってOKだよ!
ソースが見やすくなるからね
223:デフォルトの名無しさん
10/07/04 00:50:08
>>203
PIVOT処理するのが面倒なのでしてないw
SUBROUTINE GJ(a, b, n) ! Gauss-Jordan method
DIMENSION a(n, n), b(n)
DO 10 irow = 1, n
pivot = a(irow, irow)
IF (pivot .EQ. 0.0) STOP 'pivot is 0.0!'
DO 5 icol = 1, n
a(irow, icol) = a(irow, icol) / pivot
5 CONTINUE
b(irow) = b(irow) / pivot
DO 20 jrow = 1, n
IF (irow .NE. jrow) THEN
q = a(jrow, irow)
DO 30 icol = 1, n
a(jrow, icol) = a(jrow, icol) - q * a(irow, icol)
30 CONTINUE
b(jrow) = b(jrow) - q * b(irow)
END IF
20 CONTINUE
10 CONTINUE
RETURN
END
224:デフォルトの名無しさん
10/07/04 06:34:23
>>219
2000年元旦に市場で何があったんだ・・・w
>>221
/ , を空白に置き換えてから内部入力で、というやりかたもできそうだけど、どうかな?
text(ip1:ip1) = ' '
(略)
READ(text,*) iyear, imonth, iday, iprice
手元にコンパイラがないから・・これで勘弁
225:デフォルトの名無しさん
10/07/04 07:24:53
>>222
俺もそうだよw
224だけど、どうかな?
226:221
10/07/04 14:20:20
>>224
>/ , を空白に置き換えてから内部入力で、というやりかたもできそうだけど、どうかな?
その方がいいな。 ↓コンマは区切り文字になっているから残してもいいのだが、INDEXの代わりにSCAN関数使ってみたかったので消した。
program hyoujisurudake2
implicit none
integer :: i, io, ip1, ip2, ip3
CHARACTER(LEN = 80) :: text
integer :: iprice, iyear, imonth, iday
open(10,file='data614.txt',status='old')
i = 0
do
read(10, '(a)', iostat = io) text
if (io <= -1 ) exit
i = i + 1
CALL cutslash(text)
READ(text, *) iyear, imonth, iday, iprice
print * , i, iprice, iyear, imonth, iday
end do
close(10)
stop
CONTAINS
SUBROUTINE cutslash(text)
CHARACTER(LEN = *), INTENT(IN OUT) :: text
INTEGER :: k
DO
k = SCAN(text, '/,')
IF (k == 0) EXIT
text(k:k) = ' '
END DO
RETURN
END SUBROUTINE cutslash
end program hyoujisurudake2
227:デフォルトの名無しさん
10/07/05 04:43:04
>>226 コンマは区切り文字になっているから残してもいい
本当だ!
いまの今まで知らんかった・・・。 CSV みたいに','が区切り記号で使われてる
ファイルもらったときも御丁寧に置き換えてた・・。
228:デフォルトの名無しさん
10/07/05 18:03:28
write文での制御編集記述子についての質問です。
100e18.10
と指定してファイルに書いていたのですが、
これを
100es18.10e2
と指定すると、一部がアスタリスクになってしまいます。
マニュアルを読むかぎり
100が書式の繰り返し数
18が小数点上の桁、小数点以下の桁、指数を含めたすべての桁数
10が小数点以下の桁数
2が指数の桁数
と理解したのですが、どこか誤りがあるでしょうか。
教えていただけないでしょうか。
229:デフォルトの名無しさん
10/07/05 20:56:57
218 219 です
>220
さん ありがとう
>221
さんコードまで書いてもらってありがとうございます。
うちのPCだとコンパイルがうまくいかないようですが、
それは多分調整のレベルなのでしょう。
ほんとにこんなに早くレスがくるとは思ってもみず 返事が遅くなりました
230:デフォルトの名無しさん
10/07/05 21:01:23
>>224
> 224 名前:デフォルトの名無しさん [sage]: 2010/07/04(日) 06:34:23
> >>219
> 2000年元旦に市場で何があったんだ・・・w
すみません、これ分かりやすくするためのものでして・・・。
「文字の数が変わっちゃうのでこまっていた」ということでした。
> >>221
> / , を空白に置き換えてから内部入力で、というやりかたもできそうだけど、どうかな?
> text(ip1:ip1) = ' '
> (略)
> READ(text,*) iyear, imonth, iday, iprice
> 手元にコンパイラがないから・・これで勘弁
いろいろ工夫が必要なのが分かって着ました。
高級言語の割には今時のRubyとかよりずっとマニュアル車っぽくていいようなかんじも・・
ありがとうございました。
これで本題の数値解析に移れます
231:デフォルトの名無しさん
10/07/05 21:04:51
>>226
> 226 名前:221 [sage]: 2010/07/04(日) 14:20:20
> >>224
> >/ , を空白に置き換えてから内部入力で、というやりかたもできそうだけど、どうかな?
> その方がいいな。 ↓コンマは区切り文字になっているから残してもいいのだが、INDEXの代わりにSCAN関数使ってみたかったので消した。
> program hyoujisurudake2
218 です いろんなやり方があるんですね。
それだけ皆さんは苦労してきたと想像します
232:デフォルトの名無しさん
10/07/05 21:06:49
>>227
> 227 名前:デフォルトの名無しさん [sage]: 2010/07/05(月) 04:43:04
> >>226 コンマは区切り文字になっているから残してもいい
>
> 本当だ!
> いまの今まで知らんかった・・・。 CSV みたいに','が区切り記号で使われてる
> ファイルもらったときも御丁寧に置き換えてた・・。
219 です
すると "," は標準で区切り文字になっているが、それを解除?することは
難しそうですね。きっとできるでしょうが、とっても深い世界
233:デフォルトの名無しさん
10/07/05 22:00:36
はい
234:デフォルトの名無しさん
10/07/05 23:46:10
>>228
Fortranの場合、Formatで指定した桁数からあふれると、アスタリスクが出力される。
今の場合、多分指数部分が溢れているんじゃないかと思う。
E-10とかが出ると、ヤバイ。E2の2には符号の分も含まれる。
>>232
>すると "," は標準で区切り文字になっているが、それを解除?することは
>難しそうですね。きっとできるでしょうが、とっても深い世界
それはFORMATをあらわに指定すれば出来る。
上の例でも、ファイルの1行を丸々文字列として読み込んでいる。
read(10, '(a)', iostat = io) text
この場合は、スラッシュもコンマもただの文字として読み込まれる。
235:デフォルトの名無しさん
10/07/06 00:17:16
読み込まれる。
236:デフォルトの名無しさん
10/07/06 00:22:20
>>235
ひがむなって。百姓・町人みたいだぞ。
237:デフォルトの名無しさん
10/07/06 01:27:54
>>234
ありがとうございます。
>>228
にある18を25などの大きな値にしてみたのですが、それでも一部でアスタリスクになってしまうことがありました。
一行にかける文字数などなにか別の制約があるのでしょうか。
238:デフォルトの名無しさん
10/07/06 02:02:43
>>237
全体の幅を増やせば仮数部は大丈夫になるが、その場合でも指数部の幅は変わらないので、指数部が問題なのでは?
239:デフォルトの名無しさん
10/07/06 20:13:16
>>237
いいよいいよ。
240:デフォルトの名無しさん
10/07/06 23:54:42
部分ピボッティング付きのガウス-ジョルダン法。これで対角要素が0でもダイジョブのはず?
SUBROUTINE GJ(a, b, n) ! Gauss-Jordan method with partial pivoting
DIMENSION a(n, n), b(n), temp(n)
DO 10 idiag = 1, n
CALL pivoting(a, b, n, idiag)
pivot = a(idiag, idiag)
DO 5 icol = 1, n
a(idiag, icol) = a(idiag, icol) / pivot
5 CONTINUE
b(idiag) = b(idiag) / pivot
DO 20 jrow = 1, n
IF (idiag .NE. jrow) THEN
q = a(jrow, idiag)
DO 30 icol = 1, n
a(jrow, icol) = a(jrow, icol) - q * a(idiag, icol)
30 CONTINUE
b(jrow) = b(jrow) - q * b(idiag)
END IF
20 CONTINUE
10 CONTINUE
RETURN
END
241:デフォルトの名無しさん
10/07/06 23:56:18
SUBROUTINE pivoting(a, b, n, k)
DIMENSION a(n, n), b(n)
temp = 0.0
ipiv = k
DO 10 i = k, n
IF (ABS(a(i, k)) .GT. temp) THEN
temp = ABS(a(i, k))
ipiv = i
END IF
10 CONTINUE
DO 20 i = k, n
temp = a(ipiv, i)
a(ipiv, i) = a(k, i)
a(k, i) = temp
20 CONTINUE
temp = b(ipiv)
b(ipiv) = b(k)
b(k) = temp
RETURN
END
メインルーチン:ただしf90機能を使用w
PROGRAM test
PARAMETER( n = 5 )
REAL a0(n, n), a(n, n), b0(n), b(n)
CALL RANDOM_SEED()
CALL RANDOM_NUMBER(a0)
CALL RANDOM_NUMBER(b0)
a = a0
b = b0
CALL GJ(a, b, n)
PRINT *, SQRT( SUM( (MATMUL(a0, b) - b0)**2 ) / N )
END
242:デフォルトの名無しさん
10/07/07 00:40:13
>>238
ありがとうございました。ようやくおっしゃる意味がわかりました。
指数の部分を2桁にしてことが原因ということですね。
納得しました。明日試してみます。
243:デフォルトの名無しさん
10/07/07 03:23:33
>>221
> 221 名前:デフォルトの名無しさん [sage]: 2010/07/03(土) 01:44:30
> >>219
> program hyoujisurudake2
> implicit none
> integer :: i, io, ip1, ip2, ip3
> CHARACTER(LEN = 80) :: text
> integer :: iprice, iyear, imonth, iday
> open(10,file='data614.txt',status='old')
> i = 0
> do
> read(10, '(a)', iostat = io) text
> if(io <= -1 ) exit !★ここです
> i=i+1
> ip1 = INDEX(text, '/')
> 中略
> end do
> close(10)
> stop
> end
-----
> 3 23456 2000 1 2
16行目の if(io <= -1 ) exit !★ここですが「-1」を「0」とか他の値にしても出ないかEnd of File のエラーになるのですが、これはUbuntu910 + gfortran だからでしょうか?
いくつを入れてもうまくいかないです
244:デフォルトの名無しさん
10/07/07 03:42:24
>>243
自己レスです
すみません データーの最後の行に「 / / , 」という空白でータ行が入っていた!
だから最後まで読むけど 終わりを過ぎてしまう というエラーが出ていた おろかしー
245:デフォルトの名無しさん
10/07/08 15:45:51
3元以上、9元までの連立一次方程式を解くプログラムをg77で作成しているんですが、なかなかエラーなしにすんなりとソースプログラムを作ることができません。
ガウス・ジョルダン法を利用して作れと指示があり、一応作ってみたのですが、エラーがいたるところに出て、エラーの内容もわからないため、訂正をお願いしたいです。
なにせFORTRANを使い始めて間もないため、超初心者でもここまでひどいソースは書かないとおもわれるほどのひどいソースかもしれませんが、どうかお願いします。
Cygwin 1.7.5-1 の fortranコンパイラを使用しています。以下、作った未完成ソースプログラムです。
real i,j,N,k,aij,bij
read(5,*) N
DO 100 i=1,N
DO 110 j=1,N
read(5,*) aij
110 continue
100 continue
DO 120 i=1,N
read(5,*) bi
120 continue
call GJ(aij,bi)
130 write(6,*) bi
end
subroutine GJ(aij,bi)
DO 130 k=1,N
akj=akj/akk
if(i=k)
aij=aij
else
aij=aij-akj*ajk
if(i=k)
bk=bk/akk
else
120 bi=bi-bk*aik
DO 130 i=1,N
return
end
246:デフォルトの名無しさん
10/07/08 20:04:08
GJのアルゴリズムは確認していないけど、とりあえず配列の作り方を確認してみ。
配列変数には()が必要。
あと、エラー内容をコピペしてみて。
247:デフォルトの名無しさん
10/07/08 20:54:40
エラーをがんばって見て作りなおしてみましたがエラーがでます。
以下、GJのサブルーチンを抜かしたソースです
implicit none
integer s,t,n,k
real a,b
read(5,*) n
dimension a(n,n),b(n)
DO 100 s=1,n
DO 110 t=1,n
read(5,*) a(s,t)
110 continue
100 continue
DO 120 s=1,n
read(5,*) b(s)
120 continue
連投になって申し訳ないですが、次にエラーのコピペします。
248:デフォルトの名無しさん
10/07/08 21:01:06
>>246
先ほど言い忘れましたが、レスありがとうございます。
全部コピペは入りきらないので最初のエラーかつ一番多い文の一つをコピペしました。
内容は、辞書で調べながらやったのですが、宣言が間違っていると言ってるように思います。
114.for: In program `MAIN__':
114.for:2:
integer s,t,n,k
1
114.for:5: (continued):
dimension a(n,n),b(n)
2
Invalid declaration of or reference to symbol `n' at (2) [initially seen at (1)]
お願いします。
249:デフォルトの名無しさん
10/07/08 22:42:33
> implicit none
> integer s,t,n,k
> real a,b
> read(5,*) n
> dimension a(n,n),b(n)
ここの部分が間違っている。
implicit none
real a(n,n),b(n)
integer s,t,n,k
read(5,*) n
と書くのが正しい配列の定義の仕方。このばあい、属性を意味する"dimension"は書かなくてok
あと注意点だけど、変数定義の途中に実行可能な文を入れてはダメ。
>>247の場合dimensionの前にreadがはいってるけど、readは変数をすべて定義した後にやる。
250:249
10/07/08 22:50:07
あ、間違えた。
配列は定義する時点でサイズが決定していないとだめなんだ。
配列サイズをreadする場合には、動的なメモリの割付けが必要で、allocatable属性を指定しなければならない。
readでnを呼んだ後、allocate文で実際にメモリを割り当てる。
implicit none
integer s,t,n,k
real,allocatable a(:,:),b(:)
read(5,*) n
allocate( a(n,n), b(n) )
251:デフォルトの名無しさん
10/07/09 00:30:22
>>250
多分質問者は、F77でかつDIMENSIONとGOTOを使えと言われている人なので、その辺を察してあげないと・・・
252:古い質問者
10/07/09 09:53:09
>>251さんの言う通りで…質問してるのに申し訳ないです。
allocatableというのは聞いたことがないので、使わずにやれということなんだと思います。
>>248,>>249を参考に最初の5行を訂正してみました。
implicit none
integer s,t,n,k
real a(n,n),b(n)
dimension a(n,n),b(n)
read(5,*) n
エラーは>>248と全く同様に出力されました。
ちなみにa,b,n,iに関して全く同様のエラーが何回も出力されています。
日をまたいでレス遅れてしまって申し訳ないです。
よろしくお願いします。
253:古い質問者
10/07/09 10:25:09
>>252
訂正:a,b,n,iに関して→a,b,iに関して
連投失礼します。
254:デフォルトの名無しさん
10/07/09 11:31:04
宣言部は全て最初にやらないといけないんだよなぁ
コード真ん中のスコープ内でローカルに宣言できたら便利なのにといつも思う
あ、でも次のFortranで実装するって話を聞いたことがあるような
次の次だっけかも
255:デフォルトの名無しさん
10/07/09 15:20:01
allocatableがつかえないと、余分にメモリを食っちゃうね。
まず、配列変数の定義の時点で
real, dimension(100,100) :: a
real, dimension(100) :: b
と、ある程度大きいメモリ容量を割り付けておいて、すべての変数に0を代入して初期化。
a(:,:) = 0.0
b(:) = 0.0
そのあとnやa,bの要素をreadすればokかな?
ここで、nは単なる繰り返し制御のための変数になるけど、まぁ仕方ないか。
256:古い質問者
10/07/09 18:29:02
>>255
real, dimension(100,100) :: a
real, dimension(100) :: b
をそのまま利用すると、Fortran 90 feature at (^) unsupported (対応してない?)といわれ、
realとdimensionを分けてa,bを定義すると
Invalid form for DIMENSION statement at (^) (dimensionの宣言形式が違う?)
とdimensionを定義する箇所にエラー
a(:,:) = 0.0
1 2
Unrecognized statement name at (1) and invalid form for assignment or statement-
function definition at (2)
a,bに関して同様のエラーがでます。。。
もはやcygwinのfortranコンパイラがダメなきがしてきました。。
何度も申し訳ないです。
257:255
10/07/09 18:49:54
いやいや、fortran90形式の方法を教えてしまった。
90形式と77形式を混ぜてコンパイルしても問題にならないことが多いから、
いいかと思ったけどだめだったみたいだね。ごめん
implicit none
integer i, j
integer s,t,n,k
real, dimension(100,100) a
real, dimension(100) b
do i = 1, 100
do j = 1, 100
a(i,j) = 0.0
end do
b(i) = 0.0
end do
read(5,*) n
Fortran77形式で書いてみた。古い書き方は全然使わないから、間違っているかも。