Могу ли я использовать кумулятивную распределенную функцию в промежуточных переменных Гекко? - PullRequest
1 голос
/ 22 мая 2019

Я пытаюсь решить задачу нелинейной оптимизации, используя Gekko, где одна из моих промежуточных переменных вычисляется с использованием кумулятивной функции распределения нормального распределения, то есть 1-CDF (μ, σ, Rs-X), где Rs является другимПромежуточная переменная Гекко, а μ, σ и X - параметры Гекко / переменные Питона.

Я также реализовал это, используя функцию if3 Гекко, которая возвращает число 1, если Rs-X не является положительным.

    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.Я попытался заменить это с фиксированным номером, и ошибка ушла.

Traceback (последний вызов был последним): файл "solve_v2.py", строка 59, в 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))... Файл "C: \ Users \ Programs \ Python \ Python37 \ lib \ site-packages \ gekko \ gk_operators.py", строка 25, в <strong>len return len (self.value) Файл "C:\ Users \ Programs \ Python \ Python37 \ lib \ site-packages \ gekko \ gk_operators.py ", строка 137, в len return len (self.value) TypeError: объект типа 'int' не имеетlen ()

Как обойти эту ошибку?

1 Ответ

0 голосов
/ 28 мая 2019

Эта ошибка возникает из-за того, что 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
...