Skip to content

Instantly share code, notes, and snippets.

@SteveDiamond
Created May 13, 2015 22:03
Show Gist options
  • Save SteveDiamond/1e48bc42155cd66bc638 to your computer and use it in GitHub Desktop.
Save SteveDiamond/1e48bc42155cd66bc638 to your computer and use it in GitHub Desktop.
Problems that are slow to parse in cvxpy
{
"metadata": {
"name": "",
"signature": "sha256:05f6de9d45e00b178239617584530f1cfb2110e0d666cb4e0ec80599e1dd0269"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These are a list of problems where parsing is slow in CVXPY.\n",
"\n",
"The first four are all from the Convex.jl paper.\n",
"\n",
"Be careful when profiling CVXPY that you create a new problem each time.\n",
"When you solve a problem it caches the cone program matrices, so if you solve it again it doesn't run the matrix stuffing algorithm."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Preparation:\n",
"from cvxpy import *\n",
"import numpy"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Summation.\n",
"n = 10000\n",
"x = Variable()\n",
"e = 0\n",
"for i in range(n):\n",
" e = e + x\n",
"p = Problem(Minimize(norm(e-1,2)), [x>=0])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"# This generates the cone program matrices but doesn't solve the cone program.\n",
"# 99% of the time here is spent in the matrix stuffing algorithm (going from LinOps to the final matrix).\n",
"p = Problem(Minimize(norm(e-1,2)), [x>=0])\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 4.07 s per loop\n"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can replace %%timeit with %%prun to profile the script."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Indexing.\n",
"n = 10000\n",
"x = Variable(n)\n",
"e = 0\n",
"for i in range(n):\n",
" e += x[i];"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"p = Problem(Minimize(norm(e-1,2)), [x>=0])\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 10.9 s per loop\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Transpose\n",
"n = 500\n",
"A = numpy.random.randn(n,n)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"X = Variable(n,n)\n",
"p = Problem(Minimize(norm(X.T-A,'fro')), [X[1,1] == 1])\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 332 ms per loop\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Matrix constraint.\n",
"# CVXPY actually does a pretty good job with this one.\n",
"# Convex.jl and CVX are slower (at least when they were profiled for the paper).\n",
"n = 500\n",
"A = numpy.random.randn(n,n)\n",
"B = numpy.random.randn(n,n)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"X = Variable(n,n)\n",
"p = Problem(Minimize(norm(X-A,'fro')), [X == B])\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 230 ms per loop\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Matrix product.\n",
"# This one is a bit different, because the issue is that the coefficient for A.T*X*A has n^4 nonzeros.\n",
"# A fix is to introduce the variable A.T*X = Y, and rewrite A.T*X*A as Y*A. \n",
"# This will only add 2n^3 nonzeros.\n",
"n = 50\n",
"A = numpy.random.randn(n,n)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"X = Variable(n,n)\n",
"p = Problem(Minimize(norm(X,'fro')), [A.T*X*A >= 1])\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 3.37 s per loop\n"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# SVM with indexing.\n",
"def gen_data(n):\n",
" pos = numpy.random.multivariate_normal([1.0,2.0],numpy.eye(2),size=n)\n",
" neg = numpy.random.multivariate_normal([-1.0,1.0],numpy.eye(2),size=n)\n",
" return pos, neg\n",
"\n",
"N = 2\n",
"C = 10\n",
"pos, neg = gen_data(500)\n",
"\n",
"w = Variable(N)\n",
"b = Variable()\n",
"xi_pos = Variable(pos.shape[0])\n",
"xi_neg = Variable(neg.shape[0])\n",
"cost = sum_squares(w) + C*sum_entries(xi_pos) + C*sum_entries(xi_neg)\n",
"constrs = []\n",
"for j in range(pos.shape[0]):\n",
" constrs += [w.T*pos[j,:] - b >= 1 - xi_pos[j]]\n",
" \n",
"for j in range(neg.shape[0]):\n",
" constrs += [-(w.T*neg[j,:] - b) >= 1 - xi_neg[j]]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 34
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%timeit\n",
"p = Problem(Minimize(cost), constrs)\n",
"p.get_problem_data(ECOS)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 loops, best of 3: 3.71 s per loop\n"
]
}
],
"prompt_number": 35
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment