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