2024年のうちにやっておきたいこと、ここで宣言しませんか?

FORTRANのDO WHILE問題です。

次の漸化式で与えられる数列{Xk}が、
|Xk - Xk-1|< 0.00001
となる時のXkの値を求めよ。
Xk+1 = Xk -
(Xk)^3 - 6(Xk)^2 + 11Xk - 6
              / 3(Xk)^2 - 12Xk + 11

(Xk)^3はXkの3乗です。

私の回答は、

implicit none
integer :: k
real,dimension(100000000) :: x
 k = 1
x(0) = 0
do while ( abs(x(k)-x(k-1)) >= 0.00001 )
  x(k+1)=x(k)-(x(k)**3-6*(x(k)**2)+(11*x(k))-6)&
      /(3*(x(k)**2)-12*x(k)+11)
x(k) = x(k+1)
k = k +1
end do
write(*,*) x(k)
stop

というものなんですが、作動しません。
どこが違うのか教えてください!!お願いします!!

A 回答 (3件)

うーん、新しいFORTRANは読みにくい



簡単に指摘すると
・FORTRANでは、配列の添え字は何も書かないと1からです(0:1000とかで指定すればいいのかな)。なので、最初のx(0)への代入はバウンダリエラー
・初期化されていないx(1)を、最初に比較としてdo whileで使っているので、FORTRANの仕様上、動作は不定。実際には、大概のプログラムローダーでは0クリアされるが、その場合、0と0の比較でループは回らない
・偶々一回目のループが回ったとして、その場合、x(1)は不定なので、x(2)は不定の値を元に計算することになり、計算する度に結果が変わる。

なお、配列で処理するのもあまり感心できません、100000000までに必ず収束するかは場合によって変わりますからね。

というわけで、FORTRAN77で書きますが

integer k
real*8 x0, x1

k = 1

x0 = 0
x1 = xfunc(x0)
do while ( abs(x1-x0) >= 0.00001 )
 x0=x1
 x1=xfunc(x0)
 k = k +1
end do
write(*,*) k,x1
stop

real*8 function xfunc(x)
xfunc=x-x**3-6*(x**2)+11*x-6/(3*(x**2)-12*x+11
return

最近、FORTRANさわってないので、シンタックスは危ないと思う
    • good
    • 0

かなり昔の経験なので自信はありませんが・・・



初期値はx(1)であり、x(0)はおかしいと思います。
判別の不等号が逆では?
計算式のミスなどにより永久ループとなるのを防止するために、do whileの判別式には直接の計算結果を使わない方が良いでしょう。

 k = 1
x(1) = 0
do while ( k > 10000000 )
x(k+1)=x(k)-(x(k)**3-6*(x(k)**2)+(11*x(k))-6)&
      /(3*(x(k)**2)-12*x(k)+11)
if ( abs(x(k)-x(k-1)) <= 0.00001 ) k=10000001
x(k) = x(k+1)
k = k +1
end do

間違っていたら、ごめんなさいね

この回答への補足

すみません!!漸化式に
X0 = 0
もあったの書き忘れてました(><)
補足させていただきますm(_ _)m

補足日時:2005/10/18 16:24
    • good
    • 0
この回答へのお礼

そうなんですかっ!!
アドバイスを参考にもう一度考え直してみます☆
補足にも書きましたが、
問題文が十分でなかったことをお詫びします(><)
ありがとうございました!!!

お礼日時:2005/10/18 16:49

k = 1 の場合の While 条件が「偽」になるので


ループ内の処理は実行しない。

※一般にFortranでは宣言した数値変数は0になっています。
    • good
    • 0
この回答へのお礼

そうなんですか?
参考にしてもう一度考えてみますね!!
ありがとうございました☆

お礼日時:2005/10/18 16:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報