• 締切済み

Fortranについて教えてください!

こんにちわ。 ヤマといいます。 以下について教えて頂けないでしょうか? ------------------- 途中省略 ------------------- DO 31 I = 1,NCARDS LC = LC + 1 READ(8,FMAT) (XR(J), J=1,NPL) IF(I.NE.NCARDS) GO TO 6 IF(JL.EQ.0) GO TO 6 JL=NPL+1-JL DO 5 J=JL,NPL 5 XR(J)=0. C--------------------------------------------------------------- C ONLY PRINT OUT A FEW OF THE FIRST AND THE LAST LINES of Input Motion C--------------------------------------------------------------- 6 ICHECK = NCARDS - I IF (I .LE. 5 .OR. ICHECK .LT. 5) WRITE(6,2008) I,(XR(J), J=1,NPL) IF (I .EQ. 10) WRITE (6,2009) 2009 FORMAT(3X,'........ INPUT MOTION READ NOT ECHOED...........') C ENDIF C C FIND MAX. INPUT ACC. (XMAX) C 311 DO 31 J = 1,NPL,2 N = N + 1 X(N) = CMPLX(XR(J),XR(J+1)) 31 CONTINUE ........................................... とあります。 いま、XRは、 ----------------データ------------------------ -0.001694 -0.001668 -0.000086 -0.001356 -0.000678 0.000700 -0.001209 -0.000604 ・・・・・・・・・・・・・・・・・・・・・ ----------------データ------------------------ と1行に8列分のデータが存在します。 ソース中に「CMPLX(XR(J),XR(J+1))」とあります。 この意味がよく分かりません。通常だと実部にXR(J),虚部 にXR(J+1)を入れるというように解釈できるのですが、 本当でしょうか?ご存知の方ご意見よろしくお願いいたします。

みんなの回答

noname#65504
noname#65504
回答No.9

#1,4,6,7です。 FFTという情報が出ており、既に#5,8で解答が出ているようです必要ないと思いますが、 もし、FFTのプログラミングを勉強中でしたら、以下の書籍にも理論及びFORTRANのソースが書かれていますので、参考にされてはいかがでしょうか? 日野 幹雄 著「統計ライブラリー スペクトル解析」1977年 朝倉書店 ISBN 4-254-12511-9 大崎 順彦 著 「新・地震動のスペクトル解析入門」1994年 鹿島出版会 ISBN 4-306-03270-1 後者はスペクトルの定義が一般のものと若干異なった定義をしているので取扱は注意する必要がありますが、フーリエ解析の入門書としてはお勧めです(建築・土木系の方でしたら特に)。

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.8

No. 2 = No. 5 ですが蛇足です。 実データ x(0), x(1), ...., x(N-1) の DFT は F(k) = Σ[j=0, N-1] W^jk x(j), ここで W = exp(-i 2π/N): 回転因子, i は虚数単位 x(j) を偶数番目と奇数番目にわけると F(k) = Σ[j=0, N/2-1] W^2jk x(2j) + Σ[j=0, N/2-1] W^(2j+1)k x(2j+1) = Σ[j=0, N/2-1] U^jk x(2j) + W^k Σ[j=0, N/2-1] U^jk x(2j+1), ここで U = W^2: N/2 での回転因子 となって、最右辺第1項は偶数番目のデータの DFT、第2項は奇数番目のデータの DFT です。ただし、サンプル数は N/2 と半分になっています。 お尋ねの問題では、偶数番目 x(2j) を実部、奇数番目 x(2j+1) を虚部に入れて DFT (N/2) を計算するのですが、得られた DFT とその共役複素数から、実部、虚部それぞれの DFT (N/2) を簡単に計算できます。それを上の式に代入することにより、サンプル数 N の DFT が計算できます。N が大きくなると計算量は FFT の計算量が支配的で、ほぼ半分の計算時間ですみます。 昔の FORTRAN は配列の添え字に 0 が許されないので、DFT の式との対応で苦労したものです。

noname#65504
noname#65504
回答No.7

#6の訂正 FORTRANの場合、累乗を示すのは 「^」ではなくで「**」の間違いでした。 時刻歴波形を用いて複素数を計算するのはFFTがぱっと思いつきます。 たしか1960年代半ばにFFTを用いた計算法が用いられるようになったので、プログラムの作成時代からいっても、#5さんの解答にもあるようにFFT(高速フーリエ変換)でしょうか?

yamayama1
質問者

お礼

ご回答ありがとうございます。その通りです。FFTの計算に使用いたします。

noname#65504
noname#65504
回答No.6

#1,4です。 #4を書いている間に#2さんに補足していたようで、#2さんへの補足で入力データが時刻歴データであることがわかりました。 入力データは加速度時刻歴ですね(質問文のコメントにACCとあるので)。 #4で書いた内容と相反するのですが、なぜ複素数化するのかと言うことと、複素数の絶対値をとると言うことの意味を考えてみましたので、書き込みします。 実数上で扱うと、サブルーチンの計算部分は以下のような内容になります。 XMAX=0. DO 1 I=1,MX XA = SQRT(XR(I)^2+XR(I+1)^2) IF (XMAX.GT.XA) GO TO 1 NXMAX = I XMAX = XA 1 CONTINUE これは連続した2つのデータの2乗和の平方根を求めています。 なぜそんなすること、計算目的が書いていないのではよくわかりませんが、エネルギーとしてのデータに変換する(速度データでしたら速度の2乗は運動エネルギーに比例する量なのですが、加速度のようですから物理的な意味はちょっとわかりません)、平均化・スムージングするなどの理由を思いつきます。 なお、もしXA = SQRT((XR(I)^2+XR(I+1)^2)/2)なら時間刻み分の時間を時定数とした実行値を求めていることになります。 わざわざ複素数化して計算したのは、計算上のテクニックだと推定されます。 特に補足にあったサブルーチンのコードされた年が1971年10月になっており、データ入力もカードから読み込んでいるような時代のもののような記述になっています(NCARDSとかいう変数があるので)。 このプログラムが書かれた当時のコンピュータは汎用の大型計算機でもかなりメモリが小さかったために、大量データの計算を行う際にメモリを有効に使う方法として一見変な方法を用いて計算するという手法を高度なプログラマーは用いていることがあったのでそのためではないかと思います。 ちなみにX(J)=CMPLX(XR(J),0.0)という複素変換は実数の時刻歴波形をから周波数分析を行う際に、複素領域上の計算が必要なFFTのプログラムなどでよく使用します。 都合により本日はこれにて失礼しますが、補足が必要でしたら書き込んでおいてください。明日なら補足できます。

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.5

No. 2 です。 私のアドバイスへのお礼で、「時時刻暦波形(意味不明)」を左から順に X に入れるとあります。 しかし、プログラムを見ると波形(恐らく等間隔にサンプリングされた値)が配列 XR に読み込まれ、それを2個づつまとめて複素数配列 X に格納しています。 これから推測されることはFFTをさらに高速(2倍速)にするためではないかと思われます。普通にFFTを行うには、実部にデータを入れ虚部を0としてデータ配列を作り、FFTサブルーチンを呼びます。しかし、これではデータが実数であるという特性を生かしていません。 データが実であるとき、この例のように実部と虚部に交互にデータを入れ、FFTを呼ぶとデータ数が半分で済みます(FFTの出力に細工をする必要はあります)。 それ以外に、同質のデータを実部と虚部に交互に入れる必要性は思い浮かびません。

yamayama1
質問者

お礼

おはようございます!失礼いたしました。「時時刻暦波形」ではなく「時刻暦波形」の間違いでした。これは具体的に言えば、地震波形のデータを並べたものになります。 それと、複素数配列Xの実部と虚部にに実であるデータを交互に入れるという方法ならばデータ数が半分で済むということは初めて知りました。賢いですね、ありがとうございました。

