Skip to content

Commit

Permalink
updated README
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Diamond committed Aug 15, 2013
1 parent cf189f5 commit acb904a
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 1 deletion.
27 changes: 26 additions & 1 deletion README.md
@@ -1,6 +1,31 @@
CVXPY
=====
CVXPY is a Python modeling language for optimization problems.
CVXPY is a Python modeling language for optimization problems. CVXPY lets you express your problem in a natural way. It automatically transforms the problem into a standard form, calls a solver, and unpacks the results.

For example, consider the LASSO problem:
minimize ||Ax-b||~2~ + \lambda||x||~1~

The problem can be expressed in CVXPY like so:

```
from cvxpy import *
# Problem data.
n = 10
m = 5
A = cvxopt.normal(n,m)
b = cvxopt.normal(m)
lambda = 1
# Construct the problem.
x = Variable(m)
p = Problem(Minimize(norm2(A*x - b) + lambda*norm1(x)))
# The optimal objective is returned by p.solve().
result = p.solve()
# The optimal value for x is stored in x.value.
print x.value
```

Currently supports numpy arrays and matrices, cvxopt matrices, numbers, and python lists as constants. Matrices and vectors must be declared as Constants, i.e. A = Constant(numpy array).

Expand Down
11 changes: 11 additions & 0 deletions add_gpl
@@ -0,0 +1,11 @@
#!/bin/bash
# http://stackoverflow.com/questions/151677/tool-for-adding-license-headers-to-source-files
DIRECTORY=$1
for i in $DIRECTORY/*.py # or whatever other pattern...
do
if ! grep -q Copyright $i
then
cat copyright.txt $i >$i.new && mv $i.new $i
echo $i
fi
done
19 changes: 19 additions & 0 deletions copyright.txt
@@ -0,0 +1,19 @@
"""
Copyright 2013 Steven Diamond

This file is part of CVXPY.

CVXPY is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CVXPY is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CVXPY. If not, see <http://www.gnu.org/licenses/>.
"""

79 changes: 79 additions & 0 deletions examples/flows/leaky_edges.py
@@ -0,0 +1,79 @@
"""
Copyright 2013 Steven Diamond
This file is part of CVXPY.
CVXPY is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CVXPY is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CVXPY. If not, see <http://www.gnu.org/licenses/>.
"""

from cvxpy import *
import create_graph as g
from max_flow import Node, Edge
import pickle

# Max-flow with different kinds of edges.
class Directed(Edge):
""" A directed, capacity limited edge """
# Returns the edge's internal constraints.
def constraints(self):
return [self.in_flow <= 0] + super(Directed, self).constraints()

class LeakyDirected(Edge):
""" A directed edge that leaks flow. """
EFFICIENCY = .95
# Returns the edge's internal constraints.
def constraints(self):
return [self.EFFICIENCY*self.in_flow + self.out_flow == 0,
self.in_flow <= 0,
abs(self.in_flow) <= self.capacity]

class LeakyUndirected(Edge):
""" An undirected edge that leaks flow. """
# Model a leaky undirected edge as two leaky directed
# edges pointing in opposite directions.
def __init__(self, capacity):
self.forward = LeakyDirected(capacity)
self.backward = LeakyDirected(capacity)
self.in_flow = self.forward.in_flow + self.backward.out_flow
self.out_flow = self.forward.out_flow + self.backward.in_flow

def constraints(self):
return self.forward.constraints() + self.backward.constraints()

if __name__ == "__main__":
# Read a graph from a file.
f = open(g.FILE, 'r')
data = pickle.load(f)
f.close()

# Construct nodes.
node_count = data[g.NODE_COUNT_KEY]
nodes = [Node() for i in range(node_count)]
# Add source.
nodes[0].accumulation = Variable()
# Add sink.
nodes[-1].accumulation = Variable()

# Construct edges.
edges = []
for n1,n2,capacity in data[g.EDGES_KEY]:
edges.append(LeakyUndirected(capacity))
edges[-1].connect(nodes[n1], nodes[n2])

# Construct the problem.
constraints = []
map(constraints.extend, (o.constraints() for o in nodes + edges))
p = Problem(Maximize(nodes[-1].accumulation), constraints)
result = p.solve()
print result
67 changes: 67 additions & 0 deletions examples/image_processing.py
@@ -0,0 +1,67 @@
from cvxpy import *
from itertools import izip, imap
import cvxopt
import pylab
import math

# create simple image
n = 32
img = cvxopt.matrix(0.0,(n,n))
img[1:2,1:2] = 0.5

# add noise
img = img + 0.1*cvxopt.uniform(n,n)

# show the image
plt = pylab.imshow(img)
plt.set_cmap('gray')
pylab.show()

# define the gradient functions
def grad(img, direction):
m, n = img.size
for i in range(m):
for j in range(n):
if direction == 'y' and j > 0 and j < m-1:
yield img[i,j+1] - img[i,j-1]
elif direction == 'x' and i > 0 and i < n-1:
yield img[i+1,j] - img[i-1,j]
else:
yield 0.0

# take the gradients
img_gradx, img_grady = grad(img,'x'), grad(img,'y')

# filter them (remove ones with small magnitude)

def denoise(gradx, grady, thresh):
for dx, dy in izip(gradx, grady):
if math.sqrt(dx*dx + dy*dy) >= thresh: yield (dx,dy)
else: yield (0.0,0.0)

denoise_gradx, denoise_grady = izip(*denoise(img_gradx, img_grady, 0.2))

# function to get boundary of image
def boundary(img):
m, n = img.size
for i in range(m):
for j in range(n):
if i == 0 or j == 0 or i == n-1 or j == n-1:
yield img[i,j]

# now, reconstruct the image by solving a constrained least-squares problem
new_img = Variable(n,n)
gradx_obj = imap(square, (fx - gx for fx, gx in izip(grad(new_img,'x'),denoise_gradx)))
grady_obj = imap(square, (fy - gy for fy, gy in izip(grad(new_img,'y'),denoise_grady)))

p = Problem(
Minimize(sum(gradx_obj) + sum(grady_obj)),
list(px == 0 for px in boundary(new_img)))
p.solve()

# show the reconstructed image
plt = pylab.imshow(new_img.value)
plt.set_cmap('gray')
pylab.show()

print new_img.value
45 changes: 45 additions & 0 deletions examples/optimal_control.py
@@ -0,0 +1,45 @@
"""
Copyright 2013 Steven Diamond
This file is part of CVXPY.
CVXPY is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CVXPY is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CVXPY. If not, see <http://www.gnu.org/licenses/>.
"""

from cvxpy import *
import cvxopt
# Problem data
T = 10
n,p = (10,5)
A = cvxopt.normal(n,n)
B = cvxopt.normal(n,p)
x_init = cvxopt.normal(n)
x_final = cvxopt.normal(n)

# Object oriented optimal control problem.
class Stage(object):
def __init__(self, A, B, x_prev):
self.x = Variable(n)
self.u = Variable(p)
self.cost = sum(square(self.u)) + sum(abs(self.x))
self.constraint = (self.x == A*x_prev + B*self.u)

stages = [Stage(A, B, x_init)]
for i in range(T):
stages.append(Stage(A, B, stages[-1].x))

obj = sum(s.cost for s in stages)
constraints = [stages[-1].x == x_final]
map(constraints.append, (s.constraint for s in stages))
print Problem(Minimize(obj), constraints).solve()

0 comments on commit acb904a

Please sign in to comment.