1 名前:デフォルトの名無しさん [2006/01/24(火) 09:48:23 ] このスレッドは、他のスレッドでは書き込めない超低レベル、 もしくは質問者自身何が何だが分からない質問を勇気を持って書き込むスレッドです。 FORTRAN使いが優しくコメントを返しますが、 お礼はFORTRANの布教と初心者の救済をお願いします。
874 名前:デフォルトの名無しさん mailto:sage [2006/09/21(木) 21:18:24 ] >>868 mixiでも質問してだだろ。
875 名前:デフォルトの名無しさん [2006/09/21(木) 22:06:02 ] >>873 がんばれ! うまくいかなかったら、また聞きに来い そのかわりちんちんうp
876 名前:デフォルトの名無しさん mailto:sage [2006/09/29(金) 13:40:50 ] ルンゲクッタつかおうとおもったら functionの形じゃないとだめですかね? というかfunction以外でできる方法あるの?
877 名前:デフォルトの名無しさん [2006/09/29(金) 20:54:07 ] >>876 つ SUBROUTINE
878 名前:デフォルトの名無しさん [2006/09/30(土) 00:22:52 ] 簡単すぎて申し訳ないとは思うんですがどうしていいのか... real dI,dV,dR3,R1,R2,R3,Rx write(*,*) 'dR3 ?' read(*,*) dR3 write(*,*) 'R1 ?' read(*,*) R1 write(*,*) 'R2 ?' read(*,*) R2 write(*,*) 'R3 ?' read(*,*) R3 write(*,*) 'Rx ?' read(*,*) Rx dI=R2*2*dR3/(R1*R2(R3+Rx)+R3*Rx(R1+R2)+9090(R1+R2)(R3+Rx)) write(*,*) 'dI=',dI dV=dI*9090 write(*,*) 'dV=',dV stop end
879 名前:デフォルトの名無しさん [2006/09/30(土) 00:24:32 ] をコンパイルするとこんなエラーが出ました。 どうすればいいのですか? 0013) dI=R2*2*dR3/(R1*R2(R3+Rx)+R3*Rx(R1+R2)+9090(R1+R2)(R3+Rx)) 0014) *** R2 is already in use as a local name 1 ERRORS [<MAIN@>FTN77 Ver 4.03] *** Compilation failed
880 名前:デフォルトの名無しさん mailto:sage [2006/09/30(土) 00:32:21 ] 13行目途中から掛け算の*が消えているのを直せばいいんじゃない? 始めに消えたR2(R3+Rx)のとこで、R2が実数ではなくて関数とみなされたんで、 もうR2ってのは実数として定義してますよっていうエラーだと思う。
881 名前:デフォルトの名無しさん [2006/09/30(土) 00:35:20 ] いけました!ありがとうございます!
882 名前:初心者 [2006/10/04(水) 21:11:02 ] フォートランでサブルーチンを使ってフーリエ変換をするプログラムをつくりましたが、横軸の値のとり方がわかりません!!わかる方いらっしゃいましたらどうか教えてください!
883 名前:デフォルトの名無しさん [2006/10/04(水) 22:18:19 ] >>882 その質問では、そなたがフーリエ変換をよく理解していないという以外分からない。 もう少し、詳しく書き込め 3行で
884 名前:sage [2006/10/05(木) 05:43:12 ] >>882 横軸は、周波数か周期では?
885 名前:初心者 [2006/10/05(木) 18:46:37 ] 作ったプログラムを書きます。 C USE NUMERICAL_LIBRARIES PARAMETER(NN=3000000) C REAL XN(0:NN),XX(0:NN),N(10000),COEF(0:NN),FFTN(0:NN) INTEGER NNF CHARACTER DATAFILE*35 C DATAFILE='experience.csv' OPEN(100,FILE='data.csv') DO 110,I=1,1024 READ(100,*) XN(I) 110 CONTINUE CLOSE(100) C N=I NNF=I CALL FFTRF(NNF, XN, COEF) DO 200 K=0,(NNF)-1 FFTN(K)=ABS(COEF(K))/DBLE(NNF/2) 200CONTINUE C OPEN(200,FILE='OUTPUT.dat') DO 210,K=0, NNF-1 WRITE(200,*) FFTN(K) 210CONTINUE CLOSE(200) END 縦軸はFFTN(K)ですが、横軸の周波数をどのようにすればいいのでしょうか??
886 名前:デフォルトの名無しさん mailto:sage [2006/10/06(金) 03:08:16 ] >>885 プログラムがどうこう言う前にフーリエ変換の基礎から勉強し直せ。
887 名前:デフォルトの名無しさん [2006/10/07(土) 00:34:18 ] 関数COTH(X)を使うために、実行文の前に COTH(X) = 1.0 / TANH(X) と定義したのですが,コンパイルしてみると COTH is not an array とエラーが出ます。どんな原因が考えられますか?
888 名前:デフォルトの名無しさん [2006/10/07(土) 02:17:17 ] >>887 コンパイラは何ですか? 文関数は最新の規格では廃止になっているので厳格なコンパイラならエラーになります。 その配列と間違えるエラーは、実行文より後に使うと出るものです。
889 名前:887 [2006/10/07(土) 10:57:16 ] レスありがとうございます。 プログラムは本当に初心者でコンパイルがどれをさすのか 分かってないのですが、silverfrostのFTN95の個人用を使っています。 関数の定義は、変数の型宣言の直後に書いています。 他に簡単なプログラムを書いてみて、試してみたところ、 うまくいきました。エラーはここ以外に出ていませんが、 warningでIn a previous call to COTH, the first argument was of type REAL (KIND=1), it is now INTEGER (KIND=3) と出ています。
890 名前:887 [2006/10/07(土) 12:36:34 ] 自己解決しました。 他の部分に不備があったようです。
891 名前:デフォルトの名無しさん mailto:sage [2006/10/08(日) 15:07:12 ] f(x)の区間[0,b]の積分を台形公式で近似した ∫f(x)dx=(h/2)*(f(x_0)+2(x_1)+2f(x_2)+…+2f(x_n-1)+f(x_n)) (ただしh=b/nはn分割したときの刻み幅でx_i=h*i) という式を数値積分をしようと思うのですが、 f(x)=((x^4)*exp(x))/((exp(x)-1)^2) なのでf(0)が発散してしまいます。 こういう場合、どう処理したらよいのでしょうか? 思いついたのは (f(x_0)+2(x_1)+2f(x_2)+… という部分を f(x_1)+2(x_2)+2f(x_3)+… とする方法(端のほうを無視する)なのですが、他に方法はないのでしょうか? みなさんでしたら、どうするのか、あるいは他に方法はない(思いつかない)のか、 どうか助言お願いします。
892 名前:デフォルトの名無しさん [2006/10/08(日) 20:31:02 ] >>891 変数変換するべし。
893 名前:891 mailto:sage [2006/10/08(日) 22:58:27 ] なるほど! どうもありがとうございます。 少しまた考えて見ます。
894 名前:デフォルトの名無しさん mailto:sage [2006/10/10(火) 00:20:42 ] >>893 というか、そもそもf(+0)は0なのでは? 確かに、f(0)そのものは分母がゼロになるので、計算できないが、 f(x) x->0 はゼロなので、普通に端っこだけ除けば計算できる。 (もちろん、十分結果が収束するまで分割数は多くしないとダメだけど) それか、計算区間を[0,b]ではなく、[ε,b](εは十分小さい数)で計算するとか。 同じことだけど。
895 名前:デフォルトの名無しさん [2006/10/11(水) 22:29:36 ] ちょっとお聞きしたいのですが atanとatan2とdatanの違いはなんなのでしょうか? 検索してみたのですがいまいちわかりません(バカですいません) プログラム書いてるのですが、どう考えてもここしか間違いがないのですが・・・
896 名前:デフォルトの名無しさん mailto:sage [2006/10/11(水) 23:10:24 ] 引数の型(個数) 関数の型 atan 実数型(1) 実数型 datan 倍精度実数型(1) 倍精度実数型 atan2 実数型(2) 実数型 datan2 倍精度実数型(2) 倍精度実数型
897 名前:デフォルトの名無しさん [2006/10/12(木) 00:38:18 ] >>895 ATANではよく、ATAN(Y/X) みたいな計算をするが、この場合X=0の時、 0割の例外が起きて困る。だが実際はATAN(∞)=π/2だ。 こういうのを避けるのに使うのがATAN2(Y,X)だ。
898 名前:デフォルトの名無しさん mailto:sage [2006/10/12(木) 01:50:11 ] >>896 ,897 ありがとうございます。 もしかしてatan(-1/-1)=atan(1/1)じゃないんでしょうか?
899 名前:デフォルトの名無しさん mailto:sage [2006/10/12(木) 01:58:35 ] >>898 それはFortranの話ではなく高校数学の話。 atan(-1/-1)=atan(1/1)=atan(1)=π/4
900 名前:デフォルトの名無しさん mailto:sage [2006/10/12(木) 02:46:10 ] >>899 ありがとうございました! なぞがすべて解決しました。深夜にサンクスでした
901 名前:デフォルトの名無しさん mailto:sage [2006/10/12(木) 18:43:21 ] 高速化したい場合は、どのような場合でも-O5をつけてOKですか?
902 名前:デフォルトの名無しさん [2006/10/12(木) 23:16:29 ] >>898 それはいい質問だ。 ATAN(y/x)の場合、象限に関する情報が失われてしまうのも問題で、 x=0.0のゼロ割りの時と並んで厄介なものである。 ATAN2の場合、その問題にも少し対応している。 ATANの場合は値域が−π/2〜π/2だが、ATAN2の場合象限に関する付加的な 情報があるので、返す値域が−π〜πに拡大している。 >>901 その質問は難しい。一概には答えられない。 まぁ最適化の手引きのようなものを読んで勉強するしかない。 その上でマニュアルを読んで、使用しているコンパイラの最適化がオプションごとに どうなっているかを知ったうえで、自分のプログラムと合わせて考えねばならない。 単純には、人間が見ても自明なソースはコンパイラも素直にコンパイル&最適化 できるので、正しく最適化されることが多い。
903 名前:デフォルトの名無しさん mailto:sage [2006/10/13(金) 02:46:34 ] なんだ、昨日はいろいろなスレにatan厨が湧いたのか
904 名前:デフォルトの名無しさん mailto:sage [2006/10/15(日) 15:04:15 ] FortranのDLLをC#もしくはBasicから呼び出そうとしています。 ↓このあたりを参考にコードを書いているのですが、FatalExecutionEngineErrorというエラーが出てしまいます。 www.atmarkit.co.jp/fdotnet/dotnettips/025w32string/w32string.html www.xlsoft.com/jp/products/intel/cvf/docs/vf-html/pg/pg18_05_01.htm#EXPORT dotnet247.com/247reference/msgs/32/164624.aspx 文字列をあつかわない関数に関しては成功しているので、文字列の引渡しがうまくいっていないようです。 DllImport文には以下のようにCharSetの記述をしています。 [DllImport("*****.DLL", CharSet=CharSet.Unicode)] 文字列の渡し方は、stringで渡す、stringBuilderで渡す、char配列で渡す、の3通りを試しましたがいずれもエラーとなりました。 もとのFortranコードおよび 自分が具体的に書いたコードを以下に記します。 なにかお気づきの点などあれば教えていただけないでしょうか?
905 名前:904 mailto:sage [2006/10/15(日) 15:05:00 ] オリジナルのFortranコード subroutine SETUPdll(i,hfld,hfm,hrf,ierr,herr) implicit double precision (a-h,o-z) implicit integer (i-k,m,n) dll_export SETUPdll parameter (ncmax=20) character hfld*10000,hfm*255,hrf*3,herr*255,hfmix*255 character*255 hf(ncmax) do 10 j=1, ncmax 10 hf(j)=' ' if (i.eq.1) then hf(1)=hfld else m=1 do 20 k=1,i j=index(hfld(m:10000),'|') if (j.ne.0) then j=j+m-1 hf(k)=hfld(m:j-1) m=j+1 endif 20 continue endif hfmix=hfm call SETUP (i,hf,hfmix,hrf,ierr,herr) end
906 名前:904 [2006/10/15(日) 15:06:52 ] 自分で書いたコード(char配列を利用) [DllImport("*****.DLL", CharSet=CharSet.Unicode)] private extern static void SETUPdll(ref int nc, ref char[] hfld, ref char[] hfm, char[] hrf, ref int ierr, ref char[] herr); static void Main(string[] args){ int nc = 1; char[] hfld = new char[10000]; char[] hfmix = new char[255]; char[] hrf = new char[3]; char[] herr = new char[255]; string strBuff = "fluids/nitrogen.fld"; strBuff.CopyTo(0, hfld, 0, strBuff.Length); strBuff = "fluids/hmx.bnc"; strBuff.CopyTo(0, hfmix, 0, strBuff.Length); strBuff = "DEF"; strBuff.CopyTo(0, hrf, 0, strBuff.Length); strBuff = " "; strBuff.CopyTo(0, herr, 0, strBuff.Length); int ierr = 0; SETUPdll(ref nc, ref hfld, ref hfmix, hrf, ref ierr, ref herr); }
907 名前:904 mailto:sage [2006/10/15(日) 15:09:49 ] 自分で書いたコード(stringBuilderを利用) [DllImport("*****.DLL", CharSet=CharSet.Unicode)] private extern static void SETUPdll(ref int nc, ref char[] hfld, ref char[] hfm, char[] hrf, ref int ierr, ref char[] herr); static void Main(string[] args){ int nc = 1; StringBuilder hfld = new StringBuilder(10000); hfld.Append("fluids\\nitrogen.fld"); StringBuilder hfmix = new StringBuilder(255); hfmix.Append("fluids\\hmx.bnc"); StringBuilder hrf = new StringBuilder(3); hrf.Append("DEF"); StringBuilder herr = new StringBuilder(255) ; herr.Append(""); int ierr = 0; SETUPdll(ref nc, ref hfld, ref hfmix, hrf, ref ierr, ref herr); }
908 名前:904 mailto:sage [2006/10/15(日) 15:12:50 ] 自分で書いたコード(stringを利用) [DllImport("*****.DLL", CharSet=CharSet.Unicode)] private extern static void SETUPdll(ref int nc, ref string hfld, ref string hfm, ref string hrf, ref int ierr, ref string herr); static void Main(string[] args){ int nc = 1; string hfld = "fluids\\nitrogen.fld"; string hfmix = "fluids\\hmx.bnc"; string hrf = "DEF"; string herr = ""; int ierr = 0; SETUPdll(ref nc, ref hfld, ref hfmix, ref hrf, ref ierr, ref herr); }
909 名前:デフォルトの名無しさん [2006/10/15(日) 20:03:53 ] >>904 難しい質問だなw Fortranコンパイラはなんなの? 一般的にC言語などは尻にx00のNULL文字が入る内部構造なので、 Fortan側で文字列をいじったあとは尻にNULLをつけたりしないと駄目だったりするが・・・ DECの拡張では尻にCと書くことでNULL文字が付け加わる。
910 名前:904 [2006/10/17(火) 08:48:25 ] 出張で返信遅れました。 すみません。 コンパイラはSalfordのftn77を使っています。 Salfordのftn95を使って.NET用にコンパイルしたところ、 一応は使えるようになりました。 ただ、一定時間広告が出てしまうのでできるならばftn77でなんとかしたいところです。 !DEC$ の末尾にCも付け加えましたが、やはり同一のエラーが出ます。 もう少し検討してみます。
911 名前:デフォルトの名無しさん mailto:sage [2006/10/17(火) 09:49:08 ] で、公開関数はいつはいるの?
912 名前:デフォルトの名無しさん mailto:sage [2006/10/17(火) 19:01:46 ] intelfortran ver.9.0を使っています。 教官からもらったプログラムをコンパイルしたところ npionkai.f(2803) : Error: This character is not valid in a format list. [R] 6000 FORMAT(/42H TOO MANY VARIABLE PARAMETERS. YOU REQUEST,I5/47H THIS -^ compilation aborted for npionkai.f (code 1) といわれました。 これはformat文の中に[R]を使うなボケェってことなんでしょうか それならなんか理不尽です
913 名前:デフォルトの名無しさん mailto:sage [2006/10/17(火) 21:35:29 ] >>912 プログラムの"6000 FORMAT ..."の行を晒しては如何。 その書式は教官以上にエッチにならないと使えないらしいよ。
914 名前:デフォルトの名無しさん mailto:sage [2006/10/17(火) 21:41:49 ] ホレリスの文字数がずれてたり、1行当たりの文字数制限でいつの間にかお尻が切れてたりする可能性がある。
915 名前:デフォルトの名無しさん [2006/10/17(火) 23:00:53 ] >>912 たぶん継続行のところでホレリスの数えがずれたんじゃないかな。 その行だけじゃなく、文全部をだせや
916 名前:912 mailto:sage [2006/10/18(水) 00:11:18 ] format文全文は WRITE(2,6000) NINT,MAXINT 6000 FORMAT(/42H TOO MANY VARIABLE PARAMETERS. YOU REQUEST,I5/47H THIS 1 VERSION OF MINUIT IS ONLY DIMENSIONED FOR,I4//) です。 このformat文があるサブルーチン内で IMPLICIT REAL*8(A-H,O-Z) を宣言しています。 よろしくお願いします。 やはりホレリスずれで最後のFORの[R}が文句いわれてるんですか
917 名前:912 mailto:sage [2006/10/18(水) 00:15:09 ] 連投すみません 47Hを48Hにかえたらいいんですね
918 名前:デフォルトの名無しさん mailto:sage [2006/10/18(水) 00:31:10 ] >>916 6000 FORMAT(/42H TOO MANY VARIABLE PARAMETERS. YOU REQUEST,I5/47H THIS ホレリスの途中で行を分けてるのが不味いな。 行末の「THIS」の後ろにスペースが入ってるとそれがカウントされて文字数がずれる。
919 名前:デフォルトの名無しさん mailto:sage [2006/10/18(水) 08:04:08 ] Fortran77を使っているんですが, 乱数を発生させようと思い real a do i= 1,10 a = rand() write(*,*)a enddo stop end このようなプログラムを作ったところ, 乱数は書き出されるのですが毎回同じものになってしまいます. 実行するたびに違う乱数を得るにはどうしたらいいのでしょうか.
920 名前:デフォルトの名無しさん mailto:sage [2006/10/18(水) 09:34:30 ] >>919 乱数を使用する前に SRAND で乱数の種を設定する。 PROGRAM HOGE REAL A CALL SRAND(TIME()) DO I=1, 10 A = RAND() WRITE(*,*) I, A END DO STOP END 但し、RAND/SRAND/TIME はFORTRAN77標準ではないので もし使っている処理系にない場合は同等のサブルーチン/関数を探すこと。
921 名前:デフォルトの名無しさん mailto:sage [2006/10/18(水) 11:19:26 ] >>920 さんのプログラムを入力してみたのですが やはり何回やっても同じ値しか返してきません。 >もし使っている処理系にない場合は同等のサブルーチン/関数を探すこと なんでしょうか。もう少し調べてみます。
922 名前:デフォルトの名無しさん [2006/10/18(水) 12:42:59 ] >>921 F90にはRANDOMIZEというのが標準であったはずだが・・・ しかし、この手の問題はBASIC全盛時代のゲームの乱数の頃からのFAQだw 時計で乱数の種を作る。 宿題程度ならともかく、まじめなシミュレーションをやりたいなら、乱数の専門サイトへ行って、 乱数マニアの御託を我慢して読んで、目的にあった適切な擬似乱数のルーチンを貰ってくるのが吉。 大体言語内蔵の乱数はウンコなことが多いという経験的な事実がある。 金が余っているならハードウェア的に乱数を吐き出すボードもあるようだ。 熱雑音か放射性物質の崩壊を利用して天然物の乱数を出してくれる。
923 名前:デフォルトの名無しさん [2006/10/18(水) 21:00:08 ] fortran77で計算結果をfile.csvに記録するとき WRITE(3,*)a(1),',',a(2),',',a(3)・・・ (a(n)は数値) とカンマ区切りで出力しているのですが、70文字目くらいで折り返されて 記録されているため、Excelで開いたときに1行で結果が見られません。 これを1行で記録するにはどうすればいいのでしょうか?
924 名前:デフォルトの名無しさん mailto:sage [2006/10/18(水) 21:45:57 ] >>923 横着せずに書式を指定する write(3, '(100(F8.3,:,'',''))') (a(i), i=1,100)
925 名前:923 mailto:sage [2006/10/18(水) 22:11:40 ] >>924 出来ました! ありがとうございます。
926 名前:ふつふつ [2006/10/19(木) 23:25:37 ] fortran77を使っているんですけど、得られた6つの値を1行1列、2行1列、3行1列 1行2列、2行2列、2行3列の順番にformat文を使って表示するにはどのようにしたら いいでしょうか?初心者でぜんぜんわからなくて。どなたかお願いします。
927 名前:デフォルトの名無しさん mailto:sage [2006/10/19(木) 23:33:15 ] >>926 >得られた6つの値 どんな形式で与えられるのか、詳しく説明せい。
928 名前:ふつふつ [2006/10/19(木) 23:41:23 ] >>927 説明不足ですみません。E25.16E3です
929 名前:デフォルトの名無しさん [2006/10/19(木) 23:44:46 ] 掲示板のHTTML教えてください
930 名前:ふつふつ [2006/10/20(金) 00:45:03 ] ほんとごめんなさい。どこに書いてあるのですか?htmlって?
931 名前:デフォルトの名無しさん [2006/10/20(金) 21:41:25 ] >>926 データ数とフォーマットによる表示数が合ってない。 >>927 の書式もおかしい。 問題文を忠実に写せ。このままでは答えようが無い。
932 名前:ふつふつ [2006/10/22(日) 02:30:06 ] Nx=256,Ny=256で、以下のプログラムでやっています。これを一列目に256個の結果を出し、257個目から 2列目に結果を表示していき、行256、列256にしたいんです。E25.16E3は変えられません DO 250 I=1,Nx DO 250 J=1,Ny write(30,260) U(I,J) 250 continue 260 Format (E25.16E3)
933 名前:デフォルトの名無しさん mailto:sage [2006/10/22(日) 03:04:50 ] >>932 なんか >>926 と言ってることが違うんだが… >>932 のプログラムから察するとこういうことか? WRITE(30, 260) ((U(I,J), J=1,256), I=1,256) 260 FORMAT(256(256E25.16E3,/))
934 名前:ふつふつ [2006/10/22(日) 17:45:27 ] 実はこのプログラムが実際のものだったんです。逆にややこしくしてしまったようです。 それにもかかわらず答えていただきありがとうございました。 明日試してみます。
935 名前:デフォルトの名無しさん [2006/10/23(月) 20:21:09 ] 学校でfortranやらされる事になった・・・
936 名前:デフォルトの名無しさん mailto:sage [2006/10/23(月) 20:29:55 ] >>935 おめでとう!
937 名前:デフォルトの名無しさん [2006/10/23(月) 23:10:38 ] >>935 FORTRANはいいぞぅ! 1950年代のコードが未だに生き残っている。 ソース再利用では最高水準の言語だw
938 名前:デフォルトの名無しさん mailto:sage [2006/10/23(月) 23:21:30 ] 7カラムにぴったり揃えたあの美しさ。インデント糞喰らえ。 これに匹敵できるのはアセンブリしかない。
939 名前:デフォルトの名無しさん mailto:sage [2006/10/23(月) 23:27:21 ] おいおい、そんなこと言ってるとCOBOLerの皆さんが…
940 名前:デフォルトの名無しさん mailto:sage [2006/10/24(火) 10:45:52 ] × 匹敵できる ○ 匹敵する ○ 比肩できる
941 名前:stack overflow [2006/10/24(火) 14:17:33 ] severe(170): Program Exception - stack overflow というエラーが出るのですが、解決方法が分かりません。 過去の書き込みに同様のものがありますが、もう1度スタックのサイズの増やし方を教えてください。 あと、配列はすべてallocatableで宣言していて、deallocateを繰り返しているのですが、stack overflowになってしまうものなんでしょうか? エラーの出る行がcall文だし、そもそも、どうするとメモリが消費されるのか分かりません。 ど素人にご教授願います。
942 名前:デフォルトの名無しさん mailto:sage [2006/10/24(火) 20:07:34 ] fortran4で書かれたコードを使いたいのですがgccではコンパイルできませんでした。 fortran4でもコンパイルできる今手に入るコンパイラはないでしょうか?
943 名前:デフォルトの名無しさん mailto:sage [2006/10/24(火) 22:24:00 ] >>941 >スタックのサイズの増やし方 Windows上のCompaq Visual Fortranなら df hoge.f90 /link /stack:0x12ab000 Intel Visual Fortranなら ifort /F0x12ab000 hoge.f90 ほかは知らん。 >エラーの出る行がcall文 (FORTRAN77形式の)次元と範囲が明示された配列を引数に取るサブルーチンに (Fortran90以降の)部分配列やポインタを渡して呼び出そうとすると 暗黙のうちに一時的な配列が作られ、これがサブルーチンに渡される。 このとき要求される配列のサイズが大きいとスタックがあふれる可能性がある。
944 名前:stack overflow [2006/10/24(火) 23:06:34 ] エラーの出るサブルーチンの引数に配列は含まれていません。 ループを繰り返していると、見えないところで、メモリが切られて、スタックがあふれてしまう???っぽいんですが・・・
945 名前:デフォルトの名無しさん [2006/10/24(火) 23:44:35 ] 動的メモリー割付をとる領域には、ヒープとスタックの2種類がある。 普通はヒープはOSの管理下に、スタックはプログラムの管理下にある。 ゆえにスタックサイズはリンカーで指定することになる。 allocateはヒープ領域からメモリーを取られるのが一般的だ。 スタックの方は、オートマチック変数などに取られる。 呼び出し側のサブルーチンで、オートマチック変数を取っていないか? これがでかすぎるとスタックオーバーフローが起こる。 コンパイラの実装にもよるが、スタックオーバーフローはallocateではないんじゃないか?
946 名前:デフォルトの名無しさん [2006/10/24(火) 23:55:32 ] >>942 CP/Mのエミュレーターを入れて、その上でFORTRAN IVのコンパイラを動かす ことは出来る。エミュレータとソフトはネットに流れているので拾える。 というのは冗談だ。 FORTRANIVはFORTRAN66と同じものだと考えてよい。 FORTRAN66は、ごく些細な部分を除けばFORTRAN77に含まれている。 したがって、(色々落とし穴はあるが)若干の修正で動くはずである。 FORTRAN90→95→2003 と進むにつれて徐々に古臭い機能を切り落としているが、 現実の実装では機能は生き残らせてあるのが普通だ。 新しいコンパイラでも動くだろう。 DEC/INTEL FORTRANなどではFORTRAN66形式のDO廻り (条件にかかわらず必ず1回は回る)とかをオプションで指定できる。 あと拡張DO LOOPもDEC時代には対応していた。 GCCでどうなってるかは知らん。
947 名前:942 mailto:sage [2006/10/25(水) 00:16:11 ] >>946 回答ありがとうございます。intelで試してみます
948 名前:デフォルトの名無しさん mailto:sage [2006/10/25(水) 01:33:30 ] 大学でFortranを使うことになったのですが、詰まってしまいまして。 以下のようなプログラムを作るのですが……。 1.すでにAと言うデータファイルがあり、2列で構成されている。 それぞれの列が粒子のx座標、y座標に対応で、1行1粒子に当たります(座標情報は実数です) 2.ここから新たに別のファイルBを作成して、 Bに原点からの距離(sqrt(x**2+y**2))を計算して入力していく。 というものです。 試しにプログラムを作り入力データが1行のAを用いたところ、できたBの中に距離を表す数値が 一つだけ表示されていて成功したのですが、行数が2行以上になると、どう試してもできず。 Aの各行の値がばらばらでも、Bで表示される数値が全部の行で同じに……orz 行数が少ないなら自力で計算するところなのですが、Aが数千万行クラスのファイルなので 手計算ではどう考えても時間がかかりすぎます。 内容的に初歩の物だとは思うのですが、幾つかのサイトを見てみても複数行のデータを うまく読み込み、計算して書き出す方法がわからず、先に進めません。 どなたか、御力をお貸しくださいませ。よろしくお願いしますm(_ _)m
949 名前:デフォルトの名無しさん mailto:sage [2006/10/25(水) 02:08:57 ] >>948 program main implicit none real(kind=SELECTED_REAL_KIND(10)) :: x, y, d integer :: ios open(unit=11, file="A", status="OLD") open(unit=12, file="B", status="REPLACE") do read(unit=11, fmt=*, iostat=ios) x, y if (ios /= 0) exit d = sqrt(x**2 + y**2) write(unit=12, fmt=*) d end do close(11) close(12) end program main
950 名前:948 mailto:sage [2006/10/25(水) 15:46:23 ] >>949 すぐに答えて頂いたのに、返答が遅くなってしまい申し訳ありませんm(_ _)m さっそく上記のプログラムを用いたところ、無事計算されたファイルが 出力されました。 これでようやく先に進めそうです。本当にありがとうございました!! ただ、一つ疑問点が……。 3行目のreal以下の()文を書いたままコンパイルすると、 Invalid declaration of or reference to symbol `selected_real_kind' at (^) [initially seen at (^)] という警告文がでて、コンパイルが止まってしまいました。 中身を含めて()を消してみたところうまくコンパイルできたのですが。 もしよろしければ、()内の意味を教えていただけないでしょうか。 重ね重ね申し訳ありませんが、よろしくお願いします。
951 名前:stack overflow [2006/10/25(水) 23:16:42 ] 返信遅くなりました。昨日(945)の続きお願いします。 今日は寝ないつもりです。(もちろんデフォルトの名無しさん には強制しません) オートマチック変数ってどのような変数のことをいうのでしょうか? いろいろ調べてみたのですが、いまいちです。 結局、オートマチック変数が原因の場合どうすればよいのでしょう?
952 名前:デフォルトの名無しさん [2006/10/25(水) 23:28:30 ] >>950 あれはFORTRAN90以降で導入された精度保障のための関数だ。 kind=SELECTED_REAL_KIND(10) これは有効数字10桁を保障するような型に対応する種類(KIND)を返す。 普通のFORTRANは短精度と倍精度を持つが、短精度の有効桁は7〜8、 倍精度は14〜15なので、倍精度に相当する値を返す。 FORTRAN77で言えばREAL(8)に相当する。 これでコンパイラのエラーが出るとすると、FORTRAN90完全準拠で無いと思われる。
953 名前:デフォルトの名無しさん [2006/10/25(水) 23:39:38 ] >>951 オートマチック変数または自動変数とは、サブルーチンが呼び出されたときに 一時的に割り付けられる変数だ。 SUBROUTINE unko(a, n) IMPLICITE NONE REAL, INTENT(IN) :: a(n) REAL :: work(SIZE(a)) 云々 とあったとすると、配列workが自動変数にあたる。 これはあまり大きなものを取ることを想定しておらず、スタック領域に割り付ける。 こういう使い方で大きな配列などを取っていると、スタックオーバーフローがおきる。 サブルーチンを呼び出すと、戻る場所などの情報をスタックに保存することになる。 またサブルーチンで一時的に使用するメモリー等もスタックに取る。 サブルーチンの呼び出しが過剰に多いか(再帰関数が無限ループとか)、 一時変数が領域を食いすぎるとオーバーフローが出る可能性がある。 エラーメッセージからするとDEC系のコンパイラの感じだが、トレースバック情報などの デバッグ情報を吐き出させるオプションをつけてコンパイルし実行してみるのも手だ。 まぁ、もう少し詳しい情報が無いと助言のしようが無い。
954 名前:stack overflow [2006/10/26(木) 00:19:00 ] programを省略して書くと、 (宣言文) open(21,file='filelist') do allocate read(21,*,end=1000)unko open(51,file=unko) (計算) close(51) deallocate end do 1000 close(21) stop end データのファイル(具体的には地震動の波形)がたくさんあって 1つ1つに同じ処理をして出力ファイルを作成したかったので、 cmdで入力ファイルのパスのリストを作って、リストのファイルが読み終わるまで、 doループで繰り返すように動かしたいのです。 大体2000回くらいループを繰り返すとstack overflowします。(動かして20分ぐらい) mainで使う配列はすべて、doループのなかでallocateとdeallocateを繰り返しています。 subroutine内でも引数でない配列は、allocateとdeallocateをしています。 こんな風な動かし方ってできないんですかね? OSはWindowsXP、programはvisual studioで動かしています。
955 名前:デフォルトの名無しさん [2006/10/26(木) 00:43:27 ] >>954 その範囲内では問題ないと思われる。 20分はちゃんと動いているとすれば、結構厄介なBugかもしれない。 Visual Studioを使っているという事は、コンパイラはIntelのものでいいのか? 昔のMSPowerStationだとI/OにメモリーリークがあるのでI/Oを繰り返すと 死にメモリーが増えて行きどこかで死亡することになっていた。 これはタスクモニターでメモリー使用量を観察していると分かる。 Intelではそういう事は無いと思うのだが、もしかしたらそういう可能性が無いともいえない。 ALLOCATEとDEALLOCATEの対応が狂って、きちんとメモリーが解放されていない場合も タスクモニターでメモリー使用量を見ていると、どんどん使用メモリーが増えてゆくので 見て取れる。 ところで実行はDEBUG MODEでためしているだろうか?
956 名前:stack overflow [2006/10/26(木) 00:47:04 ] プログラム概要を記します。 (宣言文) open(21,file='filelist') do allocate read(21,end=1000)unko open(51,file=unko) read(51) (計算) close(51) deallocate enddo 1000 close(21) deallocate stop end データ(具体的には地震動波形(6000stepから10000stepぐらい))のファイルがたくさんあって、 1つ1つに同じ処理をしたいので、cmdでファイルのパスのリストを作って、このリストを読み終わるまでdoループを繰り返しているのですが、 2000回くらい繰り返すと(大体20分ぐらい)stack overflowになります。 mainで使う配列はすべてdoループのなかでallocateとdeallocateを繰り返しています。 subroutineでも引数でない配列はallocateとdeallocateを繰り返しています。 こんな使い方しませんか? OSはwindowsXPで、visual studioでプログラムを作ってます。
957 名前:stack overflow [2006/10/26(木) 00:47:56 ] プログラム概要を記します。 (宣言文) open(21,file='filelist') do allocate read(21,end=1000)unko open(51,file=unko) read(51) (計算) close(51) deallocate enddo 1000 close(21) deallocate stop end
958 名前:stack overflow [2006/10/26(木) 00:48:58 ] 957の続き データ(具体的には地震動波形(6000stepから10000stepぐらい))のファイルがたくさんあって、 1つ1つに同じ処理をしたいので、cmdでファイルのパスのリストを作って、このリストを読み終わるまでdoループを繰り返しているのですが、 2000回くらい繰り返すと(大体20分ぐらい)stack overflowになります。 mainで使う配列はすべてdoループのなかでallocateとdeallocateを繰り返しています。 subroutineでも引数でない配列はallocateとdeallocateを繰り返しています。 こんな使い方しませんか? OSはwindowsXPで、visual studioでプログラムを作ってます。
959 名前:stack overflow [2006/10/26(木) 00:50:11 ] 957の続き データ(具体的には地震動波形(6000stepから10000stepぐらい))のファイルがたくさんあって、 1つ1つに同じ処理をしたいので、cmdでファイルのパスのリストを作って、このリストを読み終わるまでdoループを繰り返しているのですが、 2000回くらい繰り返すと(大体20分ぐらい)stack overflowになります。 mainで使う配列はすべてdoループのなかでallocateとdeallocateを繰り返しています。 subroutineでも引数でない配列はallocateとdeallocateを繰り返しています。 こんな使い方しませんか? OSはwindowsXPで、visual studioでプログラムを作ってます。
960 名前:stack overflow [2006/10/26(木) 00:51:33 ] すいません。 同じ内容を何度も書き込んでしまいました。
961 名前:stack overflow [2006/10/26(木) 01:17:54 ] ファイルリストがいくつもあるのでバッチファイルで動かしていました。 filelistをcall getargで読み込ませています。 DEBUG MODEでやった方がいいですか? タスクモニターを見ながらもう一度動かしてみようと思います。
962 名前:stack overflow [2006/10/26(木) 01:43:26 ] つかぬ事をお聞きしますが、タスクモニタのどこをみればよいのでしょうか? 見ながら動かして見ましたが、あまり変わりません。 コンパイラはIntel FORTRANです。
963 名前:948 mailto:sage [2006/10/26(木) 01:58:24 ] >>952 なるほど、精度保障のための関数でしたか。勉強になりました。 一度、自分の使っているFORTRANのバージョンを確認してみます。 お答えいただき、どうもありがとうございました!
964 名前:stack overflow [2006/10/26(木) 02:15:31 ] !!!!なぜか、急に動くようになりました。???? もう少し長い時間動くかどうか、やってみます。結果は明日報告します。 ご丁寧に説明していただき、ありがとうございました。お時間取らせてしまってすいません。 and同じ書き込み何度もして、すいません。
965 名前:デフォルトの名無しさん [2006/10/26(木) 02:39:52 ] >>961 一応DEBUG MODEで1回は動かしておくのがいい。 時間はかかるので小さめのデータを用意して確かめておくのがマナー。 いきなりリリースモードに行くのは、体を洗わずに湯船につかるようなものw >>962 概略ならパフォーマンスのところを見るとグラフが書かれているのでそれで傾向を知れる。 プロセスのところでMEMUSAGEをみれば、数値でどのくらい使われているかが分かる。
966 名前:デフォルトの名無しさん [2006/10/26(木) 05:22:04 ] f90glを使いたいのですが、導入の方法からつまづいています。 math.nist.gov/f90gl/f90gl-1.2.12.zip を取ってきたあと、どうすれば導入&コンパイルできるのですか? 環境はWindowsXP、cygwinでインストールしたOpenGLを使っています。 コンパイラは何を使うのでしょう?gfortran?g95?
967 名前:stack overflow [2006/10/26(木) 09:07:18 ] >>965 お騒がせしました。program無事に終了しています。 stack overflowが出る前は、debug modeで試すというのはやっていましたが、 そのあとの修正が反映されてなかったってことなのかな・・・ コンパイルはしてたはずだったんですが・・・ 初心者なもんでお許しを 何がともあれできてよかったっす。ありがとうございました。
968 名前:stack overflow [2006/10/26(木) 10:53:04 ] できたと思ったのですが、やっぱりできていませんでした。 昨日か一昨日、どこでメモリが食われているのか、調べるために 出力の部分をコメントアウトしたりしていたのですが、 コメントアウトしたままで実行したので動いていたようです。 やはり、出力時にメモリが使われているようです。 出力はバイナリ形式なんですが、なにか関係があるのかなあ・・・
969 名前:デフォルトの名無しさん mailto:sage [2006/10/26(木) 22:03:07 ] >>966 まず、f90glから使える GLUTが必要。 これは(少々バージョンが古いようだが)ソースとWindows用にコンパイルした物が f90gl Softwareのページから拾える。 次に f90gl-*/INSTALL, mf_keyをよく読んで自分の使っているOS/C/Fortranコンパイラに 合ったMakefile(mf*)またはバッチファイル(mf8n*.bat)を探す。 適切な物が見つかれば、それを自分の環境に合わせて修正し makeまたはバッチファイルを実行し、ライブラリとモジュールファイルを作る。 適切な物がなければ、似たような物から自分でMakefile/バッチファイルを作るか Makefile/バッチファイルの処理内容を見て手動でコンパイルする。 f90gl-1.2.12.zipにはcygwin gcc + g95/gfortran用のmf*は含まれていないようなので 自分でMakefileを作るしかないようだな。
970 名前:デフォルトの名無しさん [2006/10/26(木) 22:54:26 ] >968 or1cedar.cps.intel.com/ISN/Community/en-US/forums/thread/30223289.aspx まずはここを嫁 コメントアウトして動くようになった行をうpれ!
971 名前:デフォルトの名無しさん [2006/10/26(木) 23:43:58 ] VC++を勉強しようと思うのですが、お勧めの参考書があれば教えてください!!
972 名前:デフォルトの名無しさん [2006/10/27(金) 00:14:28 ] >>971 つ ttp://www.amazon.co.jp/gp/product/4320029658
973 名前:stack overflow [2006/10/27(金) 00:38:09 ] >>970 コメントアウトの行は、出力部分で、 ファイル形式が某企業のもので詳しく載せれません。 open文×10 write文×20 close×10 もうそろそろ諦めます。 最後に紹介して頂いたintelのサイトに書いてあるのは、誰かが出したエラーの原因か何かですか? 英語苦手なんで、どういうサイトなのかだけ教えてください。
974 名前:966 mailto:sage [2006/10/27(金) 02:15:38 ] >969 丁寧にありがとうございます!