{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "What is CVXPY?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "CVXPY is a Python-embedded modeling language for convex optimization problems. CVXPY allows you to express your problem in a natural way. It automatically transforms the problem into standard form, calls a solver, and unpacks the results.\n", "\n", "The code below solves a simple optimization problem in CVXPY:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from cvxpy import *\n", "\n", "# Create two scalar variables.\n", "x = Variable()\n", "y = Variable()\n", "\n", "# Create two constraints.\n", "constraints = [x + y == 1,\n", " x - y >= 1]\n", "\n", "# Form objective.\n", "obj = Minimize(square(x - y))\n", "\n", "# Form and solve problem.\n", "prob = Problem(obj, constraints)\n", "prob.solve() # Returns the optimal value.\n", "print \"status:\", prob.status\n", "print \"optimal value\", prob.value\n", "print \"optimal var\", x.value, y.value" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "status: optimal\n", "optimal value 0.999999989323\n", "optimal var 0.999999998248 1.75244914951e-09\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The status, which was assigned a value \"optimal\" by the solve method, tells us the problem was solved successfully. The optimal value (basically 1 here) is the minimum value of the objective over all choices of variables that satisfy the constraints. The last thing printed gives values of x and y (basically 1 and 0 respectively) that achieve the optimal objective.\n", "\n", "`prob.solve()` returns the optimal value and updates `prob.status`, `prob.value`, and the `value` field of all the variables in the problem." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Namespace" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Python examples in this tutorial import CVXPY using the syntax ``from cvxpy import *``.\n", "This is done to make the examples easier to read. But for production\n", "code you should always import CVXPY as a namespace. For example,\n", "``import cvxpy as cvx``. \n", "\n", "Here's the code from the previous section with\n", "CVXPY imported as a namespace:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import cvxpy as cvx\n", "\n", "# Create two scalar variables.\n", "x = cvx.Variable()\n", "y = cvx.Variable()\n", "\n", "# Create two constraints.\n", "constraints = [x + y == 1,\n", " x - y >= 1]\n", "\n", "# Form objective.\n", "obj = cvx.Minimize(cvx.square(x - y))\n", "\n", "# Form and solve problem.\n", "prob = cvx.Problem(obj, constraints)\n", "prob.solve() # Returns the optimal value.\n", "print \"status:\", prob.status\n", "print \"optimal value\", prob.value\n", "print \"optimal var\", x.value, y.value" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "status: optimal\n", "optimal value 0.999999989323\n", "optimal var 0.999999998248 1.75244914951e-09\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nonetheless we have constructed CVXPY so that using ``from cvxpy import *`` is generally safe for short scripts. The biggest catch is that the built-in ``max`` and ``min`` cannot be used on CVXPY expressions. Instead use the CVXPY [functions](/functions) ``maximum``, ``max``, ``minimum``, or ``min``." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Changing the Problem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After you create a problem object, you can still modify the objective and constraints." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Replace the objective.\n", "prob.objective = Maximize(x + y)\n", "print \"optimal value\", prob.solve()\n", "\n", "# Replace the constraint (x + y == 1).\n", "prob.constraints[0] = (x + y <= 3)\n", "print \"optimal value\", prob.solve()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "optimal value 1.0\n", "optimal value 3.00000000006\n" ] } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Infeasible and Unbounded Problems" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If a problem is infeasible or unbounded, the status field will be set to \"infeasible\" or \"unbounded\", respectively. The value fields of the problem variables are not updated." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from cvxpy import *\n", "\n", "x = Variable()\n", "\n", "# An infeasible problem.\n", "prob = Problem(Minimize(x), [x >= 1, x <= 0])\n", "prob.solve()\n", "print \"status:\", prob.status\n", "print \"optimal value\", prob.value\n", "\n", "# An unbounded problem.\n", "prob = Problem(Minimize(x))\n", "prob.solve()\n", "print \"status:\", prob.status\n", "print \"optimal value\", prob.value" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "status: infeasible\n", "optimal value inf\n", "status: unbounded\n", "optimal value -inf\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that for a minimization problem the optimal value is `inf` if infeasible and `-inf` if unbounded. For maximization problems the opposite is true.\n", "\n", "If the solver called by CVXPY fails to solve the problem, the problem status is set to \"solver_error\" and the optimal value is `None`. See the discussion of [Solvers](#solvers) for details.\n", "\n", "CVXPY provides the constants `OPTIMAL`, `INFEASIBLE`, `UNBOUNDED`, and `SOLVER_ERROR` as aliases for the different status strings." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Vectors and Matrices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables can be scalars, vectors, or matrices." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# A scalar variable.\n", "a = Variable()\n", "\n", "# Column vector variable of length 5.\n", "x = Variable(5)\n", "\n", "# Matrix variable with 4 rows and 7 columns.\n", "A = Variable(4, 7)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use your numeric library of choice to construct matrix and vector constants. For instance, if `x` is a CVXPY Variable in the expression `A*x + b`, `A` and `b` could be Numpy ndarrays, SciPy sparse matrices, etc. `A` and `b` could even be different types.\n", "\n", "Currently the following types may be used as constants:\n", "\n", "* Numpy ndarrays\n", "* Numpy matrices\n", "* SciPy sparse matrices\n", "* CVXOPT dense matrices\n", "* CVXOPT sparse matrices\n", "\n", "Here's an example of a CVXPY problem with vectors and matrices:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Solves a bounded least-squares problem.\n", "\n", "from cvxpy import *\n", "import numpy\n", "\n", "# Problem data.\n", "m = 10\n", "n = 5\n", "numpy.random.seed(1)\n", "A = numpy.random.randn(m, n)\n", "b = numpy.random.randn(m)\n", "\n", "# Construct the problem.\n", "x = Variable(n)\n", "objective = Minimize(sum(square(A*x - b)))\n", "constraints = [0 <= x, x <= 1]\n", "prob = Problem(objective, constraints)\n", "\n", "print \"Optimal value\", prob.solve()\n", "print \"Optimal var\"\n", "print x.value # A numpy matrix." ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Optimal value " ] }, { "output_type": "stream", "stream": "stdout", "text": [ "4.14133859146\n", "Optimal var\n", "[[ -2.76479783e-10]\n", " [ 3.59742090e-10]\n", " [ 1.34633378e-01]\n", " [ 1.24978611e-01]\n", " [ -3.67846924e-11]]\n" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Parameters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Parameters are symbolic representations of constants. The purpose of parameters is to change the value of a constant in a problem without reconstructing the entire problem.\n", "\n", "Parameters can be vectors or matrices, just like variables. When you create a parameter you have the option of specifying the sign of the parameter's entries (positive, negative, or unknown). The sign is unknown by default. The sign is used in [DCP convexity analysis](#disciplined-convex-programming-dcp). Parameters can be assigned a constant value any time after they are created. The constant value must have the same dimensions and sign as those specified when the parameter was created." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Positive scalar parameter.\n", "m = Parameter(nonneg=True)\n", "\n", "# Column vector parameter with unknown sign (by default).\n", "c = Parameter(5)\n", "\n", "# Matrix parameter with negative entries.\n", "G = Parameter(4, 7, nonpos=True)\n", "\n", "# Assigns a constant value to G.\n", "G.value = -numpy.ones((4, 7))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Computing trade-off curves is a common use of parameters. The example below computes a trade-off curve for a LASSO problem." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from cvxpy import *\n", "import numpy\n", "import matplotlib.pyplot as plt\n", "\n", "# Problem data.\n", "n = 15\n", "m = 10\n", "numpy.random.seed(1)\n", "A = numpy.random.randn(n, m)\n", "b = numpy.random.randn(n)\n", "# gamma must be positive due to DCP rules.\n", "gamma = Parameter(nonneg=True) \n", "\n", "# Construct the problem.\n", "x = Variable(m)\n", "sum_of_squares = sum(square(A*x - b))\n", "obj = Minimize(sum_of_squares + gamma*norm(x, 1))\n", "prob = Problem(obj)\n", "\n", "# Construct a trade-off curve of ||Ax-b||^2 vs. ||x||_1\n", "sq_penalty = []\n", "l1_penalty = []\n", "x_values = []\n", "gamma_vals = numpy.logspace(-4, 6)\n", "for val in gamma_vals:\n", " gamma.value = val\n", " prob.solve()\n", " # Use expr.value to get the numerical value of\n", " # an expression in the problem.\n", " sq_penalty.append(sum_of_squares.value)\n", " l1_penalty.append(norm(x, 1).value)\n", " x_values.append(x.value)\n", "\n", "%matplotlib inline\n", "plt.rc('text', usetex=True)\n", "plt.rc('font', family='serif')\n", "plt.figure(figsize=(6,10))\n", "\n", "# Plot trade-off curve.\n", "plt.subplot(211)\n", "plt.plot(l1_penalty, sq_penalty)\n", "plt.xlabel(r'\\|x\\|_1', fontsize=16)\n", "plt.ylabel(r'\\|Ax-b\\|^2', fontsize=16)\n", "plt.title('Trade-Off Curve for LASSO', fontsize=16)\n", "\n", "# Plot entries of x vs. gamma.\n", "plt.subplot(212)\n", "for i in range(m):\n", " plt.plot(gamma_vals, [xi[i,0] for xi in x_values])\n", "plt.xlabel(r'\\gamma', fontsize=16)\n", "plt.ylabel(r'x_{i}', fontsize=16)\n", "plt.xscale('log')\n", "plt.title(r'\\text{Entries of x vs. }\\gamma', fontsize=16)\n", "\n", "plt.tight_layout()\n", "plt.show()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Trade-off curves can easily be computed in parallel. The code below computes in parallel the optimal x for each $\\gamma$ in the LASSO problem above." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from multiprocessing import Pool\n", "\n", "# Assign a value to gamma and find the optimal x.\n", "def get_x(gamma_value):\n", " gamma.value = gamma_value\n", " result = prob.solve()\n", " return x.value\n", "\n", "# Parallel computation (set to 1 process here).\n", "pool = Pool(processes = 1)\n", "x_values = pool.map(get_x, gamma_vals)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 } ], "metadata": {} } ] }