くだすれFORTRAN(超 ..
259:デフォルトの名無しさん
08/04/23 23:54:16
>>255
Fortranはスピード優先なので、配列のはみだしは普通チェックしない。
コンパイラの実行時オプションでチェックするように出来るのが普通だが、あくまでデバッグ用の位置づけ。
今の場合、配列をはみだして他の変数を上書きしている可能性が高い。
MAPオプションでメモリー上に変数がどうアロケートされているかを調べれば、どの変数が壊されているか
見当がつく。
>>257
そういう関数はFortranの標準には無い。
今の場合、ATAN(y/x)よりもATAN2(y、x)を使うほうが適切、X=0.0の場合の0割エラーなどを避けられる。
詳しくはマニュアル味噌。
>>258
素直に前後左右斜めを調べるしかないべ。
DO i=-1,1
DO j = -1,1
CALL check(ix + i, iy + j)
END DO
END DO
枡をはみだす端っこの処理を簡素化するには、配列を0〜9までで宣言して端っこマスは
別途の方法で処理するとかできる。空=0、白=1、l黒=2、マスの外=−999とか。
260:デフォルトの名無しさん
08/04/24 09:51:47
>>259
atan2なんてあったんですね!ありがとうございました。
261:デフォルトの名無しさん
08/04/24 17:00:17
form指定子のunformattedとbinaryはどちらが推奨とかあるんですか?
unformattedは機種依存みたいだから、やっぱりbinary?
「Fortranのunformatted=バイナリ」と勘違いしてる人もたまに見かけますが
確かに紛らわしいところだと思いますが、どういう経緯でそういう仕様になったのだろう・・・
262:デフォルトの名無しさん
08/04/24 23:52:06
>>261
普通に数値ファイルなどをシーケンシャルに読み書きするなら UNFORMATTED のほうがいいと思う。
ここでUNFORMATTED の SEQUENTIAL FILE は、改行コードが入っている。
DIRECT ACCESS の場合はベンダー依存だが、トランスパレントにべた書きされていることが多いと思う。
本来はランダムアクセスのためのファイル形式だが、レコード長を1BYTEに指定して順繰りに読んでゆく
ことで binary の代用に出来ることが多い。
昔のマンガや映画でコンピュータがガタガタ磁気テープをアクセスしているのは、DIRECT ACCESS で
ランダムアクセスしてデータを読み出しているところと思われる。
binary は、本当に改行コードなども含めてトランスパレントな生のデータが欲しいときに使うものなので
UNFORMATTED と直接比較されるものではないと思う。
ついでにいうと binary は Fortran2003 で導入される規格で、Fortran95までではコンパイラー側の拡張になっているはず。
歴史的には、文字コードも、数値フォーマットも、1ワードのビット数も機種依存だったので、
UNFORMATTED を機種依存と責めるのは可哀想です。
たとえていうなら、『僕の肛門もEBCDIC(K)をぶち込まれそうです(><;』といった感じ。
263:デフォルトの名無しさん
08/04/25 10:39:23
改行コードって、一行のバイト数合計値を一行の前後にサンドイッチするやつだよね?
od -t x4で覗いたら、この値って4バイトだけど、これだと一行4Gバイトまでしか書けないことにならない?
264:デフォルトの名無しさん
08/04/25 11:14:27
>>263
処理系依存だろうけど、今まで一語4バイトが主流だったから、そのくらいなんじゃない。
10年位前まではスパコンでも1配列のMaxが4Gだったし。
265:デフォルトの名無しさん
08/04/25 15:07:14
>>264
そっか
でもそろそろ拡張してもいいような
266:デフォルトの名無しさん
08/04/26 23:34:36
アナル拡張
267:デフォルトの名無しさん
08/04/28 13:05:57
*
268:助けてください
08/04/29 14:17:32
あの〜私FORTRAN90初心者なんですが、ガウスの消去法のプログラムを作りたいのですが、
どなたか簡単に作っていただけないでしょうか?
ちなみに格子点の間隔は0.25で格子点9個です。
時間が無いので本当にお願いします。
269:助けてください
08/04/29 14:51:02
マルチポストしています。
270:デフォルトの名無しさん
08/04/29 16:05:54
>>268 ググレカスでございます
URLリンク(www.tnb.sd.kanagawa-it.ac.jp)
271:デフォルトの名無しさん
08/04/29 19:02:53
複素数のべき乗の計算はどのようにすればいいのでしょうか
272:デフォルトの名無しさん
08/05/01 00:52:00
>>271
複素数の実数べきか?実数の複素数べきか?
273:デフォルトの名無しさん
08/05/01 10:28:55
いえ10の100乗のタンジェントです
274:デフォルトの名無しさん
08/05/06 01:05:31
行列を作って対角化するプログラムを作っています。
行列を作るプログラムが動いたので
それをサブルーチンに入れると
コンパイルできるのですが、実行すると
Segmentation fault (core dumped)のエラーが出ます。
行列の大きさは1000×1000です。
試しに行列のサイズを小さくすると350×350では動きました。
使ってるOSはvistaでcygwin上でg77でコンパイルしています。
メモリは2Gです。
行列サイズを大きいままで動かすことはできないでしょうか?
275:274
08/05/06 01:07:44
行列を作るプログラムは
1000×1000でもちゃんと動きます。
276:デフォルトの名無しさん
08/05/06 03:06:32
>>274
これだけでは、なんとも言えんなw
g77だから動的にメモリー取ったりはしていないんだろうし?
とりあえず、
-fbounds-check
-ffortran-bounds-check
この辺のオプションで配列はみだしチェックを。
もう少しヒントを呉。
たとえば行列は実対称の単精度の密行列で、ライブラリはLAPACK、呼んでるルーチンは、某。
呼び出し行は
CALL xxxxx(xxxxxx)
使用変数の宣言行は、カクカクしかじか
REAL H(1000, 1000), xxxxxxxxxxxx
ぐらいあるとありがたい。
277:274
08/05/06 04:16:04
>>276
-fbounds-check
をオプションにしてコンパイルしたらエラーは出ませんでした
コンパイルしてできたexeを実行したら
Segmentation fault (core dumped)のエラーが出ました
配列のはみ出しチェックのしかたがよくわからないのですが
これでいいんですかね?
あと行列は実対称の倍精度です。
今は対角化する以前の段階でプログラムは以下のような感じで作っています。
implicit none
integer m
parameter (m=1000)
real*8 a(m,m)
・・・
call matrix(a,m,mm ・・・)
write(*,*) mm
(mmは実際に行列が書かれている行数)
stop
end
subroutine matrix(a,m,mm ・・・)
implicit none
integer m, mm, ・・・
real*8 a(m,m), b(m,m), ・・・
・・・
(行列を作る)
return
end
278:274
08/05/06 04:22:23
上のようなプログラムです。
subroutineに入れなければm=2000でもきちんと動いたのですが
入れるとコンパイルはとおりますが
実行するとSegmentation fault (core dumped)のエラーが出ます(上に書いたとうりです)
このくらいの情報でよろしいでしょうか?
足りないのなら付け足します。
よろしくお願いします。
279:274
08/05/06 17:18:06
自己解決しました。
subroutine の中の大きい行列(>>277のa(m,m)、b(m,m)など)全部を
メインプログラムので定義してやるとm=1000でも動きました。
subroutineの中にだけでかい行列を何個も定義したらダメなんですね。
知らなかった。
280:デフォルトの名無しさん
08/05/06 18:48:57
>>279
それは多分スタックオーバーフローだな。
g77エラーメッセージは不親切だな。
281:デフォルトの名無しさん
08/05/06 19:02:33
>>277
よく分からないのだけど mm はメインで定義しなくてイイの?
282:274
08/05/06 21:25:45
>>280
スタックオーバーフローと思います。
今まででかい行列はメインで定義しないと
スタックからあふれるということを知らなかったです。
>>281
すいません、メインでmmは定義してます。
283:281
08/05/06 22:25:27
下のコードを g77 でオプション無しでコンパイルした時も
-ffortran-bounds-check を付けてコンパイルした時も
正常に動作したけど。もぅワカリマセン。
program call_matrix
implicit none
integer m ,i ,j
parameter (m=1000)
real*8 a(m,m)
call matrix( a, m )
do i = 1, m , 1
do j = 1, m , 1
write(*,*)"a(",i,",",j,")=",a(i,j)
end do
end do
stop
end program call_matrix
subroutine matrix( a, m )
implicit none
integer m, i,j
real*8 a(1:m,1:m), b(1:m,1:m)
do i = 1, m , 1
do j = 1, m , 1
a(i,j) = dble( i+j )
b(i,j) = dble( i*j )
end do
end do
return
end subroutine matrix
284:274
08/05/07 04:21:21
>>283さんのプログラムをg77でオプション無しでコンパイルして実行したところ
Segmentation fault (core dumped)のエラーが出ました。
mの値を変えてコンパイルして実行を繰り返したところ
m=509以上だとSegmentation fault (core dumped)のエラーがでます。
何か異常があるんですかね?
関係あるかどうかわかりませんがcygwinで ulimit -a を実行した結果を下に書きます。
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 2033
cpu time (seconds, -t) unlimited
max user processes (-u) 63
virtual memory (kbytes, -v) 2097152
285:デフォルトの名無しさん
08/05/07 09:54:02
>>284
509 * 509 * 8byte(倍精度) = 2,072,648 なので virtual memory の
MAX超えてるのかもしれんな。Cygwin はよく知らんが、こんな小さい初期値なのか?
286:285
08/05/07 09:55:53
ごめんw
よく見たら単位が kbytes だったw
だからメモリーはまだ余裕だwwwwww
287:281
08/05/07 12:09:31
コンパイラを変えてみたらどうでしょうか?
g95 と gfortran くらいしか思いつきませんが。
288:デフォルトの名無しさん
08/05/07 16:16:23
配列サイズを引数で渡さずにサブルーチン内で定義すれば?
んで、common 文をつかって、コンパイラに
「いちいちallocateしなくてもいいよ」と教えてあげる。
「common文は使っちゃだめ教」があるのは知ってるけど
試してみてちょ。
289:288
08/05/07 16:16:54
program call_matrix
implicit none
integer m ,i ,j
parameter (m=1000)
real*8 a(m,m)
common /gyouretu/ a ! <-- ここ加えた
call matrix( ) ! <-- ここ変えた
do i = 1, m , 1
do j = 1, m , 1
write(*,*)"a(",i,",",j,")=",a(i,j)
end do
end do
stop
end program call_matrix
subroutine matrix( ) ! <-- ここ変えた
implicit none
integer m
parameter (m=1000) ! <-- ここ加えた
integer m, i,j
real*8 a(1:m,1:m), b(1:m,1:m)
common /gyouretu/ a ! <-- ここ加えた
do i = 1, m , 1
do j = 1, m , 1
a(i,j) = dble( i+j )
b(i,j) = dble( i*j )
end do
end do
return
end subroutine matrix
290:288
08/05/07 16:19:57
あと、関係なとは思うけど多重ループはこの例の場合、
ループ制御のincrementalの整数は
内側をi
外側をj
にする習慣を付けていた方が良いよ。知ってたらごめん。
291:288
08/05/07 16:25:02
コンパイル通らなかったw
サブルーチンの中でmを2回定義しているから後のはとってね。
自分の所の g77 on linux (バージョン不明) だと動いたよ。
がんばってね。
292:288
08/05/07 16:48:44
更にお節介。
parameter文で定義した変数を
subroutineの引数に使うのはよした方が良いよ。
・・・・ cygwin 最近使ってないなぁ。
274さんはhostのOSは何?もうvistaに対応してる?
293:デフォルトの名無しさん
08/05/07 18:10:04
OS :Windows Vista
gfortranをインストールしてコンパイルしようとしたのですが、
下記のようなメッセージが出てコンパイルできません。
ld: crtbegin.o: No such file: No such file or directory
どうすれば、コンパイルできるようになりますか?
294:293
08/05/07 18:20:36
下記のページを参考にして、コンパイルを行いました。
URLリンク(www.esst.kyushu-u.ac.jp)
295:デフォルトの名無しさん
08/05/07 18:41:31
>>293
可能性は3つある。
インストールしたバイナリに問題がある。
インストール方法に問題がある。
コンパイルしようとしたプログラムソースに問題がある。
あとは任せた。君なら出来る。
296:281
08/05/07 19:11:08
>>292
> 更にお節介。
> parameter文で定義した変数を
> subroutineの引数に使うのはよした方が良いよ。
ココ詳しく。実はよくやってます。
297:293
08/05/07 19:35:54
>>295
g95をインストールしてコンパイルしたら、できました。
ありがとうございました。
298:デフォルトの名無しさん
08/05/08 11:51:23
>>296
281さんが例として出したプログラムだと問題ないんだけど、
何かの拍子にサブルーチン内でmの値を変更してしまう場合にややこしい。
おおざっぱに言って、メインレベルで定義された固定変数はコンパイラによって
m = 1000 の代入処理+メインレベルでmが変更されていないかを監視するだけか、
前処理の段階でメインレベルでの変数mを1000に置き換えるかのどちらかをするんだけど
前者の場合、副プログラムで値が変わる場合までチェックしないので面倒。たとえば
parameter(m=1000)
call foo(m)
write(*,*) m
で副プログラムfoo中でm=1という代入文があるばあいに結果が保証されなくなっちゃう。
出力はコンパイラによって1000だったり1だったり、浮動小数点なら値がエンディアンレベルで壊れていたりする。
ぜったいmを副プログラムで変えない(intent文でチェックするとか)ならいいけど、
習慣として引数渡しせずに副プログラムでも
parameter(m=1000)と定義してやった方が安全。
mの値の変更はたいていのエディタなら一括置換で出来るしね。
あるいはm2=mとかして非固定変数に値を移してからそれを引数にするとかすると良いと思う。
似た理由で
do i = 1, 100
call foo(i)
enddo
みたいにループ制御の(整数)変数も引数に使わない方が安心。
あくまで「安心と安全」という気分の問題だけどね。コードが大きくなるとデバッグするときに
こういう部分ががボディブローよろしく効いてくるので。老婆心。
299:デフォルトの名無しさん
08/05/10 18:09:15
100×100くらいの大きな対称行列の逆行列を求める方法を探しています。
どのような方法が一番精度が良いでしょうか?お知恵をお貸し頂ければ幸いです。
300:デフォルトの名無しさん
08/05/10 20:46:45
>>299
対象の行列に因ると思う。実対称とか色々。
私は考えるのがメンドーなので lapack に丸投げしてるが。
301:デフォルトの名無しさん
08/05/10 20:59:38
lapack 丸投げでいいと思う。
lapack は誤差減らす工夫してたと思うし。
対称行列なら対角化を経由する方法がいいかと。
数値誤差で対称性がくずれるなんてこともないし。
三角行列で扱うから。
302:デフォルトの名無しさん
08/05/11 22:23:14
やっぱ極力ライブラリ使うべきだよね
大抵のはあるし
303:デフォルトの名無しさん
08/05/12 01:02:12
Fortranでは何次元配列で何要素数あつかえるのでしょうか。
メモリとCPUによる?
ちなみにFloatの4次元で、130559044000個(1ファイルで50GBのデータサイズ)を処理したい。
304:デフォルトの名無しさん
08/05/12 01:16:18
確実にメモリには載らない。
1. 小出しに処理する
2. 圧縮する
のどちらかになるな。
305:299
08/05/12 04:37:39
300,301,302さん、レスどうもありがとうございます。
自分の素人っぷりが恥ずかしい限りなのですが
扱う行列が倍精度でもLAPACKで大丈夫でしょうか?
何はともあれ、試行錯誤してみます
306:助けてください
08/05/13 13:59:50
今FORTRANで「ガウスの消去法のプログラムを作れ」とのことなのですが、サブルーチンを
使ったプログラムが作れません。ALLOCATABLEを使ったプログラムなら作れたのですが、誰か
ひとつ例として作って頂けませんか?お願いします。
307:デフォルトの名無しさん
08/05/13 16:29:56
>>306
宿題スレではないぞよ。
308:デフォルトの名無しさん
08/05/13 16:48:18
では宿題スレを紹介してください
309:299
08/05/13 19:27:04
>>305
DSYTRF、DSYTRIを使ったのですがうまくいきませんでした ...orz
310:300
08/05/13 19:47:51
>>309
DSYSV で B = 単位行列ってしたらダメ?やったコト無いけど(私は固有値問題しか解かないし)。
上手くいかないというなら何が可笑しいか。INFO の値は? 多くの場合、INFO=0 は正常終了の筈。
man を見る限り、DSYTRF は目的に合ってないように思うが、それはきっと私の気のせいだ。
ということで、もちっと何か晒せません?(差し障りの無い範囲で)
311:デフォルトの名無しさん
08/05/13 23:47:10
>>310
丁寧な指導ありがとうございます。
いま扱っている対称行列Aは倍精度で、次元が40×40です。
各要素の値には8桁ぐらいのバラつきがあります。
DSYSVでAX=EとなるようなXを求めて、その後実際に
matmulでAXの積を計算して出力しているのですが
対角部分以外の値が全く0に近づきません。
infoは0で出てきてます。
WinXp、cygwin、g95でやってます。これがまずいのでしょか
312:300
08/05/14 00:21:48
>>311
dsysv() から出た後の A が最初の A のままという保証は無いような。その所為では?
つまり dsysv() の中で A の中身が書き変わっている可能性がある。
だとしたら AX =E が成立しなくても可笑しくはない。
313:デフォルトの名無しさん
08/05/14 00:29:11
説明不足ですみません。
DSYSVにはAをコピーしたA'を入力しています。
matmulには元のAを使っています。
314:300
08/05/14 00:41:25
B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
On entry, the N-by-NRHS right hand side matrix B. On exit, if
INFO = 0, the N-by-NRHS solution matrix X.
だから、実行前に A のコピーを取って(C とでもする)、実行後に B と C の積を見れば?
やってみたら A の中身変わってた。あと (2,2) の実対称でやったら、ソレっぽい結果が出てた。
まぁアレだ、頑張れ。
315:313
08/05/14 02:03:19
>>300
アドバイスどうもありがとうございまs。
もすこし頑張ってみます
316:名 無し
08/05/14 18:06:09
質問があります。
linux上でFortran77を使えるようにするにはどうすればいいのですか?
何かインストールすべきコンパイラがあったりしたら教えて下さい。
317:デフォルトの名無しさん
08/05/15 00:00:21
>>316
大抵のディス鳥はg77が含まれているだろうから
$ which g77
で見つからなかったら
# yum install gcc-g77
とか
# apt-get install gcc-g77
とか
# yum install compat-gcc-34-g77
みたいな感じで。
318:名 無し
08/05/15 15:47:37
>>316
$ which g77で見つかったんですけど開けませんでした・・・
319:デフォルトの名無しさん
08/05/15 17:24:18
>>318
which g77 で見つかったなら、Fortran77が使える準備が出来てるってことよん。
g77は開くものじゃない。
320:デフォルトの名無しさん
08/05/15 21:15:39
fortranってブール型ないんですか?
321:デフォルトの名無しさん
08/05/15 21:21:57
>>320
つ LOGICAL
322:デフォルトの名無しさん
08/05/16 09:03:44
>>321
あったんですか、失礼しました
今まで0、1をfalse、trueとしてやってて、なんかかっこ悪いなぁと思ってまた。というか危険ですよね
ありがとうございました
323:デフォルトの名無しさん
08/05/17 21:46:14
初歩的な質問で申し訳ないのですが。
資料を読み込む時、上からのn行が全ていりません場合はどうすればいいのですか?
僕はこう考えますが:
open(unit=10,file=filename,access="sequential",status="old")
do while( .true. )
read(unit=10,fmt="???",iostat=status)
???のところをいじればいいのですか?
それとも何か他の書き方にした方がいいのですか?
324:デフォルトの名無しさん
08/05/17 22:37:39
>>323
DO i = 1, 10
READ(10, *)
END DO
325:デフォルトの名無しさん
08/05/19 12:50:03
DO i = 1, 10
READ(10, *)
END DO
はどこに入れますか?
これで10行までの資料が読まれるけど保存されてないですよね?
僕はn行まではいらないけが、
n+1以後の資料はちゃんと読まれて配列に保存したいんです。
326:デフォルトの名無しさん
08/05/19 19:09:07
fortran90で、ターミナルへの出力を一旦停止して、
例えば1分後に再開するという感じにしたいのですが
これは pause を使ってできますか?
pause だけだと、何か入力しないと再開しないのですよね?
僕は1分後に自動的に再開したいんです。
327:デフォルトの名無しさん
08/05/20 00:44:47
>>325
DO i = 1, n
READ(10, *)
END DO
DO
READ(10, *, IOSTAT = io) a, b, c
IF (io == -1) EXIT
END DO
io = -1 は End of File
>>326
Fortranの規格の範囲内では基本的には無理。
空ループをまわして、DATE_TIMEで時間を監視してやれば出来ないことは無い。
しかしCPUが無意味に使われるのでお勧めできない。
ただコンパイラの多くは SLEEP() 関数等を用意しているので、マニュアルのコンパイラ独自拡張の所を
よく読めば出来る可能性が高い。またはライブラリなどの外部ルーチンを呼ぶという方法も無くは無い。
難易度はやや高い。
328:デフォルトの名無しさん
08/05/20 09:35:10
>>326、>>327
call system( ' sleep 60 ' )
ってダメかな?
329:デフォルトの名無しさん
08/05/20 10:37:59
>>327, 328
どうもありがとうございます。がんばってみます。
330:デフォルトの名無しさん
08/06/02 20:31:19
ファイルをEOFまで読む場合、read文にend=99とかして飛ばすようにすればできますが、
行番号使うのはあまりスマートじゃないし、基本的に使うべきじゃないですよね。
他の方法ってないでしょうか?
331:デフォルトの名無しさん
08/06/03 01:00:15
>>330
>>327に出ている。
IOSTATの番号は機種依存だが、EOFの-1は確定と見ていい(これが規格に定められて
いるのか、慣習なのかよく分からんw)
それと行番号差別はよくない。行番号だっていい子なんだw
使いたいときは使うがいい。
あとFortran2003では、定数としてEOFやEOL等が定められている。
332:デフォルトの名無しさん
08/06/03 17:31:23
fortranってスコープ内のローカル変数とかって作れないんすかね?
333:デフォルトの名無しさん
08/06/03 18:48:12
>>332
サブルーチン化する
334:デフォルトの名無しさん
08/06/03 22:12:51
NaN を代入したいときってどうしたらいいですか。
たとえば function を作るとき、定義域外の引数を受け取ると NaN を
返すようにしたいんです。
ゼロで割り算すると NaN が返るけど、コンパイラによってはエラーや
警告が出るのでそれは避けたい。
335:デフォルトの名無しさん
08/06/04 00:47:24
>>334
PROGRAM NAN
IMPLICIT NONE
REAL(4) :: a
! 12345678901234567890123456789012
a = TRANSFER(B'01111111100000000000000111111110', 0.0)
PRINT *, a
STOP
END PROGRAM NAN
a には NaN が入る。NaN は指数部が全ビット立っていて、仮数部が0以外なので
単精度の場合はこれでいい。endian の違いによらないように左右対称にしてみたw
TRANSFER関数を使えば任意の型の中に任意の型での値を入れられるので
それを用いればよい。ここでは2進表現の整数を入れたが、別に文字列とかでもいいので、
たとえば倍精度で64こ0と1を並べる必要も無い。
336:デフォルトの名無しさん
08/06/04 00:51:54
>>332
Fortranではスコープ内のローカル変数は無い。
というかスコープという概念は無い。
もともとのFortranは暗黙の型宣言がなされているので、宣言にこだわる必要は無い。
一方Fortran90以降では、ALGOL/Pascal/Modulaの系列の影響を受けたので、
宣言部はプログラム頭部に集中される。
スコープなどは忘れて、早く暗黙の型宣言を信仰するんだ。
最近の言語では型宣言の省略が流行り始めているので、一周遅れでTopに立てるww
337:335
08/06/04 00:57:48
補足
PROGRAM NAN
IMPLICIT NONE
REAL(4) :: a
REAL(8) :: d
a = TRANSFER(-1_4, a)
d = TRANSFER(-1_8, d)
PRINT *, a, d
STOP
END PROGRAM NAN
実行結果 by Intel Fortran
NaN NaN
Press any key to continue . . .
ここで -1_4 と -1_8 はそれぞれ4バイトと8バイトの整数の -1 。
2の補数表現なので整数の -1 は全ビット立ってる。
338:334
08/06/04 07:51:04
>>337
ありがとうございます。やってみます。
助かりました
339:デフォルトの名無しさん
08/06/05 18:46:57
character*3 str
str='ABC'
print *,str(1:1)
とすると、Aが出力されますが、
character*3 str(1)
str(1)='ABC'
print *,str(1:1)
とすると、ABCが出力されます。
これはどういう仕組みでこうなるんでしょうか?
characterは文字の配列で実現されているんですよね?
340:デフォルトの名無しさん
08/06/05 21:19:30
後者だと str は大きさ1の1次元配列で、配列の各要素は長さ3の文字列。
341:デフォルトの名無しさん
08/06/06 00:24:53
>>339
>characterは文字の配列で実現されているんですよね?
ちがう。
それはCとかのやり方。
character*3 str(1)
これは>>340が書いているように長さ3の文字型の全要素数1の配列の宣言。
そこでやりたいことは、これで実現される。
PRINT *, str(1)(1:1)
むろん
PRINT *, str(1:1)(1:1)
でも同じこと。
部分文字列は定数でも指定出来る。
print *, 'abe-san'(1:3)
これは
abe
を出力する。
マニュアルをよく読み返すことをおすすめする。
Fortran90では文字列操作の便利な関数が増えたので読み甲斐ある。
342:339
08/06/06 21:33:39
>>340,341
ありがとうございます。Cとは違うんですね。
Fortranって文字処理苦手な印象持ってましたが、最近は違うんでしょうかね
343:デフォルトの名無しさん
08/06/07 02:04:05
FORTRAN90の質問です。
初心者なので課題が手につきません。お願いします。
「うるう年のプログラム」
「2次方程式の判定プログラム」
344:デフォルトの名無しさん
08/06/07 04:00:31
>>343
Fortran ResQ 閏年
fortran 方程式の実数解
でググレ
345:デフォルトの名無しさん
08/06/07 11:14:49
>>343
先生に聞けよ、授業料払ってるんだろ。
346:デフォルトの名無しさん
08/06/08 01:32:43
>>343
うるう年の方。結果を確認していないw
PROGRAM leap
IMPLICIT NONE
INTEGER :: iy
LOGICAL :: qleap
PRINT *, 'INPUT YEAR'
READ *, iy
qleap = .FALSE.
IF ( MOD(iy, 4) == 0 ) qleap = .TRUE.
IF ( MOD(iy, 100) == 0 ) qleap = .FALSE.
IF ( MOD(iy, 400) == 0 ) qleap = .TRUE.
IF ( qleap ) THEN
PRINT *, 'LEAP YEAR'
ELSE
PRINT *, 'ORDINARY YEAR'
END IF
STOP
END PROGRAM leap
347:デフォルトの名無しさん
08/06/08 01:42:58
>>343
二次方程式の分類
一切チェックをしていないw 英語は適当www
PROGRAM quadratic_eq
IMPLICIT NONE
REAL :: a, b, c, d
PRINT *, 'INPUT A, B, C OF A QUADRATIC EQUATION AX**2 + BX + C = 0.'
READ *, a, b, c
d = b**2 - 4.0 * a * c
IF ( a == 0.0 ) THEN
IF ( b == 0.0 ) THEN
IF ( c == 0.0 ) THEN
PRINT *, 'UNDETERMINABLE' ! a=0, b=0, c=0
ELSE
PRINT *, 'INCONSISTENT' ! a=0, b=0, c/=0
END IF
ELSE
PRINT *, 'ONE NON-DEGENERATE SOLUTION' ! a=0, b/=0
END IF
ELSE
IF (D > 0.0) THEN
PRINT *, 'TWO REAL SOLUTIONS' ! D > 0
ELSE IF (D < 0.0) THEN
PRINT *, 'TWO COMPLEX SOLUTIONS' ! D < 0
ELSE
PRINT *, 'TWO-FOLD DEGENERATE SOLUTIONS' ! D = 0
END IF
END IF
STOP
END PROGRAM quadratic_eq
348:デフォルトの名無しさん
08/06/08 02:39:33
>>346
オマエさん、凄くいい奴。改訂ユリウス暦ってのもあるんだな。
(第三条件:西暦年を900で割った余りが200または600になる年は閏年)
出題者は、グレゴリオ暦と正確に指示しているんだろうか?
「明治31年勅令第90号に基づき閏年を判定するプログラムを作成すること」
というマニアックな教師がいたら嫌だな。
349:デフォルトの名無しさん
08/06/08 02:51:19
>>347
IF の分岐、上手いね。不定・不能まで判定してやるとは、さすが。
EPS で0判定したいところだが、READ なら不要かな?
350:デフォルトの名無しさん
08/06/08 02:57:12
BASICかと思ったぜ
FORTRAN90なのか
351:デフォルトの名無しさん
08/06/08 02:59:14
>>347
追加演習問題として、次のようなのはどう?
「数学的には重解になるが、自らのプログラムで重解と判定されない
二次方程式の係数を一例あげよ。」
352:デフォルトの名無しさん
08/06/08 03:00:47
>>350
PRINT とあるとBASIC っぽいが、宿題レベルなら十分だろうね。
353:デフォルトの名無しさん
08/06/08 04:17:23
>>351 ぐはw
0.1 2 1.0 で既に重根判定が崩れているw 0.125 2.0 8.0 とか二進法での有理数なら大丈夫なんだがw
a==0.0の類もどうかと思ったが、EPSILONとか使うと初心者らしくないかと思ってチョンボしたが、
Dは掛け算の後の引き算があるから避けられないなw
PROGRAM quadratic_eq
IMPLICIT NONE
REAL :: a, b, c, d
WRITE(*, *) 'INPUT A, B, C OF A QUADRATIC EQUATION AX**2 + BX + C = 0.'
READ(*, *) a, b, c
d = b**2 - 4.0 * a * c
IF ( a == 0.0 ) THEN
IF ( b == 0.0 ) THEN
IF ( c == 0.0 ) THEN
WRITE(*, *) 'UNDETERMINABLE' ! a=0, b=0, c=0
ELSE
WRITE(*, *) 'INCONSISTENT' ! a=0, b=0, c/=0
END IF
ELSE
WRITE(*, *) 'ONE NON-DEGENERATE SOLUTION' ! a=0, b/=0
END IF
ELSE
IF (D < EPSILON(0.0) ) THEN
WRITE(*, *) 'TWO-FOLD DEGENERATE SOLUTIONS' ! D = 0
ELSE IF (D > 0.0) THEN
WRITE(*, *) 'TWO REAL SOLUTIONS' ! D > 0
ELSE
WRITE(*, *) 'TWO COMPLEX SOLUTIONS' ! D < 0
END IF
END IF
STOP
END PROGRAM quadratic_eq
354:デフォルトの名無しさん
08/06/08 04:27:57
0.1 2 1.0 →0.1 2.0 10.0 の間違いw
PRINT * はデバッグの時使うと便利。
普通のコンソール出力をWRITE(*,*)で書いておけば、後からデバッグ用出力を消し忘れることが無い。
READ * もたまに便利。
一応、宿題なので初心者っぽく、ちぐはぐなところを演出してみましたw
>>348
グレゴリオ暦のうるう年のアルゴリズムを確認しにWikipediaを見たときに、下のほうに改訂ユリウス暦と
いうのがあったので嫌な予感がしたがw やはりそう来ますかw
355:デフォルトの名無しさん
08/06/08 06:10:32
>>353
ダメじゃん、学生さんに考えてもらわないとw
初心者だと整数と決め込んでしまいがちだから、
試行錯誤してもらえるかなと。
「丸め誤差に対する考察と、プログラム改良とその改善効果の提示」
A4一枚にまとめてもらえると、講師冥利につきるね。
学年に数人はそういう学生さんがいてほしいな。
不能・不定は、数学的な気配りがないと見過ごしがちだから、
考慮していない学生さんもいるだろうね。
丸め誤差は、数値計算の経験がないと気付かないから、
IF文を習ったばかりなら配慮できっこないねw
356:デフォルトの名無しさん
08/06/08 06:18:01
>>353
さらに追加演習問題(表現は曖昧)として、次のようなのはどう?
「この二次方程式に解がある場合、その解を出力するように改造せよ。
相異なる二つの実数解をもつ場合、
数学的な厳密解と出力した実数解との誤差が大きい
二次方程式の係数を一例あげよ。」
倍精度実数型や計算手順配慮の必要性を
学生さんに感じてもらえるかな。
357:デフォルトの名無しさん
08/06/08 16:42:46
丸め誤差ってコンパイラオプションによっては違った結果になるよね
あんま気をつけたことはないけど、精度命な人はその辺も考えてるのかな
358:デフォルトの名無しさん
08/06/08 18:45:04
文を改行後も続ける場合、&を行末に付加するって仕様、早く直らないかなぁ。
面倒で仕方ない。
359:デフォルトの名無しさん
08/06/08 20:57:27
>>358
?
昔のように頭の方に継続記号を入れろってことか?
360:デフォルトの名無しさん
08/06/08 21:34:06
考えようによってはCみたいに文末ごとに ; を付けるよりよっぽどお手軽だぞw
361:デフォルトの名無しさん
08/06/08 22:06:47
>>358
Fortran文法は行番号があって,しかも予約語がない
end
= 1 +
end
print *,
end,
end;
end
とか
do
10
do=
10,
10
10
end
do
end
いや聞くだけでわくわくする文法ですね
362:デフォルトの名無しさん
08/06/09 00:42:13
PASCALとかCとかって終端文字;を書くのがめんどくさくて死にそう
FORTRANはやっぱイイナと思うよ。
363:デフォルトの名無しさん
08/06/10 12:04:01
Fortran77の質問です。初心者なので次の課題がでてよく分かりません。お願いします。
「フィボナッチ数列を配列f()とDo文を使って計算させ、30項までの結果を8i8の書式で出力せよ。
「日本で現在の流通通貨は1万円札から1円玉まで9種類ある(2千円札を除く)。
5桁の金額 kin を最も少ない枚数でそろえるには、それぞれ何枚になるか出力する。
貨幣9種の額はファイル kahei.txt から読み込む。出力の書式は○○yen ○○mai.」
364:デフォルトの名無しさん
08/06/10 17:28:54
>>360
文が複数行に渡るなんてよくあるし、Cみたいな;のほうが良いと思う俺はFortraner失格ですか?
最近遊びでVSのC#を触ったが、色んな意味で感動したw
他の言語触るのはなかなかイイもんですな
365:デフォルトの名無しさん
08/06/10 18:11:18
>>363
フィボナッチらしき(間違えている)ものを作った。
宿題に合わせて、間違えを修正しろ。
program main
integer f(10)
f(1)=1
f(2)=1
do 10 i=3,10
f(i)=f(i)+f(i)
10 continue
write(6,'( 8i8 )') (f(j),j=1,10)
end
366:デフォルトの名無しさん
08/06/10 18:48:57
>>363
とりあえず入出力はつくった。
計算式をよく考えろ。
program main
integer kahei(9)
integer kin
open (1,File='kahei.txt')
do 10 i=1,9
read(1,*) kahei(i)
10 continue
print *, "input kingaku"
read *, kin
do 20 i=1,9
write(6,'( i5, "yen ", i1, "mai" )') kahei(i), kin/kahei(i)
20 continue
end
kahei.txt
10000
5000
1000
500
100
50
10
5
1
367:デフォルトの名無しさん
08/06/11 00:45:49
>>363
しばらくぶりに77で書いた。すでに>>365-366があってがっくしwww
PROGRAM FIBONA
INTEGER F(0:30)
F(0) = 0
F(1) = 1
DO 10 I = 2, 30
F(I) = F(I - 1) + F(I - 2)
10 CONTINUE
WRITE(*, '(8I8)') (F(I), I = 0, 30)
STOP
END
PROGRAM KANE
INTEGER KAHEI(9), NUM(9)
OPEN(9, FILE = 'KAHEI.TXT')
DO 10 I = 1, 9
READ(9, '(I8.8)') KAHEI(I)
10 CONTINUE
WRITE(*, *) 'INPUT KINGAKU'
READ(*, *) KIN
DO 20 I = 1, 9
NUM(I) = KIN / KAHEI(I)
KIN = MOD(KIN, KAHEI(I))
20 END DO
DO 30 I = 1, 9
WRITE(*, '(I6, A, I5, A)') KAHEI(I), ' YEN ', NUM(I), ' MAI'
30 CONTINUE
STOP
END
368:デフォルトの名無しさん
08/06/11 11:32:44
>>365-367
どうもありがとうございました。助かりました。
369:デフォルトの名無しさん
08/06/12 00:12:47
>>367
「キルヒアイス、お前は優しいな。」
20ループと30ループ合体できない?
DO 20 I = 1, 9
NUM = KIN / KAHEI(I)
KIN = MOD(KIN, KAHEI(I))
WRITE(*, '(I6, A, I5, A)') KAHEI(I), ' YEN ', NUM, ' MAI'
20 END DO
370:デフォルトの名無しさん
08/06/12 02:28:49
>>369
それも思ったが、I/Oと主演算は分離すべきかなと思って分けた。
天皇陛下万歳!
371:デフォルトの名無しさん
08/06/13 01:34:43
すいません、初心者なんですが
windows上で動くFORTRANのエミュってありますか?
372:デフォルトの名無しさん
08/06/13 01:44:23
>>371
VMwareにLinux入れてg77使えばおkw
373:デフォルトの名無しさん
08/06/13 01:46:34
>>371
ある。77も95も。
ぐぐれw
374:デフォルトの名無しさん
08/06/13 04:53:55
>>373
お勧めの物はないのでしょうか?
375:デフォルトの名無しさん
08/06/13 08:01:12
fortran のエミュってどういう意味なんだろう?
単に IDE があってコンパイルができればいいなら silverfrost ftn95 でググれば見つかるよ。
376:デフォルトの名無しさん
08/06/16 02:07:35
>>374
G95とかどう?
URLリンク(ftp.g95.org)
Self-extracting Windows x86かそのへん
377:デフォルトの名無しさん
08/06/17 01:57:48
>>376
cygwin入れるのがだるい。
378:デフォルトの名無しさん
08/06/17 02:42:03
>>377
まあマジレスすると Self-extracting Windows x86 の方はMinGWだから
Cygwin環境が無くても単独で動くわけだが。
379:デフォルトの名無しさん
08/06/17 09:13:45
しかし Cygwin のインストールがだるいって相当だな
380:デフォルトの名無しさん
08/06/17 19:07:53
倍精度計算で、D○.○のようにして出力すると
例えば 0.12345D-3 のように表示されてしまうのですが
これを1.2345D-4
と表示する事は可能でしょうか?
試行錯誤しているのですが全然分からず教えて頂きたいです
381:デフォルトの名無しさん
08/06/17 19:41:00
昔はcygwin入れるのは当たり前って感じだったが今はな・・・
最近影薄くて心配になるけど、細々と続いてるようね
382:デフォルトの名無しさん
08/06/17 19:51:44
>>380
ESでできなかったかな。
383:デフォルトの名無しさん
08/06/17 23:44:40
>>380
フォーマット指定するだけじゃん・・・
384:デフォルトの名無しさん
08/06/17 23:55:47
>>382-383
ESとはなんでしょうか・・
ごめんなさい、どのようにしたら良いのかさっぱりで・・
385:デフォルトの名無しさん
08/06/18 00:43:11
>>384
フォーマットの指定で"D○.○"の所を"ES○.○"にする
"D○.○"→0.100D+00
"ES○.○"→1.000E+00
"ES○.○E3"→1.00E+000
試してないから間違ってるかも
386:デフォルトの名無しさん
08/06/18 01:20:56
>>380
Fortran90でよければ、上にみんなが書いているようにESでおk。
FORTRAN77ならば、1P D○.○ 0P でいける。
P 指定子は破壊力がでかいので、使ったらすぐ 0P で元に戻すが吉。
ま、マニュアル嫁
PROGRAM ppp
IMPLICIT NONE
REAL(8) :: d
d = 1.234567d-2
PRINT '(D15.6, ES15.6, 1P, D15.6, 0P)', d, d, d
STOP
END PROGRAM ppp
実行出力
0.123457D-01 1.234567E-02 1.234567D-02
Press any key to continue . . .
387:デフォルトの名無しさん
08/06/19 11:57:12
P指定子ってすごいよな・・・
今考えるとアリエンけど、昔はああいう仕様は全然平気だったんだろうな
388:デフォルトの名無しさん
08/06/19 17:08:36
世の中の処理系のほとんどが対応してると言っていいFortranのバージョンって、95でしょうか?
ちょっと前は、95はまだ早いから無難に行くなら90にしとけ、って声を聞きましたが。
389:デフォルトの名無しさん
08/06/19 20:44:00
>>387
P指定子ってなんでありえないの??
よく使うのだが…
390:デフォルトの名無しさん
08/06/19 23:07:51
昔、>>380の様に考えて出力用にP指定子を使ったが、クリアしていなかったので
READのところでFフォーマットの値がスケールされて読まれてしまい、とんでもない結果が出て悩んだw
たしかEとかベキ記号がついているときはスケールされないので、すげー悩んだ。
Fortran90の勉強を始めたとき、ESフォーマットがあったので、あぁアリガテーと思った。
391:デフォルトの名無しさん
08/06/20 12:47:18
>>389
マジで言ってんの・・・?
まぁ気をつけてれば問題ないけどさ
392:デフォルトの名無しさん
08/06/23 16:22:50
学校の課題で次のものが出たんですけど、初心者なのでわかりません。お願いします。ちなみにFORTRAN77です。
今日の月日と曜日を入力し,これを用いて今年の任意の月日の曜日を出力させよ.
各月の日数はファイルから読み込む.ファイル名や変数名は自分で付ける.
曜日は数値で代用してよい.日曜=1,月曜=2,・・・土曜=7.
目標の月日が何日後か(前か)を出す.それから曜日を計算する.
today
6 23 2
when
1 1
-174days 3you
today
6 23 2
when
12 31
191days 4you
393:デフォルトの名無しさん
08/06/23 17:25:50
>>392
「今年」と銘打っているのに、曜日の入力を要求するんだな。
今日の月日と曜日に不整合があった場合、どうするんだろう。
まずは次の課題を考えなさい。
今日の月日を入力し、一年の経過日数(正月=1)を出力するプログラムを作成せよ。
394:デフォルトの名無しさん
08/06/23 20:34:09
わかってるところとわからんことを書かないと、アドバイスのしようがないのでは?
全部かいてもらう気なら別だが。
395:392
08/06/23 20:41:37
>>394
上にも書きましたが初心者です。
全部わからないので全部書いてください。
396:392
08/06/23 20:54:35
上の人は別人です
まだFORTRAN77を触り始めて間が無いので表示するプログラムが限界です
勉強のためにコメントをつけてくだされば嬉しいです
って言いたいと思う
397:デフォルトの名無しさん
08/06/23 21:17:09
>>396
本質的には >>395 と言っている事が一緒だね。
さらに解説ヨロってのも凄いが。
398:デフォルトの名無しさん
08/06/23 21:36:47
まぁとりあえず、作ってみようぜ
399:デフォルトの名無しさん
08/06/23 23:13:44
学校の課題なんだから必要な構文の説明あるだろ
初心者じゃなくて怠け者だろ
400:デフォルトの名無しさん
08/06/24 02:33:14
この問題がわかりません↓
0.0 から 1.0 までの 10 個の値、 0.12, 0.32, 0.09, 0.83, 0.58, 0.39,
0.72, 0.44, 0.71, 0.24 を使って、起点 0.0、幅 0.2 としたときの頻度分布
を求めるプログラムを作成せよ。
結果はこのように表示されるようです。
s < 0.2 2
0.2 <= s < 0.4 3
0.4 <= s < 0.6 2
0.6 <= s < 0.8 2
0.8 <= s 1
if文を使うのはわかるのですが、頻度分布をどう求めていいのかわかりません。
fortran77です。
どうかよろしくお願いします。
401:デフォルトの名無しさん
08/06/24 09:21:12
>>396
初心者には、入出力まわりが一番難しいのだが。
402:デフォルトの名無しさん
08/06/24 10:36:12
>>400
PROGRAM HIST
INTEGER NUM(5)
REAL S(10)
DATA S / 0.12, 0.32, 0.09, 0.83, 0.58,
$ 0.39, 0.72, 0.44, 0.71, 0.24 /
DO 10 I = 1, 5
NUM(I) = 0
10 CONTINUE
C
DO 20 I = 1, 10
IF (S(I) .LT. 0.0) THEN
WRITE(*, *) 'INPUT ERROR!'
STOP
ELSE IF (S(I) .LT. 0.2) THEN
NUM(1) = NUM(1) + 1
ELSE IF (S(I) .LT. 0.4) THEN
NUM(2) = NUM(2) + 1
ELSE IF (S(I) .LT. 0.6) THEN
NUM(3) = NUM(3) + 1
ELSE IF (S(I) .LT. 0.8) THEN
NUM(4) = NUM(4) + 1
ELSE IF (S(I) .LE. 1.0) THEN
NUM(5) = NUM(5) + 1
ELSE
WRITE(*, *) 'INPUT ERROR!'
STOP
END IF
20 CONTINUE
C
403:デフォルトの名無しさん
08/06/24 10:36:47
WRITE(*, *) 's < 0.2 ', NUM(1)
WRITE(*, *) '0.2 <= s < 0.4 ', NUM(2)
WRITE(*, *) '0.2 <= s < 0.4 ', NUM(3)
WRITE(*, *) '0.6 <= s < 0.8 ', NUM(4)
WRITE(*, *) '0.8 <= s ', NUM(5)
STOP
END
s < 0.2 2
0.2 <= s < 0.4 3
0.2 <= s < 0.4 2
0.6 <= s < 0.8 2
0.8 <= s 1
Press any key to continue . . .
404:デフォルトの名無しさん
08/06/24 11:20:33
>>392
あまりチェックしてない。
曜日求め部分をよく練っていない。
うるう年対応してしまったw 今年限定ならデータいじればよし。
FUNCTION ILEAP(IY)
ILEAP = 0
IF (MOD(IY, 4) .EQ. 0) ILEAP = 1
IF (MOD(IY, 100) .EQ. 0) ILEAP = 0
IF (MOD(IY, 400) .EQ. 0) ILEAP = 1
RETURN
END
C
FUNCTION IDAYS(IY, IM, ID)
INTEGER MDAYS(12)
DATA NFEB /28/
DATA MDAYS /31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
MDAYS(2) = NFEB + ILEAP(IY)
IDAYS = ID
DO 10 I = 1, IM - 1
IDAYS = IDAYS + MDAYS(I)
10 CONTINUE
RETURN
END
C
405:デフォルトの名無しさん
08/06/24 11:23:50
PROGRAM CALEND
1 WRITE(*, *) 'TODAY'
READ(*, *) IM0, ID0, IDW0
IF (IM0 .LE. 0) STOP 'NORMAL END'
WRITE(*, *) 'WHEN'
READ(*, *) IM1, ID1
IDAYS0 = IDAYS(2008, IM0, ID0)
IDAYS1 = IDAYS(2008, IM1, ID1)
IDIFF = IDAYS1 - IDAYS0
IDW = MOD(IDIFF, 7) + 7 + IDW0 - 1
IDW = MOD(IDW, 7) + 1
WRITE(*, *) IDIFF, 'DAYS', IDW, 'YOU'
GOTO 1
STOP
END
TODAY
6 23 2
WHEN
1 1
-174 DAYS 3 YOU
TODAY
6 23 2
WHEN
12 31
191 DAYS 4 YOU
TODAY
0 0 0
NORMAL END
Press any key to continue . . .
406:デフォルトの名無しさん
08/06/24 12:03:44
>>404 乙
「各月の日数はファイルから読み込む」となっているね。
最近みかける宿題の出題者は、
無駄にファイル処理をさせようとしていない?
407:デフォルトの名無しさん
08/06/24 12:09:14
>>406
問題よく読んでなかったw
後で直す。
408:デフォルトの名無しさん
08/06/24 13:48:19
>>402
ありがとうございました!!
NUMを使うんですね。
解決できました。感謝です。
409:デフォルトの名無しさん
08/06/24 15:03:32
>>408
> NUMを使うんですね。
ピントがずれてないか?
優しい人たち乙。
私なら「宿題は自分でやれ」で放置だな。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4399日前に更新/200 KB
担当:undef