noname#65504
noname#65504
回答No.4

#1です。補足に対してアドバイスします。 計算目的がよくわからないので、推定で書きます。データ自体は時刻歴のようなもののデータのようですので、何の計算をしているのかもわかりません。 何のための計算をするプログラムなのかを書いてもらえればもう少し推測できるのですが、 まず、複素数の絶対値を求める組み込み関数ははABSではなく、CABSです。 つぎに、サブルーチンでdimension文でX(1)と型宣言していますので、サブルーチン内ではXは実数となっています。またABSを用いていること、XMAX = 0.となっていることもサブルーチン内では、Xは実数扱いとなっています。すなわちサブルーチン内では単純に実数Xの絶対値を求めています。 データが時刻歴のような時間変動するデータでしたらこのサブルーチンはその時間内のデータ最大値を求めているだけです。 なぜこんなことになっているのかは、call文がきちんと書いてないので推定ですが、上記のことから、主文とサブルーチン内で同じ名称の変数Xを用いていても、同じ変数を意味していない可能性があります。すなわち変数名は一緒でも違う数値を取り扱っているということです。 call分の引数の位置とsubroutine文の引数の位置をチェックしてみてください。call文の最初の位置に来ている変数の値ががサブルーチン内のXに引き継がれています。 SUBROUTINE XMX(X,MX,XMAX,NXMAX) 万が一主文で複素数のXが実数としてサブルーチン内に引き継がれているようでしたら、計算自体うまくいかないものと思います。 なお、FORTRANではサブルーチン内と主文などで変数名は独立しており、同じ名称をしても関係のない変数として取り扱えます。主文とサブルーチン文の変数を関係付けているのはcall文とsubroutine文の並びやcommon文です(本ケースでは使用していないようですが)。

  • cubics
  • ベストアンサー率41% (1748/4171)
回答No.3

なぜ複素数の絶対値を取るか、そもそも問題が書いてないので、決定的なことは何もわかりませんが、推測できるのは、データが2個ずつ意味をもつこと、たとえば平面座標系の座標値として、減点からの距離が最大な座標を求める問題、といったことですね。 複素数を用いたのは、組み込み関数で、計算のステップを減らしたということしか、これだけの質問では推測しかねます。

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.2

No. 1 への補足についてですが 「そもそもどうして、こんなことをするのか分かりません。」は、このサブルーチンの内容でしょうか。複素数の配列の中での絶対値の最大値と、その要素の番号を求めるサブルーチンですね。なお、X には Complex 宣言が必要です。「X(J)=CMPLX(XR(J),0.0)とすべきか」と書かれていますが、それでは複素数にはなりません。読み込んだデータを実部に入れただけで、本質的には複素数になっていません。このプログラムでは、入力データを2個1組にして、実部・虚部にかわるがわる入れた複素数を作っています。その複素数配列の中で絶対値の最大値が必要なんです。 もしかして、最初の質問のプログラムで JL=NPL+1-JL DO 5 J=JL,NPL 5 XR(J)=0. としている部分のことでしょうか。"JL=NPL+1-JL" の右辺の JL は最初どこかで値が定められており、左辺の JL は後ろから数えた JL 番目の番号です。この DO ループは JL より後ろの値を全部0にクリアする目的です。(ただし、このように一つの変数に二つの意味を持たせるのはバグ要因です。)なぜ0でクリアする必要があるかというと、恐らく配列 X は繰り返し使われるので、データ数が少ないとき配列の後ろに以前の値が残ると困るので掃除しています。 なお、プログラムにはいくつかバグがあるように見受けられます。

yamayama1
質問者

お礼

大変申し訳ありません。実はこのXR(J)に入る値は時時刻暦波形を左から右に順番に時間刻み0.02秒毎に示しています。つまり、X(J=0)は時刻0sの値、X(J=1)は時刻0.02秒での値、X(J=2)は時刻0.04秒での値、・・・・と与えています。したがってXRの値そのものが実数値になっています。ご指摘のように実部にXRを入れて、虚部に0を入れてもXは複素数にはなりません。ここでは文が長くなると投稿できないので、前文・後文を省略させて頂いておりますが、確かにXはComplexで宣言しています。JLの値も実は前文に出てくるので、ちゃんと入っています(JL=4)。

noname#65504
noname#65504
回答No.1

CMPLXはFORTRANの組み込み関数で、複素数変換を行うためのものです。 パラメータを2つ取り、CMPLX(a,b)としたとき、質問文にあるとおり、aが実部、bが虚数部の数字になります。 また上記の例でいうと、最初に型宣言文COMPLEXでXが複素数であることを定義しておく必要があります(FORTRANでは複素数は1つの変数として取り扱えます)。 ちなみに複素数の変数から実部を取り出すにはREAL,虚部を取り出すのにはAIMAGという組み込み関数を使用します。

yamayama1
質問者

お礼

ご回答ありがとうございます。やはりそうですか。。。このXR(J)に入る値としましては、時間間隔が0.02秒毎に与えられている8F10.6形式の数字を読み込んでいきます。複素数X(N)に入れたものを今度は、 サブルーチンXMX(X,MA,XM,NXMAX)をコールして、それらXの内の最大値を取ろうとしています(入力:X,MA,出力:XM,NXMAX)。ちなみに、 C************************************* SUBROUTINE XMX(X,MX,XMAX,NXMAX) C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C C THIS ROUTINE FIND MAX. VALUE, XMAX, AND NUMBER OF MAX. VALUE, NXMAX. C OF ARRAY X WITH MX NUMBER OF VALUES C C CODED PER B SCHNABEL OCT. 1971 C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C DIMENSION X(1) XMAX = 0. DO 1 I = 1,MX XA = ABS(X(I)) IF (XMAX.GT.XA) GO TO 1 NXMAX = I XMAX = XA 1 CONTINUE RETURN END C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * です。 そもそもどうして、こんなことをするのか分かりません。 それをするならば、X(J)=CMPLX(XR(J),0.0)とすべきかかと思いました。なぜとなりの列を虚部にする必要があるのでしょうか?

