• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Fortranについての質問です。下のプログラムは、ある地点(今回は1)

Fortranによる気温データの平均値計算プログラム

f272の回答

  • f272
  • ベストアンサー率46% (8117/17343)
回答No.4

気がついたところ1 > 色々考えていたのですが、うまくまわりません。 ではなくて,どのようなエラーになるのかをちゃんと記述すること。 気がついたところ2 > real dimension(365、33) :: ndatax ではなくて, real,dimension(365、33) :: ndatax とすること。このままではコンパイルエラーになる。 気がついたところ3 > 1月1日は33個以上にいくことは恐らくないと考えています。 ではなくて,ちゃんと確認する。 ndata(doy) = ndata(doy) + 1 の次の行として if (ndata(doy)>=33) then print*,"Error: dimension overflow" stop endif としておけば確実です。 気がついたところ4 > write(6,*) i, temp(doy), ndata(doy) ではなくて write(6,*) doy, temp(doy), ndata(doy) のはずです。

ryoji
質問者

お礼

すごいです。できました。ありがとうございます。 文字制限の関係からエラーメッセージを載せれなかったのですが、次から工夫して載せるようにします。 ただ、2つの疑問がでました。 私の一番初めの質問した際のプログラムと今回のプログラムだと、値に誤差が出ています。エクセルで確認したところ、後者の方の値が間違っていました。 どうしてなのかでしょうか。。 また、標準偏差をつけてみたのですが、値が大きく違いました。これは、私のミスだと思いますが。 一応、今のプログラムを下に載せて起きます。もし、なにかお気づきになれば、アドバイスいただけると幸いです。 INTEGER :: sum, no, point INTEGER :: year, mon, day, data INTEGER :: doy REAL,dimension(365) :: temp REAL,dimension(365) :: stdev REAL,dimension(365) :: stdevplus,stdevminus INTEGER,dimension(365) :: ndata INTEGER,dimension(365,33) :: ndatax REAL :: lon, lat REAL :: ave, var CHARACTER*4 yyyy CHARACTER*5 sssss ndata(:)=0 temp(:)=0.0 do ispot=14161,14163 write(sssss,"(i5)") ispot do iwork=1976, 2008 write(yyyy,"(i4.4)") iwork open(50, file=''//sssss//'_temp'//yyyy//'.csv', status='old',iostat=io) if (io < 0) cycle ! write(6,*) ispot iwork do i = 1,366 read(50,*,iostat=io) id,year,mon,day,lon,lat,data if(io < 0) exit if(mon==2 .AND. day==29) then cycle endif call date2doy(year,mon,day,doy) ndata(doy) = ndata(doy) + 1 if( ndata(doy) > 33 ) then write(6,*)"Error" stop end if ndatax(doy,ndata(doy)) = data/10.0 ! ndata(doy)は一年のうち何日目か,個数を表している enddo close(50) enddo !!! end of year loop enddo do doy = 1,365 ave = 0.0 var = 0.0 do i=1,ndata(doy) ave = ave + ndatax(doy,i) var = var + ( ndatax(doy,i) - temp(doy))**2 end do if( ndata(doy) == 0 ) then temp(doy) = -99999.9 else temp(doy) = ave/ndata(doy) stdev(doy) = sqrt(var/(ndata(doy)-1)) endif stdevplus(doy) = temp(doy) + stdev(doy) stdevminus(doy) = temp(doy) - stdev(doy)   write(6,*) doy, temp(doy), ndata(doy),stdevplus(doy),stdevminus(doy) end do -------------------subroutine文省略--------------------------------------------

関連するQ&A

  • fortranについての質問です。

    fortranについての質問です。 このFortranは、頭にそれぞれ14161~14163とつく33個のファイル(1/1~12/31,欠損地あり1年分)を読んでいき、例えば1/1、1/2…と365日分の33年の平均値を導くはずなのですが、下のようなエラーがでます。おそらく、14161が2008までないからではないかと思うのですが、現在勉強中なので、なにかアドバイス、おかしいところ修正できるところがありましたらお願いします。 program sapporo_kikouchi    INTEGER :: sum, no, point INTEGER :: year, mon, day, data INTEGER :: doy REAL,dimension(365) :: temp, ndata REAL :: lon, lat CHARACTER*4 yyyy CHARACTER*5 sssss ndata(:)=0.0 temp(:)=0.0 do ispot=14161,14163 write(sssss,"(i5)") ispot do iwork=1976, 2008 write(yyyy,"(i4.4)") iwork open(50, file=''//sssss//'_temp'//yyyy//'.csv', status='old') ! write(6,*) ispot iwork    do i = 1,366 read(50,*,iostat=io) id,year,mon,day,lon,lat,data if(io < 0) exit if(mon==2 .AND. day==29) then cycle endif call date2doy(year,mon,day,doy) temp(doy) = temp(doy) + data/10.0 ndata(doy) = ndata(doy) + 1 end do close(50) enddo !!! end of year loop enddo do i=1,365 if( ndata(i) == 0 ) then temp(i) = -99999.9 else temp(i)=temp(i)/ndata(i) endif write(6,*) i, temp(i), ndata(i) enddo stop end program subroutine date2doy(iy,im,id,idoy) INTEGER,dimension(12) :: nday INTEGER :: uruu !!uruu=1: うるう年、uruu=0: 通常の年 uruu=0 DATA nday /31,28,31,30,31,30,31,31,30,31,30,31/ if(mod(iy,4)==0 .AND. mod(iy,100)/=0) then uruu=1 endif if(mod(iy,1000)==0) then uruu=1 endif !! うるう年も無視する itotal = 0 if( im /= 1 )then do m=1, im-1 itotal = itotal + nday(m) enddo endif idoy = id + itotal ! write(6,*) iy,im,id, idoy return end ------------------------------------------------------------------------------ At line 18 of file kikouchi.f90 file: "14161_temp1993.csv" Traceback: not available, compile with -ftrace=frame or -ftrace=full Fortran runtime error: 指定されたファイルが見つかりません。 -------------------------------------------------------------------------------

  • FORTRANについての質問です。

    FORTRANについての質問です。 現在、二つのファイル(a.csv,b.csv)を読んで,a.csvのファイル内の地点番号とb.csvのファイル内の地点番号が一緒なら抜き出すというプログラムを書きたいのですが、途中で抜け出せなくなってしまいました。下に使用しているファイルの中身を、ごくわずかですが載せておきます。 b.csvのほうは、年別で33個のファイルに分けられています。 ----------------------a.csv------------------------------------------ 30 23226 1977 大野 31 13311 1978 増毛 31 14101 1978 新篠津 31 15251 1978 芦別 31 16281 1978 真狩 31 17076 1978 興部 ----------------------------------------------------------------------- ----------------------b.csv-------------------------------------------2006,1,1,11016,141.678,45.4147,3,稚内,0,33,16,-64,-51,-75,55,1,9 2006,1,1,11151,141.138,45.1767,14,沓形,1,20,1,-52,-36,-68,4,1,6 2006,1,1,11176,141.778,45.1017,12,豊富,0,9,4,-80,-51,-116,59,0,3 2006,1,1,11206,142.362,45.1117,13,浜頓別,1,12,13,-92,-47,-140,66,1,3 2006,1,1,11276,142.28,44.965,25,中頓別,0,5,11,-137,-44,-209,46,0,2 2006,1,1,11291,142.585,44.9397,7,北見枝幸,0,25,13,-70,-47,-94,70,0,6 2006,1,1,11316,142.48,44.84,14,歌登,0,2,1,-115,-49,-170,56,0,1 ------------------------------------------------------------------------ implicit none REAL :: number,code,year,name REAL :: yea,mon,day,id,chiki,nam INTEGER :: lon,lat,pre,wind,winddirection,temp INTEGER :: hightemp,lowtemp,sunlight,maxrain,maxwind open(10,file='a.csv',status='old',iostat=ie) do iwork=1976, 2008 write(yyyy,"(i4.4)") iwork open(50, file='b'//yyyy//'.csv', status='old', & & iostat=io) if (io < 0) cycle do i = 1, 99 read(10,*) number,code,year,name if(ie < 0) exit do ii = 1, 30000 read(50,*) yea,mon,day,id,lon,lat,chiki,nam,pre,wind,winddirection,temp,& & hightemp,lowtemp,sunlight,maxrain,maxwind if(io < 0) exit write(6,*) yea stop close(10) close(50) end エラーメッセージがenddo文が予期されている。プログラムのファイルのendが予期されていない。とでます。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 よろしくおねがいします

  • アドバイスお願いします

    今,以下の様なプログラムを作っています. 正の整数nを上限とする数字の集合を考える. そのうち a*i+b*j で表現できない値の個数を出力する. a,bは事前に与えられた正の整数であり,i,jは正の整数の変数である. またa,b,nの取り得る最大値は1000000とする. とりあえずfortranで総当たりの方法で作ってみました. integer a,b,n,ans(1000000),c read(*,*)a,b,n  do i=1,n   ans(i)=i  enddo icount=0 do i=0,n  do j=0,n   c=a*i+b*j   if(c.le.n)then    do k=1,n     if(ans(k).eq.c)then      ans(k)=-1     endif    enddo   endif  enddo enddo do i=1,n  if(ans(i).gt.0)then   icount=icount+1  endif enddo write(*,*)icount end nの値があまり大きくなければ問題なく動くのですが, 最大値である1000000を入力して走らすと,とんでもなく 時間がかかってしまいます. もっとスマートな方法は無いものでしょうか? アドバイスお願い致します.

  • 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

  • fortranのtxtファイル出力書式について

    こんにちは。 fortranのtxtファイル出力について質問させていただきます。 下記のようなコードでtxtファイルに計算結果を出力させています。(途中省略) open(20, file ='outputx1.txt') do ax1 = 1, m do ax2 = 1, l if (sum2(ax1, 1, ax2) == 1) then write(20,*) ax1, ax2 endif enddo enddo close(20) ここでm=103,l=300です。 このコードで出力すると、結果は以下のようになります。      9    293      9    294      9    295      10     97      10     98      10     99 しかし、以下のようにtxtファイルを出力したいと考えています。 9 164 9 165 9 166 10 151 10 152 10 153 *の部分を色々といじってみたのですが、うまいやり方が見つかりません。 説明不足とは思いますが、アドバイスよろしくお願いします。

  • 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 行列ベクトル積

    行列ベクトル積を計算するプログラムを下のように書いたのですが、実行した結果の答えが実際計算した答えと異なります。初期の要素の設定がおかしいのでしょうか?教えて下さい。よろしくお願いします。 program list2_14 implicit none integer , parameter :: n = 2 real(8) a(n,n), x(n), y(n) integer i, j, k, l a(1,1:2) = (/1.2d0,3.4d0/) a(2,1:2) = (/5.6d0,7.8d0/) x(:) = (/9.0d0,10.0d0/) do i = 1, n y(i) = 0.0d0 do j = 1, n y(i) = y(i) + a(i,j) * x(j) enddo enddo do k = 1, n write(*,*) (a(k,l), l = 1, n) enddo write(*,*) x(:) write(*,*) y(n) end program list2_14 実行結果 1.2 3.4 5.6 7.8 9. 10. 128.4

  • 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 と書いたのですがデータの数と繰り返しの数が一致しないと、出力されません。 いちいちファイルをみるのは面倒なので、なんとか したいのですが