[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 04/11 21:43 / Filesize : 404 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

くだすれFORTRAN(超初心者用)



1 名前:デフォルトの名無しさん [2006/01/24(火) 09:48:23 ]
このスレッドは、他のスレッドでは書き込めない超低レベル、 
もしくは質問者自身何が何だが分からない質問を勇気を持って書き込むスレッドです。 
FORTRAN使いが優しくコメントを返しますが、 
お礼はFORTRANの布教と初心者の救済をお願いします。 


217 名前:デフォルトの名無しさん [2006/03/02(木) 15:41:26 ]
DO K=0,N-1

SECHYP=DBLE(1.0D0)/DCOSH((T/T0)*(DBLE(K)/DBLE(N)-DBLE(0.5D0)))

E(K)=CMPLX(EAMP0*SECHYP,0.0D0)

END DO
DO K=0,NH-1
ROU=DBLE(K)*T0/T

FRQ=PI*ROU/T0
GANMA2(K)=-H*BETA2*PI*PI*ROU*ROU/(T0*T0)
GANMA3(K)=-H*BETA3*PI*PI*PI*ROU*ROU*ROU/(T0*T0*T0)*2.0D0/3.0D0
GANMA4(K)=-H*BETA4*FRQ*FRQ*FRQ*FRQ*1.0D0/3.0D0
FQ=ROU/T0

END DO

DO K=0,20,1
EK=E(K)*CEXP(CMPLX(0.0d0,(GANMA2(K))))

EK=EK*EXP(CMPLX(0.0d0,(GANMA3(K))))

EK=EK*CEXP(CMPLX(0.0d0,(GANMA4(K))))

E(K)=EK
END DO

END PROGRAM GGGG

218 名前:デフォルトの名無しさん [2006/03/02(木) 15:47:14 ]
DO K=0,20,1
ERK=ER(K)*DCOS(GANMA2(K))-EI(K)*DSIN(GANMA2(K))
EIK=EI(K)*DCOS(GANMA2(K))+ER(K)*DSIN(GANMA2(K))

ERK=ERK*DCOS(GANMA3(K))-EIK*DSIN(GANMA3(K))
EIK=EIK*DCOS(GANMA3(K))+ERK*DSIN(GANMA3(K))

ERK=ERK*DCOS(GANMA4(K))-EIK*DSIN(GANMA4(K))
EIK=EIK*DCOS(GANMA4(K))+ERK*DSIN(GANMA4(K))

ER(K)=ERK
EI(K)=EIK

END DO

END PROGRAM GGGG

連投すみません、216,217と計算が実数か複素数かだけの違いなのですが
217ではなぜか範囲を広げるほど虚数の値がかけ離れていきます
桁落ちでもないのですが、どなたか考えられる原因を教えてくださいm(__)m

219 名前:デフォルトの名無しさん [2006/03/03(金) 12:54:26 ]
>>218
範囲を広げるという意味が良くわからんので、適当に書いてみるw

EK=E(K)*CEXP(CMPLX(0.0d0,(GANMA2(K))))
EK=EK*EXP(CMPLX(0.0d0,(GANMA3(K))))
EK=EK*CEXP(CMPLX(0.0d0,(GANMA4(K))))

この式で、EK(K)は最後に掛けたほうがいい。なぜなら、それ以外の部分は
全部位相因子なので幾ら掛けても、絶対値は1になるはずの量だから。
まずはそこでチェックしてみたらどうか?

つまり
EK = EXP(CMPLX(0.0d0,(GANMA2(K))))
EK = EK * EXP(CMPLX(0.0d0,(GANMA3(K))))
EK = EK * EXP(CMPLX(0.0d0,(GANMA4(K))))

ここでABS(EK)=1.0d0のはず(誤差を抜かして) 
もう一つの式でも同様にして、その段階で虚部を比較すれば、
より限定的な情報が得られて問題解決に近づくだろう。

EK = EK(N) * EK 
(ここで後ろのEKはpahase_factorとかの変数名にしたほうがいいと思うが
まぁ好みの問題だ)


あとCEXPは総称名EXPに統一したほうがいいだろう。
精度の規定値が気になるなるが、KIND=8をつければ強制できるはず。


220 名前:デフォルトの名無しさん mailto:sage [2006/03/03(金) 13:52:48 ]
> ERK=ERK*DCOS(GANMA3(K))-EIK*DSIN(GANMA3(K))
> EIK=EIK*DCOS(GANMA3(K))+ERK*DSIN(GANMA3(K))

とあるけど、一行目で、ERKを書き換えてしまってはダメじゃないの?



221 名前:デフォルトの名無しさん [2006/03/03(金) 15:40:33 ]
>>220
実数、虚数にわけてる計算はあっているので、ただしいはずです・・・


222 名前:デフォルトの名無しさん [2006/03/03(金) 16:13:32 ]
>>219
ありがとうございます、試してみます
EK=EXP(CMPLX(0.0d0,(GANMA2(K)),8))
といった感じで精度をあわせてしまえばいいんですよね?


223 名前:デフォルトの名無しさん [2006/03/03(金) 18:07:37 ]
>>221
いや、1行目でERKが書き換わっているので、正しいとは思えない。
その2行で1つの計算のはずだから、虚部を求める時に新しくなった実部を
使ってはいけない。

これで正しいとすると、二つが一致しないのは当然。
ただこれが正しいことはまずありえないと思う。



224 名前:デフォルトの名無しさん mailto:sage [2006/03/03(金) 18:11:08 ]
>>221
いや、式はあってるんだけど、1行目でreal partを計算する際に、
元の変数のreal partを書き換えてしまっているのでは?
2行目の右辺に出てくるERKはもはや元の変数のreal partではないないと思うけれど。


225 名前:デフォルトの名無しさん mailto:sage [2006/03/03(金) 18:11:51 ]
かぶったw



226 名前:デフォルトの名無しさん mailto:sage [2006/03/03(金) 18:15:59 ]
式があっているってのは、実部虚部への分け方はあっている、ってことね。
そのプログラムは変だと思うよ。


227 名前:デフォルトの名無しさん [2006/03/03(金) 22:14:06 ]
>>223~226
気づかなかった;;;サンクスです。

228 名前:デフォルトの名無しさん [2006/03/07(火) 22:19:56 ]
もりあげようぜ!w

229 名前:デフォルトの名無しさん mailto:sage [2006/03/07(火) 23:26:03 ]
盛り上げようにも大学が春休みで宿題がない予感。

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を求める

ということなのだろうけど
・初速度や初期位置は既知なのか、自分で決めるのか、ファイルから読み込むのか
・データファイルの書式は?
など不明な点があるのでこれ以上は自分でおやりなさい。

いずれにせよ情報を小出しにされたのではエスパーでもない限り「本当にわかりません」。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](;´∀`)<404KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef