• 締切済み

fortran 繰り返し計算の問題

皆様、先日、色々教えていただきまして、どうも有り難うございました。特にfunoe様からのお答えがとても助かりました。ただし、どうも一つの条件だけが満足されると、計算が終了に行ってしまいました。 再度問題を整理したうえで、質問させて頂けませんでしょうか。 (例えば、電気回路の例) do j=1, n  Ra(j),Qi(j) !予めある回路に初期の抵抗値と得たい電流値を与える end do Tr=1.0 / / / 10 continue / do j=1,n Vi(j)=V/Ra(j) !Vを一定値とする / do 100 j=1, n if (abs(Vi(j)-Qi(j)) > 0.1) then Ra(j)= Ra(j)+ Tr goto 100 !nまで繰り返し else goto 500 !終了する end if 100 continue 1000 continue goto 10 !戻り、再計算 500 continue stop end ***************************************** 例えば(n=10),予め与えた10本の回路のQi値がすべて同じな場合には、上記のプログラムでは、うまく行っていますが、10本回路のQi値が違い場合には、そのうち1本回路の値が満足されると、終了していしまいました。  また、elseの前に、 「elseif (Vi(j)-Qi(j) <= 0.1) then Ra(j)= Ra(j) 」 を追加すると、ループから抜き出せなくなりました。  また、初期条件としては、始めに小さいRaを与えて、最初計算したViがQiより大きくして、それから、Raを増やして、ViをQiに近づけるように考えていますが、なかなかうまく行っていないのです。また、回路ですので、一箇所のRaを変更すると、当然他の値にも影響を与えます、ここには難しくと思っております。  皆さまに、教えていただければ、幸いなことと思います。よろしくお願い致します!<!!^!!)。

みんなの回答

  • masa2211
  • ベストアンサー率43% (178/411)
回答No.3

不必要のgotoがあり、混乱の元となっていると思いますが。 (FORTRAN90かそれ以降ですよね?) >do j=1,n >Vi(j)=V/Ra(j) !Vを一定値とする このdo文に受け皿がありあません。(最新の文法でコレが大丈夫なら撤回。) Vi(j)=V/Ra(j)の次行に、end doが入るはず。 >do 100 j=1, n >  if (abs(Vi(j)-Qi(j)) > 0.1) then >   Ra(j)= Ra(j)+ Tr >   goto 100 !nまで繰り返し >  else >   goto 500 !終了する >  end if >100 continue >  goto 10 !戻り、再計算 質問文趣旨を、(abs(Vi(j)-Qi(j)) <= 0.1) がjの全てについて成立したときループ脱出 の意味に取ります。 この場合、ループ脱出時には、必ずjはnまで回ります。 よって、 Icount=0 do j=1, n   if (abs(Vi(j)-Qi(j)) > 0.1) then    Ra(j)= Ra(j)+ Tr   else    Icount=Icount+1 !高々1個成立したからといってループを脱出してはダメ。   end if end do   if (Icount.NE.n) goto 10 !戻り、再計算   以下、ループ成立時の計算 なお、ループの順序を入れ替え、 do j=1,n  Vi(j)=V/Ra(j)  do while (abs(Vi(j)-Qi(j)) > 0.1)   Ra(j)= Ra(j)+ Tr   Vi(j)=V/Ra(j)  end do end do 以下、ループ成立時の計算 (10continueのループ全てを書き直し) としても等価です。

wonwon99
質問者

お礼

教えて頂きまして、どうも有難うございました。 整理しながら、実行し見たいです。有難う!!!!<^^>

  • funoe
  • ベストアンサー率46% (222/475)
回答No.2

回路とか電気とか抵抗とかのことは全く解りませんが、ご提示のロジックで間違っているとは思えませんよね。 判定のための変数の中身が想定外に書き換わっているなど不可思議のことが起こっているのかも・・・・。 問題解決のためには、プログラムトレースのWRITE文をセットして実行すれば「何が起こっているか」がわかると思います。 do 100 j=1, n  write(6,*) '#1',j,Vi(j),Qi(j) ←ここと if (abs(Vi(j)-Qi(j)) > 0.1) then write(6,*) '#2',j,Vi(j),Qi(j) ←ここと Ra(j)= Ra(j)+ Tr goto 100 !nまで繰り返し else write(6,*) '#3',j,Vi(j),Qi(j) ←ここと goto 500 !終了する end if 100 continue  write(6,*) '#4',j,Vi(j),Qi(j) ←ここと 1000 continue goto 10 !戻り、再計算 500 continue  write(6,*) '#5',j,Vi(j),Qi(j) ←ここに追記する。 stop end