関連するQ&A

  • FORTRANの質問です

    今、実験の解析を行っています。 読み込みたいテキストファイルには -1,0.4 0,0,233 -1,0.9 ・・など左側には-1か0のどちらかがあります。 これを -1,0.4 -1,0.9 を含むファイルと 0,0.0233 を含むファイルの二つに分けたいのです。 今プログラムを作っているのですがどうしてもできません。 どうしたらいいのでしょうか? と質問しました。説明不足気味だったので、追加で説明させていただきます。 データの数はかわります。5個だったり、900個だったりします。 この数はわかりません。 program dat real n(10), y(10) write(*,*)'k=' read(*,*)k open(7,file='test.txt') do i=1,k read(7,*,end=200) n(i),y(i) end do 200 close(7) open(8,file='aftest1.txt') open(9,file='aftest2.txt') do j=1,k if(n(j).eq.0) then write(8,*) y(j) else if(n(j).eq.-1) then write(9,*) y(j) end if end do close(8) close(9) end と書いたのですがデータの数と繰り返しの数が一致しないと、出力されません。 いちいちファイルをみるのは面倒なので、なんとか したいのですが

  • fortran errorについて

    fortranを勉強していたのですがエラーがでてしまい、何時間かけても理解できなかったので質問させてください。 以下プログラム program test !ここからメインルーチン !前準備 配列の用意 implicit none integer N integer,dimension(0:N,0:N) :: A integer :: i,j,k read * ,N !初期状態の代入 do i=0,N do j=0,N A(i,j)=0 end do end do do i=N/2,N-1 A(N/2,i)=1 end do do i=N/2,N-1 A(N/2+1,i)=-1 end do !ループ 50回ループさせる do k=0,50 !状態の表示 call visualize !サブルーチン visualize subroutine visualize do i=0,N do j=0,N if(A(i,j)== 1) write(*,'(A1)',advance='NO') "*" if(A(i,j)== 0) write(*,'(A1)',advance='NO') " " if(A(i,j)==-1) write(*,'(A1)',advance='NO') "+" end do write(*,*) end do !end subroutine visualize call insert !サブルーチン insert subroutine insert do i=0,N do j=0,N if(A(i,j)== 1) A(i,j)=-1 if(A(i,j)== 0) A(i,j)=max(0,A(i-1,j),A(i,j-1),A(i,j+1),A(i+1,j)) if(A(i,j)==-1) A(i,j)=0 end do end do !end subroutine insert end do end program test これでコンパイラすると In file test.f90:48 subroutine visualize 1 Error: Unclassifiable statement at (1) In file test.f90:69 subroutine insert 1 Error: Unclassifiable statement at (1) とでます いろいろ調べたのですが全くわかりませんでした できればよろしくお願いします

  • FORTRANでのプログラミングについて

    学校で下記のカッコ内を埋めなければいけないのですが、まったく分からなくて困っています。どなたか教えてくださいませんか?下のプログラムが分かりにくくてごめんなさい。 年賀はがきの当選番号(下二ケタ)5本を配列に登録しておき、コンソールから年賀はがきの下二桁の数字を入力するたびに、あたりはずれを返すプログラムを書きなさい。 登録用当選番号 07 12 35 46 77 1.配列に登録するというのは代入しておくことです。 2.入力は下2けたのみの入力とする 3.999を入力したら終了することとする 4.あたり・はずれは画面に表示すればよい 5.入力されたデータが5つの配列と同じかどうかを 比較して、同じ場合にはあたりを表示する命令文に とぶ。 6.あたりを表示したらデータ入力にもどる 7.同じ数値が無い場合は、はずれと表示してデータ 入力にもどる プログラム integer d(5),i,j,n d(1)=7 d(2)=12 d(3)=35 d(4)=46 d(5)=77 20 ( ) ( ) go to 40 do 10 ( ) if(d(i).eq.n) then write(6,*) ( ) go to 20 end if 10 continue write(6,*) ( ) go to 20 40 stop end

  • fortran go to 文

    以下のgo to文で書かれたプログラムをdoループのプログラムに書き直したいのですがどのように直してよいかわかりません。どなたかわかる方がいらっしゃったら教えて下さい。よろしくお願いします。 subroutine fft_eth(n,cx,icon,irr) implicit none integer :: n, m, ii, l, lb, llb, k, kl, kb, klb, & j, jl, jl2, jlb, jb, jb2, jb4, jj, j1, j2, jjb, jf1, jf2, jff, jf real(8) :: fn, ff, fkl, fjl, fm, ffm, fklb, fjlb, th, th2, st, tt real(8) :: icon real(8) :: irr complex(8) :: ct, cu, ca, cx, cuc dimension cx(n) real(8), parameter :: pi = 3.141592653589793238462643d0 if(n < 2) go to 900 fn = n m = idnint(dlog(fn)/dlog(2.0d0)) ii = 2**m-n if(ii /= 0) go to 910 do 50 l = 1, m kl = 2**(l-1) fkl =kl fjl = 0.5d0*fn/fkl jl = fjl jl2 = 2*jl th = 2.0d0*pi*fkl/fn th2 = 0.5d0*th st = dsin(th) tt = -2.0d0*dsin(th2)*dsin(th2) ct = dcmplx(tt,st) do 40 k = 1, kl jj = jl2*(k-1) cu = (1.0d0,0.0d0) do 30 j = 1, jl j1 = j+jj j2 = j1+jl ca = cx(j1)-cx(j2) if(icon < 0) go to 10 cuc = dconjg(cu) cx(j2) = ca*cuc go to 20 10 continue cx(j2) = ca*cu 20 continue cu = cu+cu*ct 30 continue 40 continue 50 continue !================= ! BIT REVERSAL !================= fm = m ffm = 0.5d0*fm llb = ffm do 80 lb = 1, llb klb = 2**(lb-1) fklb =klb fjlb = 0.25d0*fn/fklb jlb = fjlb jb2 = 2*jlb jb4 = 4*jlb do 70 kb = 1, klb jjb = jb4*(kb-1) jf1 = jjb+klb jf2 = jjb+jb2 do 60 jb = 1, jlb ff = jb-1 ff = ff/fklb jff = ff jf = jb+jff*klb j1 = jf+jf1 j2 = jf+jf2 ct = cx(j1) cx(j1) = cx(j2) cx(j2) = ct 60 continue 70 continue 80 continue !======================= ! ERROR CONDITION CODE !======================= irr = 0 return 900 continue irr = -1 return 910 continue irr = -2 return end subroutine

  • FORTRAN初心者です

    以下のようなプログラミングを研究室の課題で作ってみたのですがDCSの値がどうしてもINFとなっていしまいます。どなたかエラー箇所を教えてくださいませんか? DIMENSION DCS(0:20) INTEGER*4 I,N DATA EXP1,PI/2.718281828,3.14159/ REAL*8 FKD,FKR,V2,CN,FN1 C FKD=10.0;FKR=20.0;V2=0.5;CN=1.0;FN1=1.0 N = 10 C DO 30 I = 0,N IF(I.EQ.0) THEN DCS = 0.0 GOTO 30 ELSE FNU00 = V2*FLOAT(I) FNU01 = V2*FLOAT(I+1) CN = CN/FN1 DCS1 = (-1.0/(PI*FKD))*(FKR/FKD)**(FNU00) DCS2 = (1.0/PI*SQRT(FNU00*FNU01))*((FNU00/FNU01) 1 *(FKR/FKD))**(FNU00)*(2*FNU01/(EXP1*KD)) DCS3 = (1.0/(PI*FKD))*(FKD/FKR)**(FNU00) DCS4 = -(1.0/(PI*SQRT(FNU00*FNU01))*((FNU00/FNU01) 1 *(FKD/FKR))**(FNU00)*((EXP1*KD)/(2*FNU01))) DCS = CN*(DCS1+DCS2+DCS3+DCS4) END IF 30 CONTINUE C OUTPUT THE RESULTS DO 50 I = 0,N WRITE(6,40) I,DCS(I) 40 FORMAT(2X,'I=',I3,2X,'DCS=',E12.8) 50 CONTINUE END

  • FORTRAN 初心者です

    以下の連立一次方程式をSOR法で解く問題です。 初心者なりにガウスザイデル法を応用してプログラムしたつもりですが、やはり難しいです(答えは違います)。 どこをどうすれば良いのか分かりませんので、よろしければヒントや助言をいただきたいです。 PROGRAM SOR REAL A(10,10),B(10),X(10),X0(10) INTEGER N,I,J,K,Kmax,w N=3 A(1,1)=4 ;A(1,2)=1 ;A(1,3)=2 A(2,1)=1 ;A(2,2)=3 ;A(2,3)=1 A(3,1)=1 ;A(3,2)=2 ;A(3,3)=5 B(1)=16 B(2)=10 B(3)=12 X0(1)=1 ;X0(2)=1 ;X0(3)=2 w=1.2 Kmax=50 EPS=1.D-5 DO I=1,N D=A(I,I) S=B(I) B(I)=B(I)/D END DO DO K=1,Kmax DO I=1,N DO J=1,N if(J<I) X0(J)=X(J) S=S-A(I,J)*X0(J) END DO X(I)=(1-w)*X(I)+w*S END DO DO I=1,N S=S-(X(I)-X0(I))**2 END DO IF(S<EPS) GOTO 10 DO I=1,N X0(I)=X(I) END DO END DO 10 WRITE(*,*) K DO I=1,N WRITE(*,*) 'SOR法で求めた解は' WRITE(*,*) 'X(',I,')=',X(I) END DO END PROGRAM SOR !------------------------------------ ※wは緩和係数です

  • fortran エラーについて

    fortranで、副プログラムを使ってデータを昇順または降順に並べ替えるプログラムを入力して実行しようとしたところ、 ・Unexpected junk in formal argument list at (1) ・Two main PROGRAMs at (1) and (2) という2つのエラーが出ました。 これらの改善方法を教えて頂きたいです。 初心者ですので簡単なところで間違えている可能性もありますが、ご指摘いただければ幸いです。 以下、実際に入力したプログラムです。 ------------------------------ implicit none integer::i,n real::x(1000),a(1000),b(1000) n=1000 open(10,file='input-data-1.txt') do i=1,n read(10,*) x(i) end do close(10) open(10,file='output-data-1.txt') do i=1,n call koukan(i,x(i),a(i),b(i)) write(10,'(i4,2f10.3)') i,a(i),b(i) end do close(10) stop end subroutine koukan(i,x(i),shoujun,koujun) implicit none integer::i,n,made real::x(1000),w,shoujun,koujun do made=n-1,1,-1 do i=1,made if(x(i)>x(i+1)) then w=x(i) x(i)=x(i+1) x(i+1)=w end if end do end do shoujun=x(i) do made=n-1,1,-1 do i=1,made if(x(i)<x(i+1)) then w=x(i) x(i)=x(i+1) x(i+1)=w end if end do end do koujun=x(i) return end ------------------------------

  • fortran allocateを使って配列宣言を

    今変数 aについて考えています.aは i,jの2次元の座標におけるデータです. a(1,1)は10個配列を持ちたい a(1,2)は5配列を持ちたい a(i,j)はn個配列を持ちたい このような場合どのように配列を定義すれば良いのでしょうか? 例えば 2次元の大きさが3x3の場合で,それぞれの位置に配列したいデータ個数をnとします. nには既に個数が定義されているとします.このとき aの配列は nを使ってどのように定義すれば良いのでしょうか? integer n(3,3) integer i,j real, allocatable :: a(:,:,:) do j=1,3 do i=1,3 n(i,j)=i*j end do end do do j=1,3 do i=1,3 allocate (a(n(i,j),3,3)) end do end do では aの宣言が重複するためエラーになってします. 何方か良い方法を教えて下さい.

  • Fortranの素数のプログラム

    5000万までの素数を求めるプログラムなのですが、私の作ったプログラムは実行時間26秒くらいかかります。 先生が言うには10秒台が出るとのことですが、私は頑張っても時間を短くすることができません。 下に私の作ったプログラムを載せますので短くする方法を教えて下さい。 integer table(2:50000000),pno(50000000),cnt,m,i,j m=sqrt(50000000.) do 10 i=2,m do 10 j=i*2,50000000,i table(j)=1 10 continue do 20 i=2,50000000 if(table(i).eq.0)then cnt=cnt+1 end if 20 continue write(6,610)cnt 610 format('sosu no goukei =',i8) end

  • FORTRANのプログラム

    今、実験の解析を行っています。 読み込みたいテキストファイルには -1,0.4 0,0,233 -1,0.9 ・・など左側には-1か0のどちらかがあります。 これを -1,0.4 -1,0.9 を含むファイルと 0,0.0233 を含むファイルの二つに分けたいのです。 今プログラムを作っているのですがどうしてもできません。 どうしたらいいのでしょうか? program dat real x(10), y(10) open(7,file='test.txt') do i=1,10 read(7,*,end=200) x(i),y(i) end do do j=1,10 if(x(j).eq.0.0) then open(8,file='aftest1.txt') write(8,*) y(j) else open(9,file='aftest2.txt') write(9,*) y(j) end do close(8) close(9) 200 close(7) end

専門家に質問してみよう