• ベストアンサー

fortranのデータ読み込み

fortranで下記の読み込みたいデータがあります。 j k R(j,k) L(j,k) 1 1 5 1 1 2 10 2 1 3 15 3 1 4 20 4 2 1 25 5 2 2 30 6 データが9000行あるので, do i=1,9000 read(10,*) j(i) k(i) enddo のような読み込み方だと配列が大きすぎてだめなんです。 他の方法を知っている方、教えていただけませんか。 よろしくお願いします。

  • koon1
  • お礼率69% (18/26)

質問者が選んだベストアンサー

  • ベストアンサー
  • gtx456gtx
  • ベストアンサー率18% (194/1035)
回答No.4

学校の宿題でなければ、 「配列が大きすぎてだめなんです。」は、配列ではなくデータベースを利用すれば取り扱うデータに事実上の制限はないです。 SQLiteという、無償・簡単・結構高性能なデータベースが使えますよ ^ ^

koon1
質問者

お礼

色々考えた結果、データの読み込みというよりは、計算過程でいらないデータを保持しすぎているような気がしてきました。 SQLITE...初心者なので結構未知な世界ですが、これからもプログラムは使用していくので、ぜひ利用してみたいと思います。 いろいろわかりづらくて申し訳ありませんでした。 また、よろしくお願い致します。

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

質問をするときには, なるべく実際のものを書いてください. でないと, このように無駄なやりとりをしなければなりません. そもそもそのプログラムは何をしたいのですか? データはどのくらい保持する必要があるのですか? 「i=9000ではなくてD(j,k,l,m)にしたい」とはどういうことですか?

koon1
質問者

お礼

わかりづらい質問で申し訳ありませんでした。これからは気をつけます。 あと、もっと整理してから質問するようにします。 上記の悩みも解決致しましたので、締め切らせていただきます。 ご回答ありがとうごさいました。

koon1
質問者

補足

お手間おかけしてしまい申し訳ありません。 そもそも、やりたいのは、あるイベントが50年間に9000回起こるのですが、そのイベントで発生したものAを用いて(Aはデータとしてあります)、新たにBを計算し、2回目のイベントAに1回目で求めたBを使って、あらたなBを計算したいのです。それを繰り返します。ただし、年の一番初めだけBをある量C減らします。 なので、1イベント前のデータだけ保持していれば大丈夫です。 プログラムは長くて載せられないのですが、配列を小さくする必要があるみたいです。 今まではループを9000でまわしていて、D(i=9000,l,m)を用いてたのですが、D(j=YEAR,k=EVENT,l,m)にしたら、jは最大50でkも最大250なので、配列が小さくなるのかなと思ったのですが、今思ったら変わらないですね。。。すみません、これは忘れて下さい。。 おそらくデータをすべて保持しているからだめな気がします。 1イベント前のデータのみ残して、後は消すことをしたいのですが、どうしたらいいのでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「配列が大きすぎてだめ」とは, 具体的にどういうことなんでしょうか? まさか「配列が大きすぎてだめ」とまさにそのままのエラーメッセージが出ているわけではないですよね? あと, 処理系もきちんと書いてください.

koon1
質問者

補足

説明不足ですみません。 もともとは配列D(i,l,m)だったのですが(i=9000,l,m=500でプログラムの中にこのような配列がいくつか登場します)大きすぎだったのです。 エラーメッセージは静的~が超えました、みたいなエラーでした。 そこで、i=9000ではなくて D(j,k,l,m)にしたいのです。 詳しくいうと jが年数、kがイベントの数で、j年のときにイベントが1,2,3,・・・kと増えていき、新しい年になったらまた1,2,3・・・とイベントが増えるようデータを読み込みたいのです。 ちなみに前まで使っていたiは総イベント数でした。 do j=1,year do k=1,event 処理例 x(j,k)=R(j,k)*2   end do end do みたいに使いたいです。 わかりにくかったらすみませんが、また質問してください。

  • gtx456gtx
  • ベストアンサー率18% (194/1035)
回答No.1

いまどき9,000行のデータで配列が「大きすぎてだめ」なんてないでしょう! 「普通に読んだらNGなデータをどう処理するか?」という学校の宿題でないですか?

koon1
質問者

補足

説明不足ですみません。 もともとは配列D(i,l,m)だったのですが(i=9000,l,m=500でプログラムの中にこのような配列がいくつか登場します)大きすぎだったのです。 そこで、i=9000ではなくて D(j,k,l,m)にしたいのです。 詳しくいうと jが年数、kがイベントの数で、j年のときにイベントが1,2,3,・・・kと増えていき、新しい年になったらまた1,2,3・・・とイベントが増えるようにしたいのです。 ちなみに前まで使っていたiは総イベント数でした。 わかりにくかったらすみませんが、また質問してください。

関連するQ&A

  • 【fortran77】空行を含む数値データの読み込み

    fortran77でプログラムを書いています。 いま以下のような空行を含むデータファイルを読み込んで、プログラム中で計算し、その結果を別のファイルに書き出すものを作りたいと考えています。 1.0 1.1 1.2 1.3 1.0 1.4 1.5 1.6 2.0 2.1 2.2 2.3 2.0 2.4 2.5 2.6 3.0 3.1 3.2 3.3 3.0 3.4 3.5 3.6 *数字はあくまでも例です。 例えば、1列目が2.0で始まる箇所のみ取り出したいのですが、どうもデータの読み込みのところでエラーが起こっているようです。 open(1,file="data.dat") do i = 1,8 read(1,*) (a(i,j),j=1,4) enddo 空行や空白の読み飛ばしを行う方法を自分なりに調べてみて、open文にblankを指定するなどの方法があることはわかったんですが、いまいち使いかたがわからず立ち止まってしまいました。 よろしくお願いします。

  • fortranでテキストデータ読込できない。教えて下さい。

    fortran95(g95)を使用しています。 以下のようなテキストファイルを読み込みたいのですができません。 a.txtの中身 ------------------------- 0.000000 -11084.0 1.940757E-03 0.000000 -11059.6 6.324515E-04 0.000000 -11035.2 2.825573E-02 0.000000 -11010.7 1.419570E-03 -------------------------- ----と-----の間のデータです。 最初に空白が3つ 次に8桁の実数 次に空白が1つ 次に8桁の実数(マイナス記号含む) 次に空白が2つ 最後に12桁の実数(指数含む) となっています。    real :: z(3,4)   open(1,FILE='a.txt')   do j = 1, 4 read(1,1000,end=99)(z(k,j), k=1,3) enddo 99 continue close(1) 1000 format(F11.6,F9.1,E14.6) 上記のようなコードを作成しています。 do j = 1,4 write(*,*) (z(k,j),k=1,3) enddo 上記のように出力させると 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. となります。 よくわからない。 分かる方、教えて下さい。 お願いします。

  • fortranで読み込んだ複数ファイルデータの見方

    また質問です。 character (13) :: fname do i = 1 , 3 write (fname ,"('sample_' , i2.2 , '.csv ')") , i enddo open (10 , file = fname) close (10) end fortranで連番のcsvファイルを上記のプログラムで読み込ませることはできたのですが、それぞれのファイルのデータの見方が分かりません。装置番号10でread文やwrite文を書くと最後に読み込んだファイルのデータしか見れません。どなたか教えてください。

  • 院試の問題(FORTRAN)で。

    FORTRANを昨日勉強し始めたばかりの初心者です。 とある大学院の試験問題でわからない部分があるので質問させていただきます。 問題文とソースは以下のとおりです。 以下のFORTRANプログラムについて、標準出力への出力を答えよ。 program main intger :: m(3,3),i,j,k,n n=3 m(1,1)=2; m(1,2)=1; m(1,3)=2 m(2,1)=2; m(2,2)=3; m(2,3)=12 m(3,1)=8; m(3,2)=-6; m(3,3)=2 do i=1,n-1 do j=i+1,n m(j,i)=m(j,i)/m(i,i) ← do k=i+1,n m(j,k)=m(j,k)-m(j,i)*m(i,k) enddo enddo enddo write(6,*) m(2,1),m(2,3),m(3,2),m(3,3) end これを計算していくとm(2,2)=0(計算ミスだったらすみません)となってしまって 上のソースの矢印の部分でエラーが出てしまうと思い、 それだと出力出来ないのではないかと思ったんですが、 それでは答えにならないので質問させていただきました。 コンパイラを使って実行してみたいのもやまやまなんですが、 なにしろ試験まで時間があまりないもので・・・ どなたか回答できる方いらっしゃいましたらよろしくお願いします!

  • fortranを用いた行列の掛け算について

    行列の掛け算についてなのですが、ある行列aを2乗した行列bを求める場合は以下のようなプログラムを書けば出来たのですが、これを3乗以上に拡張するためにはどうしたらよいのでしょうか? ______do i=1,3 ________do j=1,3 __________b(i,j)=0.D0 ____________do k=1,3 ______________b(i,j)=b(i,j)+a(i,k)*a(k,j) ____________enddo ________enddo ______enddo

  • fortran 配列受け渡し時の次元の一致

    fortran90、コンパイラはifortです。 普通メインプログラムとサブルーチン間での配列の受け渡しは、次元を揃えて渡すと思います。 とあるコード(以後コードA)を読んでいると、2次元配列を渡し、1次元配列で受け取っていました。 例 program test1 integer :: a(3,3) call testsub(a) end program subroutine testsub(b) integer :: b(9) end subroutine これが受け取り側でどう処理されているのかわからず、調べるために適当なテストコードを書きました。 a 123 456 789 ↓ b 123456789 になるとか 結果、コンパイルは通ったのですがサブルーチン側では全て0で置き換えられてしまいました。 コードAはpgiかなんかでコンパイルしていたようなのでコンパイラの違いでしょうか? よくわらなかったので質問させて頂きました。 質問をまとめますと、 (1)次元の異なる配列の受け渡しができるかどうか (2)その場合中身はどうなるか よろしくお願いします。 ---以下テストコード--- program testa implicit none integer :: a(3,3),i,j do i=1,3 do j=1,3 a(i,j)=j+(i-1)*3 enddo enddo do i=1,3 do j=1,3 write(6,*) a(i,j) enddo enddo call sub1(a) end program subroutine sub1(b) integer :: b(9),i do j=1,9 write(6,*) b(i),'sub' enddo end subroutine

  • FortranにあってCにない関数?について

    10年間Fortran90でプログラミングをしてきましたが、 C言語を使う必要があって、プログラムを書き直し中の者です。 入門書を数冊読んでいて疑問に思ったのですが、Fortranには、 A=SUM(B) と書けば、配列Bの全ての総和をAに返す、という関数があるのですが、C言語に同じような関数はないのでしょうか?(標準ライブラリに無いという事はないのでしょうか?) Fortranと比べてCは組み込み関数が少ないという印象を持ったのですが実際そうなのでしょうか? また、Fortanでは配列の和をとる時、 do i=0,n a(i)=b(i)+c(i) end do を一行で、 a(0:n)=b(0:n)+c(0:n) と書いても良いですし、もし定義されている全部の配列の要素が対象なら a=b+c と一行で書いても良いのですが、c言語では似たような書き方はできないのでしょうか? つまり、多次元配列を扱う時、Fortranでは単に「a=b+c」と書けば済むところを、Cでは for (i=0,i<=n,i++){ for (j=0,j<=n,j++){ for (k=0,k<=n,k++){ a[i][j][k]=b[i][j][k]+c[i][j][k]; }}} と書かなくてはいけないのか?と悩んでおります。 私がCの機能を知らないだけなのか、Cとはそうゆうことが出来ないのか、浅学なため判断できません。 ご教授ください、どうぞよろしくお願いいたします。

  • FORTRAN→Cに翻訳

     どなたか、次のFORTRANのプログラムを、Cに、翻訳して頂けないでしょうか。C++ではなく、Cです。ANSI準拠のCでお願いします。  プログラムの内容は、最小二乗法による計算プログラムです。MS-DOS Ver3.3~6.0の頃の、MS FORTRANコンパイラ仕様のものです。その頃持っていたFORTRANの本も処分してしまい、今からFORTRANを学びなおすのにも多大な労力と時間がかかりそうなので、Cに翻訳して頂ければ大変ありがたいです。よろしくお願いします。 (“□”はタブ) ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ C□LEAST SQUARE APPROXIMATION □PROGRAM MAIN9 □DIMENSION X(100),Y(100),S(0:18),T(0:9),SM(10,10),TV(10),AV(10) □WRITE(*,*) 'N ?' □READ(*,*) N □WRITE(*,*) 'x1,x2,..,xn ?' □READ(*,*) ( X(I),I=1,N ) □WRITE(*,*) 'y1,y2,..,yn ?' □READ(*,*) ( Y(I),I=1,N ) □WRITE(*,*) 'M ?' □READ(*,*) M □DO 110 K=0,M*2 □□VS=0. □□DO 100 I=1,N □100□VS=VS+X(I)**K □□S(K)=VS □110□CONTINUE □□DO 130 K=0,M □□□VS=0. □□□DO 120 I=1,N □120□VS=VS+Y(I)*X(I)**K □□□T(K)=VS □130 CONTINUE □□DO 140 I=1,M+1 □□□DO 140 J=1,M+1 □□□□K=I+J-2 □□□□SM(I,J)=S(K) □140 CONTINUE □□DO 150 I=1,M+1 □150 TV(I)=T(I-1) □□CALL SIMULE( AV, SM, TV, M+1 ) □□DO 160 I=1,M+1 □160 WRITE(*,1000) I-1,AV(I) □1000 FORMAT(1H ,'A',I1,'=',F10.5) □□STOP □□END ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

  • Fortranのエラー

    お世話になります。 Fortran初心者です。 いまFortranでcsvファイルからデータを読みこむといったプログラムを作成しようと思っております。 まず、行いたいことは、複数のcsvファイル(0001.csv→0004.csvなど)のデータをプログラムに読込ませたいのですがうまくいきません。 0001.csvや0002.csvとしたいのに、INNAME.csvとなってしまいます。 なので、次に0001.csvだけを指定してたのですが下のデータを全く読み込んでくれません。 ちなみに0001.csvは、このようなデータです。 0,0,-107.75939 ,-85.57285 ,0.00000 ,0.00000 ,0.00000 ,0.00000 1,0,-105.54305 ,-85.56864 ,0.00000 ,0.00000 ,0.00000 ,0.00000 2,0,-103.32661 ,-85.56443 ,0.00000 ,0.00000 ,0.00000 ,0.00000 3,0,-101.11009 ,-85.56022 ,0.00000 ,0.00000 ,0.00000 ,0.00000 - 7325,0,106.16862 ,80.19408 ,0.00000 ,0.00000 ,0.00000 ,0.00000 エラーの部分としては、 READ(j,*) x,y,xmm,ymm,U,V,W,Length であり、エラーが出て、ファイルを読んでくれません。  エラーは Invalid character in fieldと出て、readする書式が違うのかと 自分なりに原因を探し変更してみたのですがわかりませんでした。 みなさまお忙しいところ本当にすみません。 初心者なのでどこかつまづいているかもしれないのですが、それがわかりません。 ご教授頂けたら幸いです。 よろしくお願い致します。 プログラム全体だと長いので 以下がプログラムのはじめから途中までの中身です。 PROGRAM MAIN Implicit None INTEGER i,j,k,sample,x,y CHARACTER*4 INNAME       REAL xmm,ymm,U,V,W,Length DIMENSION x(7326),y(7326),xmm(7326),ymm(7326) & ,U(7326),V(7326),W(7326),Length(7326) i=1 j=1 x=0 y=0 WRITE(INNAME,'(I4.4)') j WRITE(*,*) INNAME !!変数INNAMEに返す値は0001です。 OPEN(j, file='0001.csv') !!'//INNAME//.csv'だとINNAME.csvに。0001.csv,0002.csvにしたい。 c !-- read data sample=7326 DO k=i,sample READ(j,*) x,y,xmm,ymm,U,V,W,Length !!READがうまくいかない。Invalid character in fieldのエラー ENDDO

  • fortran 途中まで考えたのですが。。。。

    エラトステネスのふるい(素数の倍数を除いていって残ったのが素数)で3桁の素数を求めて表示したいです。 私が考えたのは、 1・2~99までの数を素数かどうか調べて、素数を配列に入れていく 2・100~999まで素数の配列の中の数で割って、割り切れたらおしまい。割り切れなかったら表示していく ということです。 しかし下のプログラムではうまく素数配列ができていないようなのです。 ここまでかなり時間がかかったのでこのプログラムに手をいれて これ以外におかしくなるところもどこを直せばいいのか教えてくださるとうれしいです。 C C q223.f C PROGRAM q223 C IMPLICIT NONE C INTEGER N,i,K,s,l REAL a(99),b(99),c(99),X,Y C real M C a(1)=2 a(2)=3 l=2 C DO N=2,99,1 M=N**(0.5) S=M DO i=2,S,1 K=MOD(N,i) IF(K ==0)THEN exit ELSE IF(K /=0)THEN l=l+1 a(l)=N ENDIF ENDDO ENDDO C do N=100,999 do l=1,99 X=a(l) Y=N/X if(Y==0)then exit else if(Y/=0)then write(*,*)N end if end do end do c end よろしくおねがいします

専門家に質問してみよう