# 以牛頓法求 x^2 - 0.5 = 0 的根, x >= 0
# 結果應接近 sqrt(0.5) ~= 0.7071
# 初始值設定在 0-100
# 最多重覆 10 次; 若第 10 次的差值仍不小於 delta 則自我遞迴重新做一次
# 因為 fx 沒有寫死, 這個牛頓法應可以用在其它求根問題上
NTM <-
  function(fx = expression(x ^ 2 - 0.5),
           initial = expression(runif(1, 0, 100)),
           delta = 1e-10,
           iter.max = 10,
           trace = T) {
    iter <- 1
    x <- eval(initial)
    while (iter <= iter.max) {
      fx.val <- eval(fx)
      fx.dx.val <- eval(D(fx, "x"))
      x1 <- x - fx.val / fx.dx.val
      delta.this <- abs(x1 - x)
      if (trace) {
        cat(
          "iter =", iter,
          ", x =", x,
          "next x =", x1,
          ", 差值 =", delta.this,
          ", 差值是否夠小:", delta.this < delta,
          "\n"
        )
      }
      
      if (delta.this >= delta) {
        x <- x1
        iter <- iter + 1
      } else {
        break
      }
    }
    
    if (iter - 1 == iter.max & delta.this >= delta) {
      if (trace) cat("已經做", iter - 1, "次了但差值", delta.this, "仍未小於", delta, "所以自我遞迴重做一次", "\n")
      NTM(fx = fx, initial = initial, delta = delta, iter.max = iter.max, trace = trace)
    } else {
      if (trace) cat("達到標準; 完成\n\n")
      return(x)
    }
  }

# 進行 1 次 NTM()
NTM()

# 進行 5 次 NTM() 看看
res <- replicate(5, NTM(trace = F))
# 求 5 次 NTM() 的平均
mean(res)

# 改成求 x ^ 3 - 27.001 = 0 的根
NTM(fx = expression(x ^ 3 - 27.001))
