Nonlinear Feasibility Problem¶
Find a point that satisfies several nonlinear constraints, taken from this MATLAB example
Problem Description¶
\[(y+x^2)^2+0.1y^2\leq1\]
\[y\leq\exp(-x)-3\]
\[y\leq x-4\]
Does any point \((x,y)\) satisfy all of the constraints?
Modules Importing¶
Import all necessary modules and add PyGRANSO src folder to system path.
[1]:
import time
import torch
from pygranso.pygranso import pygranso
from pygranso.pygransoStruct import pygransoStruct
Function Set-Up¶
Encode the optimization variables, and objective and constraint functions.
Note: please strictly follow the format of comb_fn, which will be used in the PyGRANSO main algortihm.
[2]:
device = torch.device('cpu')
# variables and corresponding dimensions.
var_in = {"x": [1,1],"y": [1,1]}
def comb_fn(X_struct):
x = X_struct.x
y = X_struct.y
# constant objective function
f = 0*x+0*y
# inequality constraint
ci = pygransoStruct()
ci.c1 = (y+x**2)**2+0.1*y**2-1
ci.c2 = y - torch.exp(-x) - 3
ci.c3 = y-x+4
# equality constraint
ce = None
return [f,ci,ce]
User Options¶
Specify user-defined options for PyGRANSO
[3]:
opts = pygransoStruct()
opts.torch_device = device
opts.print_frequency = 1
# All the user-provided data (vector/matrix/tensor) must be in torch tensor format.
# As PyTorch tensor is single precision by default, one must explicitly set `dtype=torch.double`.
# Also, please make sure the device of provided torch tensor is the same as opts.torch_device.
opts.x0 = 0 * torch.ones((2,1)).to(device=device, dtype=torch.double)
Main Algorithm¶
[4]:
start = time.time()
soln = pygranso(var_spec = var_in,combined_fn = comb_fn,user_opts = opts)
end = time.time()
print("Total Wall Time: {}s".format(end - start))
print("PyGRANSO finds a feaible point:(%f,%f)"%(soln.final.x[0],soln.final.x[1]) )
╔═════ QP SOLVER NOTICE ════════════════════════════════════════════════════════════════════════╗
║ PyGRANSO requires a quadratic program (QP) solver that has a quadprog-compatible interface, ║
║ the default is osqp. Users may provide their own wrapper for the QP solver. ║
║ To disable this notice, set opts.quadprog_info_msg = False ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════╝
═════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
PyGRANSO: A PyTorch-enabled port of GRANSO with auto-differentiation ║
Version 1.2.0 ║
Licensed under the AGPLv3, Copyright (C) 2021-2022 Tim Mitchell and Buyun Liang ║
═════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
Problem specifications: ║
# of variables : 2 ║
# of inequality constraints : 3 ║
# of equality constraints : 0 ║
═════╦═══════════════════════════╦════════════════╦═════════════════╦═══════════════════════╦════════════════════╣
║ <--- Penalty Function --> ║ ║ Total Violation ║ <--- Line Search ---> ║ <- Stationarity -> ║
Iter ║ Mu │ Value ║ Objective ║ Ineq │ Eq ║ SD │ Evals │ t ║ Grads │ Value ║
═════╬═══════════════════════════╬════════════════╬═════════════════╬═══════════════════════╬════════════════════╣
0 ║ 1.000000 │ 4.00000000000 ║ 0.00000000000 ║ 4.000000 │ - ║ - │ 1 │ 0.000000 ║ 1 │ 1.414214 ║
1 ║ 1.000000 │ 3.40000000000 ║ 0.00000000000 ║ 3.400000 │ - ║ S │ 2 │ 2.000000 ║ 2 │ 0.245323 ║
2 ║ 1.000000 │ 0.17527969143 ║ 0.00000000000 ║ 0.175280 │ - ║ S │ 2 │ 2.000000 ║ 1 │ 0.128174 ║
3 ║ 1.000000 │ 0.00000000000 ║ 0.00000000000 ║ 0.000000 │ - ║ S │ 2 │ 2.000000 ║ 1 │ 0.000000 ║
═════╩═══════════════════════════╩════════════════╩═════════════════╩═══════════════════════╩════════════════════╣
F = final iterate, B = Best (to tolerance), MF = Most Feasible ║
Optimization results: ║
═════╦═══════════════════════════╦════════════════╦═════════════════╦═══════════════════════╦════════════════════╣
F ║ │ ║ 0.00000000000 ║ 0.000000 │ - ║ │ │ ║ │ ║
B ║ │ ║ 0.00000000000 ║ 0.000000 │ - ║ │ │ ║ │ ║
MF ║ │ ║ 0.00000000000 ║ 0.000000 │ - ║ │ │ ║ │ ║
═════╩═══════════════════════════╩════════════════╩═════════════════╩═══════════════════════╩════════════════════╣
Iterations: 3 ║
Function evaluations: 7 ║
PyGRANSO termination code: 0 --- converged to stationarity and feasibility tolerances. ║
═════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Total Wall Time: 0.04715752601623535s
PyGRANSO finds a feaible point:(1.688660,-2.486619)