wonwon99
質問者

お礼

有難う、有難う!! 正確な計算方法までに行っていないと思う。 色々教えていただき、大変助かりました。また、教えてくださいね!<~~**~~>

  • alice_44
  • ベストアンサー率44% (2109/4759)
回答No.1

カテゴリー違い。 形式的に、プログラムに関する質問であるか どうかは、問題ではありませんが、 内容的に、ルーブの組み方を 繰り返し、数学カテで質問し続けているのは、 マナー上、問題だと思います。

関連するQ&A

  • fortran  繰り返しループから抜きたい

    10 continue   :   :   :  do 100 i=1,10 if (abs(x (i)-y(i)) .lt. 1.0) then r= r + dr goto 100 else goto 1000 end if 100 continue :   : : 1000 contiue end   すべての条件(i=1~10)が満足されたら、ループから抜きたいのですが、出来ませんでした。   教えて頂けませんでしょうか?よろしくお願しますね!*<>*!

  • 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 初心者です。

    fortranでフィボナッチ数列 A0 = 0 , A1 = 1 , Ai+1 = Ai + Ai-1 (i =2,3...) を計算するプログラムを作っています。 得られた値が奇数の時には、数値の右横に*をつけ、奇数かつ3の倍数なら**をつけます。 が、以下のようにプログラムしましたが、*印がつきません。どこが、間違っているのか、アドバイスよろしくお願いします。 C Question A0 = 0.0 A1 = 1.0 A2 = 1.0 WRITE(6,*)'A0 = 0.0' WRITE(6,*)'A1 = 1.0' DO 10 I = 2,10,1 A2 = A1 + A0 N = A2-(A2/2)*2 M = A2-(A2/3)*3 IF ( M .NE. 0 .AND. N .NE.0) THEN WRITE(6,*)'A',I,'=' ,A2,'*' ELSE IF ( M .NE. 0.AND. N .EQ.0)THEN WRITE(6,*)'A',I,'=' ,A2,'**' ELSE WRITE(6,*) 'A',I,'=' ,A2 END IF A0 = A1 A1 = A2 10 CONTINUE STOP END

  • 計算速度

    a(m,n) m=20000 n=10000 のとき do j=1,n do i=1,m x=x+a(i,j) end do end do の計算速度と do j=1,n do i=1,m x=x+a(j,i) end do end do の計算速度が違うのはなぜですか?

  • fortranで図形の面積を求めるには?

    今fortranのプログラムをやっているのですが、 図形の面積を求めたいのですがどうやったらいいのでしょうか? とりあえず小さな区間に区切って足し算を行うようにしているのですが、うまく動きません・・・。 DOループをまわし過ぎなのでしょうか??? 一応下にプログラムの一部を書いておきます。 DO 444 J= 1,5000 T=FLOAT(J)*0.1 IF (T.GE.281)THEN GL3 = -0.01105*T+4.104972 ELSE    GL3 = -0.01105*T-2.1050 ENDIF     ・     ・     ・ 444 CONTINUE 誰か助けてください! 宜しくお願いします。

  • fortran

    do I = 1,40 do F = 1,4 do L = 1,100 if (I == 1. .OR. L == 1.) then A (I,F,L) = 3. else A (I,F,L) = 3.* B (I-1,F,L) end if end do end do do F = 1,4 do L = 1,100 do M = 1,100 B (I,F,L) = B (I,F,L) + C (I,F,M,L) end do end do end do end do 簡素化したプログラムなので、わかりにくいと思うのですが、後で計算するB(I,F,L)をA(I,F,L)のDOループに最初に持ってくると、I=1orL=1のときは正しい計算をしてくれるのですが、そのほかのときはB(I-1,F,L)に値が入らないのです。ちなみにC(I,F,M,L)はA(I,F,L)のループの後に計算しましたが、省略しました。 ご回答よろしくお願いします。

  • 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のプログラム

    今、実験の解析を行っています。 読み込みたいテキストファイルには -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の素数のプログラム

    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 途中まで考えたのですが。。。。

    エラトステネスのふるい(素数の倍数を除いていって残ったのが素数)で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 よろしくおねがいします