首页 > 解决方案 > 如果条件出现缺失值错误

问题描述

    realfunction1<-function(x){
  (5*x[1]-x[2])^4+(x[1]-2)^2+x[1]-(2*x[2])+12
}
func1gradient <- function(gradient){
  x<-0
  y<-0
  x <- (20*(5*gradient[1]-gradient[2]))^3+2*(gradient[1]-2)+1
  y <- (-4*(5*gradient[1]-gradient[2]))-2
  
  gradient[1]<-x
  gradient[2]<-y
  return(gradient)
}

DFP<-function(Error,xk){
  
  k <- 0
  i <- 1
  alpha<-seq(from=-100,to=100,by=0.005)
  H0 <- matrix(c(1,0,0,1), nrow=2, byrow=TRUE)
  Hk <- H0
  repeat{
    
    dk <- (-1)*(Hk%*%func1gradient(xk))
    
    if(abs(dk[1]) <= Error && abs(dk[2]) <= Error){ ####ERROR LINE
      
      return(xk)
      
    }else{
      
      for(i in i:40001){
        
        vectortofindmin<-matrix(c(1:40001),nrow=40001)
        
        variables <- xk+(alpha[i]*dk)
        
        f1valuetutucu<-matrix(c(1:40001),nrow=40001)
        
        f1valuetutucu[i] <- realfunction1(variables)
      }
      
      indexalpha<-which.min(f1valuetutucu)
      
      
      xknew <- xk + (alpha[indexalpha]*dk)
      
      pk <- xknew - xk
      
      qk <- func1gradient(xknew) - func1gradient(xk)
      
      
      ## A
      divisionval<-(t(pk)%*%qk)
      divisionmatix<-matrix(c(divisionval,divisionval,divisionval,divisionval),nrow=2)
      
      A <- (pk%*%t(pk))/divisionmatrix
      
      ###
      
      divisionval2<-t(qk)%*%Hk%*%qk
      divisionmatrix2 <- matrix(c(divisionval2,divisionval2,divisionval2,divisionval2),nrow=2)        
      B <- (Hk%*%qk)%*%t(Hk%*%qk)/divisionmatrix2
      ####
      Hknew <- Hk + A + B          
      Hk <- Hknew
      xk<-xknew
    } 
  }
}
DFP(Error=1e3,xk=matrix(c(33,12),nrow=2))

这是我的整个代码,我尝试了代码的每一行并且它工作正常但是我在 if 行“缺少 TRUE/FALSE 需要的值”“if(abs(dk[1]) <= Error && abs( dk[2]) <= 错误)"。谁能帮忙,为什么我收到此错误消息?(我写的是 Error=1e3 但稍后我会减少该错误量,我正在尝试达到工作功能:))

此代码表示 davidon-fletcher-powell 方法算法。如果您有任何补充或建议。我将不胜感激。

标签: rfunctioncompiler-errorssyntax-errorlogic

解决方案


我做了两件事:

  1. 修正了@Jan 指出的错字;和

  2. 快速tryCatch(...)插入browser()循环repeat

    iserr <-  tryCatch({if (abs(dk[1]) <= Error && abs(dk[2]) <= Error) 1;F;}, error=function(e) TRUE)
    if (iserr) {browser();1;}
    

    (在真实if陈述之前)

在那之后,我运行了你的DFP(...),它弹出了一个调试会话。然后我打破了if条件:

(abs(dk[1]) <= Error && abs(dk[2]) <= Error)
# [1] NA

这就是您收到错误的原因。(如果您使用错误消息搜索 SO [r] missing value where TRUE/FALSE needed,您会发现许多问题都讨论了您的确切错误。)

但是您需要知道为什么该条件不是真正的真/假,因此我们可以查看一些因变量。以下所有情况都会以一种或另一种形式提醒我(尽管可能xk还可以?):

dk
#      [,1]
# [1,]  NaN
# [2,]  NaN
xk
#               [,1]
# [1,]  4.16513e+145
# [2,] -5.07341e+115
func1gradient(xk)
#                [,1]
# [1,]            Inf
# [2,] -8.330259e+146
Hk
#      [,1] [,2]
# [1,]  NaN  NaN
# [2,]  NaN  NaN

我不打算剖析为什么每个所谓的数字变量都持有意想不到的值,因为这需要你在这里所做的任何事情的一些领域知识。您可能会发现Inf并非完全出乎意料,但我希望NaN您会感到惊讶。

仔细检查你的逻辑和代码,找出其中的每一个问题。

在函数中使用新数学时,我经常包含一些if过早停止或让我进入browser()调试会话的语句。例如,

if (any(is.null(z), is.nan(z), is.na(z))) { browser(); 1; }

在您执行可能将零、非常正、非常低或非常负的数字变为非数字的事情之前,检查各种组件可能对您来说是件好事。(browser();1;解决 R 中调试的一些细微差别有点小技巧。)

稍微不同的机智可能是这样的:

if (!isTRUE(is.finite(z))) { browser(); 1; }

这应该更积极地启动调试会话。

您应该在生产环境中避免使用这种类型的代码(例如,browser()),但是在开发新的基于 R 的东西和/或学习 R 的细微差别时,它可以为您节省很多时间。


推荐阅读