Kevin
Kevin

Reputation: 1233

Solve equation using fsolve with inequality equations

I am having trouble understanding how to add inequality equation to fsolve function.

for example:

This are the packages:

import numpy as np
from scipy.optimize import fsolve

These is the equations I want to use:

x1 >= 0.4 and x1 <= 0.7
x2 >= 0.2 and x2 <= 0.4
5x2**2 + 2x1**3 = 2 

and this is the function I am trying to create:

myFunc(z):
    x1 = z[0]
    x2 = z[1]
    
    F = np.empty((3))
    F[0] = x1 >= 0.4 and x1 <= 0.7 # <-- This is the first equation
    F[1] = x2 >= 0.2 and x2 <= 0.4 # <-- this is the second equation
    F[2] = 5x2**2 + 2x1**3 = 2 # <-- this is the third equation
    return F

and then we call the fsolve:

zGuess = np.array([0.3,0.3])
z = fsolve(myFunction,zGuess)
print(z)

Any ideas on how to set inequality equations?

Upvotes: 0

Views: 2355

Answers (1)

joni
joni

Reputation: 7157

The fsolve method neither can handle inequality constraints nor bounds on the variables. Your first two constraints are simple box constraints, i.e. bounds on the variables, so you just want to solve the nonlinear equation system 2x1**3 + 5x**2 == 2 subject to variable bounds. This can be formulated as a constrained minimization problem, similar to this answer:

For F(x) = 2x1**3 + 5x**2 - 2 you want to solve

min ||F(x)|| 

s.t. 0.4 <= x1 <= 0.7, 
     0.2 <= x2 <= 0.4

This constrained optimization problem can easily be solved with scipy.optimize.minimize as follows:

from scipy.optimize import minimize
import numpy as np

def obj(x): return 5*x[1]**2 + 2*x[0]**3 - 2

# Set the variable bounds
bounds = [(0.4, 0.7), (0.2, 0.4)]

# Set initial guess
x0 = np.array([0.3, 0.3])

# Solve the problem (res.x contains your solution)
res = minimize(lambda x: np.linalg.norm(obj(x)), x0=x0, bounds=bounds)

Note that there's no point within your bounds that satisfies the nonlinear equation. Anyway, as we minimized the euclidian norm of the residual, we obtained the best possible point.

Upvotes: 2

Related Questions