我可以在Gekko的中间变量中使用累积分布函数吗?

时间:2019-05-22 18:39:05

标签: python normal-distribution gekko

我正在尝试使用Gekko解决非线性优化问题,其中,我的一个中间变量是使用正态分布的累积分布函数来计算的,即1-CDF(μ,σ,Rs-X),其中Rs是另一个Gekko中间变量以及μ,σ和X是Gekko参数/ Python变量。

我还使用Gekko的if3函数实现了这一点,如果Rs-X不是正数,该函数将返回数字1。

    n = len(df_inputs.index)    # rows
    surplus = m.Array(m.Var,(n,1))
    R_sns = m.Array(m.Var,(n,1))
    R_s = m.Array(m.Var,(n,1))
    pi_s = m.Array(m.Var,(n,1))
    for i in range (n):
        surplus[i,0].value =...
        R_sns[i,0].value = m.max3(x,surplus[i,0])
        R_s[i,0].value=m.Intermediate(0.88*R_sns[i,0])
        pi_s[i,0].value = m.if3(R_s[i,0]-x<=0,1,1-norm.cdf(R_s[i,0]-x,df_inputs['Mu'].iloc[i]*0.5,df_inputs['Sigma'].iloc[i]*0.707))

在上面的最后一行代码中,我收到“ TypeError:类型为'int'的对象没有len()”的信息。该错误似乎是由中间变量Rs引起的。我尝试用一​​个固定的数字替换它,错误消失了。

  

回溯(最近通话最近):     在第59行的文件“ solve_v2.py”中       pi_s [i,0] .value = m.if3(R_s [i,0] -x <= 0,1,1-norm.cdf(R_s [i,0] -x,df_inputs ['Mu']。iloc [i] * 0.5,df_inputs ['Sigma']。iloc [i] * 0.707))    ...      len 中的文件“ C:\ Users \ Programs \ Python \ Python37 \ lib \ site-packages \ gekko \ gk_operators.py”,第25行       返回len(self.value)      len 中的文件“ C:\ Users \ Programs \ Python \ Python37 \ lib \ site-packages \ gekko \ gk_operators.py”,第137行       返回len(self.value)   TypeError:“ int”类型的对象没有len()

如何解决此错误?

1 个答案:

答案 0 :(得分:0)

发生此错误是因为norm.cdf不是Gekko函数,并且无法为基于梯度的求解器提供确切的一阶和二阶导数。如果某个功能不在Gekko中,则选项很少,例如:(1)通过在Gekko Github存储库中请求该功能来请求添加该功能,或(2)创建该功能的近似值。创建stats.norm.cdf函数近似值的一种方法是创建三次样条。下面是一个示例:

from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# create cspline of CDF
xp = np.linspace(-5,5,100)
yp = norm.cdf(xp,loc=0,scale=1)
c = GEKKO()
x = c.Var()
y = c.Var()
c.cspline(x,y,xp,yp,True)

# use cspline of CDF in optimization problem
c.Obj((y-0.75)**2)
c.solve(disp=False)

# plot results
plt.figure()
plt.plot(xp,yp,5,'b-')
plt.plot(x.value,y.value,'ro')
plt.ylim([-0.1,1.1])
plt.show()

Cubic spline of Cumulative distribution function

如果样条近似值包含两个因变量,则bspline函数是更好的选择。

上述脚本的另一个问题是使用Gekko if3函数。您可以在第一个参数中省略<=。如功能帮助中所示已经隐含了它。

        Usage: y = m.if3(condition,x1,x2)
        Inputs:
           condition: GEKKO variable, parameter, or expression
           x1 and x2: GEKKO variable, parameter, or expression
        Output: GEKKO variable y = x1 when condition<0
                               y = x2 when condition>=0