Shayan
Shayan

Reputation: 6375

GEKKO TypeError in python

suppose :

# ww is a numpy array
ww.shape
>>>(10, 1)

# C is a numpy array
C.shape
>>>(5, 10)

i want to solve a optimization problem in python with specific objective function.
Here is the code that i wrote for that purpose:

from gekko import GEKKO

m = GEKKO()
x1 = m.Var(value=0.2, lb=0, ub=1, integer=False) #float variable. Lower bound = 0, Upper Bound = 1, inirial Value = 0.2
x2 = m.Var(value=0.2, lb=0, ub=1, integer=False) #float variable. Lower bound = 0, Upper Bound = 1, inirial Value = 0.2
x3 = m.Var(value=0.2, lb=0, ub=1, integer=False) #float variable. Lower bound = 0, Upper Bound = 1, inirial Value = 0.2
x4 = m.Var(value=0.2, lb=0, ub=1, integer=False) #float variable. Lower bound = 0, Upper Bound = 1, inirial Value = 0.2
x5 = m.Var(value=0.2, lb=0, ub=1, integer=False) #float variable. Lower bound = 0, Upper Bound = 1, inirial Value = 0.2

x = [x1, x2, x3, x4, x5]

# My subjective function
m.Equation(x1 + x2 + x3 + x4 + x5 == 1)

# My specific Objective Function
## Remember that I specified about ww and C arrays right upside of these Codes
def Objective(x):
    i = 0
    j = 0
    C_b = np.zeros((1,C.shape[1])) # so C_b.shape would be (1, 10)
    
    for i in range(C.shape[1]):
        for j in range(5):
            C_b[0][i] += math.log10(x[j] * C[j,i])
    
    
    return -sum((C_b * ww)[0])


m.Obj(Objective(x))
m.solve(disp=False)

print(x1.value, x2.value, x3.value, x4.value, x5.value)

Output:

TypeError: must be real number, not GK_Operators

Picture of Error:

enter image description here

i guess this error is cause of specific objective function! because with simple objective functions like :

m.Obj(x1 + x2)

I don't get error! so I guess the error comes from specific objective function.

How can I fix this error? where is the problem?

Upvotes: 2

Views: 241

Answers (2)

Shayan
Shayan

Reputation: 6375

The Error Fixed by changing the shape of ww.
before fixing problem :

ww.shape
>>>(10, 1)

fixed The problem with :

ww.shape
>>>(10, )

Now proposed algorithm worked without any kind of error or problem. That mean it was cause of shape of ww! it fixed after I changed the shape of ww to (10, ) instead (10, 1) .

now Suppose :

# ww is a numpy array
ww.shape
>>>(10, )

# C is a numpy array
C.shape
>>>(5, 10)

Corrected & Proposed Algorithm :

from gekko import GEKKO
import numpy as np

nd = 5

m = GEKKO()
x = m.Array(m.Var,nd,value=1/nd,lb=0,ub=1)
m.Equation(sum(x)==1)

i = 0
j = 0
for i in range(C.shape[1]):
    for j in range(C.shape[0]):
        m.Maximize(ww[i]*(m.log10(x[j] *C[j,i])))
        
m.solve(disp=True)
for i,xi in enumerate(x):
    print(i+1,xi.value)

Upvotes: 1

John Hedengren
John Hedengren

Reputation: 14376

This should work for you.

from gekko import GEKKO
import numpy as np

nd = 5; md = 10
ww = np.random.rand(md)
C  = np.random.rand(nd,md)

m = GEKKO()
x = m.Array(m.Var,nd,value=1/nd,lb=0,ub=1)
m.Equation(sum(x)==1)
for i in range(C.shape[1]):
    for j in range(C.shape[0]):
        m.Maximize(ww[i]*(m.log10(x[j]*C[j,i])))
m.solve(disp=True)
for i,xi in enumerate(x):
    print(i+1,xi.value)

The solution is always 1/nd that is also the same as the initial guess. You can check that the solver converges to this optimal solution (not just stops at the initial guess) by setting the initial guess to something like 1.

Upvotes: 2

Related Questions