0

I tryed to convert this Mathcad code into the SciPy Python.

My code in Python:

from scipy.optimize import minimize
from scipy.optimize import LinearConstraint
import numpy as np

A=[[1,1,0,1],[-1,-1,1,0],[0,0,-1,-1]] 
V=[[1000, 1000], [0, 0],[-1000, -1000]]

linear_constraint = LinearConstraint (A, V[0],V[1],V[2])
x0 = np.array([0.1,0.1,0.1,0.1])
f = [5*10**-9,2*10**-9,6*10**-8,2*10**-8]

def func(x):
    sum=0
    for i in range(len(f)):
        sum += f[i]*x[i]**3
    return sum

res = minimize(func, x0,method='SLSQP',constraints=[linear_constraint] )

print(res.x)

Result: ValueError: keep_feasible has a wrong shape. What i did wrong?

Deviant
  • 3
  • 2

1 Answers1

0

You're trying to pass a list to the keep_feasible argument of the LinearConstraint constructor, which doesn't make any sense. In addition, your V array is a matrix, not a vector like in your image. LinearConstraints expects constraints in the form lb <= A * x <= ub. If you want to use a equality constraint A*x = b, you can model this through b <= A * x <= b.

It's also worth mentioning that you don't need to use a for-loop to implement your objective function:

import numpy as np
from scipy.optimize import minimize, LinearConstraint


A = np.array([[1,1,0,1],[-1,-1,1,0],[0,0,-1,-1]])
V = np.array([1000, 0, -1000])
x0 = np.array([0.1,0.1,0.1,0.1])
f = np.array([5e-9, 2e-9, 6e-8, 2e-8])

def obj_func(x):
    return np.sum(f * x**3)

# V <= A*x <= V  <-> A*x == V
lincon = LinearConstraint(A, lb=V, ub=V)


res = minimize(obj_func, x0, method='SLSQP', constraints=lincon)
joni
  • 6,840
  • 2
  • 13
  • 20
  • thanks for the answer. I took the information about the design of linear constraints from here http://scipy.github.io/devdocs/tutorial/optimize.html The code that you wrote gives as an answer [0.1,0.1,0.1,0.1] but true answer is [141.267 223.317 364.584 635.416] – Deviant Mar 20 '23 at 08:46
  • I changed method from SLSQP to trust-constr, and its finally work! Thank you. – Deviant Mar 20 '23 at 09:19