John
John

Reputation: 21

Minimize function subject to constraint

I am trying to solve a constrained optimization problem using cipy.optimize.minimize but so far had no success.

Specifically I want to minimize the objective function over y1 and y2:

f(y1,y2)=(x1(y1,y2)-x1)^2+(x2(y1,y2)-x2)^2

Subject to the constraint:

y1*y2>0

The goal is to find the values of y1 and y2 for different pairs of x1 and x2.

This is what i have so far

def f(x1,x2):
    k=(x1(y1,y2)-x1)^2+(x2(y1,y2)-x2)^2
    return k

But i am not sure how to set up the function holding the aforementioned constraint:

def constraint(x):
    ....

Once i have the constraint is the following syntax correct?

optimize.minimize(f, np.array([0, 0]), method="SLSQP",
                  constraints={"fun": constraint, "type": "ineq"})

I am new in Python so any help would be appreciated.

Upvotes: 2

Views: 1489

Answers (1)

Tarifazo
Tarifazo

Reputation: 4343

For constraints. From the docs:

Equality constraint means that the constraint function result is to be zero whereas inequality means that it is to be non-negative. Note that COBYLA only supports inequality constraints.

Therefore, your constraint is simply a function that must be non-negative. In your case:

def constraint(y):
    return y[0] * y[1]

Note that the function must input a vector. e.g.:

def f(x):
    x1, x2 = x
    return x1**2 + x2**2

EDIT Using a function that tries to fit calculated vs. observed data.

def calculated_x(y):
    """ example """
    y1, y2 = y
    x1 = 0.5 + 0.2 * y1 + 0.3 * y2
    x2 = 0.4 + 0.1 * y1 + 0.3 * y2

def f(y, x1, x2):
    x1_calc, x2_calc = calculated_x(y)
    return (x1- x1_calc)**2 + (x2 - x2_calc)**2

m = minimize(f, [0,0], args=(3,2), constraints=({'fun': lambda y: y[0] * y[1], 'type': 'ineq'},))
print(m)
>> array([3, 1.999999])

You can also build a function based on your minimization (example above):

def minimize_y(x1, x2):
    # note that x1 and x2 become arguments
    m = minimize(f, [0,0], args=(x1,x2), constraints=({'fun': lambda y: y[0] * y[1], 'type': 'ineq'},)
    return m.x

Upvotes: 1

Related Questions