简体   繁体   English

在 nloptr 中使用“算法”=“NLOPT_LN_AUGLAG”时出现 STRING_ELT 错误

[英]STRING_ELT error while using “algorithm” = “NLOPT_LN_AUGLAG” in nloptr

I am trying to optimize a function in R using the nloptr package.我正在尝试使用 nloptr package 优化 R 中的 function。 Here is the code:这是代码:

library('nloptr')

hn <- function(x, n)
{
    hret <- 0
    if (n == 0)
    {
        hret <- 1
        return (hret)
    }
    else if (n == 1)
    {
        hret <- 2*x
        return (hret)
    }
    else
    {
        
        hn2 <- 1
        hn1 <- 2*x
        all_n <- seq(from = 2, to = n, by = 1)
        for (ni in all_n)
        {
            
            hn = (2*x*hn1/sqrt(ni)) + (2*sqrt( (ni-1)/ni)*hn2)
            #print(hn)
            hn2 = hn1
            hn1 = hn
        }
        hret <- hn
        return (hret)
    }
}

term <- function(alpha, r, theta, n)
{
    beta = alpha*cosh(r) - Conj(alpha)*exp(1i*theta)*(sinh(r))
    
    
    
    hnterm <- beta/(sqrt(exp(1i*theta)*sinh(2*r)))
    term4 <- hn(hnterm, n)
    
    logterm1 <- (1/2)*log(cosh(r))
    logterm2 <- -((1/2)*(abs(alpha)^2)) + ((1/2)* (Conj(alpha)^2))*exp(1i*theta)*tanh(r)
    logterm3  <- (n/2)*( log (((1/2)*exp(1i*theta)*tanh(r)) ))
    logterm4 <- log ( term4)
    logA <- logterm1 + logterm2 + logterm3 + logterm4
    A <- exp(logA)
    
    
    retval <- c(A)
    
    return (A)
    
}


PESQ <- function(x, alpha)
{
    p0 <- x[1]
    p1 <- x[2]
    beta <- x[3]
    r <- x[4]
    theta <- x[5]
    
    N <- 30
    
    NI <- seq(from = 0, to = N, by = 1)
    
    elements <- rep(0+1i*0, length(NI))
    elements_abs_sqr <- rep(0, length(NI))
    pr <- rep(0, length(NI))
    total <- 0 + 1i*0
    for (n in NI)
    {
        w <-term(2*alpha + beta, r, theta, n)
        elements[n+1] <- w
        elements_abs_sqr[n+1] <-(abs(w)^2)
    }
    total <- sum(elements_abs_sqr)
    for (n in NI)
    {
        pr[n+1] <- Re(elements[n+1]/sqrt(total))
        pr[n+1] <- pr[n+1]^2
        
    }
    p_off_given_on <- pr[1]
    
    elements <- rep(0+1i*0, length(NI))
    elements_abs_sqr <- rep(0, length(NI))
    pr <- rep(0, length(NI))
    total <- 0 + 1i*0
    for (n in NI)
    {
        w <-term(beta, r, theta, n)
        elements[n+1] <- w
        elements_abs_sqr[n+1] <-(abs(w)^2)
    }
    total <- sum(elements_abs_sqr)
    for (n in NI)
    {
        pr[n+1] <- Re(elements[n+1]/sqrt(total))
        pr[n+1] <- pr[n+1]^2
        
    }
    
    p_on_given_off = 1 - pr[1]
    
    P_e = p0*p_off_given_on + p1*p_on_given_off
    
    return(P_e)
}

eval_g_eq <- function(x)
{
    return ( x[1] + x[2] - 1)
}

lb <- c(0, 0, -Inf, 0.001, -pi)
ub <- c(1, 1, Inf, Inf, pi)

local_opts <- list("algorithm" = "NLOPT_LD_MMA", 
                   "xtol_rel"=1.0e-18)

# Set optimization options.
opts <- list("algorithm" = "NLOPT_LN_AUGLAG",
             "xtol_rel" = 1.0e-18, "local_opts" = local_opts, "maxeval" = 10000)


x0 <- c(0.1,0.9, 0.1, 0.01, 0.7853982)


alpha <- 0.65

eval_g_ineq <- function(x)
{
    return (c (- x[1] - x[2], 
               x[1] + x[2] - 1)
    )
}

eval_f <- function(x)
{
    ret = PESQ(x, alpha)
    return(ret)
}

res <- nloptr ( x0 = x0, 
                eval_f = eval_f,
                eval_g_eq = eval_g_eq,
                eval_g_ineq = eval_g_ineq,
                lb = lb,
                ub = ub,
                opts = opts )
print(res)


Upon running this code, I get the following error:运行此代码后,我收到以下错误:

Error in nloptr(x0 = x0, eval_f = eval_f, eval_g_ineq = eval_g_ineq, eval_g_eq = eval_g_eq, : STRING_ELT() can only be applied to a 'character vector', not a 'NULL' Calls: ... withCallingHandlers -> withVisible -> eval -> eval -> nloptr Execution halted nloptr(x0 = x0, eval_f = eval_f, eval_g_ineq = eval_g_ineq, eval_g_eq = eval_g_eq, : STRING_ELT() 只能应用于“字符向量”,而不是“NULL”调用:... withCallingHandlers -> withVisible - > eval -> eval -> nloptr 执行停止

The weird thing, if I use "algorithm"="NLOPT_LN_COBYLA" in opts and I remove the equality constraint eval_g_eq in nloptr call, it runs fine and I get a solution.奇怪的是,如果我在opts中使用"algorithm"="NLOPT_LN_COBYLA"并在nloptr调用中删除等式约束eval_g_eq ,它运行良好并且我得到了解决方案。 However, I need equality constraints for my work.但是,我的工作需要平等约束。

How should I fix the issue?我应该如何解决这个问题?

This is still a bit of a guess, but: the only possibility I can come up with is that using a derivative-based optimizer for your local optimizer at the same time as you use a derivative-free optimizer for the global solution (ie, the NLopt docs clarify that LN in NLOPT_LN_AUGLAG denotes "local, derivative-free" whereas _LD_ would denote "local, derivative-based") is causing the problem?这仍然是一个猜测,但是:我能想到的唯一可能性是,在对全局解决方案使用无导数优化器的同时,对本地优化器使用基于导数的优化器(即, NLopt 文档阐明NLOPT_LN_AUGLAG中的LN表示“本地,无衍生”,而_LD_表示“本地,基于衍生”)导致问题? I got an answer (not sure if it's correct though!) by using "NLOPT_LN_COBYLA" as the algorithm in local_opts : with everything else as in your code,通过使用“NLOPT_LN_COBYLA”作为local_opts中的算法,我得到了一个答案(虽然不确定它是否正确!):与您的代码中的所有其他内容一样,

local_opts <- list("algorithm" = "NLOPT_LN_COBYLA", 
                   "xtol_rel"=1.0e-18)

# Set optimization options.
opts <- list("algorithm" = "NLOPT_LN_AUGLAG",
             "xtol_rel" = 1.0e-18, "local_opts" = local_opts, "maxeval" = 10000)

print(res <- nloptr ( x0 = x0, 
                eval_f = eval_f,
                eval_g_eq = eval_g_eq,
                eval_g_ineq = eval_g_ineq,
                lb = lb,
                ub = ub,
               opts = opts ))

Returns退货

Call:

nloptr(x0 = x0, eval_f = eval_f, lb = lb, ub = ub, eval_g_ineq = eval_g_ineq, 
    eval_g_eq = eval_g_eq, opts = opts)


Minimization using NLopt version 2.4.2 

NLopt solver status: 3 ( NLOPT_FTOL_REACHED: Optimization stopped because 
ftol_rel or ftol_abs (above) was reached. )

Number of Iterations....: 102 
Termination conditions:  xtol_rel: 1e-18    maxeval: 10000 
Number of inequality constraints:  2 
Number of equality constraints:    1 
Optimal value of objective function:  2.13836819774604e-05 
Optimal value of controls: 0 1 -0.0003556752 0.006520304 2.037835

As far as I can see this has done a plausible solution respecting the constraints:据我所知,这已经完成了一个关于约束的合理解决方案:

  • the reason for stopping ("ftol_rel or ftol_abs... was reached") is sensible停止的原因(“达到 ftol_rel 或 ftol_abs ...”)是明智的
  • it used a reasonable number (102) of iterations to get there (and not maxeval )它使用了合理数量(102)的迭代来到达那里(而不是maxeval
  • eval_g_eq(res$solution) does give 0 (which we can also see by inspection, as the condition is x[1]+x[2]-1==0 ). eval_g_eq(res$solution)确实给出了 0 (我们也可以通过检查看到,因为条件是x[1]+x[2]-1==0 )。
  • The inequality conditions are -x1-x2 and x1+x2-1 ;不等式条件为-x1-x2x1+x2-1 x2-1 ; I'm not sure how the sign of these inequalities is defined/determined?我不确定这些不等式的符号是如何定义/确定的? The same as x0 , ie assuming the initial conditions are feasible?x0相同,即假设初始条件可行? (If x1+x2 is constrained to equal 1, I'm not sure why the inequality constraints here can ever do anything?) (如果x1+x2被限制为等于 1,我不确定为什么这里的不等式约束可以做任何事情?)
  • eval_f(x0) is considerably larger than eval_f(res$solution) ... eval_f(x0)远大于eval_f(res$solution) ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM