Вопрос об условном утверждении ('m.if3') в GEKKO - PullRequest
2 голосов
/ 20 июня 2019

Я хотел бы добавить несколько условных выражений в код GEKKO.

Я добавил нижеприведенное выражение с «m.if3». Однако он вернул синтаксическую ошибку, которой не было у меня без условного выражения.

'R1_1 = m.if3 (R1 <0, 0, R1)' </p>

#%% GEKKO
m = GEKKO(remote=False)

#print(m.version)
#m.time = np.linspace(0, 3600, 100)
m.time = np.array([0,tstep])

cH = m.CV(value=cs0[0])
cM = m.CV(value=cs0[1])
cW = m.CV(value=cs0[2])
cF = m.CV(value=cs0[3])

R1_1 = m.Var()

r3 = m.Intermediate(r0*(1-cF/cFeMax)**(1/3))
r2 = m.Intermediate(r0*((2*cH + 3*cM)/cFeMax)**(1/3))
r1 = m.Intermediate(r0*(2*cH/cFeMax)**(1/3))
x = m.Intermediate(r1/r0)
y = m.Intermediate(r2/r0)
z = m.Intermediate(r3/r0)
A1 = m.Intermediate(1/x**2/(kd[0]*(1+1/Keq[0])))
A2 = m.Intermediate(1/y**2/(kd[1]*(1+1/Keq[1])))
A3 = m.Intermediate(1/z**2/(kd[2]*(1+1/Keq[2])))
B1 = m.Intermediate((y-x)/x/y*r0/Dif[1])
B2 = m.Intermediate((z-y)/y/z*r0/Dif[2])
B3 = m.Intermediate((1-z)/z*r0/Dif[3])
F = 0
W = m.Intermediate((A1+B1)*(A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))+A2*(A3*(B2+B3+F))+B2*(B3+F))
ceq1 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[0]))
ceq2 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[1]))
ceq3 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[2]))

R1 = m.Intermediate(3/r0/W*((A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))*(cg0[0]-ceq1) \
                     -(A3*(B2+B3+F)+B2*(B3+F))*(cg0[0]-ceq2) \
                     -A2*(B3+F)*(cg0[0]-ceq3)))
R2 = m.Intermediate(3/r0/W*(-(B2*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq1) \
                     +((A1+B1+B2)*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq2) \
                     -(A1+B1)*(B3+F)*(cg0[0]-ceq3)))
R3 = m.Intermediate(3/r0/W*(-A2*(B3+F)*(cg0[0]-ceq1) \
                    -(A1+B1)*(B3+F)*(cg0[0]-ceq2) \
                    +((A1+B1)*(A2+B2+B3+F)+A2*(B2+B1+F))*(cg0[0]-ceq3)))

R1_1 = m.if3(R1<0, 0, R1)

m.Equation(cH.dt() == nus[0].dot([R1_1, R2, R3]))
m.Equation(cM.dt() == nus[1].dot([R1_1, R2, R3]))
m.Equation(cW.dt() == nus[2].dot([R1_1, R2, R3]))
m.Equation(cF.dt() == nus[3].dot([R1_1, R2, R3]))

m.options.IMODE = 4
m.options.SOLVER = 3
m.options.nodes = 2

Исключение: @error: выражение модели *** Ошибка в синтаксисе строки функции: Несоответствующая скобка

Позиция: 4
(0))) - ((((1-int_v5)) * (I35) -slk_1

1 Ответ

2 голосов
/ 20 июня 2019

Для использования функции if3 в Gekko требуется только одно исправление (удалите <0).

R1_1 = m.if3(R1, 0, R1)

Функция m.if3 использует условие, которое переключает то, что используется (аргумент 2или 3) в зависимости от того, является ли условие меньше нуля или больше или равно нулю.Вот результат помощи (m.if3) с некоторыми дополнительными пояснениями:

if3(condition, x1, x2) method of gekko.gekko.GEKKO instance

IF conditional with a binary switch variable.
The traditional method for IF statements is not continuously
differentiable and can cause a gradient-based optimizer to fail
to converge.

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

Еще одна вещь, которую следует учитывать, - это то, что функция if3 использует двоичные переменные, и вам нужно будет использовать Mixed Integerрешатель, чтобы найти целочисленное решение.Вы можете удалить строку, которая переключает решатель на IPOPT (if3 переключается на решатель APOPT по умолчанию), или вы можете переключить опцию на APOPT вручную.

m.options.SOLVER = 1

Некоторые из констант отсутствовали втвой сценарийЯ добавил несколько фиктивных переменных, чтобы запустить его.

from gekko import GEKKO
import numpy as np

m = GEKKO()

help(m.if3)

tstep = 1.0
cs0=[1,1,1,1]
r0 = 1.0
cFeMax = 1.0
kd = [1,1,1]
Keq = [1,1,1]
Dif = [1,1,1,1]
cg0 = [1,1,1]
nus = np.array([[1,1,1],[1,1,1],[1,1,1],[1,1,1]])

m.time = np.array([0,tstep])

cH = m.CV(value=cs0[0])
cM = m.CV(value=cs0[1])
cW = m.CV(value=cs0[2])
cF = m.CV(value=cs0[3])

R1_1 = m.Var()

r3 = m.Intermediate(r0*(1-cF/cFeMax)**(1/3))
r2 = m.Intermediate(r0*((2*cH + 3*cM)/cFeMax)**(1/3))
r1 = m.Intermediate(r0*(2*cH/cFeMax)**(1/3))
x = m.Intermediate(r1/r0)
y = m.Intermediate(r2/r0)
z = m.Intermediate(r3/r0)
A1 = m.Intermediate(1/x**2/(kd[0]*(1+1/Keq[0])))
A2 = m.Intermediate(1/y**2/(kd[1]*(1+1/Keq[1])))
A3 = m.Intermediate(1/z**2/(kd[2]*(1+1/Keq[2])))
B1 = m.Intermediate((y-x)/x/y*r0/Dif[1])
B2 = m.Intermediate((z-y)/y/z*r0/Dif[2])
B3 = m.Intermediate((1-z)/z*r0/Dif[3])
F = 0
W = m.Intermediate((A1+B1)*(A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))+A2*(A3*(B2+B3+F))+B2*(B3+F))
ceq1 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[0]))
ceq2 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[1]))
ceq3 = m.Intermediate((cg0[0]+cg0[1])/(1+Keq[2]))

R1 = m.Intermediate(3/r0/W*((A3*(A2+B2+B3+F)+(A2+B2)*(B3+F))*(cg0[0]-ceq1) \
                     -(A3*(B2+B3+F)+B2*(B3+F))*(cg0[0]-ceq2) \
                     -A2*(B3+F)*(cg0[0]-ceq3)))
R2 = m.Intermediate(3/r0/W*(-(B2*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq1) \
                     +((A1+B1+B2)*(A3+B3+F)+A3*(B3+F))*(cg0[0]-ceq2) \
                     -(A1+B1)*(B3+F)*(cg0[0]-ceq3)))
R3 = m.Intermediate(3/r0/W*(-A2*(B3+F)*(cg0[0]-ceq1) \
                    -(A1+B1)*(B3+F)*(cg0[0]-ceq2) \
                    +((A1+B1)*(A2+B2+B3+F)+A2*(B2+B1+F))*(cg0[0]-ceq3)))

R1_1 = m.if3(R1, 0, R1)

m.Equation(cH.dt() == nus[0].dot([R1_1, R2, R3]))
m.Equation(cM.dt() == nus[1].dot([R1_1, R2, R3]))
m.Equation(cW.dt() == nus[2].dot([R1_1, R2, R3]))
m.Equation(cF.dt() == nus[3].dot([R1_1, R2, R3]))

m.options.IMODE = 4
m.options.SOLVER = 1
m.options.nodes = 2

m.solve()
...