簡體   English   中英

如何避免停止循環的 uniroot 錯誤?

[英]How can I avoid uniroot error that stops the loop?

我在循環中運行uniroot function,但遇到錯誤並且代碼停止。 代碼如下;

func <-function(f) -a*b/c*0.5*d*e^2 + (d/f-1)*g*sin(h*(pi/180))-i
dat <- data.frame(a = c(0.99,0.99,0.99),
                  b = c(0.1986572,0.1986572,0.1986572),
                  c = c(237.5,237.5,237.5),
                  d = c(1028.372, 1028.711, 1028.372),
                  e = c(2.46261, 2.986461, 2.46261),
                  f = c(-1,-1,-1),
                  g = c(9.8,9.8,9.8),
                  h = c(-54.97964, -51.65978, -54.97964),
                  i = c(0.03699588, -0.0375189, 0.03699588))

for(j in 1:length(dat$a)){
   a <- dat$a[j]
   b <- dat$b[j]
   c <- dat$c[j]
   d <- dat$d[j]
   e <- dat$e[j]
   #f: this should be solved by uniroot
   g <- dat$g[j]
   h <- dat$h[j]
   i <- dat$i[j]
   sol <- uniroot(func,c(0, 2000),extendInt = "yes") 
   dat$f[j] <- sol$root
   print(j)
}

運行上面的代碼,遇到以下錯誤:

[1] 1
Error in uniroot(func, c(0, 2000), extendInt = "yes") : 
      no sign change found in 1000 iterations

代碼在j=1處停止,並且沒有 go 到j=2 & 3 因此, dat$f顯示

> dat$f
[1] 1526.566   -1.000   -1.000

我的目標是當uniroot在給定的j中遇到錯誤時,將NA放入dat$f[j]中,然后繼續循環。

如果這可行, dat$f[1]dat$f[3]應該具有相同的值 (=1526.566) 使用上面的 dataframe。

請告訴我如何處理uniroot錯誤。

嘗試擴大區間的范圍。 例如:

sol <- uniroot(func, c(0, 5000), extendInt = "yes") 

您的代碼停止,因為在您定義的范圍內uniroot沒有找到解決方案

如果下限設置為 1 而不是 0,則問題中的代碼將起作用。問題是如果 f 為 0,則 func 未定義,因為 f 在分母中。

雖然這就足夠了,但建議您進行以下更改:

  1. 使用末尾注釋中顯示的 dat,確保它不包含 f。
  2. 更緊湊地定義 func ,如圖所示
  3. 使用try允許 uniroot 即使出現錯誤也繼續運行(盡管在他的示例中沒有)
  4. 使用 1 的下限,因為 func 在 0 處未定義
  5. 使用 uniroot 的參數將第 j 行 dat 傳遞給 func
  6. 將結果放在 res 中(如果迭代失敗,則為 NA),這樣就不會混淆輸入的內容和 output 的內容。

使用所示的更緊湊形式的 func 並將結果放入 res 中。

func <- function(f, data) with(data, -a*b/c*0.5*d*e^2 + (d/f-1)*g*sin(h*(pi/180))-i)
nr <- nrow(dat)
res <- numeric(nr)
for(j in 1:nr){
   sol <- try(uniroot(func, c(1, 2000), data = dat[j, ], extendInt = "yes") )
   res[j] <- if (inherits(sol, "try-error")) NA else sol$root
   print(j)
}
## [1] 1
## [1] 2
## [1] 3
res
## [1] 1526.566 2014.476 1526.566

筆記

dat <- data.frame(a = c(0.99,0.99,0.99),
                  b = c(0.1986572,0.1986572,0.1986572),
                  c = c(237.5,237.5,237.5),
                  d = c(1028.372, 1028.711, 1028.372),
                  e = c(2.46261, 2.986461, 2.46261),
                  g = c(9.8,9.8,9.8),
                  h = c(-54.97964, -51.65978, -54.97964),
                  i = c(0.03699588, -0.0375189, 0.03699588))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM