1

そこで、任意の数値の平方根を指定された精度 (許容誤差) で計算するニュートン法を実行するコードを書くことになっています。

これが私のコードです:

MySqrt <- function(x, eps = 1e-6, itmax = 100, verbose = TRUE) {
  GUESS <- 11
  myvector <- integer(0)
  i <- 1
  if (x < 0) {
    stop("Square root of negative value")
  }
  else {
    myvector[i] <- GUESS

    while (i <= itmax) {
      GUESS <- (GUESS + (x/GUESS)) * 0.5
      myvector[i+1] <- GUESS

      if (abs(GUESS-myvector[i]) < eps) {
        break()
      } 

      if (verbose) {
        cat("Iteration: ", formatC(i, width = 1), formatC(GUESS, digits = 10, width = 12),     "\n")
      }

      i <- i + 1

    }
  }    
  myvector[i]
}

eps は公差です。この関数を使用して、たとえば 21 の平方根を計算すると、次のような結果が得られました。

> MySqrt(21, eps = 1e-1, verbose = TRUE)
Iteration:  1  6.454545455 
Iteration:  2  4.854033291 
Iteration:  3   4.59016621 

ただし、関数が想定されているときに反復の実行を停止するかどうかはわかりません。誰かが私のコードが正しいかどうかを確認できますか? これは大歓迎です!

4

1 に答える 1

3

あなたのコードはほぼ正しいです。正しい回数繰り返しています。唯一のバグはi、break ステートメントの後までインクリメントしないため、最新の近似値が返されないことです。代わりに、前のものを返しています。

適切なタイミングで停止していることを確認するために、トレース ラインをブレークの上に移動できます。トレースに追加することもGUESS-myvector[i]できるので、差が十分に小さくなったらすぐに停止するのを見ることができます。これを行って関数を実行すると、適切なタイミングで停止しているという事実と、間違った値を返しているという事実が明らかになります。

> MySqrt(21,eps=1e-1)
Iteration:  1 6.454545 -4.545455 
Iteration:  2 4.854033 -1.600512 
Iteration:  3 4.590166 -0.2638671 
Iteration:  4 4.582582 -0.007584239 
[1] 4.590166

あなたのコードは (ほぼ) 正しいですが、あまり良い R スタイルで書かれていません。たとえば、推定値のベクトル全体を返したい場合を除き、それらを保持する必要がある理由はありません。また、while ループを使用するよりも、ここでは for ループを使用する方が理にかなっています。ここで、関数の改善されたバージョンの 1 つを示します。

MySqrt <- function(x, eps = 1e-6, itmax = 100, verbose = TRUE) {
  GUESS <- 11
  if (x < 0) {
    stop("Square root of negative value")
  }
  for(i in 1:itmax){
      nextGUESS <- (GUESS + (x/GUESS)) * 0.5
      if (verbose)
        cat("Iteration: ", i, nextGUESS, nextGUESS-GUESS, "\n")

      if (abs(GUESS-nextGUESS) < eps) 
        break

      GUESS<- nextGUESS
    }
  nextGUESS
}
于 2013-10-21T22:24:18.797 に答える