[cvxopt] 31/64: Imported Upstream version 1.1.4

Andreas Tille tille at debian.org
Wed Jul 20 11:23:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository cvxopt.

commit b79420f7866272efa3c8d5b32aebcbd95d1cfc35
Author: Andreas Tille <tille at debian.org>
Date:   Wed Jul 20 08:26:59 2016 +0200

    Imported Upstream version 1.1.4
---
 INSTALL                             |   4 +-
 LICENSE                             |   4 +-
 doc/source/blas.rst                 |   4 +-
 doc/source/c-api.rst                |  29 +-
 doc/source/coneprog.rst             |  36 +-
 doc/source/copyright.rst            |   2 +-
 doc/source/index.rst                |   2 +-
 doc/source/lapack.rst               |  58 ++--
 doc/source/matrices.rst             | 252 +++++++-------
 doc/source/modeling.rst             |  34 +-
 doc/source/printing.rst             |   8 +-
 doc/source/solvers.rst              |  16 +-
 doc/source/spsolvers.rst            |  32 +-
 examples/book/chap4/portfolio.py    |  63 ++--
 examples/book/chap4/rls.py          |  50 +--
 examples/book/chap6/basispursuit.py | 133 ++++----
 examples/book/chap6/consumerpref.py |  90 ++---
 examples/book/chap6/cvxfit.py       |  33 +-
 examples/book/chap6/huber.py        |  28 +-
 examples/book/chap6/inputdesign.py  |  79 +++--
 examples/book/chap6/penalties.py    |  74 ++--
 examples/book/chap6/polapprox.py    | 100 +++---
 examples/book/chap6/regsel.py       |  75 +++--
 examples/book/chap6/robls.py        |  69 ++--
 examples/book/chap6/smoothrec.py    |  94 +++---
 examples/book/chap6/tv.py           | 191 ++++++-----
 examples/book/chap7/chernoff.py     |  52 +--
 examples/book/chap7/expdesign.py    |  69 ++--
 examples/book/chap7/logreg.py       |  29 +-
 examples/book/chap7/maxent.py       |  46 +--
 examples/book/chap7/probbounds.py   | 159 ++++-----
 examples/book/chap8/centers.py      | 158 ++++-----
 examples/book/chap8/ellipsoids.py   | 118 +++----
 examples/book/chap8/floorplan.py    |  90 ++---
 examples/book/chap8/linsep.py       |  86 ++---
 examples/book/chap8/placement.py    | 144 ++++----
 examples/doc/chap10/l1svc.py        |   2 +-
 examples/doc/chap10/lp.py           |  26 +-
 examples/doc/chap10/roblp.py        |   2 +-
 examples/doc/chap4/acent            |  76 -----
 examples/doc/chap4/acent.py         |  12 +-
 examples/doc/chap7/covsel.py        |  16 +-
 examples/doc/chap8/conelp.py        |   8 +-
 examples/doc/chap8/coneqp.py        |   3 +-
 examples/doc/chap8/lp.py            |   3 +-
 examples/doc/chap8/mcsdp.py         |  24 +-
 examples/doc/chap8/portfolio.py     |  60 ++--
 examples/doc/chap8/qcl1.py          |   2 +-
 examples/doc/chap8/sdp.py           |   9 +-
 examples/doc/chap8/socp.py          |   9 +-
 examples/doc/chap9/acent2.py        |   3 +-
 examples/doc/chap9/floorplan.py     | 102 +++---
 examples/doc/chap9/gp.py            |   2 +-
 examples/doc/chap9/robls.py         |   1 -
 examples/filterdemo/README          |   4 +-
 examples/filterdemo/filterdemo_cli  |  24 +-
 examples/filterdemo/filterdemo_gui  |   2 +-
 src/C/amd.c                         | 106 ++++--
 src/C/base.c                        | 213 +++++++++++-
 src/C/blas.c                        | 367 ++++++++++++++++++--
 src/C/cholmod.c                     | 189 ++++++++++-
 src/C/cvxopt.h                      |  40 +--
 src/C/dense.c                       | 522 ++++++++++++++++++++++-------
 src/C/dsdp.c                        | 162 ++++++---
 src/C/fftw.c                        | 230 ++++++++++---
 src/C/glpk.c                        | 218 +++++++++---
 src/C/gsl.c                         |  43 ++-
 src/C/lapack.c                      | 652 +++++++++++++++++++++++++++++++-----
 src/C/misc.h                        |  19 +-
 src/C/misc_solvers.c                | 204 ++++++++++-
 src/C/sparse.c                      | 386 ++++++++++++++-------
 src/C/umfpack.c                     | 177 +++++++++-
 src/python/__init__.py              |  32 +-
 src/python/coneprog.py              | 108 +++---
 src/python/cvxprog.py               |  32 +-
 src/python/info.py                  |   6 +-
 src/python/misc.py                  |  86 ++---
 src/python/modeling.py              | 313 ++++++++++-------
 src/python/msk.py                   |  18 +-
 src/python/printing.py              |  64 ++--
 src/python/solvers.py               |   4 +-
 src/setup.py                        |   4 +-
 82 files changed, 4758 insertions(+), 2338 deletions(-)

diff --git a/INSTALL b/INSTALL
index e821da8..638e2e2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-Installation instructions for CVXOPT Version 1.1.3.
+Installation instructions for CVXOPT Version 1.1.4.
 
-The package requires version 2.5 or newer of Python, and is built from 
+The package requires version 2.7 or newer of Python, and is built from 
 source, so the header files and libraries for Python must be installed, 
 as well as the core binaries.
 
diff --git a/LICENSE b/LICENSE
index 9ba88e1..883e140 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
-CVXOPT version 1.1.3. 
+CVXOPT version 1.1.4. 
 
-Copyright (c) 2010 L. Vandenberghe.
+Copyright (c) 2010-2011 L. Vandenberghe.
 Copyright (c) 2004-2009 J. Dahl and L. Vandenberghe.
 
 This program is free software; you can redistribute it and/or modify
diff --git a/doc/source/blas.rst b/doc/source/blas.rst
index 22c3a15..c8757ea 100644
--- a/doc/source/blas.rst
+++ b/doc/source/blas.rst
@@ -715,7 +715,7 @@ with the vector :math:`x = (1,-1,2,-2)`.
 >>> x = matrix([1., -1., 2., -2.])
 >>> y = matrix(0., (3,1))
 >>> gbmv(A, 3, 1, x, y)
->>> print y
+>>> print(y)
 [-5.00e+00]
 [ 1.20e+01]
 [-1.00e+00]
@@ -729,7 +729,7 @@ The following example illustrates the use of
 >>> A = matrix([-6., 5., -1., 2.], (1,4))
 >>> x = matrix(1.0, (4,1))
 >>> tbsv(A, x)  # x := diag(A)^{-1}*x
->>> print x
+>>> print(x)
 [-1.67e-01]
 [ 2.00e-01]
 [-1.00e+00]
diff --git a/doc/source/c-api.rst b/doc/source/c-api.rst
index 412b8a5..3d356ef 100644
--- a/doc/source/c-api.rst
+++ b/doc/source/c-api.rst
@@ -18,15 +18,36 @@ the API:
 
 ::
 
+    #if PY_MAJOR_VERSION >= 3
+
+    static PyModuleDef blas_module = {
+        PyModuleDef_HEAD_INIT,
+        "blas",
+        blas__doc__,
+        -1,
+        blas_functions,
+        NULL, NULL, NULL, NULL
+    };
+    
+    PyMODINIT_FUNC PyInit_blas(void)
+    {
+      PyObject *m;
+      if (!(m = PyModule_Create(&blas_module))) return NULL;
+      if (import_cvxopt() < 0) return NULL;
+      return m;
+    }
+    
+    #else 
+    
     PyMODINIT_FUNC initblas(void)
     {
       PyObject *m;
-
       m = Py_InitModule3("cvxopt.blas", blas_functions, blas__doc__);
-
-      if (import_cvxopt() < 0)
-        return;
+      if (import_cvxopt() < 0) return ;
     }
+    
+    #endif
+
 
   
 Dense Matrices
diff --git a/doc/source/coneprog.rst b/doc/source/coneprog.rst
index b545de6..5fa29c9 100644
--- a/doc/source/coneprog.rst
+++ b/doc/source/coneprog.rst
@@ -329,11 +329,11 @@ As an example we solve the problem
 >>> sol = solvers.conelp(c, G, h, dims)
 >>> sol['status']
 'optimal'
->>> print sol['x']
+>>> print(sol['x'])
 [-1.22e+00]
 [ 9.66e-02]
 [ 3.58e+00]
->>> print sol['z']
+>>> print(sol['z'])
 [ 9.30e-02]
 [ 2.04e-08]
 [ 2.35e-01]
@@ -593,7 +593,7 @@ with
 >>> h = matrix(n*[0.0] + [1.0] + n*[0.0])
 >>> dims = {'l': n, 'q': [n+1], 's': []}
 >>> x = solvers.coneqp(A.T*A, -A.T*b, G, h, dims)['x']
->>> print x
+>>> print(x)
 [ 7.26e-01]
 [ 6.18e-01]
 [ 3.03e-01]
@@ -665,7 +665,7 @@ As a simple example we solve the LP
 >>> G = matrix([[2., 1., -1., 0.], [1., 2., 0., -1.]])
 >>> h = matrix([3., 3., 0., 0.])
 >>> sol = solvers.lp(c, G, h)
->>> print sol['x']
+>>> print(sol['x'])
 [ 1.00e+00]
 [ 1.00e+00]
 
@@ -786,7 +786,7 @@ the trade-off curve and produces two figures using the
 
     # Compute trade-off.
     N = 100
-    mus = [ 10**(5.0*t/N-1.0) for t in xrange(N) ]
+    mus = [ 10**(5.0*t/N-1.0) for t in range(N) ]
     portfolios = [ qp(mu*S, -pbar, G, h, A, b)['x'] for mu in mus ]
     returns = [ dot(pbar,x) for x in portfolios ]
     risks = [ sqrt(dot(x, S*x)) for x in portfolios ]
@@ -873,7 +873,7 @@ cone programs with no linear matrix inequality constraints.
 
     The input argument ``c`` is a real single-column dense matrix.  The 
     arguments ``Gl`` and ``hl`` are the coefficient matrix :math:`G_0` and 
-    the righthand side :math:`h_0` of the componentwise inequalities.
+    the right-hand side :math:`h_0` of the componentwise inequalities.
     ``Gl`` is a real dense or sparse matrix; ``hl`` is a real single-column
     dense matrix.  The default values for ``Gl`` and ``hl`` are matrices 
     with zero rows.
@@ -954,15 +954,15 @@ As an example, we solve  the second-order cone program
 >>> sol = solvers.socp(c, Gq = G, hq = h)
 >>> sol['status']
 optimal
->>> print sol['x']
+>>> print(sol['x'])
 [-5.02e+00]
 [-5.77e+00]
 [-8.52e+00]
->>> print sol['zq'][0]
+>>> print(sol['zq'][0])
 [ 1.34e+00]
 [-7.63e-02]
 [-1.34e+00]
->>> print sol['zq'][1]
+>>> print(sol['zq'][1])
 [ 1.02e+00]
 [ 4.02e-01]
 [ 7.80e-01]
@@ -1017,14 +1017,14 @@ option of using the DSDP semidefinite programming solver.
         s_0 \succeq 0, \qquad z_0 \succeq 0
 
     are componentwise vector inequalities.  The other inequalities are 
-    matrix inequalities (\ie, the require the lefthand sides to be positive
-    semidefinite).  We use the notation :math:`\mathbf{vec}(z)` to denote 
-    a symmetric matrix :math:`z` stored in column major order as a column 
-    vector.
+    matrix inequalities (\ie, the require the left-hand sides to be 
+    positive semidefinite).  We use the notation :math:`\mathbf{vec}(z)` 
+    to denote a symmetric matrix :math:`z` stored in column major order 
+    as a column vector.
 
     The input argument ``c`` is a real single-column dense matrix.  The 
     arguments ``Gl`` and ``hl`` are the coefficient matrix :math:`G_0` and
-    the righthand side :math:`h_0` of the componentwise inequalities.
+    the right-hand side :math:`h_0` of the componentwise inequalities.
     ``Gl`` is a real dense or sparse matrix;  ``hl`` is a real 
     single-column dense matrix.   The default values for ``Gl`` and ``hl``
     are matrices with zero rows.
@@ -1137,14 +1137,14 @@ We illustrate the calling sequence with a small example.
 >>> h = [ matrix([[33., -9.], [-9., 26.]]) ]
 >>> h += [ matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) ]
 >>> sol = solvers.sdp(c, Gs=G, hs=h)  
->>> print sol['x']
+>>> print(sol['x'])
 [-3.68e-01]
 [ 1.90e+00]
 [-8.88e-01]
->>> print sol['zs'][0]
+>>> print(sol['zs'][0])
 [ 3.96e-03 -4.34e-03]
 [-4.34e-03  4.75e-03]
->>> print sol['zs'][1]
+>>> print(sol['zs'][1])
 [ 5.58e-02 -2.41e-03  2.42e-02]
 [-2.41e-03  1.04e-04 -1.05e-03]
 [ 2.42e-02 -1.05e-03  1.05e-02]
@@ -1307,7 +1307,7 @@ problem structure.
     The function call ``f = kktsolver(W)`` should return a routine for
     solving the KKT system :eq:`e-conelp-kkt` defined by ``W``.  It will 
     be called as ``f(bx, by, bz)``.  On entry, ``bx``, ``by``, ``bz`` 
-    contain the righthand side.  On exit, they should contain the solution
+    contain the right-hand side.  On exit, they should contain the solution
     of the KKT system, with the last component scaled, i.e., on exit,
     
     .. math::
diff --git a/doc/source/copyright.rst b/doc/source/copyright.rst
index d503e02..4635d4a 100644
--- a/doc/source/copyright.rst
+++ b/doc/source/copyright.rst
@@ -6,7 +6,7 @@ Copyright and License
 *********************
 
 |
-| :raw-html:`©` 2010 L. Vandenberghe. 
+| :raw-html:`©` 2010-2011 L. Vandenberghe. 
 | :raw-html:`©` 2004-2009 J. Dahl and L. Vandenberghe. 
 
 CVXOPT is free software; you can redistribute it and/or modify it under 
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 4e7b8ca..c14d140 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -2,7 +2,7 @@
 CVXOPT 
 ######
 
-**Release 1.1.3 -- September 15, 2010**
+**Release 1.1.4 -- December 21, 2011**
 
 **Joachim Dahl & Lieven Vandenberghe**
 
diff --git a/doc/source/lapack.rst b/doc/source/lapack.rst
index 5a575a8..19fc45f 100644
--- a/doc/source/lapack.rst
+++ b/doc/source/lapack.rst
@@ -44,7 +44,7 @@ General Linear Equations
     :math:`A` square and nonsingular.  
 
     The arguments ``A`` and ``B`` must have the same type (:const:`'d'` 
-    or :const:`'z'`).  On entry, ``B``  contains the righthand side 
+    or :const:`'z'`).  On entry, ``B``  contains the right-hand side 
     :math:`B`; on exit it contains the solution :math:`X`.  The optional 
     argument ``ipiv`` is an integer matrix of length at least :math:`n`.  
     If ``ipiv`` is provided, then :func:`gesv` solves the system, replaces
@@ -91,7 +91,7 @@ General Linear Equations
 
     On entry, ``A`` and ``ipiv`` must contain the factorization as computed
     by :func:`gesv` or :func:`getrf`.  On entry, ``B`` contains the 
-    righthand side :math:`B`; on exit it contains the solution :math:`X`.
+    right-hand side :math:`B`; on exit it contains the solution :math:`X`.
     ``B`` must have the same type as ``A``.
 
 
@@ -141,7 +141,7 @@ Separate functions are provided for equations with band matrices.
     subdiagonals.  
 
     The arguments ``A`` and ``B`` must have the same type (:const:`'d'` 
-    or :const:`'z'`).  On entry, ``B`` contains the righthand side 
+    or :const:`'z'`).  On entry, ``B`` contains the right-hand side 
     :math:`B`; on exit it contains the solution :math:`X`.  The optional 
     argument ``ipiv`` is an integer matrix of length at least :math:`n`.  
     If ``ipiv`` is provided, then ``A`` must have :math:`2k_l + k_u + 1` 
@@ -191,7 +191,7 @@ Separate functions are provided for equations with band matrices.
 
     On entry, ``A`` and ``ipiv`` must contain the factorization as computed
     by :func:`gbsv` or :func:`gbtrf`.  On entry, ``B`` contains the 
-    righthand side :math:`B`; on exit it contains the solution :math:`X`.
+    right-hand side :math:`B`; on exit it contains the solution :math:`X`.
     ``B`` must have the same type as ``A``.
 
 
@@ -211,9 +211,9 @@ As an example, we solve a linear equation with
 >>> from cvxopt.lapack import gbsv, gbtrf, gbtrs
 >>> n, kl, ku = 4, 2, 1
 >>> A = matrix([[0., 1., 3., 6.], [2., 4., 7., 10.], [5., 8., 11., 0.], [9., 12., 0., 0.]])
->>> x = matrix(1.0, (4,1))
+>>> x = matrix(1.0, (n,1))
 >>> gbsv(A, kl, x)
->>> print x
+>>> print(x)
 [ 7.14e-02]
 [ 4.64e-01]
 [-2.14e-01]
@@ -225,16 +225,16 @@ by :func:`gbsv <cvxopt.lapack.gbsv>`.
 >>> Ac = matrix(0.0, (2*kl+ku+1,n))
 >>> Ac[kl:,:] = A
 >>> ipiv = matrix(0, (n,1))
->>> x = matrix(1.0, (4,1))
+>>> x = matrix(1.0, (n,1))
 >>> gbsv(Ac, kl, x, ipiv)                 # solves A*x = 1
->>> print x
+>>> print(x)
 [ 7.14e-02]
 [ 4.64e-01]
 [-2.14e-01]
 [-1.07e-01]
->>> x = matrix(1.0, (4,1))
+>>> x = matrix(1.0, (n,1))
 >>> gbtrs(Ac, kl, ipiv, x, trans='T')     # solve A^T*x = 1
->>> print x
+>>> print(x)
 [ 7.14e-02]
 [ 2.38e-02]
 [ 1.43e-01]
@@ -245,16 +245,16 @@ factorization.
 
 >>> Ac[kl:,:] = A
 >>> gbtrf(Ac, n, kl, ipiv)                 
->>> x = matrix(1.0, (4,1))
+>>> x = matrix(1.0, (n,1))
 >>> gbtrs(Ac, kl, ipiv, x)                # solve A^T*x = 1
->>> print x                 
+>>> print(x)                 
 [ 7.14e-02]
 [ 4.64e-01]
 [-2.14e-01]
 [-1.07e-01]
->>> x = matrix(1.0, (4,1))
+>>> x = matrix(1.0, (n,1))
 >>> gbtrs(Ac, kl, ipiv, x, trans='T')     # solve A^T*x = 1
->>> print x
+>>> print(x)
 [ 7.14e-02]
 [ 2.38e-02]
 [ 1.43e-01]
@@ -280,7 +280,7 @@ simpler matrix format, with the diagonals stored in three separate vectors.
     length :math:`n-1`.  The four arguments must have the same type 
     (:const:`'d'` or :const:`'z'`).  On exit ``dl``, ``d``, ``du`` are 
     overwritten with the details of the LU factorization of :math:`A`. 
-    On entry, ``B`` contains the righthand side :math:`B`; on exit it 
+    On entry, ``B`` contains the right-hand side :math:`B`; on exit it 
     contains the solution :math:`X`.
 
     Raises an :exc:`ArithmeticError` if the matrix is singular.
@@ -316,7 +316,7 @@ simpler matrix format, with the diagonals stored in three separate vectors.
     The arguments ``dl``, ``d``, ``du``, ``du2``, and ``ipiv`` contain 
     the details of the LU factorization as returned by 
     :func:`gttrf <cvxopt.lapack.gttrf>`.
-    On entry, ``B`` contains the righthand side :math:`B`; on exit it 
+    On entry, ``B`` contains the right-hand side :math:`B`; on exit it 
     contains the solution :math:`X`.  ``B`` must have the same type as 
     the other arguments.
 
@@ -1096,13 +1096,13 @@ We illustrate this with the QR factorization of the matrix
 >>> m, n = A.size
 >>> tau = matrix(0.0, (n,1))
 >>> lapack.geqrf(A, tau)
->>> print A[:n, :]              # Upper triangular part is R.
+>>> print(A[:n, :])              # Upper triangular part is R.
 [-2.17e+01  5.08e+00 -4.76e+00]
 [ 2.17e-01 -1.06e+01 -2.66e+00]
 [ 6.87e-01  3.12e-01 -8.74e+00]
 >>> Q1 = +A
 >>> lapack.orgqr(Q1, tau)
->>> print Q1
+>>> print(Q1)
 [-2.77e-01  3.39e-01 -4.10e-01]
 [-2.77e-01 -4.16e-01  7.35e-01]
 [-8.77e-01 -2.32e-01 -2.53e-01]
@@ -1110,7 +1110,7 @@ We illustrate this with the QR factorization of the matrix
 >>> Q = matrix(0.0, (m,m))
 >>> Q[:, :n] = A
 >>> lapack.orgqr(Q, tau)
->>> print Q                     # Q = [ Q1, Q2]
+>>> print(Q)                     # Q = [ Q1, Q2]
 [-2.77e-01  3.39e-01 -4.10e-01 -8.00e-01]
 [-2.77e-01 -4.16e-01  7.35e-01 -4.58e-01]
 [-8.77e-01 -2.32e-01 -2.53e-01  3.35e-01]
@@ -1135,12 +1135,12 @@ can be generated as follows.
 >>> tau = matrix(0.0, (m,1))
 >>> lapack.geqrf(A, tau)
 >>> R = +A
->>> print R                     # Upper trapezoidal part is [R1, R2].
+>>> print(R)                     # Upper trapezoidal part is [R1, R2].
 [-9.70e+00 -1.52e+01 -3.09e+00  6.70e+00]
 [-1.58e-01  2.30e+01  1.14e+01 -1.92e+00]
 [ 7.09e-01 -5.57e-01  2.26e+00  2.09e+00]
 >>> lapack.orgqr(A, tau)
->>> print A[:, :m]              # Q is in the first m columns of A.
+>>> print(A[:, :m])              # Q is in the first m columns of A.
 [-3.09e-01 -8.98e-01 -3.13e-01]
 [ 2.06e-01 -3.85e-01  9.00e-01]
 [-9.28e-01  2.14e-01  3.04e-01]
@@ -1444,13 +1444,13 @@ As an example we compute the complex Schur form of the matrix
 >>> w = matrix(0.0, (5,1), 'z')
 >>> lapack.gees(S, w)
 0
->>> print S
+>>> print(S)
 [ 5.67e+00+j1.69e+01 -2.13e+01+j2.85e+00  1.40e+00+j5.88e+00 -4.19e+00+j2.05e-01  3.19e+00-j1.01e+01]
 [ 0.00e+00-j0.00e+00  5.67e+00-j1.69e+01  1.09e+01+j5.93e-01 -3.29e+00-j1.26e+00 -1.26e+01+j7.80e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  1.27e+01+j3.43e-17 -6.83e+00+j2.18e+00  5.31e+00-j1.69e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00 -1.31e+01-j0.00e+00 -2.60e-01-j0.00e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00 -7.86e+00-j0.00e+00]
->>> print w
+>>> print(w)
 [ 5.67e+00+j1.69e+01]
 [ 5.67e+00-j1.69e+01]
 [ 1.27e+01+j3.43e-17]
@@ -1465,13 +1465,13 @@ the complex plane ordered first, can be computed as follows.
 ...
 >>> lapack.gees(S, w, select = F)
 2
->>> print S
+>>> print(S)
 [-1.31e+01-j0.00e+00 -1.72e-01+j7.93e-02 -2.81e+00+j1.46e+00  3.79e+00-j2.67e-01  5.14e+00-j4.84e+00]
 [ 0.00e+00-j0.00e+00 -7.86e+00-j0.00e+00 -1.43e+01+j8.31e+00  5.17e+00+j8.79e+00  2.35e+00-j7.86e-01]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  5.67e+00+j1.69e+01 -1.71e+01-j1.41e+01  1.83e+00-j4.63e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  5.67e+00-j1.69e+01 -8.75e+00+j2.88e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  1.27e+01+j3.43e-17]
->>> print w
+>>> print(w)
 [-1.31e+01-j0.00e+00]
 [-7.86e+00-j0.00e+00]
 [ 5.67e+00+j1.69e+01]
@@ -1553,25 +1553,25 @@ matrix :math:`A` of the previous example, and
 >>> b = matrix(0.0, (5,1))
 >>> lapack.gges(S, T, a, b)
 0
->>> print S
+>>> print(S)
 [ 6.64e+00-j8.87e+00 -7.81e+00-j7.53e+00  6.16e+00-j8.51e-01  1.18e+00+j9.17e+00  5.88e+00-j4.51e+00]
 [ 0.00e+00-j0.00e+00  8.48e+00+j1.13e+01 -2.12e-01+j1.00e+01  5.68e+00+j2.40e+00 -2.47e+00+j9.38e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00 -1.39e+01-j0.00e+00  6.78e+00-j0.00e+00  1.09e+01-j0.00e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00 -6.62e+00-j0.00e+00 -2.28e-01-j0.00e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00 -2.89e+01-j0.00e+00]
->>> print T
+>>> print(T)
 [ 6.46e-01-j0.00e+00  4.29e-01-j4.79e-02  2.02e-01-j3.71e-01  1.08e-01-j1.98e-01 -1.95e-01+j3.58e-01]
 [ 0.00e+00-j0.00e+00  8.25e-01-j0.00e+00 -2.17e-01+j3.11e-01 -1.16e-01+j1.67e-01  2.10e-01-j3.01e-01]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  7.41e-01-j0.00e+00 -3.25e-01-j0.00e+00  5.87e-01-j0.00e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  8.75e-01-j0.00e+00  4.84e-01-j0.00e+00]
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00  0.00e+00-j0.00e+00]
->>> print a
+>>> print(a)
 [ 6.64e+00-j8.87e+00]
 [ 8.48e+00+j1.13e+01]
 [-1.39e+01-j0.00e+00]
 [-6.62e+00-j0.00e+00]
 [-2.89e+01-j0.00e+00]
->>> print b
+>>> print(b)
 [ 6.46e-01]
 [ 8.25e-01]
 [ 7.41e-01]
diff --git a/doc/source/matrices.rst b/doc/source/matrices.rst
index 696c431..dc2c96f 100644
--- a/doc/source/matrices.rst
+++ b/doc/source/matrices.rst
@@ -43,20 +43,20 @@ type (integer, double, or complex) of the matrix.
 
      >>> from cvxopt import matrix
      >>> A = matrix(1, (1,4))   
-     >>> print A
+     >>> print(A)
      [ 1  1  1  1]
      >>> A = matrix(1.0, (1,4))   
-     >>> print A
+     >>> print(A)
      [ 1.00e+00  1.00e+00  1.00e+00  1.00e+00]
      >>> A = matrix(1+1j)     
-     >>> print A
+     >>> print(A)
      [ 1.00e+00+j1.00e+00]
 
-   * If ``x`` is a sequence of numbers (list, tuple, array array, 
-     xrange object, one-dimensional NumPy array, ...),
-     then the numbers are interpreted as the coefficients of a matrix in 
-     column-major order.  The length of ``x``  must be equal to the 
-     product of ``size[0]`` and ``size[1]``.
+   * If ``x`` is a sequence of numbers (list, tuple, array, 
+     :mod:`array` array, ...), then the numbers are interpreted as the 
+     coefficients of a matrix in column-major order.     
+     The length of ``x``  must be equal to the product of 
+     ``size[0]`` and ``size[1]``.
      If ``size``  is not specified, a matrix with one column is created. 
      If ``tc``  is not specified, it is determined from the elements of 
      ``x``  (and if that is impossible, for example because ``x``  is
@@ -68,17 +68,20 @@ type (integer, double, or complex) of the matrix.
 
      >>> A = matrix([0, 1, 2, 3], (2,2))  
      >>> A = matrix((0, 1, 2, 3), (2,2))  
-     >>> A = matrix(xrange(4), (2,2))
+     >>> A = matrix(range(4), (2,2))   
      >>> from array import array
      >>> A = matrix(array('i', [0,1,2,3]), (2,2))
-     >>> print A
+     >>> print(A)
      [ 0  2]
      [ 1  3]
 
-   * If ``x``  is a dense or sparse matrix, or a two-dimensional NumPy 
-     array of type :const:`'i'`, :const:`'d'`, or :const:`'z'`, then the  
-     coefficients of ``x``  are copied, in column-major order, to a new 
-     matrix of the given size.  
+     In Python 2.7 the following also works.
+
+     >>> A = matrix(xrange(4), (2,2))   
+
+   * If ``x``  is a dense or sparse matrix, then the coefficients of 
+     ``x``  are copied, in column-major order, to a new matrix of the 
+     given size.  
      The total number of elements in the new matrix (the product of 
      ``size[0]`` and ``size[1]``) must be the same as the product 
      of  the dimensions of ``x``.  If ``size``  is not specified, the 
@@ -88,25 +91,29 @@ type (integer, double, or complex) of the matrix.
      ``tc``, in a similar way as for scalar ``x``.  
      
      >>> A = matrix([1., 2., 3., 4., 5., 6.], (2,3))  
-     >>> print A
+     >>> print(A)
      [ 1.00e+00  3.00e+00  5.00e+00]
      [ 2.00e+00  4.00e+00  6.00e+00]
      >>> B = matrix(A, (3,2))  
-     >>> print B
+     >>> print(B)
      [ 1.00e+00  4.00e+00]
      [ 2.00e+00  5.00e+00]
      [ 3.00e+00  6.00e+00]
      >>> C = matrix(B, tc='z')      
-     >>> print C
+     >>> print(C)
      [ 1.00e+00-j0.00e+00  4.00e+00-j0.00e+00]
      [ 2.00e+00-j0.00e+00  5.00e+00-j0.00e+00]
      [ 3.00e+00-j0.00e+00  6.00e+00-j0.00e+00]
+
+
+     In Python 2.7 NumPy arrays can be converted to matrices.
+
      >>> from numpy import array
      >>> x = array([[1., 2., 3.], [4., 5., 6.]])
      >>> x
      array([[ 1.  2.  3.]
             [ 4.  5.  6.]])
-     >>> print matrix(x)
+     >>> print(matrix(x))               
      [ 1.00e+00  2.00e+00  3.00e+00]
      [ 4.00e+00  5.00e+00  6.00e+00]
      
@@ -124,7 +131,7 @@ type (integer, double, or complex) of the matrix.
      a list of empty lists, a value :const:`'i'` is used).  
      The same rules for type conversion apply as for scalar ``x``.
      
-     >>> print matrix([[1., 2.], [3., 4.], [5., 6.]])
+     >>> print(matrix([[1., 2.], [3., 4.], [5., 6.]]))
      [ 1.00e+00  3.00e+00  5.00e+00]
      [ 2.00e+00  4.00e+00  6.00e+00]
      >>> A1 = matrix([1, 2], (2,1))
@@ -132,7 +139,7 @@ type (integer, double, or complex) of the matrix.
      >>> B2 = matrix([12, 13, 14, 15, 16, 17], (2,3))
      >>> B3 = matrix([18, 19, 20], (1,3))
      >>> C = matrix([[A1, 3.0, 4.0, 5.0], [B1, B2, B3]])
-     >>> print C
+     >>> print(C)
      [ 1.00e+00  6.00e+00  8.00e+00  1.00e+01]
      [ 2.00e+00  7.00e+00  9.00e+00  1.10e+01]
      [ 3.00e+00  1.20e+01  1.40e+01  1.60e+01]
@@ -144,7 +151,7 @@ type (integer, double, or complex) of the matrix.
      then the argument ``x`` can be replaced by ``x[0]``).
 
      >>> D = matrix([B1, B2, B3])
-     >>> print D
+     >>> print(D)
      [  6   8  10]
      [  7   9  11]
      [ 12  14  16]
@@ -200,10 +207,9 @@ constructs a sparse matrix from a triplet description.
 .. function:: cvxopt.spmatrix(x, I, J[, size[, tc]])
 
     ``I`` and ``J`` are sequences of integers (lists, tuples, 
-    :mod:`array` arrays, xrange objects, ...) or integer matrices 
+    :mod:`array` arrays, ...) or integer matrices 
     (:class:`matrix <cvxopt.matrix>` objects with typecode :const:`'i'`),  
-    containing the 
-    row and column indices of the nonzero entries.  
+    containing the row and column indices of the nonzero entries.  
     The lengths of ``I`` and ``J`` must be  equal.  If they are matrices, 
     they are treated as lists of indices stored in column-major order, 
     i.e., as lists ``list(I)``, respectively, ``list(J)``. 
@@ -235,7 +241,7 @@ constructs a sparse matrix from a triplet description.
         
       >>> from cvxopt import spmatrix
       >>> A = spmatrix(1.0, range(4), range(4))
-      >>> print A  
+      >>> print(A) 
          [ 1.00e+00     0         0         0    ]
          [    0      1.00e+00     0         0    ]
          [    0         0      1.00e+00     0    ]
@@ -252,7 +258,7 @@ constructs a sparse matrix from a triplet description.
       least one complex number.
       
       >>> A = spmatrix([2,-1,2,-2,1,4,3], [1,2,0,2,3,2,0], [0,0,1,1,2,3,4])
-      >>> print A 
+      >>> print(A)
         [    0      2.00e+00     0         0      3.00e+00]
         [ 2.00e+00     0         0         0         0    ]
         [-1.00e+00 -2.00e+00     0      4.00e+00     0    ]
@@ -297,22 +303,22 @@ from a block-matrix description.
     
     >>> from cvxopt import matrix, spmatrix, sparse
     >>> A = matrix([[1., 2., 0.], [2., 1., 2.], [0., 2., 1.]])
-    >>> print A
+    >>> print(A)
     [ 1.00e+00  2.00e+00  0.00e+00]
     [ 2.00e+00  1.00e+00  2.00e+00]
     [ 0.00e+00  2.00e+00  1.00e+00]
     >>> B = spmatrix([], [], [], (3,3))
-    >>> print B
+    >>> print(B)
     [0 0 0]
     [0 0 0]
     [0 0 0]
     >>> C = spmatrix([3, 4, 5], [0, 1, 2], [0, 1, 2])
-    >>> print C
+    >>> print(C)
     [ 3.00e+00     0         0    ]
     [    0      4.00e+00     0    ]
     [    0         0      5.00e+00]
     >>> D = sparse([[A, B], [B, C]])
-    >>> print D
+    >>> print(D)
     [ 1.00e+00  2.00e+00     0         0         0         0    ]
     [ 2.00e+00  1.00e+00  2.00e+00     0         0         0    ]
     [    0      2.00e+00  1.00e+00     0         0         0    ]
@@ -324,7 +330,7 @@ from a block-matrix description.
     list.
     
     >>> D = sparse([A, C])
-    >>> print D
+    >>> print(D)
     [ 1.00e+00  2.00e+00     0    ]
     [ 2.00e+00  1.00e+00  2.00e+00]
     [    0      2.00e+00  1.00e+00]
@@ -350,7 +356,7 @@ sparse matrix from a list of matrices.
     >>> B = matrix([[1,-2],[-2,1]])
     >>> C = spmatrix([1,1,1,1,1],[0,1,2,0,0,],[0,0,0,1,2])
     >>> D = spdiag([A, B, C])
-    >>> print D
+    >>> print(D)
     [ 3.00e+00     0         0         0         0         0    ]
     [    0      1.00e+00 -2.00e+00     0         0         0    ]
     [    0     -2.00e+00  1.00e+00     0         0         0    ]
@@ -387,15 +393,15 @@ number.
 | Elementwise exponentiation         | ``D**e``                |
 +------------------------------------+-------------------------+
 
-If one of the operands is integer (a scalar integer or a matrix of type
-:const:`'i'`) and the other operand is double (a scalar float or a matrix 
-of type :const:`'d'`), then the integer operand is converted to double, 
-and the result is a matrix of type :const:`'d'`.
-If one of the operands is integer or double, and the other operand is 
-complex (a scalar complex or a matrix of type :const:`'z'`), then the first 
-operand is converted to complex, and the result is a matrix of type 
-:const:`'z'`.  (An exception to this rule is elementwise exponentiation:
-the result of ``D**e`` is a real matrix if ``D`` and ``e`` are integer.)
+The type of the result of these operations generally follows the Python
+conventions.   
+For example, if ``A`` and ``c`` are integer, then in Python 2 the division
+``A/c`` is interpreted as integer division and results in a 
+type :const:`'i'` matrix, while in Python 3 it is interpreted as standard 
+divison and results in a type :const:`'d'` matrix.
+An exception to the Python conventions is elementwise exponentiation: 
+if ``D`` is an integer matrix and ``e`` is an integer number 
+than ``D**e`` is a matrix of type :const:`'d'`.
 
 Addition, subtraction, and matrix multiplication with two matrix operands 
 result in a sparse matrix if both matrices are sparse, and in a dense 
@@ -415,14 +421,11 @@ size of ``A`` and all entries equal to ``c[0]``.
 If ``c`` is a 1 by 1 dense matrix, then, if possible, the products 
 ``c*A`` and ``A*c`` are interpreted as matrix-matrix products.
 If the product cannot be interpreted as a matrix-matrix product
-(because the dimensions of ``A`` are incompatible), then the product is 
+because the dimensions of ``A`` are incompatible, then the product is 
 interpreted as the scalar multiplication with ``c[0]``.
 The division ``A/c`` and remainder ``A%c`` with ``c`` a 
 1 by 1 matrix are always interpreted as ``A/c[0]``, resp., ``A%c[0]``.
 
-Note that Python rounds the result of an integer division towards minus 
-infinity.
-
 The following in-place operations are also defined, but only if they do 
 not change the type (sparse or dense, integer, real, or complex) of the 
 matrix ``A``.  These in-place operations do not return a new matrix but 
@@ -461,12 +464,12 @@ The following rules apply.
   pointer) to the object referenced by ``B``.
 
   >>> B = matrix([[1.,2.], [3.,4.]])  
-  >>> print B
+  >>> print(B)
   [ 1.00e+00  3.00e+00]
   [ 2.00e+00  4.00e+00]
   >>> A = B
   >>> A[0,0] = -1 
-  >>> print B   # modifying A[0,0] also modified B[0,0]
+  >>> print(B)   # modifying A[0,0] also modified B[0,0]
   [-1.00e+00  3.00e+00]
   [ 2.00e+00  4.00e+00]
   
@@ -476,7 +479,7 @@ The following rules apply.
   >>> B = matrix([[1.,2.], [3.,4.]])  
   >>> A = +B
   >>> A[0,0] = -1 
-  >>> print B   # modifying A[0,0] does not modify B[0,0]
+  >>> print(B)   # modifying A[0,0] does not modify B[0,0]
   [ 1.00e+00  3.00e+00]
   [ 2.00e+00  4.00e+00]
   
@@ -486,11 +489,11 @@ The following rules apply.
   >>> B = matrix([[1.,2.], [3.,4.]])  
   >>> A = B
   >>> A *= 2
-  >>> print B   # in-place operation also changed B
+  >>> print(B)   # in-place operation also changed B
   [ 2.00e+00  6.00e+00]
   [ 4.00e+00  8.00e+00]
   >>> A = 2*A
-  >>> print B   # regular operation creates a new A, so does not change B
+  >>> print(B)   # regular operation creates a new A, so does not change B
   [ 2.00e+00  6.00e+00]
   [ 4.00e+00  8.00e+00]
   
@@ -544,7 +547,7 @@ The following example illustrates one-argument indexing.
 
 >>> from cvxopt import matrix, spmatrix
 >>> A = matrix(range(16), (4,4), 'd')
->>> print A
+>>> print(A)
 [ 0.00e+00  4.00e+00  8.00e+00  1.20e+01]
 [ 1.00e+00  5.00e+00  9.00e+00  1.30e+01]
 [ 2.00e+00  6.00e+00  1.00e+01  1.40e+01]
@@ -552,13 +555,13 @@ The following example illustrates one-argument indexing.
 >>> A[4]
 4.0
 >>> I = matrix([0, 5, 10, 15])
->>> print A[I]      # the diagonal
+>>> print(A[I])      # the diagonal
 [ 0.00e+00]
 [ 5.00e+00]
 [ 1.00e+01]
 [ 1.50e+01]
 >>> I = [0,2];  J = [1,3]
->>> print A[2*I+J]  # duplicate I and append J
+>>> print(A[2*I+J])  # duplicate I and append J
 [ 0.00e+00]
 [ 2.00e+00]
 [ 0.00e+00]
@@ -566,10 +569,10 @@ The following example illustrates one-argument indexing.
 [ 1.00e+00]
 [ 3.00e+00]
 >>> I = matrix([0, 2]);  J =  matrix([1, 3])
->>> print A[2*I+J]  # multiply I by 2 and add J
+>>> print(A[2*I+J])  # multiply I by 2 and add J
 [ 1.00e+00]
 [ 7.00e+00]
->>> print A[4::4]   # get every fourth element skipping the first four  
+>>> print(A[4::4])   # get every fourth element skipping the first four  
 [ 4.00e+00]
 [ 8.00e+00]
 [ 1.20e+01]
@@ -580,39 +583,41 @@ the matrix and the second argument indexes the columns.  If both
 indices are scalars, then a scalar is returned.  In all other cases, 
 a matrix is returned.  We continue the example.
 
->>> print A[:,1]
+>>> print(A[:,1])
 [ 4.00e+00]
 [ 5.00e+00]
 [ 6.00e+00]
 [ 7.00e+00]
 >>> J = matrix([0, 2])
->>> print A[J,J]
+>>> print(A[J,J])
 [ 0.00e+00  8.00e+00]
 [ 2.00e+00  1.00e+01]
->>> print A[:2, -2:]   
+>>> print(A[:2, -2:])
 [ 8.00e+00  1.20e+01]
 [ 9.00e+00  1.30e+01]
 >>> A = spmatrix([0,2,-1,2,-2,1], [0,1,2,0,2,1], [0,0,0,1,1,2]) 
->>> print A[:, [0,1]]
+>>> print(A[:, [0,1]])
 [ 0.00e+00  2.00e+00]
 [ 2.00e+00     0    ]
 [-1.00e+00 -2.00e+00]
 >>> B = spmatrix([0,2*1j,0,-2], [1,2,1,2], [0,0,1,1,])
->>> print B[-2:,-2:]
+>>> print(B[-2:,-2:])
 [ 0.00e+00-j0.00e+00  0.00e+00-j0.00e+00]
 [ 0.00e+00+j2.00e+00 -2.00e+00-j0.00e+00]
 
 Expressions of the form ``A[I]`` or ``A[I,J]`` can also appear on 
-the lefthand side of an assignment.   The righthand side must be a scalar 
+the left-hand side of an assignment.   The right-hand side must be a 
+scalar 
 (i.e., a number or a 1 by 1 dense matrix), a sequence of numbers, or a 
-dense or sparse matrix.  If the righthand side is a scalar, it is 
+dense or sparse matrix.  If the right-hand side is a scalar, it is 
 interpreted as a dense matrix with identical entries and the dimensions of
-the lefthand side.  If the righthand side is a sequence of numbers (list, 
-tuple, :mod:`array` array, xrange object, ...) its values are interpreted 
+the left-hand side.  If the right-hand side is a sequence of numbers 
+(list, tuple, :mod:`array` array, range object, ...) its values are 
+interpreted 
 as the coefficients of a dense matrix in column-major order.  If the 
-righthand side is a matrix (:class:`matrix` or 
+right-hand side is a matrix (:class:`matrix` or 
 :class:`spmatrix`), it must 
-have the same size as the lefthand side.  Sparse matrices are 
+have the same size as the left-hand side.  Sparse matrices are 
 converted to dense in the assignment to a dense matrix.
 
 Indexed assignments are only allowed if they do not change the type of 
@@ -626,57 +631,57 @@ The following examples illustrate indexed assignment.
 
 >>> A = matrix(range(16), (4,4))
 >>> A[::2,::2] = matrix([[-1, -2], [-3, -4]])
->>> print A
+>>> print(A)
 [ -1   4  -3  12]
 [  1   5   9  13]
 [ -2   6  -4  14]
 [  3   7  11  15]
 >>> A[::5] += 1
->>> print A
+>>> print(A)
 [  0   4  -3  12]
 [  1   6   9  13]
 [ -2   6  -3  14]
 [  3   7  11  16]
 >>> A[0,:] = -1, 1, -1, 1
->>> print A
+>>> print(A)
 [ -1   1  -1   1]
 [  1   6   9  13]
 [ -2   6  -3  14]
 [  3   7  11  16]
->>> A[2:,2:] = xrange(4)
->>> print A
+>>> A[2:,2:] = range(4)
+>>> print(A)
 [ -1   1  -1   1]
 [  1   6   9  13]
 [ -2   6   0   2]
 [  3   7   1   3]
 >>> A = spmatrix([0,2,-1,2,-2,1], [0,1,2,0,2,1], [0,0,0,1,1,2]) 
->>> print A
+>>> print(A)
 [ 0.00e+00  2.00e+00     0    ]
 [ 2.00e+00     0      1.00e+00]
 [-1.00e+00 -2.00e+00     0    ]
 >>> C = spmatrix([10,-20,30], [0,2,1], [0,0,1])
->>> print C
+>>> print(C)
 [ 1.00e+01     0    ]
 [    0      3.00e+01]
 [-2.00e+01     0    ]
 >>> A[:,0] = C[:,0]
->>> print A
+>>> print(A)
 [ 1.00e+01  2.00e+00     0    ]
 [    0         0      1.00e+00]
 [-2.00e+01 -2.00e+00     0    ]
 >>> D = matrix(range(6), (3,2))
 >>> A[:,0] = D[:,0]
->>> print A
+>>> print(A)
 [ 0.00e+00  2.00e+00     0    ]
 [ 1.00e+00     0      1.00e+00]
 [ 2.00e+00 -2.00e+00     0    ]
 >>> A[:,0] = 1
->>> print A
+>>> print(A)
 [ 1.00e+00  2.00e+00     0    ]
 [ 1.00e+00     0      1.00e+00]
 [ 1.00e+00 -2.00e+00     0    ]
 >>> A[:,0] = 0
->>> print A
+>>> print(A)
 [ 0.00e+00  2.00e+00     0    ]
 [ 0.00e+00     0      1.00e+00]
 [ 0.00e+00 -2.00e+00     0    ]
@@ -757,18 +762,18 @@ The next example below illustrates assignments to :attr:`V`.
 
 >>> from cvxopt import spmatrix, matrix
 >>> A = spmatrix(range(5), [0,1,1,2,2], [0,0,1,1,2])
->>> print A
+>>> print(A)
 [ 0.00e+00     0         0    ]
 [ 1.00e+00  2.00e+00     0    ]
 [    0      3.00e+00  4.00e+00]
 >>> B = spmatrix(A.V, A.J, A.I, (4,4))  # transpose and add a zero row and column
->>> print B
+>>> print(B)
 [ 0.00e+00  1.00e+00     0         0    ]
 [    0      2.00e+00  3.00e+00     0    ]
 [    0         0      4.00e+00     0    ]
 [    0         0         0         0    ]
 >>> B.V = matrix([1., 7., 8., 6., 4.])   # assign new values to nonzero entries
->>> print B
+>>> print(B)
 [ 1.00e+00  7.00e+00     0         0    ]
 [    0      8.00e+00  6.00e+00     0    ]
 [    0         0      4.00e+00     0    ]
@@ -777,11 +782,6 @@ The next example below illustrates assignments to :attr:`V`.
 
 The following attributes and methods are defined for dense matrices.
 
-.. attribute:: __array_struct__
-
-    A PyCObject implementing the :program:`NumPy` array interface  
-    (see the section :ref:`s-array-interface` for details).
-
 .. method:: tofile(f)
 
     Writes the elements of the matrix in column-major order to a binary 
@@ -795,32 +795,32 @@ The last two methods are illustrated in the following examples.
 
 >>> from cvxopt import matrix, spmatrix
 >>> A = matrix([[1.,2.,3.], [4.,5.,6.]])  
->>> print A
+>>> print(A)
 [ 1.00e+00  4.00e+00]
 [ 2.00e+00  5.00e+00]
 [ 3.00e+00  6.00e+00]
->>> f = open('mat.bin','w')
+>>> f = open('mat.bin','wb')
 >>> A.tofile(f)
 >>> f.close()
 >>> B = matrix(0.0, (2,3))
->>> f = open('mat.bin','r')
+>>> f = open('mat.bin','rb')
 >>> B.fromfile(f)
 >>> f.close()
->>> print B
+>>> print(B)
 [ 1.00e+00  3.00e+00  5.00e+00]
 [ 2.00e+00  4.00e+00  6.00e+00]
 >>> A = spmatrix(range(5), [0,1,1,2,2], [0,0,1,1,2])
->>> f = open('test.bin','w')
+>>> f = open('test.bin','wb')
 >>> A.V.tofile(f)  
 >>> A.I.tofile(f) 
 >>> A.J.tofile(f)
 >>> f.close()
->>> f = open('test.bin','r')
+>>> f = open('test.bin','rb')
 >>> V = matrix(0.0, (5,1));  V.fromfile(f)  
 >>> I = matrix(0, (5,1));  I.fromfile(f)  
 >>> J = matrix(0, (5,1));  J.fromfile(f)  
 >>> B = spmatrix(V, I, J)
->>> print B
+>>> print(B)
 [ 0.00e+00     0         0    ]
 [ 1.00e+00  2.00e+00     0    ]
 [    0      3.00e+00  4.00e+00]
@@ -876,9 +876,8 @@ For example, ``list(A)`` and ``tuple(A)`` construct a list,
 respectively a tuple, from the elements of ``A`` if ``A`` is dense, and 
 of the nonzero elements of ``A`` if ``A`` is sparse.
 
-``zip(A, B, ...)`` returns a list of tuples, with the i-th 
-tuple containing the i-th elements (or nonzero elements) of 
-``A``, ``B``, ....   
+``list(zip(A, B, ...))`` returns a list of tuples, with the i-th tuple 
+containing the i-th elements (or nonzero elements) of ``A``, ``B``, ....   
 
 >>> from cvxopt import matrix
 >>> A = matrix([[-11., -5., -20.], [-6., 0., 7.]])
@@ -887,11 +886,12 @@ tuple containing the i-th elements (or nonzero elements) of
 [-11.0, -5.0, -20.0, -6.0, 0.0, 7.0]
 >>> tuple(B)
 (0, 1, 2, 3, 4, 5)
->>> zip(A, B)
+>>> list(zip(A, B))
 [(-11.0, 0), (-5.0, 1), (-20.0, 2), (-6.0, 3), (0.0, 4), (7.0, 5)]
 
-``map(f, A)``, where ``f`` is a function and ``A`` is a dense matrix, 
-returns a list constructed by applying ``f`` to each element of ``A``.  If
+``list(map(f, A))``, where ``f`` is a function and ``A`` is a 
+dense matrix, returns a list constructed by applying ``f`` to each 
+element of ``A``.  If
 ``A`` is sparse, the function ``f`` is applied to each nonzero element of 
 ``A``.  Multiple arguments can be provided, for example, as in 
 ``map(f, A, B)``, if ``f`` is a function with two arguments.
@@ -899,35 +899,35 @@ In the following example, we return an integer 0-1 matrix with the
 result of an elementwise comparison.
 
 >>> A = matrix([ [0.5, -0.1, 2.0], [1.5, 0.2, -0.1], [0.3, 1.0, 0.0]]) 
->>> print A
+>>> print(A)
 [ 5.00e-01  1.50e+00  3.00e-01]
 [-1.00e-01  2.00e-01  1.00e+00]
 [ 2.00e+00 -1.00e-01  0.00e+00]
->>> print matrix(map(lambda x: 0 <= x <= 1, A), A.size)
+>>> print(matrix(list(map(lambda x: 0 <= x <= 1, A), A.size)))
 [ 1  0  1]
 [ 0  1  1]
 [ 0  0  1]
 
-``filter(f, A)``, where ``f`` is a function and ``A`` is a matrix, 
+``list(filter(f, A))``, where ``f`` is a function and ``A`` is a matrix, 
 returns a list containing the elements of ``A`` (or nonzero elements of 
 ``A`` is ``A`` is sparse) for which ``f`` is true.
 
 >>> A = matrix([[5, -4, 10, -7], [-1, -5, -6, 2], [6, 1, 5, 2],  [-1, 2, -3, -7]])
->>> print A
+>>> print(A)
 [  5  -1   6  -1]
 [ -4  -5   1   2]
 [ 10  -6   5  -3]
 [ -7   2   2  -7]
->>> filter(lambda x: x%2, A)         # list of odd elements in A
+>>> list(filter(lambda x: x%2, A))         # list of odd elements in A
 [5, -7, -1, -5, 1, 5, -1, -3, -7]
->>> filter(lambda x: -2 < x < 3, A)  # list of elements between -2 and 3
+>>> list(filter(lambda x: -2 < x < 3, A))  # list of elements between -2 and 3
 [-1, 2, 1, 2, -1, 2]
 
 It is also possible to iterate over matrix elements, as illustrated in
 the following example.
 
 >>> A = matrix([[5, -3], [9, 11]])
->>> for x in A: print max(x,0)
+>>> for x in A: print(max(x,0))
 ...
 5
 0
@@ -966,7 +966,7 @@ The following functions can be imported from CVXOPT.
     >>> from cvxopt import spmatrix, sqrt
     >>> A = spmatrix([2,1,2,2,1,3,4], [1,2,0,2,3,0,2], [0,0,1,1,2,3,3]) 
     >>> B = spmatrix(sqrt(A.V), A.I, A.J)
-    >>> print B
+    >>> print(B)
     [    0      1.41e+00     0      1.73e+00]
     [ 1.41e+00     0         0         0    ]
     [ 1.00e+00  1.41e+00     0      2.00e+00]
@@ -1011,17 +1011,17 @@ The following functions can be imported from CVXOPT.
     of the other arguments are not all 1 by 1.)
 
     :func:`mul` can also be called with an iterable 
-    (list, tuple, xrange 
-    object, or generator) as its single argument, if the iterable 
-    generates a list of dense or sparse matrices or scalars.
+    (list, tuple, range object, or generator) as its single argument, 
+    if the iterable generates a list of dense or sparse matrices or 
+    scalars.
 
     >>> from cvxopt import matrix, spmatrix, mul
     >>> A = matrix([[1.0, 2.0], [3.0, 4.0]])
     >>> B = spmatrix([2.0, 3.0], [0, 1], [0, 1])
-    >>> print mul(A, B, -1.0)
+    >>> print(mul(A, B, -1.0))
     [-2.00e+00     0    ]
     [    0     -1.20e+01]
-    >>> print mul( matrix([k, k+1]) for k in [1,2,3] )
+    >>> print(mul( matrix([k, k+1]) for k in [1,2,3] ))
     [  6]
     [ 24]
 
@@ -1049,13 +1049,12 @@ The following functions can be imported from CVXOPT.
     is a dense matrix if at least one of the arguments is a dense matrix.
     
     :func:`max <cvxopt.max>` can also be called with an iterable 
-    (list, tuple, xrange 
-    object, or generator) as its single argument, if the iterable 
-    generates a list of dense or sparse matrices or scalars.
-    
+    (list, tuple, range object, or generator) as its single argument, 
+    if the iterable generates a list of dense or sparse matrices or 
+    scalars.  
     >>> from cvxopt import matrix, spmatrix, max
     >>> A = spmatrix([2, -3], [0, 1], [0, 1])
-    >>> print max(A, -A, 1)
+    >>> print(max(A, -A, 1))
     [ 2.00e+00  1.00e+00]
     [ 1.00e+00  3.00e+00]
     
@@ -1074,7 +1073,7 @@ The following functions can be imported from CVXOPT.
     >>> from cvxopt import max
     >>> max(A)          # cvxopt.max takes maximum over all the  elements
     0.0
-    >>> print max(A, -1.5)
+    >>> print(max(A, -1.5))
     [-1.00e+00  0.00e+00]
     [ 0.00e+00 -1.50e+00]
     
@@ -1093,9 +1092,9 @@ The following functions can be imported from CVXOPT.
     as a dense matrix with all its entries equal to the scalar.
     
     :func:`min <cvxopt.min>` can also be called with an iterable 
-    (list, tuple, xrange 
-    object, or generator) as its single argument, if the iterable generates
-    a list of dense or sparse matrices or scalars.
+    (list, tuple, range object, or generator) as its single argument, 
+    if the iterable generates a list of dense or sparse matrices or 
+    scalars.
     
     
 .. _s-random:
@@ -1148,18 +1147,13 @@ functions based on the :mod:`random` module.
 The NumPy Array Interface
 =========================
 
-The CVXOPT :class:`matrix` object is compatible with the 
-NumPy Array 
+This section only applies to the Python 2 version of CVXOPT.
+
+The CVXOPT :class:`matrix` object is compatible with the NumPy Array 
 Interface, which allows Python objects that represent multidimensional 
 arrays to exchange data using information stored in the attribute 
 :attr:`__array_struct__`.  
 
-.. seealso::
-
-    * `NumPy Array Interface Specification <http://numpy.scipy.org/array_interface.shtml>`_
-
-    * `Numpy home page <http://numpy.scipy.org>`_
-
 As already mentioned in the section :ref:`s-dense-matrices`, a 
 two-dimensional array 
 object (for example, a NumPy matrix or two-dimensional array) can be 
@@ -1171,7 +1165,7 @@ CVXOPT matrices and NumPy arrays.
 
 >>> from cvxopt import matrix
 >>> a = matrix(range(6), (2,3), 'd')
->>> print a
+>>> print(a)
 [ 0.00e+00  2.00e+00  4.00e+00]
 [ 1.00e+00  3.00e+00  5.00e+00]
 >>> from numpy import array
diff --git a/doc/source/modeling.rst b/doc/source/modeling.rst
index c3f27cb..eae0758 100644
--- a/doc/source/modeling.rst
+++ b/doc/source/modeling.rst
@@ -65,17 +65,17 @@ A :class:`variable` ``x`` has two attributes.
 >>> x = variable(3,'a')
 >>> len(x)
 3
->>> print x.name
+>>> print(x.name)
 a
->>> print x.value 
+>>> print(x.value)
 None
 >>> x.value = matrix([1.,2.,3.])
->>> print x.value
+>>> print(x.value)
 [ 1.00e+00]
 [ 2.00e+00]
 [ 3.00e+00]
 >>> x.value = 1
->>> print x.value
+>>> print(x.value)
 [ 1.00e+00]
 [ 1.00e+00]
 [ 1.00e+00]
@@ -201,7 +201,7 @@ length 2.  The functions ``f`` and ``g`` are given by
 >>> A = matrix([[1., 2.], [3.,4.]])
 >>> b = matrix([1.,-1.])
 >>> g = A*f + sum(y) + b 
->>> print g
+>>> print(g)
 affine function of length 2
 constant term:
 [ 1.30e+01]
@@ -232,7 +232,7 @@ coefficient of variable(1,'x'):
 
 >>> x = variable(4,'x')
 >>> f = x[::2]
->>> print f 
+>>> print(f)
 linear function of length 2
 linear term: linear function of length 2
 coefficient of variable(4,'x'):
@@ -240,7 +240,7 @@ coefficient of variable(4,'x'):
 [    0         0      1.00e+00     0    ]
 >>> y = variable(3,'x')
 >>> g = matrix(range(12),(3,4),'d')*x - 3*y + 1
->>> print g[0] + g[2]
+>>> print(g[0] + g[2])
 affine function of length 1
 constant term:
 [ 2.00e+00]
@@ -577,19 +577,19 @@ As an example we solve the LP
 >>> lp1.solve()
 >>> lp1.status
 'optimal'
->>> print lp1.objective.value()
+>>> print(lp1.objective.value())
 [-9.00e+00]
->>> print x.value
+>>> print(x.value)
 [ 1.00e+00]
->>> print y.value
+>>> print(y.value)
 [ 1.00e+00]
->>> print c1.multiplier.value
+>>> print(c1.multiplier.value)
 [ 1.00e+00]
->>> print c2.multiplier.value
+>>> print(c2.multiplier.value)
 [ 2.00e+00]
->>> print c3.multiplier.value
+>>> print(c3.multiplier.value)
 [ 2.87e-08]
->>> print c4.multiplier.value
+>>> print(c4.multiplier.value)
 [ 2.80e-08]
 
 
@@ -603,12 +603,12 @@ We can solve the same LP in  matrix form as follows.
 >>> ineq = ( A*x <= b )
 >>> lp2 = op(dot(c,x), ineq)
 >>> lp2.solve()
->>> print lp2.objective.value()
+>>> print(lp2.objective.value())
 [-9.00e+00]
->>> print x.value
+>>> print(x.value)
 [ 1.00e+00]
 [ 1.00e+00]
->>> print ineq.multiplier.value
+>>> print(ineq.multiplier.value)
 [1.00e+00]
 [2.00e+00]
 [2.87e-08]
diff --git a/doc/source/printing.rst b/doc/source/printing.rst
index b5847d1..aa4dc5c 100644
--- a/doc/source/printing.rst
+++ b/doc/source/printing.rst
@@ -16,7 +16,7 @@ formatting of dense matrices.
 >>> A = matrix(range(50), (5,10), 'd')
 >>> A  
 <5x10 matrix, tc='d'>
->>> print A
+>>> print(A)
 [ 0.00e+00  5.00e+00  1.00e+01  1.50e+01  2.00e+01  2.50e+01  3.00e+01 ... ]
 [ 1.00e+00  6.00e+00  1.10e+01  1.60e+01  2.10e+01  2.60e+01  3.10e+01 ... ]
 [ 2.00e+00  7.00e+00  1.20e+01  1.70e+01  2.20e+01  2.70e+01  3.20e+01 ... ]
@@ -41,7 +41,7 @@ displayed.  The default values of :attr:`options['width']` and
 {'width': 7, 'dformat': '% .2e', 'iformat': '% i', 'height': -1}
 >>> printing.options['dformat'] = '%.1f'
 >>> printing.options['width'] = -1
->>> print A
+>>> print(A)
 [ 0.0  5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0]
 [ 1.0  6.0 11.0 16.0 21.0 26.0 31.0 36.0 41.0 46.0]
 [ 2.0  7.0 12.0 17.0 22.0 27.0 32.0 37.0 42.0 47.0]
@@ -84,7 +84,7 @@ and :func:`cvxopt.spmatrix_str`, respectively.  By default, they are set to
 >>> A = spmatrix(range(5), range(5), range(5), (5,10))
 >>> A
 <5x10 sparse matrix, tc='d', nnz=5>
->>> print A
+>>> print(A)
 [ 0.00e+00     0         0         0         0         0         0     ... ]
 [    0      1.00e+00     0         0         0         0         0     ... ]
 [    0         0      2.00e+00     0         0         0         0     ... ]
@@ -105,7 +105,7 @@ entire matrix including structural zeros. An alternative triplet printing
 style is defined in :func:`printing.spmatrix_str_triplet`. 
 
 >>> cvxopt.spmatrix_str = printing.spmatrix_str_triplet
->>> print A
+>>> print(A)
 (0,0)  0.00e+00
 (1,1)  1.00e+00
 (2,2)  2.00e+00
diff --git a/doc/source/solvers.rst b/doc/source/solvers.rst
index ad42e67..1504d68 100644
--- a/doc/source/solvers.rst
+++ b/doc/source/solvers.rst
@@ -241,7 +241,7 @@ Problems with Nonlinear Objectives
     .. math::
      
         \begin{array}{ll}
-        \mbox{minimize} & -\sum_{i=1}^m \log x_i \\
+        \mbox{minimize} & -\sum\limits_{i=1}^m \log x_i \\
         \mbox{subject to} & Ax = b. 
         \end{array}
 
@@ -272,7 +272,7 @@ Problems with Nonlinear Objectives
     .. math::
 
         \begin{array}{ll}
-        \mbox{minimize} &  \sum_{k=1}^m \phi((Ax-b)_k), 
+        \mbox{minimize} &  \sum\limits_{k=1}^m \phi((Ax-b)_k), 
         \end{array} 
         \qquad \phi(u) = \sqrt{\rho + u^2},
 
@@ -339,7 +339,7 @@ Problems with Nonlinear Objectives
         h = matrix([1.0, 0.0, 0.0, 0.0, 20., 10., 40., 10., 80., 10., 40., 10., 15.])
         dims = {'l': 0, 'q': [4], 's':  [3]}
         sol = solvers.cp(F, G, h, dims)
-        print sol['x']
+        print(sol['x'])
         [ 4.11e-01]
         [ 5.59e-01]
         [-7.20e-01]
@@ -688,7 +688,7 @@ Problems with Linear Objectives
         pylab.subplot(221)
         Amin = matrix([100., 100., 100., 100., 100.])
         W, H, x, y, w, h =  floorplan(Amin)
-        for k in xrange(5):
+        for k in range(5):
             pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
                        [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
             pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
@@ -699,7 +699,7 @@ Problems with Linear Objectives
         pylab.subplot(222)
         Amin = matrix([20., 50., 80., 150., 200.])
         W, H, x, y, w, h =  floorplan(Amin)
-        for k in xrange(5):
+        for k in range(5):
             pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
                        [y[k], y[k]+h[k], y[k]+h[k], y[k]], 'facecolor = #D0D0D0')
             pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
@@ -710,7 +710,7 @@ Problems with Linear Objectives
         pylab.subplot(223)
         Amin = matrix([180., 80., 80., 80., 80.])
         W, H, x, y, w, h =  floorplan(Amin)
-        for k in xrange(5):
+        for k in range(5):
             pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
                        [y[k], y[k]+h[k], y[k]+h[k], y[k]], 'facecolor = #D0D0D0')
             pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
@@ -721,7 +721,7 @@ Problems with Linear Objectives
         pylab.subplot(224)
         Amin = matrix([20., 150., 20., 200., 110.])
         W, H, x, y, w, h =  floorplan(Amin)
-        for k in xrange(5):
+        for k in range(5):
             pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
                        [y[k], y[k]+h[k], y[k]+h[k], y[k]], 'facecolor = #D0D0D0')
             pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
@@ -1038,7 +1038,7 @@ that take advantage of problem structure.
     The function call ``f = kktsolver(x, z, W)`` should return a 
     routine for solving the KKT system :eq:`e-cp-kkt` defined by ``x``, 
     ``z``, ``W``.  It will be called as ``f(bx, by, bz)``.
-    On entry, ``bx``, ``by``, ``bz`` contain the righthand side.  On exit,
+    On entry, ``bx``, ``by``, ``bz`` contain the right-hand side.  On exit,
     they should contain the solution of the KKT system, with the last 
     component scaled, i.e., on exit,
 
diff --git a/doc/source/spsolvers.rst b/doc/source/spsolvers.rst
index 20971e5..453d619 100644
--- a/doc/source/spsolvers.rst
+++ b/doc/source/spsolvers.rst
@@ -25,7 +25,7 @@ ignored.
 A general sparse square matrix of order :math:`n` is represented by an
 :class:`spmatrix` object of size (:math:`n`, :math:`n`).
 
-Dense matrices, which appear as righthand sides of equations, are 
+Dense matrices, which appear as right-hand sides of equations, are 
 stored using the same conventions as in the BLAS and LAPACK modules.
 
 
@@ -72,7 +72,7 @@ As an example we consider the matrix
 >>> from cvxopt import spmatrix, amd 
 >>> A = spmatrix([10,3,5,-2,5,2], [0,2,1,2,2,3], [0,0,1,1,2,3])
 >>> P = amd.order(A)
->>> print P
+>>> print(P)
 [ 1]
 [ 0]
 [ 2]
@@ -136,7 +136,7 @@ In the following example we solve an equation with coefficient matrix
 >>> A = spmatrix(V,I,J)
 >>> B = matrix(1.0, (5,1))
 >>> umfpack.linsolve(A,B)
->>> print B
+>>> print(B)
 [ 5.79e-01]
 [-5.26e-02]
 [ 1.00e+00]
@@ -186,7 +186,7 @@ equivalent to the following three functions called in sequence.
 
 
 These separate functions are useful for solving several sets of linear 
-equations with the same coefficient matrix and different righthand sides, 
+equations with the same coefficient matrix and different right-hand sides, 
 or with coefficient matrices that share the same sparsity pattern.
 The symbolic factorization depends only on the sparsity pattern of
 the matrix, and not on the numerical values of the nonzero coefficients. 
@@ -228,7 +228,7 @@ code computes
 >>> umfpack.solve(A, FA, x)
 >>> umfpack.solve(B, FB, x)
 >>> umfpack.solve(A, FA, x, trans='T')
->>> print x
+>>> print(x)
 [ 5.81e-01]
 [-2.37e-01]
 [ 1.63e+00]
@@ -297,7 +297,7 @@ As an  example, we solve
 >>> A = spmatrix([10, 3, 5, -2, 5, 2], [0, 2, 1, 3, 2, 3], [0, 0, 1, 1, 2, 3])
 >>> X = matrix(range(8), (4,2), 'd')
 >>> cholmod.linsolve(A,X)
->>> print X
+>>> print(X)
 [-1.46e-01  4.88e-02]
 [ 1.33e+00  4.00e+00]
 [ 4.88e-01  1.17e+00]
@@ -316,7 +316,7 @@ The following code computes the inverse of the coefficient matrix
 in :eq:`e-A-pd` as a sparse matrix.
 
 >>> X = cholmod.splinsolve(A, spmatrix(1.0,range(4),range(4)))
->>> print X
+>>> print(X)
 [ 1.22e-01     0     -7.32e-02     0    ]
 [    0      3.33e-01     0      3.33e-01]
 [-7.32e-02     0      2.44e-01     0    ]
@@ -437,7 +437,7 @@ For the same example as above:
 >>> F = cholmod.symbolic(A)
 >>> cholmod.numeric(A, F)
 >>> cholmod.solve(F, X)
->>> print X
+>>> print(X)
 [-1.46e-01  4.88e-02]
 [ 1.33e+00  4.00e+00]
 [ 4.88e-01  1.17e+00]
@@ -484,14 +484,14 @@ of the coefficient matrix in :eq:`e-A-pd` by two methods.
 >>> from cvxopt import log
 >>> F = cholmod.symbolic(A)
 >>> cholmod.numeric(A, F)
->>> print 2.0 * sum(log(cholmod.diag(F)))
+>>> print(2.0 * sum(log(cholmod.diag(F))))
 5.50533153593
 >>> options['supernodal'] = 0
 >>> F = cholmod.symbolic(A)
 >>> cholmod.numeric(A, F)
 >>> Di = matrix(1.0, (4,1))
 >>> cholmod.solve(F, Di, sys=6)
->>> print -sum(log(Di))
+>>> print(-sum(log(Di)))
 5.50533153593
 
 
@@ -575,7 +575,7 @@ where :math:`\circ` denotes Hadamard product.
         """
         Returns the solution of
 
-             minimize    -logdet K + Tr(KY)
+             minimize    -log det K + Tr(KY)
              subject to  K_{ij}=0,  (i,j) not in indices listed in I,J.
 
         Y is a symmetric sparse matrix with nonzero diagonal elements.
@@ -585,7 +585,7 @@ where :math:`\circ` denotes Hadamard product.
         I, J = Y.I, Y.J
         n, m = Y.size[0], len(I) 
         N = I + J*n         # non-zero positions for one-argument indexing 
-        D = [k for k in xrange(m) if I[k]==J[k]]  # position of diagonal elements
+        D = [k for k in range(m) if I[k]==J[k]]  # position of diagonal elements
 
         # starting point: symmetric identity with nonzero pattern I,J
         K = spmatrix(0.0, I, J) 
@@ -600,7 +600,7 @@ where :math:`\circ` denotes Hadamard product.
         # Kinv will be the inverse of K
         Kinv = matrix(0.0, (n,n))
         
-        for iters in xrange(100):
+        for iters in range(100):
 
             # numeric factorization of K
             cholmod.numeric(K, F)
@@ -619,9 +619,9 @@ where :math:`\circ` denotes Hadamard product.
             
             # stopping criterion
             sqntdecr = -blas.dot(grad,v) 
-            print "Newton decrement squared:%- 7.5e" %sqntdecr
+            print("Newton decrement squared:%- 7.5e" %sqntdecr)
             if (sqntdecr < 1e-12):
-                print "number of iterations: ", iters+1 
+                print("number of iterations: ", iters+1)
                 break
 
             # line search
@@ -629,7 +629,7 @@ where :math:`\circ` denotes Hadamard product.
             dx[D] *= 2      # scale the diagonal elems        
             f = -2.0 * sum(log(d))    # f = -log det K
             s = 1
-            for lsiter in xrange(50):
+            for lsiter in range(50):
                 Kn.V = K.V + s*dx
                 try: 
                     cholmod.numeric(Kn, F)
diff --git a/examples/book/chap4/portfolio.py b/examples/book/chap4/portfolio.py
index 9f53cf5..fa0b8b4 100644
--- a/examples/book/chap4/portfolio.py
+++ b/examples/book/chap4/portfolio.py
@@ -5,7 +5,6 @@ from math import sqrt
 from cvxopt import matrix
 from cvxopt.blas import dot 
 from cvxopt.solvers import qp, options 
-import pylab
 
 n = 4
 S = matrix( [[ 4e-2,  6e-3, -4e-3,   0.0 ], 
@@ -21,35 +20,41 @@ A = matrix(1.0, (1,n))
 b = matrix(1.0)
 
 N = 100
-mus = [ 10**(5.0*t/N-1.0) for t in xrange(N) ]
-options['show_progress'] = False
+mus = [ 10**(5.0*t/N-1.0) for t in range(N) ]
+#options['show_progress'] = False
 xs = [ qp(mu*S, -pbar, G, h, A, b)['x'] for mu in mus ]
 returns = [ dot(pbar,x) for x in xs ]
 risks = [ sqrt(dot(x, S*x)) for x in xs ]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(risks, returns)
-pylab.xlabel('standard deviation')
-pylab.ylabel('expected return')
-pylab.axis([0, 0.2, 0, 0.15])
-pylab.title('Risk-return trade-off curve (fig 4.12)')
-pylab.yticks([0.00, 0.05, 0.10, 0.15])
-
-pylab.figure(2, facecolor='w')
-c1 = [ x[0] for x in xs ] 
-c2 = [ x[0] + x[1] for x in xs ]
-c3 = [ x[0] + x[1] + x[2] for x in xs ] 
-c4 = [ x[0] + x[1] + x[2] + x[3] for x in xs ]
-pylab.fill(risks + [.20], c1 + [0.0], facecolor = '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1, facecolor = '#D0D0D0') 
-pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, facecolor = '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3, facecolor = '#D0D0D0') 
-pylab.axis([0.0, 0.2, 0.0, 1.0])
-pylab.xlabel('standard deviation')
-pylab.ylabel('allocation')
-pylab.text(.15,.5,'x1')
-pylab.text(.10,.7,'x2')
-pylab.text(.05,.7,'x3')
-pylab.text(.01,.7,'x4')
-pylab.title('Optimal allocations (fig 4.12)')
-pylab.show()
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(risks, returns)
+    pylab.xlabel('standard deviation')
+    pylab.ylabel('expected return')
+    pylab.axis([0, 0.2, 0, 0.15])
+    pylab.title('Risk-return trade-off curve (fig 4.12)')
+    pylab.yticks([0.00, 0.05, 0.10, 0.15])
+    
+    pylab.figure(2, facecolor='w')
+    c1 = [ x[0] for x in xs ] 
+    c2 = [ x[0] + x[1] for x in xs ]
+    c3 = [ x[0] + x[1] + x[2] for x in xs ] 
+    c4 = [ x[0] + x[1] + x[2] + x[3] for x in xs ]
+    pylab.fill(risks + [.20], c1 + [0.0], facecolor = '#F0F0F0') 
+    pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1, 
+        facecolor = '#D0D0D0') 
+    pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, 
+        facecolor = '#F0F0F0') 
+    pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3, 
+        facecolor = '#D0D0D0') 
+    pylab.axis([0.0, 0.2, 0.0, 1.0])
+    pylab.xlabel('standard deviation')
+    pylab.ylabel('allocation')
+    pylab.text(.15,.5,'x1')
+    pylab.text(.10,.7,'x2')
+    pylab.text(.05,.7,'x3')
+    pylab.text(.01,.7,'x4')
+    pylab.title('Optimal allocations (fig 4.12)')
+    pylab.show()
diff --git a/examples/book/chap4/rls.py b/examples/book/chap4/rls.py
index c47f4b4..72403ac 100644
--- a/examples/book/chap4/rls.py
+++ b/examples/book/chap4/rls.py
@@ -1,13 +1,12 @@
 # Figure 4.11, page 185.
 # Regularized least-squares.
 
-import pylab
 from pickle import load
 from cvxopt import blas, lapack, matrix
 from cvxopt import solvers 
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
 
-data = load(open("rls.bin",'r'))
+data = load(open("rls.bin",'rb'))
 A, b = data['A'], data['b']
 m, n = A.size
 
@@ -42,35 +41,38 @@ h = matrix( [ [ A.T * A,  b.T * A ], [ A.T * b, b.T * b ] ] )
 c = matrix(1.0, (2,1))
 
 nopts = 40
-alpha1 = [ 2.0/(nopts/2-1) * alpha for alpha in xrange(nopts/2) ] + \
-    [ 2.0 + (15.0 - 2.0)/(nopts/2) * alpha for alpha in 
-    xrange(1,nopts/2+1) ]
+alpha1 = [2.0/(nopts//2-1) * alpha for alpha in range(nopts//2) ] + \
+    [ 2.0 + (15.0 - 2.0)/(nopts//2) * alpha for alpha in 
+        range(1,nopts//2+1) ]
 lbnds = [ blas.nrm2(b)**2 ]
 for alpha in alpha1[1:]:  
     c[1:] = alpha
     lbnds += [ -blas.dot(c, solvers.sdp(c, Gs=[G], hs=[h])['x']) ]
 
 nopts = 10
-alpha2 = [ 1.0/(nopts-1) * alpha for alpha in xrange(nopts) ] 
+alpha2 = [ 1.0/(nopts-1) * alpha for alpha in range(nopts) ] 
 ubnds = [ blas.nrm2(b)**2 ]
 for alpha in alpha2[1:]:  
     c[1:] = alpha
     ubnds += [ blas.dot(c, solvers.sdp(c, Gs=[G], hs=[-h])['x']) ]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(lbnds, alpha1, 'b-', ubnds, alpha2, 'b-')
-kmax = max([ k for k in xrange(len(alpha1)) if alpha1[k] < 
-    blas.nrm2(xls)**2 ])
-pylab.plot( [ blas.nrm2(b)**2 ] + lbnds[:kmax] + 
-    [ blas.nrm2(A*xls-b)**2 ], [0.0] + alpha1[:kmax] + 
-    [ blas.nrm2(xls)**2 ], '-', linewidth=2)
-pylab.plot([ blas.nrm2(b)**2, blas.nrm2(A*xls-b)**2 ], 
-    [0.0, blas.nrm2(xls)**2], 'bo')
-pylab.fill(lbnds[-1::-1] + ubnds + [ubnds[-1]], 
-    alpha1[-1::-1] + alpha2+ [alpha1[-1]], facecolor = '#D0D0D0')
-pylab.axis([0, 15, -1.0, 15])
-pylab.xlabel('||A*x-b||_2^2')
-pylab.ylabel('||x||_2^2')
-pylab.grid()
-pylab.title('Regularized least-squares (fig. 4.11)')
-pylab.show()
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(lbnds, alpha1, 'b-', ubnds, alpha2, 'b-')
+    kmax = max([ k for k in range(len(alpha1)) if alpha1[k] < 
+        blas.nrm2(xls)**2 ])
+    pylab.plot( [ blas.nrm2(b)**2 ] + lbnds[:kmax] + 
+        [ blas.nrm2(A*xls-b)**2 ], [0.0] + alpha1[:kmax] + 
+        [ blas.nrm2(xls)**2 ], '-', linewidth=2)
+    pylab.plot([ blas.nrm2(b)**2, blas.nrm2(A*xls-b)**2 ], 
+        [0.0, blas.nrm2(xls)**2], 'bo')
+    pylab.fill(lbnds[-1::-1] + ubnds + [ubnds[-1]], 
+        alpha1[-1::-1] + alpha2+ [alpha1[-1]], facecolor = '#D0D0D0')
+    pylab.axis([0, 15, -1.0, 15])
+    pylab.xlabel('||A*x-b||_2^2')
+    pylab.ylabel('||x||_2^2')
+    pylab.grid()
+    pylab.title('Regularized least-squares (fig. 4.11)')
+    pylab.show()
diff --git a/examples/book/chap6/basispursuit.py b/examples/book/chap6/basispursuit.py
index bccb0d8..8a4feba 100644
--- a/examples/book/chap6/basispursuit.py
+++ b/examples/book/chap6/basispursuit.py
@@ -3,7 +3,9 @@
 
 from cvxopt import matrix, mul, div, cos, sin, exp, sqrt 
 from cvxopt import blas, lapack, solvers
-import pylab
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 # Basis functions are Gabor pulses:  for k = 0,...,K-1,
 #
@@ -25,36 +27,36 @@ A = matrix(0.0, (N, K*(2*L+1)))
 
 # First K columns are DC pulses for k = 0,...,K-1
 A[:,:K] = B
-for l in xrange(L):
+for l in range(L):
 
     # Cosine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
-    A[:, K+l*(2*K) : K+l*(2*K)+K] = \
-        mul(B, cos((l+1)*omega0*ts)[:, K*[0]])
+    A[:, K+l*(2*K) : K+l*(2*K)+K] = mul(B, cos((l+1)*omega0*ts)[:, K*[0]])
 
     # Sine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
     A[:, K+l*(2*K)+K : K+(l+1)*(2*K)] = \
         mul(B, sin((l+1)*omega0*ts)[:,K*[0]])
 
-
-pylab.figure(1, facecolor='w')
-pylab.subplot(311)
-# DC pulse for k = 250 (tau = 0.5)
-pylab.plot(ts, A[:,250])
-pylab.ylabel('f(0.5, 0, c)')
-pylab.axis([0, 1, -1, 1])
-pylab.title('Three basis elements (fig. 6.21)')
-# Cosine pulse for k = 250 (tau = 0.5) and l = 15  (omega = 75)
-pylab.subplot(312)
-pylab.ylabel('f(0.5, 75, c)')
-pylab.plot(ts, A[:, K + 14*(2*K) + 250])
-pylab.axis([0, 1, -1, 1])
-pylab.subplot(313)
-# Cosine pulse for k = 250 (tau = 0.5) and l = 30  (omega = 150)
-pylab.plot(ts, A[:, K + 29*(2*K) + 250])
-pylab.ylabel('f(0.5, 150, c)')
-pylab.axis([0, 1, -1, 1])
-pylab.xlabel('t')
-
+if pylab_installed:
+
+    pylab.figure(1, facecolor='w')
+    pylab.subplot(311)
+    # DC pulse for k = 250 (tau = 0.5)
+    pylab.plot(ts, A[:,250])
+    pylab.ylabel('f(0.5, 0, c)')
+    pylab.axis([0, 1, -1, 1])
+    pylab.title('Three basis elements (fig. 6.21)')
+    # Cosine pulse for k = 250 (tau = 0.5) and l = 15  (omega = 75)
+    pylab.subplot(312)
+    pylab.ylabel('f(0.5, 75, c)')
+    pylab.plot(ts, A[:, K + 14*(2*K) + 250])
+    pylab.axis([0, 1, -1, 1])
+    pylab.subplot(313)
+    # Cosine pulse for k = 250 (tau = 0.5) and l = 30  (omega = 150)
+    pylab.plot(ts, A[:, K + 29*(2*K) + 250])
+    pylab.ylabel('f(0.5, 150, c)')
+    pylab.axis([0, 1, -1, 1])
+    pylab.xlabel('t')
+    
 # Signal.
 y = mul( 1.0 + 0.5 * sin(11*ts), sin(30 * sin(5*ts)))
 
@@ -156,7 +158,7 @@ def Fkkt(W):
  
     # Asc = A*diag(d)^-1/2
     blas.copy(A, Asc)
-    for k in xrange(m):
+    for k in range(m):
         blas.tbsv(ds, Asc, n=n, k=0, ldA=1, incx=m, offsetx=k)
 
     # S = I + A * D^-1 * A'
@@ -199,47 +201,48 @@ def Fkkt(W):
 
 x = solvers.coneqp(P, q, G, h, kktsolver = Fkkt)['x'][:n]
 
-I = [ k for k in xrange(n) if abs(x[k]) > 1e-2 ]
+I = [ k for k in range(n) if abs(x[k]) > 1e-2 ]
 xls = +y
 lapack.gels(A[:,I], xls)
 ybp = A[:,I]*xls[:len(I)]
 
-print "Sparse basis contains %d basis functions." %len(I)
-print "Relative RMS error = %.1e." %(blas.nrm2(ybp-y) / blas.nrm2(y))
-
-pylab.figure(2, facecolor='w')
-pylab.subplot(211)
-pylab.plot(ts, y, '-', ts, ybp, 'r--')
-pylab.xlabel('t')
-pylab.ylabel('y(t), yhat(t)')
-pylab.axis([0, 1, -1.5, 1.5])
-pylab.title('Signal and basis pursuit approximation (fig. 6.22)')
-pylab.subplot(212)
-pylab.plot(ts, y-ybp, '-')
-pylab.xlabel('t')
-pylab.ylabel('y(t)-yhat(t)')
-pylab.axis([0, 1, -0.05, 0.05])
-       
-pylab.figure(3, facecolor='w')
-pylab.subplot(211)
-pylab.plot(ts, y, '-')
-pylab.xlabel('t')
-pylab.ylabel('y(t)')
-pylab.axis([0, 1, -1.5, 1.5])
-pylab.title('Signal and time-frequency plot (fig. 6.23)')
-pylab.subplot(212)
-omegas, taus = [], []
-for i in I:
-    if i < K: 
-        omegas += [0.0]
-        taus += [i*tau]
-    else:
-        l = (i-K)/(2*K)+1
-        k = ((i-K)%(2*K)) %K
-        omegas += [l*omega0]
-        taus += [k*tau]
-pylab.plot(ts, 150*abs(cos(5.0*ts)), '-', taus, omegas, 'ro')
-pylab.xlabel('t')
-pylab.ylabel('omega(t)')
-pylab.axis([0, 1, -5, 155])
-pylab.show()
+print("Sparse basis contains %d basis functions." %len(I))
+print("Relative RMS error = %.1e." %(blas.nrm2(ybp-y) / blas.nrm2(y)))
+
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
+    pylab.subplot(211)
+    pylab.plot(ts, y, '-', ts, ybp, 'r--')
+    pylab.xlabel('t')
+    pylab.ylabel('y(t), yhat(t)')
+    pylab.axis([0, 1, -1.5, 1.5])
+    pylab.title('Signal and basis pursuit approximation (fig. 6.22)')
+    pylab.subplot(212)
+    pylab.plot(ts, y-ybp, '-')
+    pylab.xlabel('t')
+    pylab.ylabel('y(t)-yhat(t)')
+    pylab.axis([0, 1, -0.05, 0.05])
+           
+    pylab.figure(3, facecolor='w')
+    pylab.subplot(211)
+    pylab.plot(ts, y, '-')
+    pylab.xlabel('t')
+    pylab.ylabel('y(t)')
+    pylab.axis([0, 1, -1.5, 1.5])
+    pylab.title('Signal and time-frequency plot (fig. 6.23)')
+    pylab.subplot(212)
+    omegas, taus = [], []
+    for i in I:
+        if i < K: 
+            omegas += [0.0]
+            taus += [i*tau]
+        else:
+            l = (i-K)/(2*K)+1
+            k = ((i-K)%(2*K)) %K
+            omegas += [l*omega0]
+            taus += [k*tau]
+    pylab.plot(ts, 150*abs(cos(5.0*ts)), '-', taus, omegas, 'ro')
+    pylab.xlabel('t')
+    pylab.ylabel('omega(t)')
+    pylab.axis([0, 1, -5, 155])
+    pylab.show()
diff --git a/examples/book/chap6/consumerpref.py b/examples/book/chap6/consumerpref.py
index 72ddd62..c917592 100644
--- a/examples/book/chap6/consumerpref.py
+++ b/examples/book/chap6/consumerpref.py
@@ -1,10 +1,12 @@
 # Figures 6.25 and 6.26, page 342.
 # Consumer preference analysis.
 
-import pylab
 from cvxopt import solvers, matrix, sqrt
 from cvxopt.modeling import variable, op
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
+try: import pylab 
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 def utility(x, y): 
     return (1.1 * sqrt(x) + 0.8 * sqrt(y)) / 1.9
@@ -56,19 +58,21 @@ m = B.size[1]
 nopts = 200
 a = (1.0/nopts)*matrix(range(nopts), tc='d')
 X, Y = a[:,nopts*[0]].T,  a[:,nopts*[0]]
-pylab.figure(1, facecolor='w')
-pylab.plot(B[0,:], B[1,:], 'wo', markeredgecolor='b')
-pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
-    [.1*(k+1) for k in xrange(9)], colors='k')
-pylab.xlabel('x1')
-pylab.ylabel('x2')
-pylab.title('Goods baskets and utility function (fig. 6.25)')
-#print "Close figure to start analysis."
-#pylab.show()
+
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(B[0,:], B[1,:], 'wo', markeredgecolor='b')
+    pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
+        [.1*(k+1) for k in range(9)], colors='k')
+    pylab.xlabel('x1')
+    pylab.ylabel('x2')
+    pylab.title('Goods baskets and utility function (fig. 6.25)')
+    #print("Close figure to start analysis.")
+    #pylab.show()
 
 
 # P are basket indices in order of increasing preference 
-l = zip(utility(B[0,:], B[1,:]), range(m))
+l = list(zip(utility(B[0,:], B[1,:]), range(m)))
 l.sort()
 P = [ e[1] for e in l ]
 
@@ -82,51 +86,51 @@ gxc = variable(1)
 gyc = variable(1)
 
 monotonicity = [ gx >= 0, gy >= 0, gxc >= 0, gyc >= 0 ]
-preferences = [ u[P[j+1]] >= u[P[j]] + 1.0 for j in xrange(m-1) ]
+preferences = [ u[P[j+1]] >= u[P[j]] + 1.0 for j in range(m-1) ]
 concavity = [ u[j] <= u[i] + gx[i] * ( B[0,j] - B[0,i] ) + 
-    gy[i] * ( B[1,j] - B[1,i] ) for i in xrange(m) for j in 
-    xrange(m) ] 
+    gy[i] * ( B[1,j] - B[1,i] ) for i in range(m) for j in range(m) ] 
 concavity += [ 0 <= u[i] + gx[i] * ( 0.5 - B[0,i] ) + 
-    gy[i] * ( 0.5 - B[1,i] ) for i in xrange(m) ]  
+    gy[i] * ( 0.5 - B[1,i] ) for i in range(m) ]  
 concavity += [ u[j] <= gxc * ( B[0,j] - 0.5 ) + 
-    gyc * ( B[1,j] - 0.5 ) for j in xrange(m) ]  
+    gyc * ( B[1,j] - 0.5 ) for j in range(m) ]  
 
 preferred, rejected, neutral = [], [], []
-for k in xrange(m):
+for k in range(m):
     p = op(-u[k], monotonicity + preferences + concavity)
     p.solve()
     if p.status == 'optimal' and p.objective.value()[0] > 0:
         rejected += [k]
-        print "Basket (%1.2f, %1.2f) rejected." %(B[0,k],B[1,k])
+        print("Basket (%1.2f, %1.2f) rejected." %(B[0,k],B[1,k]))
     else: 
         p = op(u[k], monotonicity + preferences + concavity)
         p.solve()
         if p.status == 'optimal' and p.objective.value()[0] > 0: 
-            print "Basket (%1.2f, %1.2f) preferred." %(B[0,k],B[1,k])
+            print("Basket (%1.2f, %1.2f) preferred." %(B[0,k],B[1,k]))
             preferred += [k]
         else:
-            print "No conclusion about basket (%1.2f, %1.2f)." \
-                %(B[0,k],B[1,k])
+            print("No conclusion about basket (%1.2f, %1.2f)." \
+                %(B[0,k],B[1,k]))
             neutral += [k]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(B[0,:], B[1,:], 'wo', markeredgecolor='b')
-pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
-    [.1*(k+1) for k in xrange(9)], colors='k')
-pylab.xlabel('x1')
-pylab.ylabel('x2')
-pylab.title('Goods baskets and utility function (fig. 6.25)')
-
-pylab.figure(2, facecolor='w')
-pylab.plot(B[0,preferred], B[1,preferred], 'go')
-pylab.plot(B[0,rejected], B[1,rejected], 'ro')
-pylab.plot(B[0,neutral], B[1,neutral], 'ys')
-pylab.plot([0.5], [0.5], '+')
-pylab.plot([0.5, 0.5], [0,1], ':', [0,1], [0.5,0.5], ':')
-pylab.axis([0,1,0,1])
-pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
-    [utility(0.5,0.5)], colors='k')
-pylab.xlabel('x1')
-pylab.ylabel('x2')
-pylab.title('Result of preference analysis (fig. 6.26)')
-pylab.show()
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(B[0,:], B[1,:], 'wo', markeredgecolor='b')
+    pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
+        [.1*(k+1) for k in range(9)], colors='k')
+    pylab.xlabel('x1')
+    pylab.ylabel('x2')
+    pylab.title('Goods baskets and utility function (fig. 6.25)')
+    
+    pylab.figure(2, facecolor='w')
+    pylab.plot(B[0,preferred], B[1,preferred], 'go')
+    pylab.plot(B[0,rejected], B[1,rejected], 'ro')
+    pylab.plot(B[0,neutral], B[1,neutral], 'ys')
+    pylab.plot([0.5], [0.5], '+')
+    pylab.plot([0.5, 0.5], [0,1], ':', [0,1], [0.5,0.5], ':')
+    pylab.axis([0,1,0,1])
+    pylab.contour(pylab.array(X), pylab.array(Y), pylab.array(utility(X,Y)),
+        [utility(0.5,0.5)], colors='k')
+    pylab.xlabel('x1')
+    pylab.ylabel('x2')
+    pylab.title('Result of preference analysis (fig. 6.26)')
+    pylab.show()
diff --git a/examples/book/chap6/cvxfit.py b/examples/book/chap6/cvxfit.py
index 441e8d5..0c1f91e 100644
--- a/examples/book/chap6/cvxfit.py
+++ b/examples/book/chap6/cvxfit.py
@@ -1,12 +1,11 @@
 # Figure 6.24, page 339.
 # Least-squares fit of a convex function.
 
-import pylab
 from cvxopt import solvers, matrix, spmatrix, mul
 from pickle import load
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
 
-data = load(open('cvxfit.bin','r'))
+data = load(open('cvxfit.bin','rb'))
 u, y = data['u'], data['y']
 m = len(u)
 
@@ -26,15 +25,15 @@ q[:m] = -y
 
 G = spmatrix([],[],[], (m**2, nvars))
 I = spmatrix(1.0, range(m), range(m))
-for i in xrange(m):  
+for i in range(m):  
     # coefficients of yhat[i]
-    G[range(i*m, (i+1)*m), i] = 1.0
+    G[list(range(i*m, (i+1)*m)), i] = 1.0
 
     # coefficients of g[i]
-    G[range(i*m, (i+1)*m), m+i] = u - u[i]
+    G[list(range(i*m, (i+1)*m)), m+i] = u - u[i]
 
     # coefficients of yhat[j]
-    G[range(i*m, (i+1)*m), range(m)] -= I
+    G[list(range(i*m, (i+1)*m)), list(range(m))] -= I
 
 h = matrix(0.0, (m**2,1))
 
@@ -43,12 +42,16 @@ yhat = sol['x'][:m]
 g = sol['x'][m:]
 
 nopts = 1000
-ts = [ 2.2/nopts * t for t in xrange(1000) ]
+ts = [ 2.2/nopts * t for t in range(1000) ]
 f = [ max(yhat + mul(g, t-u)) for t in ts ]
-pylab.figure(1, facecolor='w')
-pylab.plot(u, y, 'wo', markeredgecolor='b') 
-pylab.plot(ts, f, '-g')
-pylab.axis([-0.1, 2.3, -1.1, 7.2])
-pylab.axis('off')
-pylab.title('Least-squares fit of convex function (fig. 6.24)')
-pylab.show()
+
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(u, y, 'wo', markeredgecolor='b') 
+    pylab.plot(ts, f, '-g')
+    pylab.axis([-0.1, 2.3, -1.1, 7.2])
+    pylab.axis('off')
+    pylab.title('Least-squares fit of convex function (fig. 6.24)')
+    pylab.show()
diff --git a/examples/book/chap6/huber.py b/examples/book/chap6/huber.py
index 0a80c69..e74f10f 100644
--- a/examples/book/chap6/huber.py
+++ b/examples/book/chap6/huber.py
@@ -2,11 +2,10 @@
 # Robust regression.
 
 from cvxopt import solvers, lapack, matrix, spmatrix
-import pylab
 from pickle import load
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
 
-data = load(open('huber.bin','r'))
+data = load(open('huber.bin','rb'))
 u, v = data['u'], data['v']
 m, n = len(u), 2
 
@@ -68,13 +67,16 @@ G[4*m:,n+m:] = spmatrix(-1.0, range(m), range(m))
 
 xh = solvers.qp(P, q, G, h)['x'][:n]
 
-pylab.figure(1,facecolor='w')
-pylab.plot(u, v,'o', 
-    [-11,11], [xh[0]-11*xh[1], xh[0]+11*xh[1]], '-g', 
-    [-11,11], [xls[0]-11*xls[1], xls[0]+11*xls[1]], '--r',
-    markerfacecolor='w', markeredgecolor='b') 
-pylab.axis([-11, 11, -20, 25])
-pylab.xlabel('t')
-pylab.ylabel('f(t)')
-pylab.title('Robust regression (fig. 6.5)')
-pylab.show()
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(1,facecolor='w')
+    pylab.plot(u, v,'o', 
+        [-11,11], [xh[0]-11*xh[1], xh[0]+11*xh[1]], '-g', 
+        [-11,11], [xls[0]-11*xls[1], xls[0]+11*xls[1]], '--r',
+        markerfacecolor='w', markeredgecolor='b') 
+    pylab.axis([-11, 11, -20, 25])
+    pylab.xlabel('t')
+    pylab.ylabel('f(t)')
+    pylab.title('Robust regression (fig. 6.5)')
+    pylab.show()
diff --git a/examples/book/chap6/inputdesign.py b/examples/book/chap6/inputdesign.py
index ebf5150..5a633ca 100644
--- a/examples/book/chap6/inputdesign.py
+++ b/examples/book/chap6/inputdesign.py
@@ -3,13 +3,15 @@
 
 from math import cos, sqrt
 from cvxopt import lapack, matrix
-import pylab
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 m, n = 201, 201
 
 # Jtrack = 1/n * ||H*u-ydes||_2^2.
 H = matrix(0.0, (m,m))
-for t in xrange(m):
+for t in range(m):
     H[t::m+1] = (1.0/9.0) * .9**t * (1.0 - 0.4 * cos(2*t))
 ydes = matrix( 40*[0.0] + 50*[1.0] + 50*[-1.0] + 61*[0.0] )
 
@@ -34,20 +36,21 @@ x = +bb
 lapack.gels(+AA, x)
 u1 = x[:n]
 
-pylab.figure(1, facecolor='w', figsize=(10,10))
-ts = matrix(range(n), tc='d')
-pylab.subplot(321)
-pylab.plot(ts, u1, '-')
-pylab.xlabel('t')
-pylab.ylabel('u(t)')
-pylab.axis([0, 200, -10, 5])
-pylab.title('Optimal input (fig. 6.6.)')
-pylab.subplot(322)
-pylab.plot(ts, H*u1, '-', ts, ydes, 'g--')
-pylab.xlabel('t')
-pylab.ylabel('y(t)')
-pylab.axis([0, 200, -1.1, 1.1])
-pylab.title('Output')
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(10,10))
+    ts = matrix(range(n), tc='d')
+    pylab.subplot(321)
+    pylab.plot(ts, u1, '-')
+    pylab.xlabel('t')
+    pylab.ylabel('u(t)')
+    pylab.axis([0, 200, -10, 5])
+    pylab.title('Optimal input (fig. 6.6.)')
+    pylab.subplot(322)
+    pylab.plot(ts, H*u1, '-', ts, ydes, 'g--')
+    pylab.xlabel('t')
+    pylab.ylabel('y(t)')
+    pylab.axis([0, 200, -1.1, 1.1])
+    pylab.title('Output')
 
 
 delta, eta = 0.0, 0.05
@@ -57,16 +60,17 @@ x = +bb
 lapack.gels(+AA, x)
 u2 = x[:n]
 
-pylab.subplot(323)
-pylab.plot(ts, u2, '-')
-pylab.xlabel('t')
-pylab.ylabel('u(t)')
-pylab.axis([0, 200, -4, 4])
-pylab.subplot(324)
-pylab.plot(ts, H*u2, '-', ts, ydes, 'g--')
-pylab.ylabel('y(t)')
-pylab.xlabel('t')
-pylab.axis([0, 200, -1.1, 1.1])
+if pylab_installed:
+    pylab.subplot(323)
+    pylab.plot(ts, u2, '-')
+    pylab.xlabel('t')
+    pylab.ylabel('u(t)')
+    pylab.axis([0, 200, -4, 4])
+    pylab.subplot(324)
+    pylab.plot(ts, H*u2, '-', ts, ydes, 'g--')
+    pylab.ylabel('y(t)')
+    pylab.xlabel('t')
+    pylab.axis([0, 200, -1.1, 1.1])
 
 
 delta, eta = 0.3, 0.05
@@ -76,15 +80,16 @@ x = +bb
 lapack.gels(+AA, x)
 u3 = x[:n]
 
-pylab.subplot(325)
-pylab.plot(ts, u3, '-')
-pylab.xlabel('t')
-pylab.ylabel('u(t)')
-pylab.axis([0, 200, -4, 4])
-pylab.subplot(326)
-pylab.plot(ts, H*u3, '-', ts, ydes, 'g--')
-pylab.ylabel('y(t)')
-pylab.xlabel('t')
-pylab.axis([0, 200, -1.1, 1.1])
+if pylab_installed:
+    pylab.subplot(325)
+    pylab.plot(ts, u3, '-')
+    pylab.xlabel('t')
+    pylab.ylabel('u(t)')
+    pylab.axis([0, 200, -4, 4])
+    pylab.subplot(326)
+    pylab.plot(ts, H*u3, '-', ts, ydes, 'g--')
+    pylab.ylabel('y(t)')
+    pylab.xlabel('t')
+    pylab.axis([0, 200, -1.1, 1.1])
 
-pylab.show()
+    pylab.show()
diff --git a/examples/book/chap6/penalties.py b/examples/book/chap6/penalties.py
index 964cb49..5344901 100644
--- a/examples/book/chap6/penalties.py
+++ b/examples/book/chap6/penalties.py
@@ -3,10 +3,12 @@
 #
 # The problem data are not the same as in the book figure.
 
-import pylab, numpy
 from cvxopt import lapack, solvers, matrix, spdiag, log, div, normal
 from cvxopt.modeling import variable, op, max, sum 
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
+try: import numpy, pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 m, n = 100, 30
 A = normal(m,n)
@@ -22,17 +24,18 @@ x = variable(n)
 op(sum(abs(A*x+b))).solve()
 x1 = x.value
 
-pylab.figure(1, facecolor='w', figsize=(10,10))
-pylab.subplot(411)
-nbins = 100
-bins = [-1.5 + 3.0/(nbins-1)*k for k in xrange(nbins)]
-pylab.hist( A*x1+b , numpy.array(bins))
-nopts = 200
-xs = -1.5 + 3.0/(nopts-1) * matrix(range(nopts))
-pylab.plot(xs, (35.0/1.5) * abs(xs), 'g-')
-pylab.axis([-1.5, 1.5, 0, 40])
-pylab.ylabel('l1')
-pylab.title('Penalty function approximation (fig. 6.2)')
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(10,10))
+    pylab.subplot(411)
+    nbins = 100
+    bins = [-1.5 + 3.0/(nbins-1)*k for k in range(nbins)]
+    pylab.hist( A*x1+b , numpy.array(bins))
+    nopts = 200
+    xs = -1.5 + 3.0/(nopts-1) * matrix(list(range(nopts)))
+    pylab.plot(xs, (35.0/1.5) * abs(xs), 'g-')
+    pylab.axis([-1.5, 1.5, 0, 40])
+    pylab.ylabel('l1')
+    pylab.title('Penalty function approximation (fig. 6.2)')
 
 
 
@@ -44,11 +47,12 @@ x = matrix(0.0, (m,1))
 lapack.gels(+A, x)
 x2 = x[:n]
 
-pylab.subplot(412)
-pylab.hist(A*x2+b, numpy.array(bins))
-pylab.plot(xs, (8.0/1.5**2) * xs**2 , 'g-')
-pylab.ylabel('l2')
-pylab.axis([-1.5, 1.5, 0, 10])
+if pylab_installed:
+    pylab.subplot(412)
+    pylab.hist(A*x2+b, numpy.array(bins))
+    pylab.plot(xs, (8.0/1.5**2) * xs**2 , 'g-')
+    pylab.ylabel('l2')
+    pylab.axis([-1.5, 1.5, 0, 10])
 
 
 # Deadzone approximation
@@ -59,12 +63,13 @@ x = variable(n)
 op(sum(max(abs(A*x+b)-0.5, 0.0))).solve()
 xdz = x.value
 
-pylab.subplot(413)
-pylab.hist(A*xdz+b, numpy.array(bins))
-pylab.plot(xs, 15.0/1.0 * matrix([ max(abs(xk)-0.5, 0.0) for xk 
-    in xs ]), 'g-')
-pylab.ylabel('Deadzone')
-pylab.axis([-1.5, 1.5, 0, 20])
+if pylab_installed:
+    pylab.subplot(413)
+    pylab.hist(A*xdz+b, numpy.array(bins))
+    pylab.plot(xs, 15.0/1.0 * matrix([ max(abs(xk)-0.5, 0.0) for xk 
+        in xs ]), 'g-')
+    pylab.ylabel('Deadzone')
+    pylab.axis([-1.5, 1.5, 0, 20])
 
 
 # Log barrier
@@ -82,13 +87,14 @@ def F(x=None, z=None):
     return f, gradf.T, H
 xlb = solvers.cp(F)['x']
 
-pylab.subplot(414)
-pylab.hist(A*xlb+b, numpy.array(bins))
-nopts = 200
-pylab.plot(xs, (8.0/1.5**2) * xs**2, 'g--')
-xs2 = -0.99999 + (2*0.99999 /(nopts-1)) * matrix(range(nopts))
-pylab.plot(xs2, -3.0 * log(1.0 - abs(xs2)**2), 'g-')
-pylab.ylabel('Log barrier')
-pylab.xlabel('residual')
-pylab.axis([-1.5, 1.5, 0, 10])
-pylab.show()
+if pylab_installed:
+    pylab.subplot(414)
+    pylab.hist(A*xlb+b, numpy.array(bins))
+    nopts = 200
+    pylab.plot(xs, (8.0/1.5**2) * xs**2, 'g--')
+    xs2 = -0.99999 + (2*0.99999 /(nopts-1)) * matrix(list(range(nopts)))
+    pylab.plot(xs2, -3.0 * log(1.0 - abs(xs2)**2), 'g-')
+    pylab.ylabel('Log barrier')
+    pylab.xlabel('residual')
+    pylab.axis([-1.5, 1.5, 0, 10])
+    pylab.show()
diff --git a/examples/book/chap6/polapprox.py b/examples/book/chap6/polapprox.py
index 601d338..6c7937b 100644
--- a/examples/book/chap6/polapprox.py
+++ b/examples/book/chap6/polapprox.py
@@ -3,11 +3,13 @@
 
 from cvxopt import lapack, solvers, matrix, mul
 from cvxopt.modeling import op, variable, max
-import pylab
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 from pickle import load
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
 
-data = load(open('polapprox.bin','r'))
+data = load(open('polapprox.bin','rb'))
 t, y = data['t'], data['y']
 m = len(t)
 
@@ -16,7 +18,7 @@ m = len(t)
 #     minimize ||A*x - y ||_2
 
 n = 6
-A = matrix( [[t**k] for k in xrange(n)] )
+A = matrix( [[t**k] for k in range(n)] )
 xls = +y
 lapack.gels(+A,xls)
 xls = xls[:n]
@@ -29,17 +31,18 @@ xinf = variable(n)
 op( max(abs(A*xinf - y)) ).solve()
 xinf = xinf.value
 
-pylab.figure(1, facecolor='w')
-pylab.plot(t, y, 'bo', mfc='w', mec='b')
-nopts = 1000
-ts = -1.1 + (1.1 - (-1.1))/nopts * matrix(range(nopts), tc='d')
-yls = sum( xls[k] * ts**k  for k in xrange(n) )
-yinf = sum( xinf[k] * ts**k  for k in xrange(n) )
-pylab.plot(ts,yls,'g-', ts, yinf, '--r')
-pylab.axis([-1.1, 1.1, -0.1, 0.25])
-pylab.xlabel('u')
-pylab.ylabel('p(u)')
-pylab.title('Polynomial fitting (fig. 6.19)')
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(t, y, 'bo', mfc='w', mec='b')
+    nopts = 1000
+    ts = -1.1 + (1.1 - (-1.1))/nopts * matrix(list(range(nopts)), tc='d')
+    yls = sum( xls[k] * ts**k  for k in range(n) )
+    yinf = sum( xinf[k] * ts**k  for k in range(n) )
+    pylab.plot(ts,yls,'g-', ts, yinf, '--r')
+    pylab.axis([-1.1, 1.1, -0.1, 0.25])
+    pylab.xlabel('u')
+    pylab.ylabel('p(u)')
+    pylab.title('Polynomial fitting (fig. 6.19)')
 
 
 # Fit of cubic spline
@@ -64,12 +67,12 @@ pylab.title('Polynomial fitting (fig. 6.19)')
 
 n = 12
 u1, u2 = -1.0/3, 1.0/3
-I1 = [ k for k in xrange(m) if -1.0  <= t[k] < u1 ]
-I2 = [ k for k in xrange(m) if  u1 <= t[k] < u2 ]
-I3 = [ k for k in xrange(m) if  u2 <= t[k] <= 1.0 ]
+I1 = [ k for k in range(m) if -1.0  <= t[k] < u1 ]
+I2 = [ k for k in range(m) if  u1 <= t[k] < u2 ]
+I3 = [ k for k in range(m) if  u2 <= t[k] <= 1.0 ]
 m1, m2, m3 = len(I1), len(I2), len(I3)
 A = matrix(0.0, (m,n))
-for k in xrange(4):   
+for k in range(4):   
     A[I1,k] = t[I1]**k
     A[I2,k+4] = t[I2]**k
     A[I3,k+8] = t[I3]**k
@@ -77,8 +80,10 @@ for k in xrange(4):
 G = matrix(0.0, (6,n))
 
 # p1(u1) = p2(u1),  p1(u2) = p2(u2)
-G[0, range(8)]  =  1.0,  u1,  u1**2,  u1**3, -1.0, -u1, -u1**2, -u1**3
-G[1, range(4,12)] =  1.0,  u2,  u2**2,  u2**3, -1.0, -u2, -u2**2, -u2**3
+G[0, list(range(8))]  =  \
+    1.0,  u1,  u1**2,  u1**3, -1.0, -u1, -u1**2, -u1**3
+G[1, list(range(4,12))] =  \
+    1.0,  u2,  u2**2,  u2**3, -1.0, -u2, -u2**2, -u2**3
 
 # p1'(u1) = p2'(u1),  p1'(u2) = p2'(u2)
 G[2, [1,2,3,5,6,7]] = 1.0,  2*u1,  3*u1**2, -1.0, -2*u1, -3*u1**2
@@ -117,29 +122,30 @@ xcheb = variable(12)
 op( max(abs(A*xcheb - y)), [G*xcheb == 0]).solve()
 xcheb = xcheb.value
 
-pylab.figure(2, facecolor='w')
-nopts  = 100
-ts = -1.0 + (1.0 - (-1.0))/nopts * matrix(range(nopts), tc='d')
-I1 = [ k for k in xrange(nopts) if -1.0  <= ts[k] < u1 ]
-I2 = [ k for k in xrange(nopts) if  u1 <= ts[k] < u2 ]
-I3 = [ k for k in xrange(nopts) if  u2 <= ts[k] <= 1.0 ]
-yls = matrix(0.0, (nopts,1))
-yls[I1] = sum( xls[k]*ts[I1]**k for k in xrange(4) )
-yls[I2] = sum( xls[k+4]*ts[I2]**k for k in xrange(4) )
-yls[I3] = sum( xls[k+8]*ts[I3]**k for k in xrange(4) )
-ycheb = matrix(0.0, (nopts,1))
-ycheb[I1] = sum( xcheb[k]*ts[I1]**k for k in xrange(4) )
-ycheb[I2] = sum( xcheb[k+4]*ts[I2]**k for k in xrange(4) )
-ycheb[I3] = sum( xcheb[k+8]*ts[I3]**k for k in xrange(4) )
-
-pylab.plot(t, y, 'bo', mfc='w', mec='b')
-pylab.plot([-1.0, -1.0], [-0.1, 0.25], 'k--', 
-    [-1./3,-1./3], [-0.1, 0.25], 'k--', 
-    [1./3,1./3], [-0.1, 0.25], 'k--', [1,1], [-0.1, 0.25], 'k--')
-pylab.plot(ts, yls, '-g', ts, ycheb, '--r')
-pylab.axis([-1.1, 1.1, -0.1, 0.25])
-pylab.xlabel('u')
-pylab.ylabel('p(u)')
-pylab.title('Cubic spline fitting (fig. 6.20)')
-
-pylab.show()
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
+    nopts  = 100
+    ts = -1.0 + (1.0 - (-1.0))/nopts * matrix(list(range(nopts)), tc='d')
+    I1 = [ k for k in range(nopts) if -1.0  <= ts[k] < u1 ]
+    I2 = [ k for k in range(nopts) if  u1 <= ts[k] < u2 ]
+    I3 = [ k for k in range(nopts) if  u2 <= ts[k] <= 1.0 ]
+    yls = matrix(0.0, (nopts,1))
+    yls[I1] = sum( xls[k]*ts[I1]**k for k in range(4) )
+    yls[I2] = sum( xls[k+4]*ts[I2]**k for k in range(4) )
+    yls[I3] = sum( xls[k+8]*ts[I3]**k for k in range(4) )
+    ycheb = matrix(0.0, (nopts,1))
+    ycheb[I1] = sum( xcheb[k]*ts[I1]**k for k in range(4) )
+    ycheb[I2] = sum( xcheb[k+4]*ts[I2]**k for k in range(4) )
+    ycheb[I3] = sum( xcheb[k+8]*ts[I3]**k for k in range(4) )
+    
+    pylab.plot(t, y, 'bo', mfc='w', mec='b')
+    pylab.plot([-1.0, -1.0], [-0.1, 0.25], 'k--', 
+        [-1./3,-1./3], [-0.1, 0.25], 'k--', 
+        [1./3,1./3], [-0.1, 0.25], 'k--', [1,1], [-0.1, 0.25], 'k--')
+    pylab.plot(ts, yls, '-g', ts, ycheb, '--r')
+    pylab.axis([-1.1, 1.1, -0.1, 0.25])
+    pylab.xlabel('u')
+    pylab.ylabel('p(u)')
+    pylab.title('Cubic spline fitting (fig. 6.20)')
+    
+    pylab.show()
diff --git a/examples/book/chap6/regsel.py b/examples/book/chap6/regsel.py
index 6af9b94..67b35d0 100644
--- a/examples/book/chap6/regsel.py
+++ b/examples/book/chap6/regsel.py
@@ -3,12 +3,14 @@
 #
 # The problem data are different from the book.
 
-import pylab
 from cvxopt import blas, lapack, solvers, matrix, mul
 from pickle import load
 solvers.options['show_progress'] = 0
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
-data = load(open('regsel.bin','r'))
+data = load(open('regsel.bin','rb'))
 A, b = data['A'], data['b']
 m, n = A.size 
 
@@ -47,7 +49,7 @@ for alpha in alphas:
     h[-1] = alpha
     x = solvers.qp(P, q, G, h)['x'][:n]
     xmax = max(abs(x))
-    I = [ k for k in xrange(n) if abs(x[k]) > tol*xmax ]
+    I = [ k for k in range(n) if abs(x[k]) > tol*xmax ]
     if len(I) <= m:
         xs = +b 
         lapack.gels(A[:,I], xs)
@@ -58,20 +60,21 @@ for alpha in alphas:
 
 # Eliminate duplicate cardinalities and make staircase plot.
 res2, card2 = [], []
-for c in xrange(m+1):
-    r = [ res[k] for k in xrange(len(res)) if card[k] == c ]
+for c in range(m+1):
+    r = [ res[k] for k in range(len(res)) if card[k] == c ]
     if r:  
         res2 += [ min(r), min(r) ]
         card2 += [ c, c+1 ]
 
-#pylab.figure(1, facecolor='w')
-#pylab.plot( res2[::2], card2[::2], 'o')
-#pylab.plot( res2, card2, '-') 
-#pylab.xlabel('||A*x-b||_2')
-#pylab.ylabel('card(x)')
-#pylab.title('Sparse regressor selection (fig 6.7)')
-#print "Close figure to start exhaustive search."
-#pylab.show()
+# if pylab_installed:
+#     pylab.figure(1, facecolor='w')
+#     pylab.plot( res2[::2], card2[::2], 'o')
+#     pylab.plot( res2, card2, '-') 
+#     pylab.xlabel('||A*x-b||_2')
+#     pylab.ylabel('card(x)')
+#     pylab.title('Sparse regressor selection (fig 6.7)')
+#     print("Close figure to start exhaustive search.")
+#     pylab.show()
 
 
 # Exhaustive search.
@@ -91,11 +94,12 @@ def patterns(k,n):
 bestx = matrix(0.0, (n, m))   # best solution for each cardinality
 bestres = matrix(blas.nrm2(b), (1, m+1))   # best residual
 x = matrix(0.0, (n,1))
-for k in xrange(1,m):
+for k in range(1,m):
     for s in patterns(k,n):
-        I = [ i for i in xrange(n) if s[i] ]
-        s = [k] + s 
-        print ("%d nonzeros: " + n*"%d") %tuple(s)
+        I = [ i for i in range(n) if s[i] ]
+        st = ""
+        for i in s: st += str(i)
+        print("%d nonzeros: " %k + st)
         x = +b
         lapack.gels(A[:,I], x)
         res = blas.nrm2(b - A[:,I] * x[:k])
@@ -104,21 +108,22 @@ for k in xrange(1,m):
             bestx[:,k][I] = x[:k] 
 bestres[m] = 0.0
 
-pylab.figure(1, facecolor='w')
-
-# heuristic result
-pylab.plot( res2[::2], card2[::2], 'o' )
-pylab.plot( res2, card2, '-') 
-
-# exhaustive result
-res2, card2 = [ bestres[0] ], [ 0 ] 
-for k in xrange(1,m+1):
-    res2 += [bestres[k-1], bestres[k]]
-    card2 += [ k, k]
-pylab.plot( bestres.T, range(m+1), 'go')
-pylab.plot( res2, card2, 'g-')
-
-pylab.xlabel('||A*x-b||_2')
-pylab.ylabel('card(x)')
-pylab.title('Sparse regressor selection (fig 6.7)')
-pylab.show()
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+
+    # heuristic result
+    pylab.plot( res2[::2], card2[::2], 'o' )
+    pylab.plot( res2, card2, '-') 
+    
+    # exhaustive result
+    res2, card2 = [ bestres[0] ], [ 0 ] 
+    for k in range(1,m+1):
+        res2 += [bestres[k-1], bestres[k]]
+        card2 += [ k, k]
+    pylab.plot( bestres.T, range(m+1), 'go')
+    pylab.plot( res2, card2, 'g-')
+    
+    pylab.xlabel('||A*x-b||_2')
+    pylab.ylabel('card(x)')
+    pylab.title('Sparse regressor selection (fig 6.7)')
+    pylab.show()
diff --git a/examples/book/chap6/robls.py b/examples/book/chap6/robls.py
index c62d8fa..93c9d63 100644
--- a/examples/book/chap6/robls.py
+++ b/examples/book/chap6/robls.py
@@ -4,9 +4,11 @@
 from math import pi
 from cvxopt import blas, lapack, solvers
 from cvxopt import matrix, spmatrix, mul, cos, sin, sqrt, uniform
-import pylab, numpy
 from pickle import load
-solvers.options['show_progress'] = 0
+#solvers.options['show_progress'] = 0
+try: import pylab, numpy
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 def wcls(A, Ap, b):
     """
@@ -32,10 +34,10 @@ def wcls(A, Ap, b):
     M = m + p + 1
     c = matrix( n*[0.0] + 2*[1.0])
     Fs = [spmatrix([],[],[], (M**2, novars))]
-    for k in xrange(n):
+    for k in range(n):
         # coefficient of x[k]
         S = spmatrix([], [], [], (M, M))
-        for j in xrange(p):
+        for j in range(p):
             S[m+j, :m] = -Ap[j][:,k].T
             S[-1, :m ] = -A[:,k].T
         Fs[0][:,k] = S[:] 
@@ -53,7 +55,7 @@ def wcls(A, Ap, b):
 
 # Figure 6.15
 
-data = load(open('robls.bin','r'))['6.15']
+data = load(open('robls.bin','rb'))['6.15']
 A, b, B = data['A'], data['b'], data['B']
 m, n = A.size
 
@@ -81,26 +83,28 @@ lapack.posv(S, xstoch)
 
 xwc = wcls(A, [B], b)
 
-pylab.figure(1, facecolor='w')
 nopts = 500
-us = -2.0 + (2.0 - (-2.0))/(nopts-1) * matrix(range(nopts),tc='d')
+us = -2.0 + (2.0 - (-2.0))/(nopts-1) * matrix(list(range(nopts)),tc='d')
 rnom = [ blas.nrm2( (A+u*B)*xnom - b) for u in us ]
 rstoch = [ blas.nrm2( (A+u*B)*xstoch - b) for u in us ]
 rwc = [ blas.nrm2( (A+u*B)*xwc - b) for u in us ]
-pylab.plot(us, rnom, us, rstoch, us, rwc)
-pylab.plot([-1, -1], [0, 12], '--k', [1, 1], [0, 12], '--k')
-pylab.axis([-2.0, 2.0, 0.0, 12.0])
-pylab.xlabel('u')
-pylab.ylabel('r(u)')
-pylab.text(us[9], rnom[9], 'nominal')
-pylab.text(us[9], rstoch[9], 'stochastic')
-pylab.text(us[9], rwc[9], 'worst case')
-pylab.title('Robust least-squares (fig.6.15)')
+
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(us, rnom, us, rstoch, us, rwc)
+    pylab.plot([-1, -1], [0, 12], '--k', [1, 1], [0, 12], '--k')
+    pylab.axis([-2.0, 2.0, 0.0, 12.0])
+    pylab.xlabel('u')
+    pylab.ylabel('r(u)')
+    pylab.text(us[9], rnom[9], 'nominal')
+    pylab.text(us[9], rstoch[9], 'stochastic')
+    pylab.text(us[9], rwc[9], 'worst case')
+    pylab.title('Robust least-squares (fig.6.15)')
 
 
 # Figure 6.16
 
-data = load(open('robls.bin','r'))['6.16']
+data = load(open('robls.bin','rb'))['6.16']
 A, Ap, b = data['A0'], [data['A1'], data['A2']], data['b']
 (m, n), p = A.size, len(Ap)
 
@@ -142,18 +146,19 @@ P[:,0], P[:,1] = Ap[0]*xwc, Ap[1]*xwc
 r = P*u + q[:,notrials*[0]]
 reswc = sqrt( matrix(1.0, (1,m)) * mul(r,r) )
 
-pylab.figure(2, facecolor='w')
-pylab.hist(list(resls), numpy.array([0.1*k for k in xrange(50)]), fc='w', 
-    normed=True)
-pylab.text(4.4, 0.4, 'least-squares')
-pylab.hist(list(restik), numpy.array([0.1*k for k in xrange(50)]), fc='#D0D0D0', 
-    normed=True)
-pylab.text(2.9, 0.75, 'Tikhonov')
-pylab.hist(list(reswc), numpy.array([0.1*k for k in xrange(50)]), fc='#B0B0B0', 
-    normed=True)
-pylab.text(2.5, 2.0, 'robust least-squares')
-pylab.xlabel('residual')
-pylab.ylabel('frequency/binwidth')
-pylab.axis([0, 5, 0, 2.5])
-pylab.title('LS, Tikhonov and robust LS solutions (fig. 6.16)')
-pylab.show()
+if pylab_installed:
+   pylab.figure(2, facecolor='w')
+   pylab.hist(list(resls), numpy.array([0.1*k for k in range(50)]), fc='w', 
+       normed=True)
+   pylab.text(4.4, 0.4, 'least-squares')
+   pylab.hist(list(restik), numpy.array([0.1*k for k in range(50)]), fc='#D0D0D0', 
+       normed=True)
+   pylab.text(2.9, 0.75, 'Tikhonov')
+   pylab.hist(list(reswc), numpy.array([0.1*k for k in range(50)]), fc='#B0B0B0', 
+       normed=True)
+   pylab.text(2.5, 2.0, 'robust least-squares')
+   pylab.xlabel('residual')
+   pylab.ylabel('frequency/binwidth')
+   pylab.axis([0, 5, 0, 2.5])
+   pylab.title('LS, Tikhonov and robust LS solutions (fig. 6.16)')
+   pylab.show()
diff --git a/examples/book/chap6/smoothrec.py b/examples/book/chap6/smoothrec.py
index 0f51fc1..3639746 100644
--- a/examples/book/chap6/smoothrec.py
+++ b/examples/book/chap6/smoothrec.py
@@ -3,23 +3,26 @@
 
 from math import pi
 from cvxopt import blas, lapack, matrix, sin, mul, normal
-import pylab
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 n = 4000
-t = matrix(range(n), tc='d')
+t = matrix(list(range(n)), tc='d')
 ex = 0.5 * mul( sin(2*pi/n * t), sin(0.01 * t))
 corr = ex + 0.05 * normal(n,1)
 
-pylab.figure(1, facecolor='w', figsize=(8,5))
-pylab.subplot(211)
-pylab.plot(t, ex)
-pylab.ylabel('x[i]')
-pylab.xlabel('i')
-pylab.title('Original and corrupted signal (fig. 6.8)')
-pylab.subplot(212)
-pylab.plot(t, corr)
-pylab.ylabel('xcor[i]')
-pylab.xlabel('i')
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(8,5))
+    pylab.subplot(211)
+    pylab.plot(t, ex)
+    pylab.ylabel('x[i]')
+    pylab.xlabel('i')
+    pylab.title('Original and corrupted signal (fig. 6.8)')
+    pylab.subplot(212)
+    pylab.plot(t, corr)
+    pylab.ylabel('xcor[i]')
+    pylab.xlabel('i')
 
 
 # A = D'*D is an n by n tridiagonal matrix with -1.0 on the 
@@ -28,7 +31,7 @@ Ad = matrix([1.0] + (n-2)*[2.0] + [1.0])
 As = matrix(-1.0, (n-1,1))
 
 nopts = 50
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
+deltas = -10.0 + 20.0/(nopts-1) * matrix(list(range(nopts)))
 cost1, cost2 = [], []
 for delta in deltas:
     xr = +corr 
@@ -47,35 +50,36 @@ mv3, k3 = min(zip([abs(c - 1.0) for c in cost1], range(nopts)))
 xr3 = +corr 
 lapack.ptsv(1.0 + 10**deltas[k3] * Ad, 10**deltas[k3] *As, xr3)
 
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'bo') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'bo', [cost1[k2]], [cost2[k2]], 'bo',
-    [cost1[k3]], [cost2[k3]], 'bo')
-pylab.text(cost1[k1], cost2[k1],'1')
-pylab.text(cost1[k2], cost2[k2],'2')
-pylab.text(cost1[k3], cost2[k3],'3')
-pylab.title('Optimal trade-off curve (fig. 6.9)')
-pylab.xlabel('|| xhat - xcor ||_2')
-pylab.ylabel('|| D*xhat ||_2')
-pylab.axis([-0.4, 20, -0.1, 5])
-pylab.grid()
-
-pylab.figure(3, facecolor='w', figsize=(8,7.5))
-pylab.subplot(311)
-pylab.plot(t, xr1)
-pylab.axis([0, 4000, -0.6, 0.6])
-pylab.ylabel('xhat1[i]')
-pylab.title('Three smoothed sigals (fig. 6.10).')
-
-pylab.subplot(312)
-pylab.plot(t, xr2)
-pylab.ylabel('xhat2[i]')
-pylab.axis([0, 4000, -0.6, 0.6])
-
-pylab.subplot(313)
-pylab.plot(t, xr3)
-pylab.axis([0, 4000, -0.6, 0.6])
-pylab.ylabel('xhat3[i]')
-pylab.xlabel('i')
-pylab.show()
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
+    pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
+        [0], [blas.nrm2(corr[1:] - corr[:-1])], 'bo') 
+    pylab.plot([cost1[k1]], [cost2[k1]], 'bo', [cost1[k2]], [cost2[k2]], 'bo',
+        [cost1[k3]], [cost2[k3]], 'bo')
+    pylab.text(cost1[k1], cost2[k1],'1')
+    pylab.text(cost1[k2], cost2[k2],'2')
+    pylab.text(cost1[k3], cost2[k3],'3')
+    pylab.title('Optimal trade-off curve (fig. 6.9)')
+    pylab.xlabel('|| xhat - xcor ||_2')
+    pylab.ylabel('|| D*xhat ||_2')
+    pylab.axis([-0.4, 20, -0.1, 5])
+    pylab.grid()
+    
+    pylab.figure(3, facecolor='w', figsize=(8,7.5))
+    pylab.subplot(311)
+    pylab.plot(t, xr1)
+    pylab.axis([0, 4000, -0.6, 0.6])
+    pylab.ylabel('xhat1[i]')
+    pylab.title('Three smoothed sigals (fig. 6.10).')
+    
+    pylab.subplot(312)
+    pylab.plot(t, xr2)
+    pylab.ylabel('xhat2[i]')
+    pylab.axis([0, 4000, -0.6, 0.6])
+    
+    pylab.subplot(313)
+    pylab.plot(t, xr3)
+    pylab.axis([0, 4000, -0.6, 0.6])
+    pylab.ylabel('xhat3[i]')
+    pylab.xlabel('i')
+    pylab.show()
diff --git a/examples/book/chap6/tv.py b/examples/book/chap6/tv.py
index 5f25fc8..13862bd 100644
--- a/examples/book/chap6/tv.py
+++ b/examples/book/chap6/tv.py
@@ -4,27 +4,30 @@
 from math import pi
 from cvxopt import blas, lapack, solvers 
 from cvxopt import matrix, spmatrix, sin, mul, div, normal
-solvers.options['show_progress'] = 0
-import pylab
+#solvers.options['show_progress'] = 0
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 n = 2000
-t = matrix( range(n), tc='d' )
-ex = matrix( n/4*[1.0] + n/4*[-1.0] + n/4*[1.0] + n/4*[-1.0] ) + \
+t = matrix( list(range(n)), tc='d' )
+ex = matrix( n//4*[1.0] + n//4*[-1.0] + n//4*[1.0] + n//4*[-1.0] ) + \
     0.5 * sin( 2.0*pi/n * t )
 corr = ex + 0.1 * normal(n,1)
 
-pylab.figure(1, facecolor='w', figsize=(8,5))
-pylab.subplot(211)
-pylab.plot(t, ex)
-pylab.ylabel('x[i]')
-pylab.xlabel('i')
-pylab.axis([0, 2000, -2, 2])
-pylab.title('Original and corrupted signal (fig. 6.11)')
-pylab.subplot(212)
-pylab.plot(t, corr)
-pylab.ylabel('xcor[i]')
-pylab.xlabel('i')
-pylab.axis([0, 2000, -2, 2])
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(8,5))
+    pylab.subplot(211)
+    pylab.plot(t, ex)
+    pylab.ylabel('x[i]')
+    pylab.xlabel('i')
+    pylab.axis([0, 2000, -2, 2])
+    pylab.title('Original and corrupted signal (fig. 6.11)')
+    pylab.subplot(212)
+    pylab.plot(t, corr)
+    pylab.ylabel('xcor[i]')
+    pylab.xlabel('i')
+    pylab.axis([0, 2000, -2, 2])
 
 
 # Quadratic smoothing.
@@ -34,7 +37,7 @@ Ad = matrix([1.0] + (n-2)*[2.0] + [1.0])
 As = matrix(-1.0, (n-1,1))
 
 nopts = 100
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
+deltas = -10.0 + 20.0/(nopts-1) * matrix(list(range(nopts)))
 
 cost1, cost2 = [], []
 for delta in deltas:
@@ -54,37 +57,38 @@ mv3, k3 = min(zip([abs(c - 4.0) for c in cost1], range(nopts)))
 xr3 = +corr 
 lapack.ptsv(1.0 + 10**deltas[k3] * Ad, 10**deltas[k3] * As, xr3)
 
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'bo') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'bo', 
-    [cost1[k2]], [cost2[k2]], 'bo', [cost1[k3]], [cost2[k3]], 'bo')
-pylab.text(cost1[k1], cost2[k1], '1')
-pylab.text(cost1[k2], cost2[k2], '2')
-pylab.text(cost1[k3], cost2[k3], '3')
-pylab.title('Optimal trade-off curve (quadratic smoothing)')
-pylab.xlabel('|| xhat - xcor ||_2')
-pylab.ylabel('|| D*xhat ||_2')
-pylab.axis([-0.4, 50, -0.1, 8.0])
-pylab.grid()
-
-pylab.figure(3, facecolor='w', figsize=(8,7.5))
-pylab.subplot(311)
-pylab.plot(t, xr1)
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.ylabel('xhat1[i]')
-pylab.title('Three quadratically smoothed sigals (fig. 6.12).')
-pylab.subplot(312)
-pylab.plot(t, xr2)
-pylab.ylabel('xhat2[i]')
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.subplot(313)
-pylab.plot(t, xr3)
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.ylabel('xhat3[i]')
-pylab.xlabel('i')
-#print "Close figures to start total variation reconstruction."
-#pylab.show()
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
+    pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
+        [0], [blas.nrm2(corr[1:] - corr[:-1])], 'bo') 
+    pylab.plot([cost1[k1]], [cost2[k1]], 'bo', 
+        [cost1[k2]], [cost2[k2]], 'bo', [cost1[k3]], [cost2[k3]], 'bo')
+    pylab.text(cost1[k1], cost2[k1], '1')
+    pylab.text(cost1[k2], cost2[k2], '2')
+    pylab.text(cost1[k3], cost2[k3], '3')
+    pylab.title('Optimal trade-off curve (quadratic smoothing)')
+    pylab.xlabel('|| xhat - xcor ||_2')
+    pylab.ylabel('|| D*xhat ||_2')
+    pylab.axis([-0.4, 50, -0.1, 8.0])
+    pylab.grid()
+    
+    pylab.figure(3, facecolor='w', figsize=(8,7.5))
+    pylab.subplot(311)
+    pylab.plot(t, xr1)
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.ylabel('xhat1[i]')
+    pylab.title('Three quadratically smoothed sigals (fig. 6.12).')
+    pylab.subplot(312)
+    pylab.plot(t, xr2)
+    pylab.ylabel('xhat2[i]')
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.subplot(313)
+    pylab.plot(t, xr3)
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.ylabel('xhat3[i]')
+    pylab.xlabel('i')
+    #print "Close figures to start total variation reconstruction."
+    #pylab.show()
 
 
 # Total variation smoothing.
@@ -224,9 +228,9 @@ def tv(delta):
 
 
 nopts = 15
-deltas = -3.0 + (3.0-(-3.0))/(nopts-1) * matrix(range(nopts))
+deltas = -3.0 + (3.0-(-3.0))/(nopts-1) * matrix(list(range(nopts)))
 cost1, cost2 = [], []
-for delta, k in zip(deltas, xrange(nopts)):
+for delta, k in zip(deltas, range(nopts)):
     xtv = tv(10**delta)
     cost1 += [blas.nrm2(xtv - corr)] 
     cost2 += [blas.asum(xtv[1:] - xtv[:-1])] 
@@ -237,46 +241,47 @@ xtv2 = tv(10**deltas[k2])
 mv3, k3 = min(zip([abs(c - 5.0) for c in cost2], range(nopts)))
 xtv3 = tv(10**deltas[k3])
 
-pylab.figure(4, facecolor='w', figsize=(8,5))
-pylab.subplot(211)
-pylab.plot(t, ex)
-pylab.ylabel('x[i]')
-pylab.xlabel('i')
-pylab.axis([0, 2000, -2, 2])
-pylab.title('Original and corrupted signal (fig. 6.11)')
-pylab.subplot(212)
-pylab.plot(t, corr)
-pylab.ylabel('xcor[i]')
-pylab.xlabel('i')
-pylab.axis([0, 2000, -2, 2])
-
-pylab.figure(5, facecolor='w') #figsize=(8,7.5))
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
-        [0], [blas.asum(corr[1:] - corr[:-1])], 'bo') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'bo', [cost1[k2]], [cost2[k2]], 'bo',
-    [cost1[k3]], [cost2[k3]], 'bo')
-pylab.text(cost1[k1], cost2[k1],'1')
-pylab.text(cost1[k2], cost2[k2],'2')
-pylab.text(cost1[k3], cost2[k3],'3')
-pylab.grid()
-pylab.axis([-1, 50, -5, 250])
-pylab.xlabel('||xhat-xcor||_2')
-pylab.ylabel('||D*xhat||_1')
-pylab.title('Optimal trade-off curve (fig. 6.13)')
-
-pylab.figure(6, facecolor='w', figsize=(8,7.5))
-pylab.subplot(311)
-pylab.plot(t, xtv1)
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.ylabel('xhat1[i]')
-pylab.title('Three reconstructed signals (fig. 6.14)')
-pylab.subplot(312)
-pylab.plot(t, xtv2)
-pylab.ylabel('xhat2[i]')
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.subplot(313)
-pylab.plot(t, xtv3)
-pylab.axis([0, 2000, -2.0, 2.0])
-pylab.ylabel('xhat3[i]')
-pylab.xlabel('i')
-pylab.show()
+if pylab_installed:
+    pylab.figure(4, facecolor='w', figsize=(8,5))
+    pylab.subplot(211)
+    pylab.plot(t, ex)
+    pylab.ylabel('x[i]')
+    pylab.xlabel('i')
+    pylab.axis([0, 2000, -2, 2])
+    pylab.title('Original and corrupted signal (fig. 6.11)')
+    pylab.subplot(212)
+    pylab.plot(t, corr)
+    pylab.ylabel('xcor[i]')
+    pylab.xlabel('i')
+    pylab.axis([0, 2000, -2, 2])
+    
+    pylab.figure(5, facecolor='w') #figsize=(8,7.5))
+    pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'bo',
+            [0], [blas.asum(corr[1:] - corr[:-1])], 'bo') 
+    pylab.plot([cost1[k1]], [cost2[k1]], 'bo', [cost1[k2]], [cost2[k2]], 'bo',
+        [cost1[k3]], [cost2[k3]], 'bo')
+    pylab.text(cost1[k1], cost2[k1],'1')
+    pylab.text(cost1[k2], cost2[k2],'2')
+    pylab.text(cost1[k3], cost2[k3],'3')
+    pylab.grid()
+    pylab.axis([-1, 50, -5, 250])
+    pylab.xlabel('||xhat-xcor||_2')
+    pylab.ylabel('||D*xhat||_1')
+    pylab.title('Optimal trade-off curve (fig. 6.13)')
+    
+    pylab.figure(6, facecolor='w', figsize=(8,7.5))
+    pylab.subplot(311)
+    pylab.plot(t, xtv1)
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.ylabel('xhat1[i]')
+    pylab.title('Three reconstructed signals (fig. 6.14)')
+    pylab.subplot(312)
+    pylab.plot(t, xtv2)
+    pylab.ylabel('xhat2[i]')
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.subplot(313)
+    pylab.plot(t, xtv3)
+    pylab.axis([0, 2000, -2.0, 2.0])
+    pylab.ylabel('xhat3[i]')
+    pylab.xlabel('i')
+    pylab.show()
diff --git a/examples/book/chap7/chernoff.py b/examples/book/chap7/chernoff.py
index 8223449..8c0143a 100644
--- a/examples/book/chap7/chernoff.py
+++ b/examples/book/chap7/chernoff.py
@@ -1,9 +1,8 @@
 # Figure 7.8, page 384.
 # Chernoff lower bound.
 
-import pylab
 from cvxopt import matrix, mul, exp, normal, solvers, blas
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
 
 # Extreme points and inequality description of Voronoi region around 
 # first symbol (at the origin).
@@ -23,7 +22,7 @@ b = [ mul(A[0], V[:,:m].T) * matrix(1.0, (2,1)) ]
 # List of symbols.
 C = [ matrix(0.0, (2,1)) ] + \
     [ 2.0 * b[0][k] / blas.nrm2(A[0][k,:])**2 * A[0][k,:].T for k in 
-    xrange(m) ]
+    range(m) ]
 
 # Voronoi set around C[1]
 A += [ matrix(0.0, (3,2)) ] 
@@ -36,7 +35,7 @@ A[1][2,:] = (C[2] - C[1]).T
 b[1][2] = 0.5 * A[1][2,:] * ( C[2] + C[1] )
 
 # Voronoi set around C[2], ..., C[5]
-for k in xrange(2, 6):
+for k in range(2, 6):
     A += [ matrix(0.0, (3,2)) ] 
     b += [ matrix(0.0, (3,1)) ]
     A[k][0,:] = -A[0][k-1,:]
@@ -67,35 +66,38 @@ b[6][2] = 0.5 * A[6][2,:] * ( C[5] + C[6] )
 P = matrix([1.0, 0.0, 0.0, 1.0], (2,2))
 q = matrix(0.0, (2,1))
 optvals = matrix([ blas.nrm2( solvers.qp(P, q, A[k], b[k] )['x'] )**2
-    for k in xrange(1,7) ])
+    for k in range(1,7) ])
 nopts = 200
-sigmas = 0.2 + (0.5 - 0.2)/nopts * matrix(range(nopts), tc='d')
+sigmas = 0.2 + (0.5 - 0.2)/nopts * matrix(list(range(nopts)), tc='d')
 bnds = [ 1.0 - sum( exp( - optvals / (2*sigma**2) )) for sigma 
     in sigmas]
 
-pylab.figure(facecolor='w')
-pylab.plot(sigmas, bnds, '-')
-pylab.axis([0.2, 0.5, 0.9, 1.0])
-pylab.title('Chernoff lower bound (fig. 7.8)')
-pylab.xlabel('sigma')
-pylab.ylabel('Probability of correct detection')
-pylab.show()
-
-if 0:  # uncomment out for the Monte Carlo estimation.
-    N = 100000
-    mcest = []
-    ones = matrix(1.0, (1,m))
-    for sigma in sigmas: 
-        X = sigma * normal(2, N)
-        S = b[0][:,N*[0]] - A[0]*X 
-        S = ones * (S - abs(S))
-        mcest += [ N - len(filter(lambda x: x < 0.0, S)) ]
-
+try: import pylab
+except ImportError: pass
+else:
     pylab.figure(facecolor='w')
-    pylab.plot(sigmas, bnds, '-', sigmas, (1.0/N)*matrix(mcest), '--')
     pylab.plot(sigmas, bnds, '-')
     pylab.axis([0.2, 0.5, 0.9, 1.0])
     pylab.title('Chernoff lower bound (fig. 7.8)')
     pylab.xlabel('sigma')
     pylab.ylabel('Probability of correct detection')
     pylab.show()
+    
+    if 0:  # uncomment out for the Monte Carlo estimation.
+        N = 100000
+        mcest = []
+        ones = matrix(1.0, (1,m))
+        for sigma in sigmas: 
+            X = sigma * normal(2, N)
+            S = b[0][:,N*[0]] - A[0]*X 
+            S = ones * (S - abs(S))
+            mcest += [ N - len(filter(lambda x: x < 0.0, S)) ]
+    
+        pylab.figure(facecolor='w')
+        pylab.plot(sigmas, bnds, '-', sigmas, (1.0/N)*matrix(mcest), '--')
+        pylab.plot(sigmas, bnds, '-')
+        pylab.axis([0.2, 0.5, 0.9, 1.0])
+        pylab.title('Chernoff lower bound (fig. 7.8)')
+        pylab.xlabel('sigma')
+        pylab.ylabel('Probability of correct detection')
+        pylab.show()
diff --git a/examples/book/chap7/expdesign.py b/examples/book/chap7/expdesign.py
index fc7eeb9..960256a 100644
--- a/examples/book/chap7/expdesign.py
+++ b/examples/book/chap7/expdesign.py
@@ -2,10 +2,13 @@
 # Experiment design.
 
 from math import pi, log, sqrt
-import pylab
 from cvxopt import blas, lapack, solvers
 from cvxopt import matrix, spmatrix, spdiag, mul, cos, sin
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 V = matrix([-2.1213,    2.1213,
             -2.2981,    1.9284,
@@ -64,14 +67,15 @@ def F(x=None, z=None):
     return f, gradf, z[0] * H**2
 xd = solvers.cp(F, G, h, A = A, b = b)['x']
 
-pylab.figure(1, facecolor='w', figsize=(6,6)) 
-pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
-I = [ k for k in xrange(n) if xd[k] > 1e-5 ]
-pylab.plot(V[0,I], V[1,I],'or')
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(6,6)) 
+    pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
+    I = [ k for k in range(n) if xd[k] > 1e-5 ]
+    pylab.plot(V[0,I], V[1,I],'or')
 
 # Enclosing ellipse is  {x | x' * (V*diag(xe)*V')^-1 * x = sqrt(2)}
 nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
+angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
 circle = matrix(0.0, (2,nopts))
 circle[0,:], circle[1,:] = cos(angles), sin(angles)
 
@@ -79,10 +83,11 @@ W = V * spdiag(xd) * V.T
 lapack.potrf(W)
 ellipse = sqrt(2.0) * circle
 blas.trmm(W, ellipse)
-pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
-pylab.axis([-5, 5, -5, 5])
-pylab.title('D-optimal design (fig. 7.9)')
-pylab.axis('off')
+if pylab_installed:
+    pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
+    pylab.axis([-5, 5, -5, 5])
+    pylab.title('D-optimal design (fig. 7.9)')
+    pylab.axis('off')
 
 
 # E-design.
@@ -96,7 +101,7 @@ novars = n+1
 c = matrix(0.0, (novars,1))
 c[-1] = -1.0
 Gs = [matrix(0.0, (4,novars))]
-for k in xrange(n):  Gs[0][:,k] = -(V[:,k]*V[:,k].T)[:]
+for k in range(n):  Gs[0][:,k] = -(V[:,k]*V[:,k].T)[:]
 Gs[0][[0,3],-1] = 1.0
 hs = [matrix(0.0, (2,2))]
 Ge = matrix(0.0, (n, novars))
@@ -107,10 +112,11 @@ xe = sol['x'][:n]
 Z = sol['zs'][0]
 mu = sol['y'][0]
 
-pylab.figure(2, facecolor='w', figsize=(6,6)) 
-pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
-I = [ k for k in xrange(n) if xe[k] > 1e-5 ]
-pylab.plot(V[0,I], V[1,I],'or')
+if pylab_installed:
+    pylab.figure(2, facecolor='w', figsize=(6,6)) 
+    pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
+    I = [ k for k in range(n) if xe[k] > 1e-5 ]
+    pylab.plot(V[0,I], V[1,I],'or')
 
 # Enclosing ellipse follows from the solution of the dual problem:
 #
@@ -121,10 +127,11 @@ pylab.plot(V[0,I], V[1,I],'or')
 lapack.potrf(Z)
 ellipse = sqrt(mu) * circle
 blas.trsm(Z, ellipse, transA='T')
-pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
-pylab.axis([-5, 5, -5, 5])
-pylab.title('E-optimal design (fig. 7.10)')
-pylab.axis('off')
+if pylab_installed:
+    pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
+    pylab.axis([-5, 5, -5, 5])
+    pylab.title('E-optimal design (fig. 7.10)')
+    pylab.axis('off')
 
 
 # A-design.
@@ -143,7 +150,7 @@ novars = 3 + n
 c = matrix(0.0, (novars,1))
 c[[-3, -1]] = 1.0
 Gs = [matrix(0.0, (16, novars))]
-for k in xrange(n):
+for k in range(n):
     Gk = matrix(0.0, (4,4))
     Gk[:2,:2] = -V[:,k] * V[:,k].T
     Gs[0][:,k] = Gk[:]
@@ -161,10 +168,11 @@ xa = sol['x'][:n]
 Z = sol['zs'][0][:2,:2]
 mu = sol['y'][0]
 
-pylab.figure(3, facecolor='w', figsize = (6,6))
-pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
-I = [ k for k in xrange(n) if xa[k] > 1e-5 ]
-pylab.plot(V[0,I], V[1,I],'or')
+if pylab_installed:
+    pylab.figure(3, facecolor='w', figsize = (6,6))
+    pylab.plot(V[0,:], V[1,:],'ow', [0], [0], 'k+')
+    I = [ k for k in range(n) if xa[k] > 1e-5 ]
+    pylab.plot(V[0,I], V[1,I],'or')
 
 # Enclosing ellipse follows from the solution of the dual problem:
 #
@@ -176,8 +184,9 @@ pylab.plot(V[0,I], V[1,I],'or')
 lapack.potrf(Z)
 ellipse = sqrt(mu) * circle
 blas.trsm(Z, ellipse, transA='T')
-pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
-pylab.axis([-5, 5, -5, 5])
-pylab.title('A-optimal design (fig. 7.11)')
-pylab.axis('off')
-pylab.show()
+if pylab_installed:
+    pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k--')
+    pylab.axis([-5, 5, -5, 5])
+    pylab.title('A-optimal design (fig. 7.11)')
+    pylab.axis('off')
+    pylab.show()
diff --git a/examples/book/chap7/logreg.py b/examples/book/chap7/logreg.py
index 5af42f0..aab3753 100644
--- a/examples/book/chap7/logreg.py
+++ b/examples/book/chap7/logreg.py
@@ -1,11 +1,11 @@
 # Figures 7.1, page 355.
 # Logistic regression.
 
-import pylab, pickle
+import pickle
 from cvxopt import solvers, matrix, spdiag, log, exp, div
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
 
-data = pickle.load(open("logreg.bin"))
+data = pickle.load(open("logreg.bin", 'rb'))
 u, y = data['u'], data['y']
 
 # minimize   sum_{y_k = 1} (a*uk + b) + sum log (1 + exp(a*u + b))
@@ -32,13 +32,16 @@ def F(x=None, z=None):
 sol = solvers.cp(F)
 a, b = sol['x'][0], sol['x'][1]
 
-pylab.figure(facecolor='w')
-nopts = 200
-pts = -1.0 + 12.0/nopts * matrix(range(nopts)) 
-w = exp(a*pts + b)
-pylab.plot(u, y, 'o', pts, div(w, 1+w), '-')
-pylab.title('Logistic regression (fig. 7.1)')
-pylab.axis([-1, 11, -0.1, 1.1])
-pylab.xlabel('u')
-pylab.ylabel('Prob(y=1)')
-pylab.show()
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(facecolor='w')
+    nopts = 200
+    pts = -1.0 + 12.0/nopts * matrix(list(range(nopts))) 
+    w = exp(a*pts + b)
+    pylab.plot(u, y, 'o', pts, div(w, 1+w), '-')
+    pylab.title('Logistic regression (fig. 7.1)')
+    pylab.axis([-1, 11, -0.1, 1.1])
+    pylab.xlabel('u')
+    pylab.ylabel('Prob(y=1)')
+    pylab.show()
diff --git a/examples/book/chap7/maxent.py b/examples/book/chap7/maxent.py
index a5cfa73..7bd59a1 100644
--- a/examples/book/chap7/maxent.py
+++ b/examples/book/chap7/maxent.py
@@ -1,9 +1,8 @@
 # Figures 7.2 and 7.3, pages 363 and 364.
 # Maximum entropy distribution.
 
-import pylab
 from cvxopt import solvers, blas, matrix, spmatrix, spdiag, log, div
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
 
 # minimize     p'*log p  
 # subject to  -0.1 <= a'*p <= 0.1
@@ -16,8 +15,8 @@ solvers.options['show_progress'] = False
 # The variable is p (100).
 
 n = 100 
-a = -1.0 + (2.0/(n-1)) * matrix(range(n), (1,n))
-I = [k for k in xrange(n) if a[k] < 0]
+a = -1.0 + (2.0/(n-1)) * matrix(list(range(n)), (1,n))
+I = [k for k in range(n) if a[k] < 0]
 G = matrix([-a, a, -a**2, a**2, -(3 * a**3 - 2*a), (3 * a**3 - 2*a),
     matrix(0.0, (2,n))])
 G[6,I] = -1.0
@@ -66,27 +65,30 @@ GG[:n,:8] = -G.T
 GG[:n,8] = -A.T
 GG[n::n+9] = -1.0
 hh = matrix(0.0, (n+8,n))
-hh[:n,:] = matrix([i>=j for i in xrange(n) for j in xrange(n)], 
+hh[:n,:] = matrix([i>=j for i in range(n) for j in range(n)], 
     (n,n), 'd')  # upper triangular matrix of ones
-l = [-blas.dot(cc, solvers.lp(cc, GG, hh[:,k])['x']) for k in xrange(n)]
-u = [blas.dot(cc, solvers.lp(cc, GG, -hh[:,k])['x']) for k in xrange(n)]
+l = [-blas.dot(cc, solvers.lp(cc, GG, hh[:,k])['x']) for k in range(n)]
+u = [blas.dot(cc, solvers.lp(cc, GG, -hh[:,k])['x']) for k in range(n)]
 
 def f(x,y): return x+2*[y]
 def stepl(x): return reduce(f, x[1:], [x[0]])
 def stepr(x): return reduce(f, x[:-1], []) + [x[-1]]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(stepl(a), stepr(p), '-')
-pylab.title('Maximum entropy distribution (fig. 7.2)')
-pylab.xlabel('a')
-pylab.ylabel('p = Prob(X = a)')
-
-pylab.figure(2, facecolor='w')
-pylab.plot([-1.0] + stepl(a), [0.0] + stepr(hh[:n,:].T*p), '-', 
-    [-1.0] + stepl(a), [0.0] + stepr(l), 'r-', 
-    [-1.0] + stepl(a), [0.0] + stepr(u), 'r-')
-pylab.title('Cumulative distribution (fig. 7.3)')
-pylab.xlabel('a')
-pylab.ylabel('Prob(X <= a)')
-pylab.axis([-1.1, 1.1, -0.1, 1.1])
-pylab.show()
+try: import pylab
+except ImportError: pass
+else:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(stepl(a), stepr(p), '-')
+    pylab.title('Maximum entropy distribution (fig. 7.2)')
+    pylab.xlabel('a')
+    pylab.ylabel('p = Prob(X = a)')
+    
+    pylab.figure(2, facecolor='w')
+    pylab.plot([-1.0] + stepl(a), [0.0] + stepr(hh[:n,:].T*p), '-', 
+        [-1.0] + stepl(a), [0.0] + stepr(l), 'r-', 
+        [-1.0] + stepl(a), [0.0] + stepr(u), 'r-')
+    pylab.title('Cumulative distribution (fig. 7.3)')
+    pylab.xlabel('a')
+    pylab.ylabel('Prob(X <= a)')
+    pylab.axis([-1.1, 1.1, -0.1, 1.1])
+    pylab.show()
diff --git a/examples/book/chap7/probbounds.py b/examples/book/chap7/probbounds.py
index 00c3fa3..06f3504 100644
--- a/examples/book/chap7/probbounds.py
+++ b/examples/book/chap7/probbounds.py
@@ -1,10 +1,12 @@
 # Figures 7.6 and 7.7, page 383.
 # Chebyshev bounds.
 
-import pylab
 from math import pi, sqrt
 from cvxopt import matrix, spmatrix, mul, cos, sin, solvers, blas, lapack
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 # Extreme points and inequality description of Voronoi region around 
 # first symbol (0,0).
@@ -22,8 +24,7 @@ b0 = mul(A0, V[:,:m].T) * matrix(1.0, (2,1))
 
 # List of symbols.
 C = [ matrix(0.0, (2,1)) ] + \
-    [ 2.0 * b0[k] / blas.nrm2(A0[k,:])**2 * A0[k,:].T for k in 
-    xrange(m) ]
+    [ 2.0 * b0[k] / blas.nrm2(A0[k,:])**2 * A0[k,:].T for k in range(m) ]
 
 # Voronoi set around C[1]
 A1, b1 = matrix(0.0, (3,2)), matrix(0.0, (3,1))
@@ -68,10 +69,10 @@ def cheb(A, b, Sigma):
     c[0], c[1], c[2] = Sigma[0,0], 2*Sigma[1,0], Sigma[1,1]
     c[5] = 1.0
 
-    Gs = [ spmatrix([],[],[], (9,novars)) for k in xrange(m+1) ]
+    Gs = [ spmatrix([],[],[], (9,novars)) for k in range(m+1) ]
 
     # Coefficients of P, q, r in LMI constraints.
-    for k in xrange(m+1):
+    for k in range(m+1):
         Gs[k][0,0] = -1.0   # P[0,0]
         Gs[k][1,1] = -1.0   # P[1,0]
         Gs[k][4,2] = -1.0   # P[1,1]
@@ -79,12 +80,12 @@ def cheb(A, b, Sigma):
         Gs[k][5,4] = -1.0   # q[1]
         Gs[k][8,5] = -1.0   # r
     # Coefficients of tau.
-    for k in xrange(m):
+    for k in range(m):
         Gs[k][2, 6+k] = 0.5 * A[k,0]   
         Gs[k][5, 6+k] = 0.5 * A[k,1]   
         Gs[k][8, 6+k] = -b[k]   
     
-    hs = [ matrix(8*[0.0] + [-1.0], (3,3)) for k in xrange(m) ] + \
+    hs = [ matrix(8*[0.0] + [-1.0], (3,3)) for k in range(m) ] + \
         [ matrix(0.0, (3,3)) ]
 
     # Constraints tau >= 0.
@@ -113,89 +114,93 @@ L = +P
 lapack.posv(L, xc)
 L /= sqrt(1 - r - blas.dot(q, xc))
 
-def makefig1():
-    pylab.figure(1, facecolor='w', figsize=(6,6))
-    pylab.plot(V[0,:].T, V[1,:].T, 'b-')
-    nopts = 1000
-    angles = matrix( [a*2.0*pi/nopts for a in xrange(nopts) ], 
-        (1,nopts) )
-    circle = matrix(0.0, (2,nopts))
-    circle[0,:], circle[1,:] = cos(angles), sin(angles)
-    for k in xrange(len(C)):
-        c = C[k]
-        pylab.plot([c[0]], [c[1]], 'ow')
-        pylab.text(c[0], c[1], "s%d" %k)
-        pylab.plot(c[0] + circle[0,:].T, c[1]+circle[1,:].T, 'g:')
-        if k >= 1:
-            v = V[:,k-1]
-            if k==1: 
-                dir = 0.5 * (C[k] + C[-1]) - v
-            else: 
-                dir = 0.5 * (C[k] + C[k-1]) - v
-            pylab.plot([v[0], v[0] + 5*dir[0]], 
-                [v[1], v[1] + 5*dir[1]], 'b-')
-    ellipse = +circle
-    blas.trsm(L, ellipse, transA='T')
-    pylab.plot(xc[0] + ellipse[0,:].T, xc[1]+ellipse[1,:].T, 'r-')
-    for Xk in X: 
-        pylab.plot([Xk[0]], [Xk[1]], 'ro')
-
-    pylab.axis([-5, 5, -5, 5])
-    pylab.title('Geometrical interpretation of Chebyshev bound (fig. 7.7)')
-    pylab.axis('off')
-makefig1()
-#print "Close figure to continue." 
-#pylab.show()
+if pylab_installed:
+    def makefig1():
+        pylab.figure(1, facecolor='w', figsize=(6,6))
+        pylab.plot(V[0,:].T, V[1,:].T, 'b-')
+        nopts = 1000
+        angles = matrix( [a*2.0*pi/nopts for a in range(nopts) ], 
+            (1,nopts) )
+        circle = matrix(0.0, (2,nopts))
+        circle[0,:], circle[1,:] = cos(angles), sin(angles)
+        for k in range(len(C)):
+            c = C[k]
+            pylab.plot([c[0]], [c[1]], 'ow')
+            pylab.text(c[0], c[1], "s%d" %k)
+            pylab.plot(c[0] + circle[0,:].T, c[1]+circle[1,:].T, 'g:')
+            if k >= 1:
+                v = V[:,k-1]
+                if k==1: 
+                    dir = 0.5 * (C[k] + C[-1]) - v
+                else: 
+                    dir = 0.5 * (C[k] + C[k-1]) - v
+                pylab.plot([v[0], v[0] + 5*dir[0]], 
+                    [v[1], v[1] + 5*dir[1]], 'b-')
+        ellipse = +circle
+        blas.trsm(L, ellipse, transA='T')
+        pylab.plot(xc[0] + ellipse[0,:].T, xc[1]+ellipse[1,:].T, 'r-')
+        for Xk in X: 
+            pylab.plot([Xk[0]], [Xk[1]], 'ro')
+    
+        pylab.axis([-5, 5, -5, 5])
+        pylab.title('Geometrical interpretation of Chebyshev bound (fig. 7.7)')
+        pylab.axis('off')
+    makefig1()
+    #print("Close figure to continue.")
+    #pylab.show()
 
 
 # Compute bounds for s0 with sigma in [0,2.5]
 nosigmas = 150
-sigmas = 0.001 + (2.5 - 0.001) / nosigmas * matrix(range(nosigmas), 
+sigmas = 0.001 + (2.5 - 0.001) / nosigmas * matrix(list(range(nosigmas)), 
     tc='d')
 I = matrix([1.0, 0.0, 0.0, 1.0], (2,2))
-print "Computing lower bounds for symbol 0 ..."  
+print("Computing lower bounds for symbol 0 ...")
 bnds0 = [ cheb(A0, b0, sigma**2*I)[0] for sigma in sigmas ]
 
-pylab.figure(2,facecolor='w')
-pylab.plot(sigmas, bnds0)
-pylab.axis([0, 2.5, 0.0, 1.0])
-pylab.title('Chebyshev lower bounds (fig 7.6)')
-pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
-pylab.xlabel('sigma')
-pylab.ylabel('Probability of correct detection')
-#print "Close figure to continue."
-#pylab.show()
+if pylab_installed:
+    pylab.figure(2,facecolor='w')
+    pylab.plot(sigmas, bnds0)
+    pylab.axis([0, 2.5, 0.0, 1.0])
+    pylab.title('Chebyshev lower bounds (fig 7.6)')
+    pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
+    pylab.xlabel('sigma')
+    pylab.ylabel('Probability of correct detection')
+    #print("Close figure to continue.")
+    #pylab.show()
 
 # Bounds for s1.
 b1 -= A1*C[1]  # put s1 at the origin
-print "Computing lower bounds for symbol 1 ..." 
+print("Computing lower bounds for symbol 1 ...")
 bnds1 = [ cheb(A1, b1, sigma**2*I)[0] for sigma in sigmas ]
 
-pylab.figure(2,facecolor='w')
-pylab.plot(sigmas,bnds0, '-b', sigmas, bnds1, 'r')
-pylab.axis([0, 2.5, 0.0, 1.0])
-pylab.title('Chebyshev lower bounds (fig 7.6)')
-pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
-pylab.text(sigmas[nosigmas/2], bnds1[nosigmas/2], 's1')
-pylab.xlabel('sigma')
-pylab.ylabel('Probability of correct detection')
-#print "Close figure to continue."
-#pylab.show()
-
+if pylab_installed:
+    pylab.figure(2,facecolor='w')
+    pylab.plot(sigmas,bnds0, '-b', sigmas, bnds1, 'r')
+    pylab.axis([0, 2.5, 0.0, 1.0])
+    pylab.title('Chebyshev lower bounds (fig 7.6)')
+    pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
+    pylab.text(sigmas[nosigmas/2], bnds1[nosigmas/2], 's1')
+    pylab.xlabel('sigma')
+    pylab.ylabel('Probability of correct detection')
+    #print("Close figure to continue.")
+    #pylab.show()
+    
 # Bounds for s2.
 b2 -= A2*C[2]  # put s2 at the origin
-print "Computing lower bounds for symbol 2 ..." 
+print("Computing lower bounds for symbol 2 ...")
 bnds2 = [ cheb(A2, b2, sigma**2*I)[0] for sigma in sigmas ]
 
-makefig1()
-pylab.figure(2,facecolor='w')
-pylab.plot(sigmas,bnds0, '-b', sigmas, bnds1, 'r', sigmas, bnds2, 'g')
-pylab.axis([0, 2.5, 0.0, 1.0])
-pylab.title('Chebyshev lower bounds (fig 7.6)')
-pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
-pylab.text(sigmas[nosigmas/2], bnds1[nosigmas/2], 's1')
-pylab.text(sigmas[nosigmas/2], bnds2[nosigmas/2], 's2')
-pylab.xlabel('sigma')
-pylab.ylabel('Probability of correct detection')
-
-pylab.show()
+if pylab_installed:
+    makefig1()
+    pylab.figure(2,facecolor='w')
+    pylab.plot(sigmas,bnds0, '-b', sigmas, bnds1, 'r', sigmas, bnds2, 'g')
+    pylab.axis([0, 2.5, 0.0, 1.0])
+    pylab.title('Chebyshev lower bounds (fig 7.6)')
+    pylab.text(sigmas[nosigmas/2], bnds0[nosigmas/2], 's0')
+    pylab.text(sigmas[nosigmas/2], bnds1[nosigmas/2], 's1')
+    pylab.text(sigmas[nosigmas/2], bnds2[nosigmas/2], 's2')
+    pylab.xlabel('sigma')
+    pylab.ylabel('Probability of correct detection')
+
+    pylab.show()
diff --git a/examples/book/chap8/centers.py b/examples/book/chap8/centers.py
index 3008c11..68fe026 100644
--- a/examples/book/chap8/centers.py
+++ b/examples/book/chap8/centers.py
@@ -1,12 +1,14 @@
 # Figures 8.5-7, pages 417-421.
 # Centers of polyhedra.
  
-import pylab
 from math import log, pi
 from cvxopt import blas, lapack, solvers
 from cvxopt import matrix, spdiag, sqrt, mul, cos, sin, log
 from cvxopt.modeling import variable, op 
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 # Extreme points (with first one appended at the end)
 X = matrix([ 0.55,  0.25, -0.20, -0.25,  0.00,  0.40,  0.55,  
@@ -29,34 +31,35 @@ h = matrix(1.0, (m,1))
 
 R = variable()
 xc = variable(2)
-op(-R, [ G[k,:]*xc + R*blas.nrm2(G[k,:]) <= h[k] for k in xrange(m) ] + 
+op(-R, [ G[k,:]*xc + R*blas.nrm2(G[k,:]) <= h[k] for k in range(m) ] + 
     [ R >= 0] ).solve()
 R = R.value    
 xc = xc.value    
 
-pylab.figure(1, facecolor='w')
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
 
-# polyhedron
-for k in xrange(m):
-    edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
-        (X[2*[k],:] - X[2*[k+1],:])
-    pylab.plot(edge[:,0], edge[:,1], 'k')
+    # polyhedron
+    for k in range(m):
+        edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
+            (X[2*[k],:] - X[2*[k+1],:])
+        pylab.plot(edge[:,0], edge[:,1], 'k')
 
 
-# 1000 points on the unit circle
-nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
-circle = matrix(0.0, (2,nopts))
-circle[0,:], circle[1,:] = R*cos(angles), R*sin(angles)
-circle += xc[:,nopts*[0]]
-
-# plot maximum inscribed disk
-pylab.fill(circle[0,:].T, circle[1,:].T, facecolor = '#F0F0F0')
-pylab.plot([xc[0]], [xc[1]], 'ko')
-pylab.title('Chebyshev center (fig 8.5)')
-pylab.axis('equal')
-pylab.axis('off')
-
+    # 1000 points on the unit circle
+    nopts = 1000
+    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
+    circle = matrix(0.0, (2,nopts))
+    circle[0,:], circle[1,:] = R*cos(angles), R*sin(angles)
+    circle += xc[:,nopts*[0]]
+    
+    # plot maximum inscribed disk
+    pylab.fill(circle[0,:].T, circle[1,:].T, facecolor = '#F0F0F0')
+    pylab.plot([xc[0]], [xc[1]], 'ko')
+    pylab.title('Chebyshev center (fig 8.5)')
+    pylab.axis('equal')
+    pylab.axis('off')
+    
 
 # Maximum volume enclosed ellipsoid center
 #
@@ -81,8 +84,8 @@ pylab.axis('off')
 #
 # 5 variables x = (L[0,0], L[1,0], L[1,1], c[0], c[1])
 
-D = [ matrix(0.0, (3,5)) for k in xrange(m) ]
-for k in xrange(m):
+D = [ matrix(0.0, (3,5)) for k in range(m) ]
+for k in range(m):
     D[k][ [0, 3, 7, 11, 14] ] = matrix( [G[k,0], G[k,1], G[k,1], 
         -G[k,0], -G[k,1]] )
 d = [matrix([0.0, 0.0, hk]) for hk in h]
@@ -97,14 +100,14 @@ def F(x=None, z=None):
 
     f = matrix(0.0, (m+1,1))
     f[0] = -log(x[0]) - log(x[2])
-    for k in xrange(m):  
+    for k in range(m):  
         f[k+1] = y[k][:2].T * y[k][:2] / y[k][2] - y[k][2]
        
     Df = matrix(0.0, (m+1,5))
     Df[0,0], Df[0,2] = -1.0/x[0], -1.0/x[2]
 
     # gradient of g is ( 2.0*(u/t);  -(u/t)'*(u/t) -1) 
-    for k in xrange(m):
+    for k in range(m):
         a = y[k][:2] / y[k][2]
         gradg = matrix(0.0, (3,1))
         gradg[:2], gradg[2] = 2.0 * a, -a.T*a - 1
@@ -116,7 +119,7 @@ def F(x=None, z=None):
     H[2,2] = z[0] / x[2]**2
 
     # Hessian of g is (2.0/t) * [ I, -u/t;  -(u/t)',  (u/t)*(u/t)' ]
-    for k in xrange(m):
+    for k in range(m):
         a = y[k][:2] / y[k][2]
         hessg = matrix(0.0, (3,3))
         hessg[0,0], hessg[1,1] = 1.0, 1.0
@@ -130,30 +133,30 @@ sol = solvers.cp(F)
 L = matrix([sol['x'][0], sol['x'][1], 0.0, sol['x'][2]], (2,2))
 c = matrix([sol['x'][3], sol['x'][4]])
 
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
 
-pylab.figure(2, facecolor='w')
-
-# polyhedron
-for k in xrange(m):
-    edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
-        (X[2*[k],:] - X[2*[k+1],:])
-    pylab.plot(edge[:,0], edge[:,1], 'k')
-
-
-# 1000 points on the unit circle
-nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
-circle = matrix(0.0, (2,nopts))
-circle[0,:], circle[1,:] = cos(angles), sin(angles)
-
-# ellipse = L * circle + c
-ellipse = L * circle + c[:, nopts*[0]]
+    # polyhedron
+    for k in range(m):
+        edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
+            (X[2*[k],:] - X[2*[k+1],:])
+        pylab.plot(edge[:,0], edge[:,1], 'k')
 
-pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
-pylab.plot([c[0]], [c[1]], 'ko')
-pylab.title('Maximum volume inscribed ellipsoid center (fig 8.6)')
-pylab.axis('equal')
-pylab.axis('off')
+    
+    # 1000 points on the unit circle
+    nopts = 1000
+    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
+    circle = matrix(0.0, (2,nopts))
+    circle[0,:], circle[1,:] = cos(angles), sin(angles)
+    
+    # ellipse = L * circle + c
+    ellipse = L * circle + c[:, nopts*[0]]
+    
+    pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
+    pylab.plot([c[0]], [c[1]], 'ko')
+    pylab.title('Maximum volume inscribed ellipsoid center (fig 8.6)')
+    pylab.axis('equal')
+    pylab.axis('off')
 
 
 # Analytic center.
@@ -175,30 +178,31 @@ sol = solvers.cp(F)
 xac = sol['x']
 Hac = G.T * spdiag((h-G*xac)**-1) * G
 
-pylab.figure(3, facecolor='w')
-
-# polyhedron
-for k in xrange(m):
-    edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
-        (X[2*[k],:] - X[2*[k+1],:])
-    pylab.plot(edge[:,0], edge[:,1], 'k')
-
-
-# 1000 points on the unit circle
-nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
-circle = matrix(0.0, (2,nopts))
-circle[0,:], circle[1,:] = cos(angles), sin(angles)
-
-# ellipse = L^-T * circle + xc  where Hac = L*L'
-lapack.potrf(Hac)
-ellipse = +circle
-blas.trsm(Hac, ellipse, transA='T')
-ellipse += xac[:, nopts*[0]]
-pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
-pylab.plot([xac[0]], [xac[1]], 'ko')
-
-pylab.title('Analytic center (fig 8.7)')
-pylab.axis('equal')
-pylab.axis('off')
-pylab.show()
+if pylab_installed:
+    pylab.figure(3, facecolor='w')
+
+    # polyhedron
+    for k in range(m):
+        edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
+            (X[2*[k],:] - X[2*[k+1],:])
+        pylab.plot(edge[:,0], edge[:,1], 'k')
+    
+    
+    # 1000 points on the unit circle
+    nopts = 1000
+    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
+    circle = matrix(0.0, (2,nopts))
+    circle[0,:], circle[1,:] = cos(angles), sin(angles)
+    
+    # ellipse = L^-T * circle + xc  where Hac = L*L'
+    lapack.potrf(Hac)
+    ellipse = +circle
+    blas.trsm(Hac, ellipse, transA='T')
+    ellipse += xac[:, nopts*[0]]
+    pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
+    pylab.plot([xac[0]], [xac[1]], 'ko')
+    
+    pylab.title('Analytic center (fig 8.7)')
+    pylab.axis('equal')
+    pylab.axis('off')
+    pylab.show()
diff --git a/examples/book/chap8/ellipsoids.py b/examples/book/chap8/ellipsoids.py
index 96e5bc2..6b59d02 100644
--- a/examples/book/chap8/ellipsoids.py
+++ b/examples/book/chap8/ellipsoids.py
@@ -1,10 +1,12 @@
 # Figures 8.3 and 8.4, pages 412 and 416.
 # Ellipsoidal approximations.
  
-import pylab
 from math import log, pi
 from cvxopt import blas, lapack, solvers, matrix, sqrt, mul, cos, sin
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 # Extreme points (with first one appended at the end)
 X = matrix([ 0.55,  0.25, -0.20, -0.25,  0.00,  0.40,  0.55,  
@@ -47,7 +49,7 @@ def F(x=None, z=None):
     #    = (xk - c)' * A * (xk - c) - 1  where c = A^-1*b  
     c = x[3:]
     lapack.potrs(L, c)  
-    for k in xrange(m):
+    for k in range(m):
         f[k+1] = (X[k,:].T - c).T * A * (X[k,:].T - c) - 1.0 
 
     # gradf0 = (-A^-1, 0) = (-B, 0)
@@ -98,31 +100,32 @@ sol = solvers.cp(F)
 A = matrix( sol['x'][[0, 1, 1, 2]], (2,2)) 
 b = sol['x'][3:]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(X[:,0], X[:,1], 'ko', X[:,0], X[:,1], '-k')
-
-# Ellipsoid in the form { x | || L' * (x-c) ||_2 <= 1 }
-L = +A
-lapack.potrf(L)
-c = +b
-lapack.potrs(L, c)    
-
-# 1000 points on the unit circle
-nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
-circle = matrix(0.0, (2,nopts))
-circle[0,:], circle[1,:] = cos(angles), sin(angles)
-
-# ellipse = L^-T * circle + c
-blas.trsm(L, circle, transA='T')
-ellipse = circle + c[:, nopts*[0]]
-ellipse2 = 0.5 * circle + c[:, nopts*[0]]
-
-pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k-')
-pylab.fill(ellipse2[0,:].T, ellipse2[1,:].T, facecolor = '#F0F0F0')
-pylab.title('Loewner-John ellipsoid (fig 8.3)')
-pylab.axis('equal')
-pylab.axis('off')
+if pylab_installed:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(X[:,0], X[:,1], 'ko', X[:,0], X[:,1], '-k')
+    
+    # Ellipsoid in the form { x | || L' * (x-c) ||_2 <= 1 }
+    L = +A
+    lapack.potrf(L)
+    c = +b
+    lapack.potrs(L, c)    
+    
+    # 1000 points on the unit circle
+    nopts = 1000
+    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
+    circle = matrix(0.0, (2,nopts))
+    circle[0,:], circle[1,:] = cos(angles), sin(angles)
+    
+    # ellipse = L^-T * circle + c
+    blas.trsm(L, circle, transA='T')
+    ellipse = circle + c[:, nopts*[0]]
+    ellipse2 = 0.5 * circle + c[:, nopts*[0]]
+    
+    pylab.plot(ellipse[0,:].T, ellipse[1,:].T, 'k-')
+    pylab.fill(ellipse2[0,:].T, ellipse2[1,:].T, facecolor = '#F0F0F0')
+    pylab.title('Loewner-John ellipsoid (fig 8.3)')
+    pylab.axis('equal')
+    pylab.axis('off')
 
 
 # Maximum volume enclosed ellipsoid
@@ -148,8 +151,8 @@ pylab.axis('off')
 #
 # 5 variables x = (L[0,0], L[1,0], L[1,1], c[0], c[1])
 
-D = [ matrix(0.0, (3,5)) for k in xrange(m) ]
-for k in xrange(m):
+D = [ matrix(0.0, (3,5)) for k in range(m) ]
+for k in range(m):
     D[k][ [0, 3, 7, 11, 14] ] = matrix( [G[k,0], G[k,1], G[k,1], 
         -G[k,0], -G[k,1]] )
 d = [matrix([0.0, 0.0, hk]) for hk in h]
@@ -164,14 +167,14 @@ def F(x=None, z=None):
 
     f = matrix(0.0, (m+1,1))
     f[0] = -log(x[0]) - log(x[2])
-    for k in xrange(m):  
+    for k in range(m):  
         f[k+1] = y[k][:2].T * y[k][:2] / y[k][2] - y[k][2]
        
     Df = matrix(0.0, (m+1,5))
     Df[0,0], Df[0,2] = -1.0/x[0], -1.0/x[2]
 
     # gradient of g is ( 2.0*(u/t);  -(u/t)'*(u/t) -1) 
-    for k in xrange(m):
+    for k in range(m):
         a = y[k][:2] / y[k][2]
         gradg = matrix(0.0, (3,1))
         gradg[:2], gradg[2] = 2.0 * a, -a.T*a - 1
@@ -183,7 +186,7 @@ def F(x=None, z=None):
     H[2,2] = z[0] / x[2]**2
 
     # Hessian of g is (2.0/t) * [ I, -u/t;  -(u/t)',  (u/t)*(u/t)' ]
-    for k in xrange(m):
+    for k in range(m):
         a = y[k][:2] / y[k][2]
         hessg = matrix(0.0, (3,3))
         hessg[0,0], hessg[1,1] = 1.0, 1.0
@@ -197,29 +200,30 @@ sol = solvers.cp(F)
 L = matrix([sol['x'][0], sol['x'][1], 0.0, sol['x'][2]], (2,2))
 c = matrix([sol['x'][3], sol['x'][4]])
 
-pylab.figure(2, facecolor='w')
+if pylab_installed:
+    pylab.figure(2, facecolor='w')
 
-# polyhedron
-for k in xrange(m):
-    edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
-        (X[2*[k],:] - X[2*[k+1],:])
-    pylab.plot(edge[:,0], edge[:,1], 'k')
-
-
-# 1000 points on the unit circle
-nopts = 1000
-angles = matrix( [ a*2.0*pi/nopts for a in xrange(nopts) ], (1,nopts) )
-circle = matrix(0.0, (2,nopts))
-circle[0,:], circle[1,:] = cos(angles), sin(angles)
-
-# ellipse = L * circle + c
-ellipse = L * circle + c[:, nopts*[0]]
-ellipse2 = 2.0 * L * circle + c[:, nopts*[0]]
-
-pylab.plot(ellipse2[0,:].T, ellipse2[1,:].T, 'k-')
-pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
-pylab.title('Maximum volume inscribed ellipsoid (fig 8.4)')
-pylab.axis('equal')
-pylab.axis('off')
+    # polyhedron
+    for k in range(m):
+        edge = X[[k,k+1],:] + 0.1 * matrix([1., 0., 0., -1.], (2,2)) * \
+            (X[2*[k],:] - X[2*[k+1],:])
+        pylab.plot(edge[:,0], edge[:,1], 'k')
+    
+    
+    # 1000 points on the unit circle
+    nopts = 1000
+    angles = matrix( [ a*2.0*pi/nopts for a in range(nopts) ], (1,nopts) )
+    circle = matrix(0.0, (2,nopts))
+    circle[0,:], circle[1,:] = cos(angles), sin(angles)
+    
+    # ellipse = L * circle + c
+    ellipse = L * circle + c[:, nopts*[0]]
+    ellipse2 = 2.0 * L * circle + c[:, nopts*[0]]
+    
+    pylab.plot(ellipse2[0,:].T, ellipse2[1,:].T, 'k-')
+    pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
+    pylab.title('Maximum volume inscribed ellipsoid (fig 8.4)')
+    pylab.axis('equal')
+    pylab.axis('off')
 
-pylab.show()
+    pylab.show()
diff --git a/examples/book/chap8/floorplan.py b/examples/book/chap8/floorplan.py
index 3043173..3a44a2b 100644
--- a/examples/book/chap8/floorplan.py
+++ b/examples/book/chap8/floorplan.py
@@ -1,8 +1,10 @@
 # Figure 8.20, page 444.
 # Floor planning example.
 
-import pylab
 from cvxopt import solvers, matrix, spmatrix, mul, div
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
 def floorplan(Amin):
 
@@ -155,52 +157,60 @@ def floorplan(Amin):
     return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], \
         sol['x'][12:17], sol['x'][17:] 
 
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
 
-pylab.figure(facecolor='w')
+if pylab_installed: pylab.figure(facecolor='w')
 
-pylab.subplot(221)
 Amin = matrix([100., 100., 100., 100., 100.])
 W, H, x, y, w, h =  floorplan(Amin)
-for k in xrange(5):
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
-pylab.axis([-1.0, 26, -1.0, 26])
-pylab.xticks([])
-pylab.yticks([])
-
-pylab.subplot(222)
+if pylab_installed:
+    if pylab_installed: pylab.subplot(221)
+    for k in range(5):
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
+    pylab.axis([-1.0, 26, -1.0, 26])
+    pylab.xticks([])
+    pylab.yticks([])
+
 Amin = matrix([20., 50., 80., 150., 200.])
 W, H, x, y, w, h =  floorplan(Amin)
-for k in xrange(5):
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
-pylab.axis([-1.0, 26, -1.0, 26])
-pylab.xticks([])
-pylab.yticks([])
-
-pylab.subplot(223)
+if pylab_installed:
+    pylab.subplot(222)
+    for k in range(5):
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
+    pylab.axis([-1.0, 26, -1.0, 26])
+    pylab.xticks([])
+    pylab.yticks([])
+
 Amin = matrix([180., 80., 80., 80., 80.])
 W, H, x, y, w, h =  floorplan(Amin)
-for k in xrange(5):
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
-pylab.axis([-1.0, 26, -1.0, 26])
-pylab.xticks([])
-pylab.yticks([])
-
-pylab.subplot(224)
+if pylab_installed:
+    pylab.subplot(223)
+    for k in range(5):
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
+    pylab.axis([-1.0, 26, -1.0, 26])
+    pylab.xticks([])
+    pylab.yticks([])
+    
 Amin = matrix([20., 150., 20., 200., 110.])
 W, H, x, y, w, h =  floorplan(Amin)
-for k in xrange(5):
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
-pylab.axis([-1.0, 26, -1.0, 26])
-pylab.xticks([])
-pylab.yticks([])
-
-pylab.show()
+if pylab_installed:
+    pylab.subplot(224)
+    for k in range(5):
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]], 
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))
+    pylab.axis([-1.0, 26, -1.0, 26])
+    pylab.xticks([])
+    pylab.yticks([])
+
+    pylab.show()
diff --git a/examples/book/chap8/linsep.py b/examples/book/chap8/linsep.py
index f5c0c15..3315ea1 100644
--- a/examples/book/chap8/linsep.py
+++ b/examples/book/chap8/linsep.py
@@ -1,13 +1,16 @@
 # Figures 8.10-12, page 426-429.
 # Approximate linear discrimination.
 
-import pylab, pickle
+import pickle
 from cvxopt import solvers, matrix, spmatrix, spdiag, log, exp, div
 from cvxopt.blas import dot
 from cvxopt.modeling import variable, op
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+try: import pylab
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
-data = pickle.load(open("linsep.bin"))
+data = pickle.load(open("linsep.bin", 'rb'))
 X, Y = data['X'], data['Y']
 n, N, M = X.size[0], X.size[1], Y.size[1]
 
@@ -25,17 +28,18 @@ op( sum(u)+sum(v), [X.T*a-b >= 1-u,  Y.T*a-b <= -1+v,
 a = a.value
 b = b.value
 
-pylab.figure(1, facecolor='w', figsize=(5,5))
-pts = matrix([-10.0, 10.0], (2,1))
-pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
-    pts, (b - a[0]*pts)/a[1], '-r', 
-    pts, (b+1.0 - a[0]*pts)/a[1], '--r',
-    pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
-pylab.title('Separation via linear programming (fig. 8.10)')
-pylab.axis([-10, 10, -10, 10])
-pylab.axis('off')
-pylab.xticks([])
-pylab.yticks([])
+if pylab_installed:
+    pylab.figure(1, facecolor='w', figsize=(5,5))
+    pts = matrix([-10.0, 10.0], (2,1))
+    pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
+        pts, (b - a[0]*pts)/a[1], '-r', 
+        pts, (b+1.0 - a[0]*pts)/a[1], '--r',
+        pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
+    pylab.title('Separation via linear programming (fig. 8.10)')
+    pylab.axis([-10, 10, -10, 10])
+    pylab.axis('off')
+    pylab.xticks([])
+    pylab.yticks([])
 
 # Support vector classifier.
 #
@@ -81,19 +85,20 @@ sol = solvers.sdp(c, Gl, hl, Gs, hs)
 a = sol['x'][:2]
 b = sol['x'][2]
 
-pylab.figure(2, facecolor='w', figsize=(5,5))
-pts = matrix([-10.0, 10.0], (2,1))
-pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
-    pts, (b - a[0]*pts)/a[1], '-r', 
-    pts, (b+1.0 - a[0]*pts)/a[1], '--r',
-    pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
-pylab.title('Support vector classifier (fig. 8.11)')
-pylab.axis([-10, 10, -10, 10])
-pylab.xticks([])
-pylab.yticks([])
-pylab.axis('off')
-
-
+if pylab_installed:
+    pylab.figure(2, facecolor='w', figsize=(5,5))
+    pts = matrix([-10.0, 10.0], (2,1))
+    pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
+        pts, (b - a[0]*pts)/a[1], '-r', 
+        pts, (b+1.0 - a[0]*pts)/a[1], '--r',
+        pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
+    pylab.title('Support vector classifier (fig. 8.11)')
+    pylab.axis([-10, 10, -10, 10])
+    pylab.xticks([])
+    pylab.yticks([])
+    pylab.axis('off')
+    
+    
 # Via logistic modeling.
 #
 # minimize -sum(X'*a - b) + sum log (1 + exp([X';Y']*a - b))
@@ -116,16 +121,17 @@ def F(x=None, z=None):
 sol = solvers.cp(F)
 a, b = sol['x'][:2],  sol['x'][2]
 
-pylab.figure(3, facecolor='w', figsize=(5,5))
-pts = matrix([-10.0, 10.0], (2,1))
-pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
-    pts, (b - a[0]*pts)/a[1], '-r', 
-    pts, (b+1.0 - a[0]*pts)/a[1], '--r',
-    pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
-pylab.title('Separation via logistic modeling (fig. 8.12)')
-pylab.axis([-10, 10, -10, 10])
-pylab.xticks([])
-pylab.yticks([])
-pylab.axis('off')
-
-pylab.show()
+if pylab_installed:
+    pylab.figure(3, facecolor='w', figsize=(5,5))
+    pts = matrix([-10.0, 10.0], (2,1))
+    pylab.plot(X[0,:], X[1,:], 'ow', Y[0,:], Y[1,:], 'ok',
+        pts, (b - a[0]*pts)/a[1], '-r', 
+        pts, (b+1.0 - a[0]*pts)/a[1], '--r',
+        pts, (b-1.0 - a[0]*pts)/a[1], '--r' )
+    pylab.title('Separation via logistic modeling (fig. 8.12)')
+    pylab.axis([-10, 10, -10, 10])
+    pylab.xticks([])
+    pylab.yticks([])
+    pylab.axis('off')
+    
+    pylab.show()
diff --git a/examples/book/chap8/placement.py b/examples/book/chap8/placement.py
index 04241fb..bb3c650 100644
--- a/examples/book/chap8/placement.py
+++ b/examples/book/chap8/placement.py
@@ -3,12 +3,15 @@
 #
 # The problem data are different from the example in the book.
 
-import pylab, numpy, pickle
+import pickle
 from cvxopt import lapack, solvers, matrix, spmatrix, sqrt, mul
 from cvxopt.modeling import variable, op
-solvers.options['show_progress'] = False
+#solvers.options['show_progress'] = False
+try: import pylab, numpy
+except ImportError: pylab_installed = False
+else: pylab_installed = True
 
-data = pickle.load(open("placement.bin", "r"))
+data = pickle.load(open("placement.bin", "rb"))
 Xf = data['X']  # M by n matrix with coordinates of M fixed nodes
 M = Xf.size[0]  
 E = data['E']   # list of edges 
@@ -17,7 +20,7 @@ N = max(max(e) for e in E) + 1 - M  # number of free nodes; fixed nodes
                                     # have the highest M indices.
 # arc-node incidence matrix
 A = matrix(0.0, (L,M+N))
-for k in xrange(L):  A[k, E[k]] = matrix([1.0, -1.0], (1,2))
+for k in range(L):  A[k, E[k]] = matrix([1.0, -1.0], (1,2))
 
 
 # minimize sum h( sqrt( (A1*X[:,0] + B[:,0])**2 + 
@@ -40,15 +43,15 @@ B = A[:,N:]*Xf
 novars = L + 2*N
 c = matrix(0.0, (novars,1))
 c[:L] = 1.0
-G = [ spmatrix([], [], [], (9, novars)) for k in xrange(L) ]
-h = [ matrix(0.0, (3,3)) for k in xrange(L) ]
-for k in xrange(L):
+G = [ spmatrix([], [], [], (9, novars)) for k in range(L) ]
+h = [ matrix(0.0, (3,3)) for k in range(L) ]
+for k in range(L):
 
     # coefficient of tk
     C = spmatrix(-1.0, [0,1,2], [0,1,2])
     G[k][C.I + 3*C.J, k] = C.V
 
-    for j in xrange(N):
+    for j in range(N):
         # coefficient of x[j]
         C = spmatrix(-A[k,j], [2, 0], [0, 2])
         G[k][C.I + 3*C.J, L+j] = C.V
@@ -101,7 +104,7 @@ def F(x=None, z=None):
     g = gradg.T * AA
     if z is None: return f, g
     H = matrix(0.0, (2*L, 2*L))
-    for k in xrange(L):
+    for k in range(L):
         H[k,k], H[k+L,k+L] = 4*d[k], 4*d[k]
         H[[k,k+L], [k,k+L]] += 8 * y[[k,k+L]] * y[[k,k+L]].T 
     return f, g, AA.T*H*AA
@@ -110,64 +113,65 @@ sol = solvers.cp(F)
 X4 = matrix(sol['x'], (N,2))
 
 
-# Figures for linear placement.
-
-pylab.figure(1, figsize=(10,4), facecolor='w')
-pylab.subplot(121) 
-X = matrix(0.0, (N+M,2))
-X[:N,:], X[N:,:] = X1, Xf
-pylab.plot(Xf[:,0], Xf[:,1], 'sw', X1[:,0], X1[:,1], 'or', ms=10)
-for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
-pylab.axis([-1.1, 1.1, -1.1, 1.1])
-pylab.axis('equal')
-pylab.title('Linear placement')
-
-pylab.subplot(122) 
-lngths = sqrt((A1*X1 + B)**2 * matrix(1.0, (2,1)))
-pylab.hist(lngths, numpy.array([.1*k for k in xrange(15)]))
-x = pylab.arange(0, 1.6, 1.6/500)
-pylab.plot( x, 5.0/1.6*x, '--k')
-pylab.axis([0, 1.6, 0, 5.5])
-pylab.title('Length distribution')
-
-
-# Figures for quadratic placement.
-
-pylab.figure(2, figsize=(10,4), facecolor='w')
-pylab.subplot(121) 
-X[:N,:], X[N:,:] = X2, Xf
-pylab.plot(Xf[:,0], Xf[:,1], 'sw', X2[:,0], X2[:,1], 'or', ms=10)
-for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
-pylab.axis([-1.1, 1.1, -1.1, 1.1])
-pylab.axis('equal')
-pylab.title('Quadratic placement')
-
-pylab.subplot(122) 
-lngths = sqrt((A1*X2 + B)**2 * matrix(1.0, (2,1)))
-pylab.hist(lngths, numpy.array([.1*k for k in xrange(15)]))
-x = pylab.arange(0, 1.5, 1.5/500)
-pylab.plot( x, 5.0/1.5**2 * x**2, '--k')
-pylab.axis([0, 1.5, 0, 5.5])
-pylab.title('Length distribution')
-
-
-# Figures for fourth order placement.
-
-pylab.figure(3, figsize=(10,4), facecolor='w')
-pylab.subplot(121) 
-X[:N,:], X[N:,:] = X4, Xf
-pylab.plot(Xf[:,0], Xf[:,1], 'sw', X4[:,0], X4[:,1], 'or', ms=10)
-for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
-pylab.axis([-1.1, 1.1, -1.1, 1.1])
-pylab.axis('equal')
-pylab.title('Fourth order placement')
-
-pylab.subplot(122) 
-lngths = sqrt((A1*X4 + B)**2 * matrix(1.0, (2,1)))
-pylab.hist(lngths, numpy.array([.1*k for k in xrange(15)]))
-x = pylab.arange(0, 1.5, 1.5/500)
-pylab.plot( x, 6.0/1.4**4 * x**4, '--k')
-pylab.axis([0, 1.4, 0, 6.5])
-pylab.title('Length distribution')
-
-pylab.show()
+if pylab_installed:
+    # Figures for linear placement.
+
+    pylab.figure(1, figsize=(10,4), facecolor='w')
+    pylab.subplot(121) 
+    X = matrix(0.0, (N+M,2))
+    X[:N,:], X[N:,:] = X1, Xf
+    pylab.plot(Xf[:,0], Xf[:,1], 'sw', X1[:,0], X1[:,1], 'or', ms=10)
+    for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
+    pylab.axis([-1.1, 1.1, -1.1, 1.1])
+    pylab.axis('equal')
+    pylab.title('Linear placement')
+    
+    pylab.subplot(122) 
+    lngths = sqrt((A1*X1 + B)**2 * matrix(1.0, (2,1)))
+    pylab.hist(lngths, numpy.array([.1*k for k in range(15)]))
+    x = pylab.arange(0, 1.6, 1.6/500)
+    pylab.plot( x, 5.0/1.6*x, '--k')
+    pylab.axis([0, 1.6, 0, 5.5])
+    pylab.title('Length distribution')
+    
+    
+    # Figures for quadratic placement.
+    
+    pylab.figure(2, figsize=(10,4), facecolor='w')
+    pylab.subplot(121) 
+    X[:N,:], X[N:,:] = X2, Xf
+    pylab.plot(Xf[:,0], Xf[:,1], 'sw', X2[:,0], X2[:,1], 'or', ms=10)
+    for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
+    pylab.axis([-1.1, 1.1, -1.1, 1.1])
+    pylab.axis('equal')
+    pylab.title('Quadratic placement')
+    
+    pylab.subplot(122) 
+    lngths = sqrt((A1*X2 + B)**2 * matrix(1.0, (2,1)))
+    pylab.hist(lngths, numpy.array([.1*k for k in range(15)]))
+    x = pylab.arange(0, 1.5, 1.5/500)
+    pylab.plot( x, 5.0/1.5**2 * x**2, '--k')
+    pylab.axis([0, 1.5, 0, 5.5])
+    pylab.title('Length distribution')
+    
+    
+    # Figures for fourth order placement.
+    
+    pylab.figure(3, figsize=(10,4), facecolor='w')
+    pylab.subplot(121) 
+    X[:N,:], X[N:,:] = X4, Xf
+    pylab.plot(Xf[:,0], Xf[:,1], 'sw', X4[:,0], X4[:,1], 'or', ms=10)
+    for s, t in E:  pylab.plot([X[s,0], X[t,0]], [X[s,1],X[t,1]], 'b:')
+    pylab.axis([-1.1, 1.1, -1.1, 1.1])
+    pylab.axis('equal')
+    pylab.title('Fourth order placement')
+    
+    pylab.subplot(122) 
+    lngths = sqrt((A1*X4 + B)**2 * matrix(1.0, (2,1)))
+    pylab.hist(lngths, numpy.array([.1*k for k in range(15)]))
+    x = pylab.arange(0, 1.5, 1.5/500)
+    pylab.plot( x, 6.0/1.4**4 * x**4, '--k')
+    pylab.axis([0, 1.4, 0, 6.5])
+    pylab.title('Length distribution')
+    
+    pylab.show()
diff --git a/examples/doc/chap10/l1svc.py b/examples/doc/chap10/l1svc.py
index df0fcd2..9199dfd 100644
--- a/examples/doc/chap10/l1svc.py
+++ b/examples/doc/chap10/l1svc.py
@@ -14,4 +14,4 @@ op(sum(abs(x)) + sum(u), [A*x >= 1-u, u >= 0]).solve()
 x2 = variable(A.size[1],'x')  
 op(sum(abs(x2)) + sum(max(0, 1 - A*x2))).solve() 
 
-print "\nDifference between two solutions: %e" %nrm2(x.value - x2.value)
+print("\nDifference between two solutions: %e" %nrm2(x.value - x2.value))
diff --git a/examples/doc/chap10/lp.py b/examples/doc/chap10/lp.py
index 8226346..ff2fd7c 100644
--- a/examples/doc/chap10/lp.py
+++ b/examples/doc/chap10/lp.py
@@ -11,14 +11,14 @@ c3 = ( x >= 0 )
 c4 = ( y >= 0 )  
 lp1 = op(-4*x-5*y, [c1,c2,c3,c4])  
 lp1.solve()  
-print "\nstatus: %s" %lp1.status  
-print "optimal value: %f"  %lp1.objective.value()[0]
-print "optimal x: %f" %x.value[0]  
-print "optimal y: %f" %y.value[0]  
-print "optimal multiplier for 1st constraint: %f" %c1.multiplier.value[0] 
-print "optimal multiplier for 2nd constraint: %f" %c2.multiplier.value[0] 
-print "optimal multiplier for 3rd constraint: %f" %c3.multiplier.value[0]
-print "optimal multiplier for 4th constraint: %f\n" %c4.multiplier.value[0]
+print("\nstatus: %s" %lp1.status) 
+print("optimal value: %f"  %lp1.objective.value()[0])
+print("optimal x: %f" %x.value[0])
+print("optimal y: %f" %y.value[0])  
+print("optimal multiplier for 1st constraint: %f" %c1.multiplier.value[0])
+print("optimal multiplier for 2nd constraint: %f" %c2.multiplier.value[0])
+print("optimal multiplier for 3rd constraint: %f" %c3.multiplier.value[0])
+print("optimal multiplier for 4th constraint: %f\n" %c4.multiplier.value[0])
 
 x = variable(2)  
 A = matrix([[2.,1.,-1.,0.], [1.,2.,0.,-1.]])  
@@ -28,7 +28,9 @@ ineq = ( A*x <= b )
 lp2 = op(dot(c,x), ineq)  
 lp2.solve()  
 
-print "\nstatus: %s" %lp2.status  
-print "optimal value: %f"  %lp2.objective.value()[0]
-print "optimal x: \n", x.value  
-print "optimal multiplier: \n", ineq.multiplier.value  
+print("\nstatus: %s" %lp2.status)  
+print("optimal value: %f"  %lp2.objective.value()[0])
+print("optimal x: \n") 
+print(x.value) 
+print("optimal multiplier: \n") 
+print(ineq.multiplier.value)
diff --git a/examples/doc/chap10/roblp.py b/examples/doc/chap10/roblp.py
index 8ba724a..7ac7589 100644
--- a/examples/doc/chap10/roblp.py
+++ b/examples/doc/chap10/roblp.py
@@ -16,4 +16,4 @@ x2 = variable(n)
 y = variable(n)  
 op(dot(c,x2), [A*x2+sum(y) <= b, -y <= x2, x2 <= y]).solve()
 
-print "\nDifference between two solutions %e" %nrm2(x.value - x2.value)
+print("\nDifference between two solutions %e" %nrm2(x.value - x2.value))
diff --git a/examples/doc/chap4/acent b/examples/doc/chap4/acent
deleted file mode 100755
index af02707..0000000
--- a/examples/doc/chap4/acent
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/python
-
-# The analytic centering example at the end of chapter 4 (The LAPACK 
-# interface).
-
-from cvxopt import matrix, log, mul, div, blas, lapack, base
-from math import sqrt
-
-def acent(A,b):
-    """  
-    Computes analytic center of A*x <= b with A m by n of rank n. 
-    We assume that b > 0 and the feasible set is bounded.
-    """
-
-    MAXITERS = 100
-    ALPHA = 0.01
-    BETA = 0.5
-    TOL = 1e-8
-
-    ntdecrs = []
-    m, n = A.size
-    x = matrix(0.0, (n,1))
-    H = matrix(0.0, (n,n))
-
-    for iter in xrange(MAXITERS):
-        
-        # Gradient is g = A^T * (1./(b-A*x)).
-        d = (b-A*x)**-1
-        g = A.T * d
-
-        # Hessian is H = A^T * diag(1./(b-A*x))^2 * A.
-        Asc = mul( d[:,n*[0]], A)
-        blas.syrk(Asc, H, trans='T')
-
-        # Newton step is v = H^-1 * g.
-        v = -g
-        lapack.posv(H, v)
-
-        # Directional derivative and Newton decrement.
-	lam = blas.dot(g, v)
-        ntdecrs += [ sqrt(-lam) ]
-        print "%2d.  Newton decr. = %3.3e" %(iter,ntdecrs[-1])
-        if ntdecrs[-1] < TOL: return x, ntdecrs
-
-        # Backtracking line search.
-        y = mul(A*v, d)
-	step = 1.0
-        while 1-step*max(y) < 0: step *= BETA 
-	while True:
-            if -sum(log(1-step*y)) < ALPHA*step*lam: break
-	    step *= BETA
-        x += step*v
-
-
-# Generate an analytic centering problem  
-#
-#    -b1 <=  Ar*x <= b2 
-#
-# with random mxn Ar and random b1, b2.
-
-m, n  = 500, 500
-Ar = base.normal(m,n);
-A = matrix([Ar, -Ar])
-b = base.uniform(2*m,1)
-
-x, ntdecrs = acent(A, b)  
-try: 
-    import pylab
-except ImportError: 
-    pass
-else:
-    pylab.semilogy(range(len(ntdecrs)), ntdecrs, 'o', 
-             range(len(ntdecrs)), ntdecrs, '-')
-    pylab.xlabel('Iteration number')
-    pylab.ylabel('Newton decrement')
-    pylab.show()
diff --git a/examples/doc/chap4/acent.py b/examples/doc/chap4/acent.py
index 81c09da..e24bf55 100644
--- a/examples/doc/chap4/acent.py
+++ b/examples/doc/chap4/acent.py
@@ -20,7 +20,7 @@ def acent(A,b):
     x = matrix(0.0, (n,1))
     H = matrix(0.0, (n,n))
 
-    for iter in xrange(MAXITERS):
+    for iter in range(MAXITERS):
         
         # Gradient is g = A^T * (1./(b-A*x)).
         d = (b-A*x)**-1
@@ -35,18 +35,18 @@ def acent(A,b):
         lapack.posv(H, v)
 
         # Directional derivative and Newton decrement.
-	lam = blas.dot(g, v)
+        lam = blas.dot(g, v)
         ntdecrs += [ sqrt(-lam) ]
-        print "%2d.  Newton decr. = %3.3e" %(iter,ntdecrs[-1])
+        print("%2d.  Newton decr. = %3.3e" %(iter,ntdecrs[-1]))
         if ntdecrs[-1] < TOL: return x, ntdecrs
 
         # Backtracking line search.
         y = mul(A*v, d)
-	step = 1.0
+        step = 1.0
         while 1-step*max(y) < 0: step *= BETA 
-	while True:
+        while True:
             if -sum(log(1-step*y)) < ALPHA*step*lam: break
-	    step *= BETA
+            step *= BETA
         x += step*v
 
 
diff --git a/examples/doc/chap7/covsel.py b/examples/doc/chap7/covsel.py
index eb0b47c..dd14387 100644
--- a/examples/doc/chap7/covsel.py
+++ b/examples/doc/chap7/covsel.py
@@ -8,7 +8,7 @@ def covsel(Y):
     """
     Returns the solution of
  
-        minimize    -logdet K + tr(KY)
+        minimize    -log det K + tr(KY)
         subject to  K_ij = 0  if (i,j) not in zip(I, J).
 
     Y is a symmetric sparse matrix with nonzero diagonal elements.
@@ -22,7 +22,7 @@ def covsel(Y):
     # non-zero positions for one-argument indexing 
     N = I + J*n         
     # position of diagonal elements
-    D = [ k for k in xrange(m) if I[k]==J[k] ]  
+    D = [ k for k in range(m) if I[k]==J[k] ]  
 
     # starting point: symmetric identity with nonzero pattern I,J
     K = spmatrix(0.0, I, J) 
@@ -37,7 +37,7 @@ def covsel(Y):
     # Kinv will be the inverse of K
     Kinv = matrix(0.0, (n,n))
 
-    for iters in xrange(100):
+    for iters in range(100):
 
         # numeric factorization of K
         cholmod.numeric(K, F)
@@ -57,9 +57,9 @@ def covsel(Y):
                                                   
         # stopping criterion
         sqntdecr = -blas.dot(grad,v) 
-        print "Newton decrement squared:%- 7.5e" %sqntdecr
+        print("Newton decrement squared:%- 7.5e" %sqntdecr)
         if (sqntdecr < 1e-12):
-            print "number of iterations: ", iters+1 
+            print("number of iterations: %d" %(iters+1))
             break
 
         # line search
@@ -67,7 +67,7 @@ def covsel(Y):
         dx[D] *= 2      
         f = -2.0*sum(log(d))      # f = -log det K
         s = 1
-        for lsiter in xrange(50):
+        for lsiter in range(50):
             Kn.V = K.V + s*dx
             try: 
                 cholmod.numeric(Kn, F)
@@ -83,6 +83,6 @@ def covsel(Y):
 
     return K
 
-Y = load(open("covsel.bin","r"))
-print "%d rows/columns, %d nonzeros\n" %(Y.size[0], len(Y))
+Y = load(open("covsel.bin","rb"))
+print("%d rows/columns, %d nonzeros\n" %(Y.size[0], len(Y)))
 covsel(Y)
diff --git a/examples/doc/chap8/conelp.py b/examples/doc/chap8/conelp.py
index 8c26078..f7265be 100644
--- a/examples/doc/chap8/conelp.py
+++ b/examples/doc/chap8/conelp.py
@@ -13,6 +13,8 @@ h = matrix( [ -3., 5.,  12.,  -2., -14., -13., 10.,  0.,  0.,  0.,  68.,
     -30., -19., -30.,  99.,  23., -19.,   23.,  10.] )
 dims = {'l': 2, 'q': [4, 4], 's': [3]}
 sol = solvers.conelp(c, G, h, dims)
-print "\nStatus:", sol['status']
-print "\nx =\n\n", sol['x']
-print "\nz =\n\n", sol['z']
+print("\nStatus: " + sol['status'])
+print("\nx = \n") 
+print(sol['x'])
+print("\nz = \n")
+print(sol['z'])
diff --git a/examples/doc/chap8/coneqp.py b/examples/doc/chap8/coneqp.py
index 6e4a234..0066be8 100644
--- a/examples/doc/chap8/coneqp.py
+++ b/examples/doc/chap8/coneqp.py
@@ -17,4 +17,5 @@ G = matrix([-I, matrix(0.0, (1,n)), I])
 h = matrix(n*[0.0] + [1.0] + n*[0.0])
 dims = {'l': n, 'q': [n+1], 's': []}
 x = solvers.coneqp(A.T*A, -A.T*b, G, h, dims)['x']
-print "\nx = \n\n", x
+print("\nx = \n")
+print(x)
diff --git a/examples/doc/chap8/lp.py b/examples/doc/chap8/lp.py
index 5a0e0a4..5b95155 100644
--- a/examples/doc/chap8/lp.py
+++ b/examples/doc/chap8/lp.py
@@ -5,4 +5,5 @@ c = matrix([-4., -5.])
 G = matrix([[2., 1., -1., 0.], [1., 2., 0., -1.]])  
 h = matrix([3., 3., 0., 0.])  
 sol = solvers.lp(c, G, h)  
-print "\nx = \n\n", sol['x']  
+print("\nx = \n")
+print(sol['x'])
diff --git a/examples/doc/chap8/mcsdp.py b/examples/doc/chap8/mcsdp.py
index 6612ccc..44470a6 100644
--- a/examples/doc/chap8/mcsdp.py
+++ b/examples/doc/chap8/mcsdp.py
@@ -20,22 +20,22 @@ def mcsdp(w):
         """
             y := alpha*(-diag(x)) + beta*y.   
         """
-	if trans=='N':
+        if trans=='N':
             # x is a vector; y is a matrix.
-	    blas.scal(beta, y)
-	    blas.axpy(x, y, alpha = -alpha, incy = n+1)
+            blas.scal(beta, y)
+            blas.axpy(x, y, alpha = -alpha, incy = n+1)
 
-	else:   
+        else:   
             # x is a matrix; y is a vector.
-	    blas.scal(beta, y)
-	    blas.axpy(x, y, alpha = -alpha, incx = n+1)
+            blas.scal(beta, y)
+            blas.axpy(x, y, alpha = -alpha, incx = n+1)
 	 
 
     def cngrnc(r, x, alpha = 1.0):
         """
         Congruence transformation
 
-	    x := alpha * r'*x*r.
+            x := alpha * r'*x*r.
 
         r and x are square matrices.  
         """
@@ -59,13 +59,13 @@ def mcsdp(w):
 
         # t = rti*rti' as a nonsymmetric matrix.
         t = matrix(0.0, (n,n))
-	blas.gemm(rti, rti, t, transB = 'T') 
+        blas.gemm(rti, rti, t, transB = 'T') 
 
-	# Cholesky factorization of tsq = t.*t.
+        # Cholesky factorization of tsq = t.*t.
         tsq = t**2
-	lapack.potrf(tsq)
+        lapack.potrf(tsq)
 
-	def f(x, y, z):
+        def f(x, y, z):
             """
             Solve
                           -diag(z)                           = bx
@@ -98,7 +98,7 @@ def mcsdp(w):
             # z := -rti' * z * rti = -rti' * (diag(x) + bs) * rti 
             cngrnc(rti, z, alpha = -1.0)
 
-	return f
+        return f
 
     c = matrix(1.0, (n,1))
 
diff --git a/examples/doc/chap8/portfolio.py b/examples/doc/chap8/portfolio.py
index a65d74f..3ba219c 100644
--- a/examples/doc/chap8/portfolio.py
+++ b/examples/doc/chap8/portfolio.py
@@ -4,7 +4,6 @@ from math import sqrt
 from cvxopt import matrix
 from cvxopt.blas import dot 
 from cvxopt.solvers import qp, options 
-import pylab
 
 n = 4
 S = matrix( [[ 4e-2,  6e-3, -4e-3,   0.0 ], 
@@ -20,35 +19,40 @@ A = matrix(1.0, (1,n))
 b = matrix(1.0)
 
 N = 100
-mus = [ 10**(5.0*t/N-1.0) for t in xrange(N) ]
+mus = [ 10**(5.0*t/N-1.0) for t in range(N) ]
 options['show_progress'] = False
 xs = [ qp(mu*S, -pbar, G, h, A, b)['x'] for mu in mus ]
 returns = [ dot(pbar,x) for x in xs ]
 risks = [ sqrt(dot(x, S*x)) for x in xs ]
 
-pylab.figure(1, facecolor='w')
-pylab.plot(risks, returns)
-pylab.xlabel('standard deviation')
-pylab.ylabel('expected return')
-pylab.axis([0, 0.2, 0, 0.15])
-pylab.title('Risk-return trade-off curve (fig 4.12)')
-pylab.yticks([0.00, 0.05, 0.10, 0.15])
-
-pylab.figure(2, facecolor='w')
-c1 = [ x[0] for x in xs ] 
-c2 = [ x[0] + x[1] for x in xs ]
-c3 = [ x[0] + x[1] + x[2] for x in xs ] 
-c4 = [ x[0] + x[1] + x[2] + x[3] for x in xs ]
-pylab.fill(risks + [.20], c1 + [0.0], facecolor = '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1, facecolor='#D0D0D0') 
-pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, facecolor='#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3, facecolor='#D0D0D0') 
-pylab.axis([0.0, 0.2, 0.0, 1.0])
-pylab.xlabel('standard deviation')
-pylab.ylabel('allocation')
-pylab.text(.15,.5,'x1')
-pylab.text(.10,.7,'x2')
-pylab.text(.05,.7,'x3')
-pylab.text(.01,.7,'x4')
-pylab.title('Optimal allocations (fig 4.12)')
-pylab.show()
+try: 
+    import pylab
+except ImportError: 
+    pass
+else:
+    pylab.figure(1, facecolor='w')
+    pylab.plot(risks, returns)
+    pylab.xlabel('standard deviation')
+    pylab.ylabel('expected return')
+    pylab.axis([0, 0.2, 0, 0.15])
+    pylab.title('Risk-return trade-off curve (fig 4.12)')
+    pylab.yticks([0.00, 0.05, 0.10, 0.15])
+    
+    pylab.figure(2, facecolor='w')
+    c1 = [ x[0] for x in xs ] 
+    c2 = [ x[0] + x[1] for x in xs ]
+    c3 = [ x[0] + x[1] + x[2] for x in xs ] 
+    c4 = [ x[0] + x[1] + x[2] + x[3] for x in xs ]
+    pylab.fill(risks + [.20], c1 + [0.0], facecolor = '#F0F0F0') 
+    pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1, facecolor='#D0D0D0') 
+    pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, facecolor='#F0F0F0') 
+    pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3, facecolor='#D0D0D0') 
+    pylab.axis([0.0, 0.2, 0.0, 1.0])
+    pylab.xlabel('standard deviation')
+    pylab.ylabel('allocation')
+    pylab.text(.15,.5,'x1')
+    pylab.text(.10,.7,'x2')
+    pylab.text(.05,.7,'x3')
+    pylab.text(.01,.7,'x4')
+    pylab.title('Optimal allocations (fig 4.12)')
+    pylab.show()
diff --git a/examples/doc/chap8/qcl1.py b/examples/doc/chap8/qcl1.py
index a26b75a..0a16450 100644
--- a/examples/doc/chap8/qcl1.py
+++ b/examples/doc/chap8/qcl1.py
@@ -131,4 +131,4 @@ m, n = 100, 100
 A, b = normal(m,n), normal(m,1)
 
 x, z = qcl1(A, b)
-if x is None: print "infeasible"
+if x is None: print("infeasible")
diff --git a/examples/doc/chap8/sdp.py b/examples/doc/chap8/sdp.py
index 471370f..6c5679f 100644
--- a/examples/doc/chap8/sdp.py
+++ b/examples/doc/chap8/sdp.py
@@ -11,6 +11,9 @@ G += [ matrix([[-21., -11.,   0., -11.,  10.,   8.,   0.,   8., 5.],
 h = [ matrix([[33., -9.], [-9., 26.]]) ]  
 h += [ matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) ]  
 sol = solvers.sdp(c, Gs=G, hs=h)  
-print "\nx = \n\n", sol['x']  
-print "zs[0] =\n\n", sol['zs'][0]  
-print "zs[1] =\n\n", sol['zs'][1]  
+print("\nx = \n") 
+print(sol['x'])
+print("zs[0] = \n")
+print(sol['zs'][0])
+print("zs[1] =\n")
+print(sol['zs'][1])
diff --git a/examples/doc/chap8/socp.py b/examples/doc/chap8/socp.py
index 99772e9..04efd43 100644
--- a/examples/doc/chap8/socp.py
+++ b/examples/doc/chap8/socp.py
@@ -6,6 +6,9 @@ G = [ matrix( [[12., 13., 12.], [6., -3., -12.], [-5., -5., 6.]] ) ]
 G += [ matrix( [[3., 3., -1., 1.], [-6., -6., -9., 19.], [10., -2., -2., -3.]] ) ]  
 h = [ matrix( [-12., -3., -2.] ),  matrix( [27., 0., 3., -42.] ) ]  
 sol = solvers.socp(c, Gq = G, hq = h)  
-print "\nx = \n\n", sol['x']  
-print "zq[0] = \n\n", sol['zq'][0]  
-print "zq[1] = \n\n", sol['zq'][1]  
+print("\nx = \n") 
+print(sol['x'])
+print("zq[0] = \n")
+print(sol['zq'][0])
+print("zq[1] = \n") 
+print(sol['zq'][1])
diff --git a/examples/doc/chap9/acent2.py b/examples/doc/chap9/acent2.py
index a071160..139dc0d 100644
--- a/examples/doc/chap9/acent2.py
+++ b/examples/doc/chap9/acent2.py
@@ -23,4 +23,5 @@ h = matrix(
     [1.0, 0.0, 0.0, 0.0, 20., 10., 40., 10., 80., 10., 40., 10., 15.])  
 dims = {'l': 0, 'q': [4], 's':  [3]}  
 sol = solvers.cp(F, G, h, dims)  
-print "\nx = \n\n", sol['x']  
+print("\nx = \n") 
+print(sol['x'])
diff --git a/examples/doc/chap9/floorplan.py b/examples/doc/chap9/floorplan.py
index 3ffd804..f1f6c54 100644
--- a/examples/doc/chap9/floorplan.py
+++ b/examples/doc/chap9/floorplan.py
@@ -1,6 +1,5 @@
 # The floor planning example section 9.2 (Problems with linear objectives). 
 
-import pylab  
 from cvxopt import solvers, matrix, spmatrix, mul, div  
 solvers.options['show_progress'] = False
  
@@ -135,49 +134,58 @@ def floorplan(Amin):
     return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], \
         sol['x'][12:17], sol['x'][17:]  
  
-pylab.figure(facecolor='w')  
-pylab.subplot(221)  
-Amin = matrix([100., 100., 100., 100., 100.])  
-W, H, x, y, w, h =  floorplan(Amin)  
-for k in xrange(5):  
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')  
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
-pylab.axis([-1.0, 26, -1.0, 26])  
-pylab.xticks([])  
-pylab.yticks([])  
- 
-pylab.subplot(222)  
-Amin = matrix([20., 50., 80., 150., 200.])  
-W, H, x, y, w, h =  floorplan(Amin)  
-for k in xrange(5):  
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')  
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
-pylab.axis([-1.0, 26, -1.0, 26])  
-pylab.xticks([])  
-pylab.yticks([])  
- 
-pylab.subplot(223)  
-Amin = matrix([180., 80., 80., 80., 80.])  
-W, H, x, y, w, h =  floorplan(Amin)  
-for k in xrange(5):  
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')  
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
-pylab.axis([-1.0, 26, -1.0, 26])  
-pylab.xticks([])  
-pylab.yticks([])  
- 
-pylab.subplot(224)  
-Amin = matrix([20., 150., 20., 200., 110.])  
-W, H, x, y, w, h =  floorplan(Amin)  
-for k in xrange(5):  
-    pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
-               [y[k], y[k]+h[k], y[k]+h[k], y[k]], facecolor = '#D0D0D0')  
-    pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
-pylab.axis([-1.0, 26, -1.0, 26])  
-pylab.xticks([])  
-pylab.yticks([])  
- 
-pylab.show()
+try: 
+    import pylab
+except ImportError: 
+    pass
+else:
+    pylab.figure(facecolor='w')  
+    pylab.subplot(221)  
+    Amin = matrix([100., 100., 100., 100., 100.])  
+    W, H, x, y, w, h =  floorplan(Amin)  
+    for k in range(5):  
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')  
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
+    pylab.axis([-1.0, 26, -1.0, 26])  
+    pylab.xticks([])  
+    pylab.yticks([])  
+     
+    pylab.subplot(222)  
+    Amin = matrix([20., 50., 80., 150., 200.])  
+    W, H, x, y, w, h =  floorplan(Amin)  
+    for k in range(5):  
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')  
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
+    pylab.axis([-1.0, 26, -1.0, 26])  
+    pylab.xticks([])  
+    pylab.yticks([])  
+     
+    pylab.subplot(223)  
+    Amin = matrix([180., 80., 80., 80., 80.])  
+    W, H, x, y, w, h =  floorplan(Amin)  
+    for k in range(5):  
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')  
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
+    pylab.axis([-1.0, 26, -1.0, 26])  
+    pylab.xticks([])  
+    pylab.yticks([])  
+     
+    pylab.subplot(224)  
+    Amin = matrix([20., 150., 20., 200., 110.])  
+    W, H, x, y, w, h =  floorplan(Amin)  
+    for k in range(5):  
+        pylab.fill([x[k], x[k], x[k]+w[k], x[k]+w[k]],  
+                   [y[k], y[k]+h[k], y[k]+h[k], y[k]], 
+                   facecolor = '#D0D0D0')  
+        pylab.text(x[k]+.5*w[k], y[k]+.5*h[k], "%d" %(k+1))  
+    pylab.axis([-1.0, 26, -1.0, 26])  
+    pylab.xticks([])  
+    pylab.yticks([])  
+     
+    pylab.show()
diff --git a/examples/doc/chap9/gp.py b/examples/doc/chap9/gp.py
index bce0479..a42f415 100644
--- a/examples/doc/chap9/gp.py
+++ b/examples/doc/chap9/gp.py
@@ -16,4 +16,4 @@ g = log( matrix( [1.0, 2/Awall, 2/Awall, 1/Aflr, alpha, 1/beta, gamma,
     1/delta]) )  
 K = [1, 2, 1, 1, 1, 1, 1]  
 h, w, d = exp( solvers.gp(K, F, g)['x'] )
-print "\n h = %f,  w = %f, d = %f.\n" %(h,w,d)   
+print("\n h = %f,  w = %f, d = %f.\n" %(h,w,d))   
diff --git a/examples/doc/chap9/robls.py b/examples/doc/chap9/robls.py
index 6957362..6caa977 100644
--- a/examples/doc/chap9/robls.py
+++ b/examples/doc/chap9/robls.py
@@ -4,7 +4,6 @@
 from math import sqrt, ceil, floor
 from cvxopt import solvers, blas, lapack
 from cvxopt import matrix, spmatrix, spdiag, sqrt, mul, div, setseed, normal
-import pylab
 
 def robls(A, b, rho): 
 
diff --git a/examples/filterdemo/README b/examples/filterdemo/README
index 81eb297..c156a14 100644
--- a/examples/filterdemo/README
+++ b/examples/filterdemo/README
@@ -1,5 +1,5 @@
-The filterdemo computes a FIR lowpass filter by solving a linear 
-program.  It solves a discretization of the  problem
+The filterdemo computes a FIR lowpass filter by solving a linear program.  
+It solves a discretization of the  problem
 
 minimize     d2
 subject to   -1/d1 <= H(wk) <= d1,   0 <= w <=  wc
diff --git a/examples/filterdemo/filterdemo_cli b/examples/filterdemo/filterdemo_cli
index dd8f001..c05b41b 100755
--- a/examples/filterdemo/filterdemo_cli
+++ b/examples/filterdemo/filterdemo_cli
@@ -17,7 +17,7 @@ from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
 import pylab 
 
 def frange(a,b,N):    
-    return [ a+k*float((b-a))/N  for k in xrange(N) ]
+    return [ a+k*float((b-a))/N  for k in range(N) ]
 
 def design_lowpass(N, d1, wc, ws, solver=None, Q=50):
 
@@ -26,11 +26,11 @@ def design_lowpass(N, d1, wc, ws, solver=None, Q=50):
     
     n1 = int(round(N*Q*wc/pi));
     w1 = matrix(frange(0,wc,n1))
-    G1 = matrix([cos(wi*j) for j in xrange(N+1) for wi in w1], (n1,N+1))
+    G1 = matrix([cos(wi*j) for j in range(N+1) for wi in w1], (n1,N+1))
 
     n2 = int(round(N*Q*(pi-ws)/pi));
     w2 = matrix(frange(ws,pi,n2))
-    G2 = matrix([cos(wi*j) for j in xrange(N+1) for wi in w2], (n2,N+1))
+    G2 = matrix([cos(wi*j) for j in range(N+1) for wi in w2], (n2,N+1))
     
     options['show_progress'] = 0    
     options['LPX_K_MSGLEV'] = 0
@@ -42,7 +42,7 @@ def design_lowpass(N, d1, wc, ws, solver=None, Q=50):
 def make_plot(h, d2, co, sb, pr, N, output=None):
     w = matrix(frange(0,pi,N*50));        
     C = w*matrix(range(N+1), (1,N+1), 'd');
-    for i in xrange(len(C)): C[i] = cos(C[i])
+    for i in range(len(C)): C[i] = cos(C[i])
     
     fig = pylab.figure()
     ax = fig.add_subplot(111)
@@ -61,7 +61,7 @@ def make_plot(h, d2, co, sb, pr, N, output=None):
     ax.grid()
 
 def usage():
-    print """
+    print("""
 Usage:
 filterdemo_cli --cutoff=CO --stopband=SB --ripple=RP --order=N [options]
 
@@ -73,8 +73,8 @@ Arguments:
 
 Options:
 --solver = SOLVER      One of default, mosek, glpk
---output = FILENAME    Output filename.
-"""
+--output = FILENAME    Output filename. 
+""")
     sys.exit(2)
     
 def main():
@@ -103,26 +103,26 @@ def main():
     if None in [co, sb, pr, N]: usage()
     
     if not (0.1 <= co < sb-0.01+1E-8 <= 0.5):
-        print "invalid cutoff and stopband frequencies"
+        print("invalid cutoff and stopband frequencies")
         usage()
 
     if not (0.01 <= pr <= 3):
-        print "invalid value of passband ripple"
+        print("invalid value of passband ripple")
         usage()
 
     if not (5 <= N <= 50):
-        print "invalid filterorder"
+        print("invalid filterorder")
         usage()
     
     if not solver in ['default','mosek','glpk']:
-        print "invalid solver"
+        print("invalid solver")
         usage()
 
 
     try:
         [h, d2] = design_lowpass(N, pr, co*pi, sb*pi, solver)
     except:
-        print "Please tighten filter specifications."
+        print("Please tighten filter specifications.")
         sys.exit(2)
         
         
diff --git a/examples/filterdemo/filterdemo_gui b/examples/filterdemo/filterdemo_gui
index 4beaa77..bdbcf8e 100755
--- a/examples/filterdemo/filterdemo_gui
+++ b/examples/filterdemo/filterdemo_gui
@@ -14,7 +14,7 @@ import pylab
 
 
 def frange(a,b,N):    
-    return [ a+k*float((b-a))/N  for k in xrange(N) ]
+    return [ a+k*float((b-a))/N  for k in range(N) ]
 
 
 def design_lowpass(N, d1, wc, ws, solver=None, Q=50):
diff --git a/src/C/amd.c b/src/C/amd.c
index 6092329..fe620fe 100644
--- a/src/C/amd.c
+++ b/src/C/amd.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,7 +53,11 @@ static const param_tuple AMD_PARAM_LIST[] = {
     {"AMD_AGGRESSIVE", AMD_AGGRESSIVE}
 }; /* 2 parameters */
 
+#if PY_MAJOR_VERSION >= 3
+static int get_param_idx(const char *str, int *idx)
+#else
 static int get_param_idx(char *str, int *idx)
+#endif
 {
     int i;
 
@@ -69,7 +73,10 @@ static int set_defaults(double *control)
     int_t pos=0;
     int param_id;
     PyObject *param, *key, *value;
-    char *keystr, err_str[100];
+#if PY_MAJOR_VERSION < 3
+    char *keystr; 
+#endif
+    char err_str[100];
 
     amd_defaults(control);
 
@@ -80,17 +87,25 @@ static int set_defaults(double *control)
         return 0;
     }
     while (PyDict_Next(param, &pos, &key, &value))
+#if PY_MAJOR_VERSION >= 3
+        if ((PyUnicode_Check(key)) && 
+            get_param_idx(_PyUnicode_AsString(key),&param_id)) {
+            if (!PyLong_Check(value) && !PyFloat_Check(value)){
+                sprintf(err_str, "invalid value for AMD parameter: %-.20s",
+                    _PyUnicode_AsString(key));
+#else
         if ((keystr = PyString_AsString(key)) && get_param_idx(keystr,
             &param_id)) {
             if (!PyInt_Check(value) && !PyFloat_Check(value)){
                 sprintf(err_str, "invalid value for AMD parameter: "
                     "%-.20s", keystr);
+#endif
                 PyErr_SetString(PyExc_ValueError, err_str);
                 Py_DECREF(param);
                 return 0;
             }
             control[param_id] = PyFloat_AsDouble(value);
-    }
+        }
     Py_DECREF(param);
     return 1;
 }
@@ -112,19 +127,27 @@ static char doc_order[] =
     "p         'i' matrix of length equal to the order of A";
 
 
-static PyObject* order_c(PyObject *self, PyObject *args,
-    PyObject *kwrds)
+static PyObject* order_c(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     spmatrix *A;
     matrix *perm;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     int j, k, n, nnz, alloc=0, info;
     int_t *rowind=NULL, *colptr=NULL;
     double control[AMD_CONTROL];
     char *kwlist[] = {"A", "uplo", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|C", kwlist, &A,
+        &uplo_)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|c", kwlist, &A,
         &uplo)) return NULL;
+#endif
     if (!set_defaults(control)) return NULL;
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A)){
         PyErr_SetString(PyExc_TypeError, "A must be a square sparse "
@@ -136,12 +159,11 @@ static PyObject* order_c(PyObject *self, PyObject *args,
         return PyErr_NoMemory();
     n = SP_NROWS(A);
     for (nnz=0, j=0; j<n; j++) {
-	if (uplo == 'L'){
-            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k]<j;
-                k++);
+        if (uplo == 'L'){
+            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k]<j; k++);
             nnz += SP_COL(A)[j+1] - k;
-	}
-	else {
+        }
+        else {
             for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                 k++);
             nnz += k - SP_COL(A)[j];
@@ -152,31 +174,31 @@ static PyObject* order_c(PyObject *self, PyObject *args,
         rowind = (int_t *) SP_ROW(A);
     }
     else {
-	alloc = 1;
+        alloc = 1;
         colptr = (int_t *) calloc(n+1, sizeof(int_t));
         rowind = (int_t *) calloc(nnz, sizeof(int_t));
-	if (!colptr || !rowind) {
+        if (!colptr || !rowind) {
             Py_XDECREF(perm);  free(colptr);  free(rowind);
-	    return PyErr_NoMemory();
-	}
-	colptr[0] = 0;
+            return PyErr_NoMemory();
+        }
+        colptr[0] = 0;
         for (j=0; j<n; j++) {
-	    if (uplo == 'L'){
-                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] &&
-                    SP_ROW(A)[k] < j; k++);
-		nnz = SP_COL(A)[j+1] - k;
+            if (uplo == 'L'){
+                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] < j; 
+                    k++);
+                nnz = SP_COL(A)[j+1] - k;
                 colptr[j+1] = colptr[j] + nnz;
-		memcpy(rowind + colptr[j], (int_t *) SP_ROW(A) + k,
+                memcpy(rowind + colptr[j], (int_t *) SP_ROW(A) + k,
                     nnz*sizeof(int_t));
-	    }
-	    else {
-                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] &&
-                    SP_ROW(A)[k] <= j; k++);
+            }
+            else {
+                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
+                    k++);
                 nnz = k - SP_COL(A)[j];
                 colptr[j+1] = colptr[j] + nnz;
-		memcpy(rowind + colptr[j], (int_t *) (SP_ROW(A) +
+                memcpy(rowind + colptr[j], (int_t *) (SP_ROW(A) +
                     SP_COL(A)[j]), nnz*sizeof(int_t));
-	    }
+            }
         }
     }
     info = amd_order(n, colptr, rowind, MAT_BUFI(perm), control, NULL);
@@ -200,14 +222,34 @@ static PyObject* order_c(PyObject *self, PyObject *args,
 }
 
 static PyMethodDef amd_functions[] = {
-{"order", (PyCFunction) order_c, METH_VARARGS|METH_KEYWORDS, doc_order},
-{NULL}  /* Sentinel */
+    {"order", (PyCFunction) order_c, METH_VARARGS|METH_KEYWORDS, doc_order},
+    {NULL}  /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef amd_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "amd",
+    amd__doc__,
+    -1,
+    amd_functions,
+    NULL, NULL, NULL, NULL
 };
 
+PyMODINIT_FUNC PyInit_amd(void)
+{
+    if (!(amd_module = PyModule_Create(&amd_module_def))) return NULL;
+    PyModule_AddObject(amd_module, "options", PyDict_New());
+    if (import_cvxopt() < 0) return NULL;
+    return amd_module;
+}
+
+#else
 PyMODINIT_FUNC initamd(void)
 {
-    amd_module = Py_InitModule3("cvxopt.amd", amd_functions,
-        amd__doc__);
+    amd_module = Py_InitModule3("cvxopt.amd", amd_functions, amd__doc__);
     PyModule_AddObject(amd_module, "options", PyDict_New());
     if (import_cvxopt() < 0) return;
 }
+#endif
diff --git a/src/C/base.c b/src/C/base.c
index 2f531e3..17e1bb3 100644
--- a/src/C/base.c
+++ b/src/C/base.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,9 @@ extern PyTypeObject matrix_tp ;
 matrix * Matrix_New(int, int, int) ;
 matrix * Matrix_NewFromMatrix(matrix *, int) ;
 matrix * Matrix_NewFromSequence(PyObject *, int) ;
+#if PY_MAJOR_VERSION < 3
 matrix * Matrix_NewFromArrayStruct(PyObject *, int, int *) ;
+#endif
 
 extern PyTypeObject spmatrix_tp ;
 spmatrix * SpMatrix_New(int_t, int_t, int, int ) ;
@@ -111,12 +113,15 @@ convert_inum(void *dest, void *val, int val_id, int offset)
     default: PY_ERR_INT(PyExc_TypeError,"cannot cast argument as integer");
     }
   } else { /* PyNumber */
+#if PY_MAJOR_VERSION >= 3
+    if (PyLong_Check((PyObject *)val)) {
+      *(int_t *)dest = PyLong_AS_LONG((PyObject *)val); return 0;
+    }
+#else
     if (PyInt_Check((PyObject *)val)) {
       *(int_t *)dest = PyInt_AS_LONG((PyObject *)val); return 0;
     }
-    //else if (PyFloat_Check((PyObject *)val)) {
-    //  *(int_t *)dest = roundl(PyFloat_AS_DOUBLE((PyObject *)val)); return 0;
-    //}
+#endif
     else PY_ERR_INT(PyExc_TypeError,"cannot cast argument as integer");
   }
 }
@@ -131,7 +136,11 @@ convert_dnum(void *dest, void *val, int val_id, int offset)
     default: PY_ERR_INT(PyExc_TypeError, "cannot cast argument as double");
     }
   } else { /* PyNumber */
+#if PY_MAJOR_VERSION >= 3
+    if (PyLong_Check((PyObject *)val) || PyFloat_Check((PyObject *)val)) {
+#else
     if (PyInt_Check((PyObject *)val) || PyFloat_Check((PyObject *)val)) {
+#endif
       *(double *)dest = PyFloat_AsDouble((PyObject *)val);
       return 0;
     }
@@ -309,7 +318,11 @@ int get_id(void *val, int val_type) {
     else
       return SP_ID((spmatrix *)val);
   }
+#if PY_MAJOR_VERSION >= 3
+  else if (PyLong_Check((PyObject *)val))
+#else
   else if (PyInt_Check((PyObject *)val))
+#endif
     return INT;
   else if (PyFloat_Check((PyObject *)val))
     return DOUBLE;
@@ -374,7 +387,11 @@ PyObject * base_axpy(PyObject *self, PyObject *args, PyObject *kwrds)
         Matrix_Check(x) ? MAT_BUF(x): ((spmatrix *)x)->obj,
             Matrix_Check(y) ? MAT_BUF(y): ((spmatrix *)y)->obj,
                 SpMatrix_Check(x), SpMatrix_Check(y),
+#if PY_MAJOR_VERSION >= 3
+                partial ? PyLong_AS_LONG(partial) : 0, &z))
+#else
                 partial ? PyInt_AS_LONG(partial) : 0, &z))
+#endif
       return PyErr_NoMemory();
 
     if (z) {
@@ -422,12 +439,22 @@ PyObject* base_gemm(PyObject *self, PyObject *args, PyObject *kwrds)
   PyObject *ao=NULL, *bo=NULL;
   number a, b;
   int m, n, k;
+#if PY_MAJOR_VERSION >= 3
+  int transA='N', transB='N';
+  char transA_, transB_;
+#else
   char transA='N', transB='N';
+#endif
   char *kwlist[] = {"A", "B", "C", "transA", "transB", "alpha", "beta",
       "partial", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOO:gemm",
+      kwlist, &A, &B, &C, &transA, &transB, &ao, &bo, &partial))
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOO:gemm",
       kwlist, &A, &B, &C, &transA, &transB, &ao, &bo, &partial))
+#endif
     return NULL;
 
   if (!(Matrix_Check(A) || SpMatrix_Check(A)))
@@ -457,6 +484,11 @@ PyObject* base_gemm(PyObject *self, PyObject *args, PyObject *kwrds)
   if (ao && convert_num[X_ID(A)](&a, ao, 1, 0)) err_type("alpha");
   if (bo && convert_num[X_ID(A)](&b, bo, 1, 0)) err_type("beta");
 
+#if PY_MAJOR_VERSION >= 3
+  transA_ = transA;
+  transB_ = transB;
+#endif
+
   int id = X_ID(A);
   if (Matrix_Check(A) && Matrix_Check(B) && Matrix_Check(C)) {
 
@@ -464,12 +496,28 @@ PyObject* base_gemm(PyObject *self, PyObject *args, PyObject *kwrds)
     int ldB = MAX(1,MAT_NROWS(B));
     int ldC = MAX(1,MAT_NROWS(C));
     if (id == INT) err_invalid_id;
+#if PY_MAJOR_VERSION >= 3
+    gemm[id](&transA_, &transB_, &m, &n, &k, (ao ? &a : &One[id]),
+        MAT_BUF(A), &ldA, MAT_BUF(B), &ldB, (bo ? &b : &Zero[id]),
+        MAT_BUF(C), &ldC);
+#else
     gemm[id](&transA, &transB, &m, &n, &k, (ao ? &a : &One[id]),
         MAT_BUF(A), &ldA, MAT_BUF(B), &ldB, (bo ? &b : &Zero[id]),
         MAT_BUF(C), &ldC);
+#endif
   } else {
 
     void *z = NULL;
+#if PY_MAJOR_VERSION >= 3
+    if (sp_gemm[id](transA_, transB_, (ao ? a : One[id]),
+        Matrix_Check(A) ? MAT_BUF(A) : ((spmatrix *)A)->obj,
+            Matrix_Check(B) ? MAT_BUF(B) : ((spmatrix *)B)->obj,
+                (bo ? b : Zero[id]),
+                Matrix_Check(C) ? MAT_BUF(C) : ((spmatrix *)C)->obj,
+                    SpMatrix_Check(A), SpMatrix_Check(B), SpMatrix_Check(C),
+                    partial ? PyLong_AS_LONG(partial) : 0, &z, m, n, k))
+      return PyErr_NoMemory();
+#else
     if (sp_gemm[id](transA, transB, (ao ? a : One[id]),
         Matrix_Check(A) ? MAT_BUF(A) : ((spmatrix *)A)->obj,
             Matrix_Check(B) ? MAT_BUF(B) : ((spmatrix *)B)->obj,
@@ -478,6 +526,7 @@ PyObject* base_gemm(PyObject *self, PyObject *args, PyObject *kwrds)
                     SpMatrix_Check(A), SpMatrix_Check(B), SpMatrix_Check(C),
                     partial ? PyInt_AS_LONG(partial) : 0, &z, m, n, k))
       return PyErr_NoMemory();
+#endif
 
     if (z) {
       free_ccs( ((spmatrix *)C)->obj );
@@ -528,15 +577,27 @@ static PyObject* base_gemv(PyObject *self, PyObject *args, PyObject *kwrds)
   PyObject *ao=NULL, *bo=NULL;
   number a, b;
   int m=-1, n=-1, ix=1, iy=1, oA=0, ox=0, oy=0;
+#if PY_MAJOR_VERSION >= 3
+  int trans='N';
+  char trans_;
+#else
   char trans='N';
+#endif
   char *kwlist[] = {"A", "x", "y", "trans", "alpha", "beta", "m", "n",
       "incx", "incy", "offsetA", "offsetx",
       "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiii:gemv",
+      kwlist, &A, &x, &y, &trans, &ao, &bo, &m, &n, &ix, &iy,
+      &oA, &ox, &oy))
+    return NULL;
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiii:gemv",
       kwlist, &A, &x, &y, &trans, &ao, &bo, &m, &n, &ix, &iy,
       &oA, &ox, &oy))
     return NULL;
+#endif
 
   if (!Matrix_Check(A) && !SpMatrix_Check(A))
     PY_ERR(PyExc_TypeError, "A must be a dense or sparse matrix");
@@ -579,6 +640,10 @@ static PyObject* base_gemv(PyObject *self, PyObject *args, PyObject *kwrds)
   if (ao && convert_num[MAT_ID(x)](&a, ao, 1, 0)) err_type("alpha");
   if (bo && convert_num[MAT_ID(x)](&b, bo, 1, 0)) err_type("beta");
 
+#if PY_MAJOR_VERSION >= 3
+  trans_ = trans;
+#endif
+
   if (Matrix_Check(A)) {
     int ldA = MAX(1,X_NROWS(A));
     if (trans == 'N' && n == 0)
@@ -586,15 +651,29 @@ static PyObject* base_gemv(PyObject *self, PyObject *args, PyObject *kwrds)
     else if ((trans == 'T' || trans == 'C') && m == 0)
       scal[id](&n, (bo ? &b : &Zero[id]), MAT_BUF(y)+oy*E_SIZE[id], &iy);
     else
+#if PY_MAJOR_VERSION >= 3
+      gemv[id](&trans_, &m, &n, (ao ? &a : &One[id]),
+          MAT_BUF(A) + oA*E_SIZE[id], &ldA,
+          MAT_BUF(x) + ox*E_SIZE[id], &ix, (bo ? &b : &Zero[id]),
+          MAT_BUF(y) + oy*E_SIZE[id], &iy);
+#else
       gemv[id](&trans, &m, &n, (ao ? &a : &One[id]),
           MAT_BUF(A) + oA*E_SIZE[id], &ldA,
           MAT_BUF(x) + ox*E_SIZE[id], &ix, (bo ? &b : &Zero[id]),
           MAT_BUF(y) + oy*E_SIZE[id], &iy);
+#endif
   } else {
+#if PY_MAJOR_VERSION >= 3
+    if (sp_gemv[id](trans_, m, n, (ao ? a : One[id]), ((spmatrix *)A)->obj,
+        oA, MAT_BUF(x) + ox*E_SIZE[id], ix, (bo ? b : Zero[id]),
+        MAT_BUF(y) + oy*E_SIZE[id], iy))
+      return PyErr_NoMemory();
+#else
     if (sp_gemv[id](trans, m, n, (ao ? a : One[id]), ((spmatrix *)A)->obj,
         oA, MAT_BUF(x) + ox*E_SIZE[id], ix, (bo ? b : Zero[id]),
         MAT_BUF(y) + oy*E_SIZE[id], iy))
       return PyErr_NoMemory();
+#endif
   }
 
   return Py_BuildValue("");
@@ -624,12 +703,22 @@ static PyObject* base_syrk(PyObject *self, PyObject *args, PyObject *kwrds)
 {
   PyObject *A, *C, *partial=NULL, *ao=NULL, *bo=NULL;
   number a, b;
+#if PY_MAJOR_VERSION >= 3
+  int trans='N', uplo='L';
+  char trans_, uplo_;
+#else
   char trans='N', uplo='L';
+#endif
   char *kwlist[] = {"A", "C", "uplo", "trans", "alpha", "beta", "partial",
       NULL};
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCOOO:syrk", kwlist,
+      &A, &C, &uplo, &trans, &ao, &bo, &partial))
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccOOO:syrk", kwlist,
       &A, &C, &uplo, &trans, &ao, &bo, &partial))
+#endif
     return NULL;
 
   if (!(Matrix_Check(A) || SpMatrix_Check(A)))
@@ -656,16 +745,36 @@ static PyObject* base_syrk(PyObject *self, PyObject *args, PyObject *kwrds)
   if (ao && convert_num[id](&a, ao, 1, 0)) err_type("alpha");
   if (bo && convert_num[id](&b, bo, 1, 0)) err_type("beta");
 
+#if PY_MAJOR_VERSION >= 3
+  trans_ = trans;
+  uplo_ = uplo;
+#endif
+
   if (Matrix_Check(A) && Matrix_Check(C)) {
 
     int ldA = MAX(1,MAT_NROWS(A));
     int ldC = MAX(1,MAT_NROWS(C));
 
+#if PY_MAJOR_VERSION >= 3
+    syrk[id](&uplo_, &trans_, &n, &k, (ao ? &a : &One[id]),
+        MAT_BUF(A), &ldA, (bo ? &b : &Zero[id]), MAT_BUF(C), &ldC);
+#else
     syrk[id](&uplo, &trans, &n, &k, (ao ? &a : &One[id]),
         MAT_BUF(A), &ldA, (bo ? &b : &Zero[id]), MAT_BUF(C), &ldC);
+#endif
   } else {
 
     void *z = NULL;
+#if PY_MAJOR_VERSION >= 3
+    if (sp_syrk[id](uplo_, trans_,
+        (ao ? a : One[id]),
+        Matrix_Check(A) ? MAT_BUF(A) : ((spmatrix *)A)->obj,
+            (bo ? b : Zero[id]),
+            Matrix_Check(C) ? MAT_BUF(C) : ((spmatrix *)C)->obj,
+                SpMatrix_Check(A), SpMatrix_Check(C),
+                partial ? PyLong_AS_LONG(partial) : 0,
+                    (trans == 'N' ? X_NCOLS(A) : X_NROWS(A)), &z))
+#else
     if (sp_syrk[id](uplo, trans,
         (ao ? a : One[id]),
         Matrix_Check(A) ? MAT_BUF(A) : ((spmatrix *)A)->obj,
@@ -674,6 +783,7 @@ static PyObject* base_syrk(PyObject *self, PyObject *args, PyObject *kwrds)
                 SpMatrix_Check(A), SpMatrix_Check(C),
                 partial ? PyInt_AS_LONG(partial) : 0,
                     (trans == 'N' ? X_NCOLS(A) : X_NROWS(A)), &z))
+#endif
       return PyErr_NoMemory();
 
     if (z) {
@@ -717,12 +827,22 @@ static PyObject* base_symv(PyObject *self, PyObject *args, PyObject *kwrds)
   matrix *x, *y;
   number a, b;
   int n=-1, ix=1, iy=1, oA=0, ox=0, oy=0, ldA;
+#if PY_MAJOR_VERSION >= 3
+  int uplo='L';
+  char uplo_;
+#else
   char uplo='L';
+#endif
   char *kwlist[] = {"A", "x", "y", "uplo", "alpha", "beta", "n",
       "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiii:symv",
+      kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &ix, &iy, &oA, &ox, &oy))
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiii:symv",
       kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &ix, &iy, &oA, &ox, &oy))
+#endif
     return NULL;
 
   if (!Matrix_Check(A) && !SpMatrix_Check(A))
@@ -762,17 +882,33 @@ static PyObject* base_symv(PyObject *self, PyObject *args, PyObject *kwrds)
   if (ao && convert_num[id](&a, ao, 1, 0)) err_type("alpha");
   if (bo && convert_num[id](&b, bo, 1, 0)) err_type("beta");
 
+#if PY_MAJOR_VERSION >= 3
+  uplo_ = uplo;
+#endif
+
   if (Matrix_Check(A)) {
 
+#if PY_MAJOR_VERSION >= 3
+    symv[id](&uplo_, &n, (ao ? &a : &One[id]),
+        MAT_BUF(A) + oA*E_SIZE[id], &ldA, MAT_BUF(x) + ox*E_SIZE[id],
+        &ix, (bo ? &b : &Zero[id]), MAT_BUF(y) + oy*E_SIZE[id], &iy);
+#else
     symv[id](&uplo, &n, (ao ? &a : &One[id]),
         MAT_BUF(A) + oA*E_SIZE[id], &ldA, MAT_BUF(x) + ox*E_SIZE[id],
         &ix, (bo ? &b : &Zero[id]), MAT_BUF(y) + oy*E_SIZE[id], &iy);
+#endif
   }
   else {
 
+#if PY_MAJOR_VERSION >= 3
+    if (sp_symv[id](uplo_, n, (ao ? a : One[id]), ((spmatrix *)A)->obj,
+        oA, MAT_BUF(x) + ox*E_SIZE[id], ix,
+        (bo ? b : Zero[id]), MAT_BUF(y) + oy*E_SIZE[id], iy))
+#else
     if (sp_symv[id](uplo, n, (ao ? a : One[id]), ((spmatrix *)A)->obj,
         oA, MAT_BUF(x) + ox*E_SIZE[id], ix,
         (bo ? b : Zero[id]), MAT_BUF(y) + oy*E_SIZE[id], iy))
+#endif
       return PyErr_NoMemory();
   }
 
@@ -1390,12 +1526,20 @@ PyObject * matrix_elem_mul(matrix *self, PyObject *args, PyObject *kwrds)
   int b_is_number = PyNumber_Check(B) || (Matrix_Check(B) && MAT_LGT(B) == 1);
 
   int ida, idb;
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A)) { ida = INT; }
+#else
   if (PyInt_Check(A)) { ida = INT; }
+#endif
   else if (PyFloat_Check(A)) { ida = DOUBLE; }
   else if (PyComplex_Check(A)) { ida = COMPLEX; }
   else { ida = X_ID(A); }
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(B)) { idb = INT; }
+#else
   if (PyInt_Check(B)) { idb = INT; }
+#endif
   else if (PyFloat_Check(B)) { idb = DOUBLE; }
   else if (PyComplex_Check(B)) { idb = COMPLEX; }
   else { idb = X_ID(B); }
@@ -1575,17 +1719,29 @@ PyObject * matrix_elem_div(matrix *self, PyObject *args, PyObject *kwrds)
   int b_is_number = PyNumber_Check(B) || (Matrix_Check(B) && MAT_LGT(B) == 1);
 
   int ida, idb;
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A)) { ida = INT; }
+#else
   if (PyInt_Check(A)) { ida = INT; }
+#endif
   else if (PyFloat_Check(A)) { ida = DOUBLE; }
   else if (PyComplex_Check(A)) { ida = COMPLEX; }
   else { ida = X_ID(A); }
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(B)) { idb = INT; }
+#else
   if (PyInt_Check(B)) { idb = INT; }
+#endif
   else if (PyFloat_Check(B)) { idb = DOUBLE; }
   else if (PyComplex_Check(B)) { idb = COMPLEX; }
   else { idb = X_ID(B); }
 
+#if PY_MAJOR_VERSION >= 3
+  int id  = MAX( DOUBLE, MAX( ida, idb ) ) ;
+#else
   int id  = MAX( ida, idb );
+#endif
 
   number a, b;
   if (a_is_number) convert_num[id](&a, A, PyNumber_Check(A), 0);
@@ -1707,36 +1863,58 @@ static PyMethodDef base_functions[] = {
     {NULL}		/* sentinel */
 };
 
-PyMODINIT_FUNC
-initbase(void)
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef base_module = {
+    PyModuleDef_HEAD_INIT,
+    "base",
+    base__doc__,
+    -1,
+    base_functions,
+    NULL, NULL, NULL, NULL
+};
+#define INITERROR return NULL
+PyMODINIT_FUNC PyInit_base(void)
+
+#else
+
+#define INITERROR return 
+PyMODINIT_FUNC initbase(void)
+
+#endif
 {
   static void *base_API[8];
   PyObject *base_mod, *c_api_object;
 
+#if PY_MAJOR_VERSION >= 3
+  base_mod = PyModule_Create(&base_module);
+  if (base_mod == NULL)
+#else
   if (!(base_mod = Py_InitModule3("base", base_functions, base__doc__)))
-    return;
+#endif
+    INITERROR;
 
   /* for MS VC++ compatibility */
   matrix_tp.tp_alloc = PyType_GenericAlloc;
   matrix_tp.tp_free = PyObject_Del;
   if (PyType_Ready(&matrix_tp) < 0)
-    return;
+    INITERROR;
 
   if (PyType_Ready(&matrix_tp) < 0)
-    return;
+    INITERROR;
 
   Py_INCREF(&matrix_tp);
   if (PyModule_AddObject(base_mod, "matrix", (PyObject *) &matrix_tp) < 0)
-    return;
+    INITERROR;
 
   spmatrix_tp.tp_alloc = PyType_GenericAlloc;
   spmatrix_tp.tp_free = PyObject_Del;
   if (PyType_Ready(&spmatrix_tp) < 0)
-    return;
+    INITERROR;
 
   Py_INCREF(&spmatrix_tp);
   if (PyModule_AddObject(base_mod, "spmatrix", (PyObject *) &spmatrix_tp) < 0)
-    return;
+    INITERROR;
 
   One[INT].i = 1; One[DOUBLE].d = 1.0; One[COMPLEX].z = 1.0;
 
@@ -1754,9 +1932,18 @@ initbase(void)
   base_API[6] = (void *)SpMatrix_NewFromIJV;
   base_API[7] = (void *)SpMatrix_Check_func;
 
+#if PY_MAJOR_VERSION >= 3
+  /* Create a Capsule containing the API pointer array's address */
+  c_api_object = PyCapsule_New((void *)base_API, "base_API", NULL);
+#else
   /* Create a CObject containing the API pointer array's address */
   c_api_object = PyCObject_FromVoidPtr((void *)base_API, NULL);
+#endif
 
   if (c_api_object != NULL)
     PyModule_AddObject(base_mod, "_C_API", c_api_object);
+
+#if PY_MAJOR_VERSION >= 3
+  return base_mod;
+#endif
 }
diff --git a/src/C/blas.c b/src/C/blas.c
index ad2c929..eafb957 100644
--- a/src/C/blas.c
+++ b/src/C/blas.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -173,14 +173,24 @@ static int number_from_pyobject(PyObject *o, number *a, int id)
 {
     switch (id){
         case DOUBLE:
+#if PY_MAJOR_VERSION >= 3
+            if (!PyLong_Check(o) && !PyLong_Check(o) &&
+                !PyFloat_Check(o)) return -1;
+#else
             if (!PyInt_Check(o) && !PyLong_Check(o) &&
                 !PyFloat_Check(o)) return -1;
+#endif
             (*a).d = PyFloat_AsDouble(o);
             return 0;
 
         case COMPLEX:
+#if PY_MAJOR_VERSION >= 3
+            if (!PyLong_Check(o) && !PyLong_Check(o) &&
+                !PyFloat_Check(o) && !PyComplex_Check(o)) return -1;
+#else
             if (!PyInt_Check(o) && !PyLong_Check(o) &&
                 !PyFloat_Check(o) && !PyComplex_Check(o)) return -1;
+#endif
             (*a).z = PyComplex_RealAsDouble(o) +
                 I*PyComplex_ImagAsDouble(o);
             return 0;
@@ -751,12 +761,29 @@ static PyObject* iamax(PyObject *self, PyObject *args, PyObject *kwrds)
     if (n == 0) return Py_BuildValue("i", 0);
     if (len(x) < ox + 1+(n-1)*ix) err_buf_len("x");
 
+#if PY_MAJOR_VERSION >= 3
+    double val;
+#endif
     switch (MAT_ID(x)){
         case DOUBLE:
+#if PY_MAJOR_VERSION >= 3
+            Py_BEGIN_ALLOW_THREADS
+            val = idamax_(&n, MAT_BUFD(x)+ox, &ix)-1;
+            Py_END_ALLOW_THREADS
+            return Py_BuildValue("i", val);
+#else
             return Py_BuildValue("i", idamax_(&n, MAT_BUFD(x)+ox, &ix)-1);
+#endif
 
         case COMPLEX:
-	    return Py_BuildValue("i", izamax_(&n, MAT_BUFZ(x)+ox, &ix)-1);
+#if PY_MAJOR_VERSION >= 3
+            Py_BEGIN_ALLOW_THREADS
+            val = izamax_(&n, MAT_BUFZ(x)+ox, &ix)-1;
+            Py_END_ALLOW_THREADS
+            return Py_BuildValue("i", val);
+#else
+            return Py_BuildValue("i", izamax_(&n, MAT_BUFZ(x)+ox, &ix)-1);
+#endif
 
         default:
             err_invalid_id;
@@ -803,14 +830,25 @@ static PyObject* gemv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int m=-1, n=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
     char trans='N';
     char *kwlist[] = {"A", "x", "y", "trans", "alpha", "beta", "m", "n",
         "ldA", "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiiii",
+        kwlist, &A, &x, &y, &trans_, &ao, &bo, &m, &n, &ldA, &ix, &iy,
+        &oA, &ox, &oy))
+        return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiiii",
         kwlist, &A, &x, &y, &trans, &ao, &bo, &m, &n, &ldA, &ix, &iy,
         &oA, &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -939,15 +977,26 @@ static PyObject* gbmv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int m, kl, ku=-1, n=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
-    char trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
+    char trans = 'N';
     char *kwlist[] = {"A", "m", "kl", "x", "y", "trans", "alpha", "beta",
         "n", "ku", "ldA", "incx", "incy", "offsetA", "offsetx", "offsety",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OiiOO|COOiiiiiiii",
+        kwlist, &A, &m, &kl, &x, &y, &trans_, &ao, &bo, &n, &ku, &ldA, &ix,
+        &iy, &oA, &ox, &oy))
+        return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OiiOO|cOOiiiiiiii",
         kwlist, &A, &m, &kl, &x, &y, &trans, &ao, &bo, &n, &ku, &ldA, &ix,
         &iy, &oA, &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1065,14 +1114,25 @@ static PyObject* symv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "x", "y", "uplo", "alpha", "beta", "n",
         "ldA", "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiii",
+        kwlist, &A, &x, &y, &uplo_, &ao, &bo, &n, &ldA, &ix, &iy, &oA,
+        &ox, &oy))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiii",
         kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &ldA, &ix, &iy, &oA,
         &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1163,14 +1223,25 @@ static PyObject* hemv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "x", "y", "uplo", "alpha", "beta", "n",
         "ldA", "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiii",
+        kwlist, &A, &x, &y, &uplo_, &ao, &bo, &n, &ldA, &ix, &iy, &oA,
+        &ox, &oy))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiii",
         kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &ldA, &ix, &iy, &oA,
         &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1265,14 +1336,25 @@ static PyObject* sbmv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "x", "y", "uplo", "alpha", "beta", "n", "k",
         "ldA", "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiiii",
+        kwlist, &A, &x, &y, &uplo_, &ao, &bo, &n, &k, &ldA, &ix, &iy,
+        &oA, &ox, &oy))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiiii",
         kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &k, &ldA, &ix, &iy,
         &oA, &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1357,14 +1439,25 @@ static PyObject* hbmv(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ix=1, iy=1, oA=0, ox=0, oy=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "x", "y", "uplo", "alpha", "beta", "n", "k",
         "ldA", "incx", "incy", "offsetA", "offsetx", "offsety", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COOiiiiiiii",
+        kwlist, &A, &x, &y, &uplo_, &ao, &bo, &n, &k, &ldA, &ix, &iy,
+        &oA, &ox, &oy))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOOiiiiiiii",
         kwlist, &A, &x, &y, &uplo, &ao, &bo, &n, &k, &ldA, &ix, &iy,
         &oA, &ox, &oy))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1451,13 +1544,25 @@ static PyObject* trmv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *x;
     int n=-1, ldA=0, ix=1, oA=0, ox=0;
-    char uplo='L', trans='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
+    char uplo = 'L', trans = 'N', diag = 'N';
     char *kwlist[] = {"A", "x", "uplo", "trans", "diag", "n", "ldA",
         "incx", "offsetA", "offsetx", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiii",
+        kwlist, &A, &x, &uplo_, &trans_, &diag_, &n, &ldA, &ix, &oA, &ox))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiii",
         kwlist, &A, &x, &uplo, &trans, &diag, &n, &ldA, &ix, &oA, &ox))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1539,14 +1644,27 @@ static PyObject* tbmv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *x;
     int n=-1, k=-1, ldA=0, ix=1, oA=0, ox=0;
-    char uplo='L', trans='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
+    char uplo = 'L', trans = 'N', diag = 'N';
     char *kwlist[] = {"A", "x", "uplo", "trans", "diag", "n", "k",
         "ldA", "incx", "offsetA", "offsetx", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiiii",
+        kwlist, &A, &x, &uplo_, &trans_, &diag_, &n, &k, &ldA, &ix, &oA,
+        &ox))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiiii",
         kwlist, &A, &x, &uplo, &trans, &diag, &n, &k, &ldA, &ix, &oA,
         &ox))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1624,13 +1742,25 @@ static PyObject* trsv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *x;
     int n=-1, ldA=0, ix=1, oA=0, ox=0;
-    char uplo='L', trans='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
+    char uplo = 'L', trans = 'N', diag = 'N';
     char *kwlist[] = {"A", "x", "uplo", "trans", "diag", "n", "ldA",
         "incx", "offsetA", "offsetx", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiii",
+        kwlist, &A, &x, &uplo_, &trans_, &diag_, &n, &ldA, &ix, &oA, &ox))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiii",
         kwlist, &A, &x, &uplo, &trans, &diag, &n, &ldA, &ix, &oA, &ox))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1713,14 +1843,27 @@ static PyObject* tbsv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *x;
     int n=-1, k=-1, ldA=0, ix=1, oA=0, ox=0;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
     char uplo='L', trans='N', diag='N';
     char *kwlist[] = {"A", "x", "uplo", "trans", "diag", "n", "k",
         "ldA", "incx", "offsetA", "offsetx", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiiii",
+        kwlist, &A, &x, &uplo_, &trans_, &diag_, &n, &k, &ldA, &ix, &oA,
+        &ox))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiiii",
         kwlist, &A, &x, &uplo, &trans, &diag, &n, &k, &ldA, &ix, &oA,
         &ox))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -1968,13 +2111,23 @@ static PyObject* syr(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int n=-1, ldA=0, ix=1, oA=0, ox=0;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
     char uplo='L';
     char *kwlist[] = {"x", "A", "uplo", "alpha", "n", "incx", "ldA",
         "offsetx", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|COiiiii", kwlist,
+        &x, &A, &uplo_, &ao, &n, &ix, &ldA, &ox, &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cOiiiii", kwlist,
         &x, &A, &uplo, &ao, &n, &ix, &ldA, &ox, &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -2046,13 +2199,23 @@ static PyObject* her(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int n=-1, ldA=0, ix=1, oA=0, ox=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"x", "A", "uplo", "alpha", "n", "incx", "ldA",
         "offsetx", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|COiiiii",
+        kwlist, &x, &A, &uplo_, &ao, &n, &ix, &ldA, &ox, &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cOiiiii",
         kwlist, &x, &A, &uplo, &ao, &n, &ix, &ldA, &ox, &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -2133,14 +2296,25 @@ static PyObject* syr2(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int n=-1, ldA=0, ix=1, iy=1, ox=0, oy=0, oA=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"x", "y", "A", "uplo", "alpha", "n", "incx",
         "incy", "ldA", "offsetx", "offsety", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COiiiiiii",
+        kwlist, &x, &y, &A, &uplo_, &ao, &n, &ix, &iy, &ldA, &ox, &oy,
+        &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOiiiiiii",
         kwlist, &x, &y, &A, &uplo, &ao, &n, &ix, &iy, &ldA, &ox, &oy,
         &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -2220,14 +2394,25 @@ static PyObject* her2(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int n=-1, ldA=0, ix=1, iy=1, ox=0, oy=0, oA=0;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"x", "y", "A", "uplo", "alpha", "n", "incx",
         "incy", "ldA", "offsetx", "offsety", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|COiiiiiii",
+        kwlist, &x, &y, &A, &uplo_, &ao, &n, &ix, &iy, &ldA, &ox, &oy,
+        &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cOiiiiiii",
         kwlist, &x, &y, &A, &uplo, &ao, &n, &ix, &iy, &ldA, &ox, &oy,
         &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(x)) err_mtrx("x");
@@ -2343,15 +2528,27 @@ static PyObject* gemm(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int m=-1, n=-1, k=-1, ldA=0, ldB=0, ldC=0, oA=0, oB=0, oC=0;
-    char transA='N', transB='N';
+#if PY_MAJOR_VERSION >= 3
+    int transA_ = 'N', transB_ = 'N';
+#endif
+    char transA = 'N', transB = 'N';
     char *kwlist[] = {"A", "B", "C", "transA", "transB", "alpha",
         "beta", "m", "n", "k", "ldA", "ldB", "ldC", "offsetA",
         "offsetB", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOiiiiiiiii",
+        kwlist, &A, &B, &C, &transA_, &transB_, &ao, &bo, &m, &n, &k,
+        &ldA, &ldB, &ldC, &oA, &oB, &oC))
+        return NULL;
+    transA = (char) transA_;
+    transB = (char) transB_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOiiiiiiiii",
         kwlist, &A, &B, &C, &transA, &transB, &ao, &bo, &m, &n, &k,
         &ldA, &ldB, &ldC, &oA, &oB, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -2474,15 +2671,27 @@ static PyObject* symm(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int m=-1, n=-1, ldA=0, ldB=0, ldC=0, oA=0, oB=0, oC = 0;
-    char side='L', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int side_  = 'L', uplo_ = 'L';
+#endif
+    char side = 'L', uplo = 'L';
     char *kwlist[] = {"A", "B", "C", "side", "uplo", "alpha", "beta",
         "m", "n", "ldA", "ldB", "ldC", "offsetA", "offsetB", "offsetC",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOiiiiiiii",
+        kwlist, &A, &B, &C, &side_, &uplo_, &ao, &bo, &m, &n, &ldA, &ldB,
+        &ldC, &oA, &oB, &oC))
+        return NULL;
+    side = (char) side_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOiiiiiiii",
         kwlist, &A, &B, &C, &side, &uplo, &ao, &bo, &m, &n, &ldA, &ldB,
         &ldC, &oA, &oB, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -2604,15 +2813,27 @@ static PyObject* hemm(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int m=-1, n=-1, ldA=0, ldB=0, ldC=0, oA=0, oB=0, oC = 0;
-    char side='L', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', uplo_ = 'L';
+#endif
+    char side = 'L', uplo = 'L';
     char *kwlist[] = {"A", "B", "C", "side", "uplo", "alpha", "beta",
         "m", "n", "ldA", "ldB", "ldC", "offsetA", "offsetB", "offsetC",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOiiiiiiii",
+        kwlist, &A, &B, &C, &side_, &uplo_, &ao, &bo, &m, &n, &ldA, &ldB,
+        &ldC, &oA, &oB, &oC))
+        return NULL;
+    side = (char) side_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOiiiiiiii",
         kwlist, &A, &B, &C, &side, &uplo, &ao, &bo, &m, &n, &ldA, &ldB,
         &ldC, &oA, &oB, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -2729,14 +2950,26 @@ static PyObject* syrk(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ldC=0, oA = 0, oC = 0;
-    char trans='N', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N', uplo_ = 'L';
+#endif
+    char trans = 'N', uplo = 'L';
     char *kwlist[] = {"A", "C", "uplo", "trans", "alpha", "beta", "n",
         "k", "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCOOiiiiii",
+        kwlist, &A, &C, &uplo_, &trans_, &ao, &bo, &n, &k, &ldA, &ldC,
+	&oA, &oC))
+        return NULL;
+    uplo = (char) uplo_; 
+    trans = (char) trans_; 
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccOOiiiiii",
         kwlist, &A, &C, &uplo, &trans, &ao, &bo, &n, &k, &ldA, &ldC,
 	&oA, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(C)) err_mtrx("C");
@@ -2834,14 +3067,26 @@ static PyObject* herk(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ldC=0, oA = 0, oC = 0;
-    char trans='N', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N', uplo_ = 'L';
+#endif
+    char trans = 'N', uplo = 'L';
     char *kwlist[] = {"A", "C", "uplo", "trans", "alpha", "beta", "n",
         "k", "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCOOiiiiii",
+        kwlist, &A, &C, &uplo_, &trans_, &ao, &bo, &n, &k, &ldA, &ldC,
+	&oA, &oC))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccOOiiiiii",
         kwlist, &A, &C, &uplo, &trans, &ao, &bo, &n, &k, &ldA, &ldC,
 	&oA, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(C)) err_mtrx("C");
@@ -2947,15 +3192,27 @@ static PyObject* syr2k(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ldB=0, ldC=0, oA = 0, oB = 0, oC = 0;
-    char trans='N', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N', uplo_ = 'L';
+#endif
+    char trans = 'N', uplo = 'L';
     char *kwlist[] = {"A", "B", "C", "uplo", "trans", "alpha", "beta",
         "n", "k", "ldA", "ldB", "ldC", "offsetA", "offsetB", "offsetC",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOiiiiiiii",
+        kwlist, &A, &B, &C, &uplo_, &trans_, &ao, &bo, &n, &k, &ldA, &ldB,
+	&ldC, &oA, &oB, &oC))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOiiiiiiii",
         kwlist, &A, &B, &C, &uplo, &trans, &ao, &bo, &n, &k, &ldA, &ldB,
 	&ldC, &oA, &oB, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3090,15 +3347,27 @@ static PyObject* her2k(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL, *bo=NULL;
     number a, b;
     int n=-1, k=-1, ldA=0, ldB=0, ldC=0, oA = 0, oB = 0, oC = 0;
-    char trans='N', uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N', uplo_ = 'L';
+#endif
+    char trans = 'N', uplo = 'L';
     char *kwlist[] = {"A", "B", "C", "uplo", "trans", "alpha", "beta",
         "n", "k", "ldA", "ldB", "ldC", "offsetA", "offsetB", "offsetC",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCOOiiiiiiii",
+        kwlist, &A, &B, &C, &uplo_, &trans_, &ao, &bo, &n, &k, &ldA, &ldB,
+	&ldC, &oA, &oB, &oC))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ccOOiiiiiiii",
         kwlist, &A, &B, &C, &uplo, &trans, &ao, &bo, &n, &k, &ldA, &ldB,
 	&ldC, &oA, &oB, &oC))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3229,14 +3498,28 @@ static PyObject* trmm(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int m=-1, n=-1, ldA=0, ldB=0, oA=0, oB=0;
-    char side='L', uplo='L', transA='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', uplo_ = 'L', transA_ = 'N', diag_ = 'N';
+#endif
+    char side = 'L', uplo = 'L', transA = 'N', diag = 'N';
     char *kwlist[] = {"A", "B", "side", "uplo", "transA", "diag",
         "alpha", "m", "n", "ldA", "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCCOiiiiii",
+        kwlist, &A, &B, &side_, &uplo_, &transA_, &diag_, &ao, &m, &n, 
+        &ldA, &ldB, &oA, &oB))
+        return NULL;
+    side = (char) side_;
+    uplo = (char) uplo_;
+    transA = (char) transA_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccccOiiiiii",
         kwlist, &A, &B, &side, &uplo, &transA, &diag, &ao, &m, &n, &ldA,
         &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3352,14 +3635,28 @@ static PyObject* trsm(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *ao=NULL;
     number a;
     int m=-1, n=-1, ldA=0, ldB=0, oA=0, oB=0;
-    char side='L', uplo='L', transA='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', uplo_ = 'L', transA_ = 'N', diag_ = 'N';
+#endif
+    char side = 'L', uplo = 'L', transA = 'N', diag = 'N';
     char *kwlist[] = {"A", "B", "side", "uplo", "transA", "diag",
         "alpha", "m", "n", "ldA", "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCCOiiiiii",
+        kwlist, &A, &B, &side_, &uplo_, &transA_, &diag_, &ao, &m, &n, 
+        &ldA, &ldB, &oA, &oB))
+        return NULL;
+    side = (char) side_;
+    uplo = (char) uplo_;
+    transA = (char) transA_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccccOiiiiii",
         kwlist, &A, &B, &side, &uplo, &transA, &diag, &ao, &m, &n, &ldA,
         &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3463,10 +3760,32 @@ static PyMethodDef blas_functions[] = {
   {NULL}  /* Sentinel */
 };
 
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef blas_module = {
+    PyModuleDef_HEAD_INIT,
+    "blas",
+    blas__doc__,
+    -1,
+    blas_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_blas(void)
+{
+  PyObject *m;
+  if (!(m = PyModule_Create(&blas_module))) return NULL;
+  if (import_cvxopt() < 0) return NULL;
+  return m;
+}
+
+#else 
 
 PyMODINIT_FUNC initblas(void)
 {
   PyObject *m;
   m = Py_InitModule3("cvxopt.blas", blas_functions, blas__doc__);
-  if (import_cvxopt() < 0) return;
+  if (import_cvxopt() < 0) return ;
 }
+
+#endif
diff --git a/src/C/cholmod.c b/src/C/cholmod.c
index 1655593..67c7e51 100644
--- a/src/C/cholmod.c
+++ b/src/C/cholmod.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,7 +72,10 @@ static int set_options(void)
 {
     int_t pos=0;
     PyObject *param, *key, *value;
-    char *keystr, err_str[100];
+    char err_str[100];
+#if PY_MAJOR_VERSION < 3
+    char *keystr; 
+#endif
 
     CHOL(defaults)(&Common);
     Common.print = 0;
@@ -85,13 +88,34 @@ static int set_options(void)
         return 0;
     }
     while (PyDict_Next(param, &pos, &key, &value))
+#if PY_MAJOR_VERSION >= 3
+        if (PyUnicode_Check(key)) {
+            const char *keystr = _PyUnicode_AsString(key);
+            if (!strcmp("supernodal", keystr) && PyLong_Check(value))
+                Common.supernodal = (int) PyLong_AsLong(value);
+            else if (!strcmp("print", keystr) && PyLong_Check(value))
+                Common.print = (int) PyLong_AsLong(value);
+            else if (!strcmp("nmethods", keystr) && PyLong_Check(value))
+                Common.nmethods = (int) PyLong_AsLong(value);
+            else if (!strcmp("postorder", keystr) &&
+                PyBool_Check(value))
+                Common.postorder = (int) PyLong_AsLong(value);
+            else if (!strcmp("dbound", keystr) && PyFloat_Check(value))
+                Common.dbound = (double) PyFloat_AsDouble(value);
+            else {
+                sprintf(err_str, "invalid value for CHOLMOD parameter:" \
+                   " %-.20s", keystr);
+                PyErr_SetString(PyExc_ValueError, err_str);
+                Py_DECREF(param);
+                return 0;
+            }
+        }
+#else
         if ((keystr = PyString_AsString(key))) {
-
             if (!strcmp("supernodal", keystr) && PyInt_Check(value))
                 Common.supernodal = (int) PyInt_AsLong(value);
-            else if (!strcmp("print", keystr) && PyInt_Check(value)){
+            else if (!strcmp("print", keystr) && PyInt_Check(value))
                 Common.print = (int) PyInt_AsLong(value);
-            }
             else if (!strcmp("nmethods", keystr) && PyInt_Check(value))
                 Common.nmethods = (int) PyInt_AsLong(value);
             else if (!strcmp("postorder", keystr) &&
@@ -100,13 +124,14 @@ static int set_options(void)
             else if (!strcmp("dbound", keystr) && PyFloat_Check(value))
                 Common.dbound = (double) PyFloat_AsDouble(value);
             else {
-                sprintf(err_str, "invalid value for CHOLMOD parameter: "
-                    "%-.20s", keystr);
+                sprintf(err_str, "invalid value for CHOLMOD parameter:" \
+                   " %-.20s", keystr);
                 PyErr_SetString(PyExc_ValueError, err_str);
                 Py_DECREF(param);
                 return 0;
             }
-    }
+        }
+#endif
     Py_DECREF(param);
     return 1;
 }
@@ -190,10 +215,18 @@ static void free_matrix(cholmod_sparse *A)
     CHOL(free_sparse)(&A, &Common);
 }
 
+#if PY_MAJOR_VERSION >= 3
+static void cvxopt_free_cholmod_factor(void *L)
+{
+   void *Lptr = PyCapsule_GetPointer(L, PyCapsule_GetName(L));   
+   CHOL(free_factor) ((cholmod_factor **) &Lptr, &Common);
+}
+#else
 static void cvxopt_free_cholmod_factor(void *L, void *descr)
 {
     CHOL(free_factor) ((cholmod_factor **) &L, &Common) ;
 }
+#endif
 
 
 static char doc_symbolic[] =
@@ -229,14 +262,23 @@ static PyObject* symbolic(PyObject *self, PyObject *args,
     cholmod_sparse *Ac = NULL;
     cholmod_factor *L;
     matrix *P=NULL;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_='L';
+#endif
     char uplo='L';
     int n;
     char *kwlist[] = {"A", "p", "uplo", NULL};
 
     if (!set_options()) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|OC", kwlist, &A,
+        &P, &uplo_)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|Oc", kwlist, &A,
         &P, &uplo)) return NULL;
+#endif
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A is not a square sparse matrix");
     n = SP_NROWS(A);
@@ -255,17 +297,24 @@ static PyObject* symbolic(PyObject *self, PyObject *args,
     if (Common.status != CHOLMOD_OK){
         if (Common.status == CHOLMOD_OUT_OF_MEMORY)
             return PyErr_NoMemory();
-        else
+        else{
             PyErr_SetString(PyExc_ValueError, "symbolic factorization "
                 "failed");
             return NULL;
+        }
     }
+#if PY_MAJOR_VERSION >= 3
+    return (PyObject *) PyCapsule_New((void *) L, SP_ID(A)==DOUBLE ?  
+        (uplo == 'L' ?  "CHOLMOD FACTOR D L" : "CHOLMOD FACTOR D U") :
+        (uplo == 'L' ?  "CHOLMOD FACTOR Z L" : "CHOLMOD FACTOR Z U"),
+        (PyCapsule_Destructor) &cvxopt_free_cholmod_factor); 
+#else
     return (PyObject *) PyCObject_FromVoidPtrAndDesc((void *) L,
-        SP_ID(A)==DOUBLE ?  (uplo == 'L' ?
-            "CHOLMOD FACTOR D L" : "CHOLMOD FACTOR D U") :
-            (uplo == 'L' ?
-            "CHOLMOD FACTOR Z L" : "CHOLMOD FACTOR Z U"),
-	    cvxopt_free_cholmod_factor);
+        SP_ID(A)==DOUBLE ?  
+        (uplo == 'L' ?  "CHOLMOD FACTOR D L" : "CHOLMOD FACTOR D U") :
+        (uplo == 'L' ?  "CHOLMOD FACTOR Z L" : "CHOLMOD FACTOR Z U"),
+	cvxopt_free_cholmod_factor);
+#endif
 }
 
 
@@ -303,7 +352,12 @@ static PyObject* numeric(PyObject *self, PyObject *args)
     PyObject *F;
     cholmod_factor *Lc;
     cholmod_sparse *Ac = NULL;
-    char *descr, uplo;
+    char uplo;
+#if PY_MAJOR_VERSION >= 3
+    const char *descr; 
+#else
+    char *descr; 
+#endif
 
     if (!set_options()) return NULL;
 
@@ -312,9 +366,14 @@ static PyObject* numeric(PyObject *self, PyObject *args)
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A is not a sparse matrix");
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
+        err_CO("F");
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     descr = PyCObject_GetDesc(F);
     if (!descr) PY_ERR_TYPE("F is not a CHOLMOD factor");
+#endif
     if (SP_ID(A) == DOUBLE){
         if (!strcmp(descr, "CHOLMOD FACTOR D L"))
 	    uplo = 'L';
@@ -330,7 +389,11 @@ static PyObject* numeric(PyObject *self, PyObject *args)
         else
 	    PY_ERR_TYPE("F is not the CHOLMOD factor of a 'z' matrix");
     }
+#if PY_MAJOR_VERSION >= 3
+    Lc = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
+#else
     Lc = (cholmod_factor *) PyCObject_AsVoidPtr(F);
+#endif
     if (!(Ac = pack(A, uplo))) return PyErr_NoMemory();
     CHOL(factorize) (Ac, Lc, &Common);
     CHOL(free_sparse)(&Ac, &Common);
@@ -403,7 +466,11 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
     matrix *B;
     PyObject *F;
     int i, n, oB=0, ldB=0, nrhs=-1, sys=0;
+#if PY_MAJOR_VERSION >= 3
+    const char *descr;
+#else
     char *descr;
+#endif
     char *kwlist[] = {"F", "B", "sys", "nrhs", "ldB", "offsetB", NULL};
     int sysvalues[] = { CHOLMOD_A, CHOLMOD_LDLt, CHOLMOD_LD,
         CHOLMOD_DLt, CHOLMOD_L, CHOLMOD_Lt, CHOLMOD_D, CHOLMOD_P,
@@ -414,11 +481,19 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|iiii", kwlist,
         &F, &B, &sys, &nrhs, &ldB, &oB)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
+        err_CO("F");
+    if (strncmp(descr, "CHOLMOD FACTOR", 14))
+        PY_ERR_TYPE("F is not a CHOLMOD factor");
+    cholmod_factor *L = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     descr = PyCObject_GetDesc(F);
     if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
         PY_ERR_TYPE("F is not a CHOLMOD factor");
     cholmod_factor *L = (cholmod_factor *) PyCObject_AsVoidPtr(F);
+#endif
     if (L->xtype == CHOLMOD_PATTERN)
         PY_ERR(PyExc_ValueError, "called with symbolic factor");
 
@@ -497,7 +572,11 @@ static PyObject* spsolve(PyObject *self, PyObject *args,
     PyObject *F;
     cholmod_factor *L;
     int n, sys=0;
+#if PY_MAJOR_VERSION >= 3
+    const char *descr;
+#else
     char *descr;
+#endif
     char *kwlist[] = {"F", "B", "sys", NULL};
     int sysvalues[] = {CHOLMOD_A, CHOLMOD_LDLt, CHOLMOD_LD,
         CHOLMOD_DLt, CHOLMOD_L, CHOLMOD_Lt, CHOLMOD_D, CHOLMOD_P,
@@ -508,11 +587,19 @@ static PyObject* spsolve(PyObject *self, PyObject *args,
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|i", kwlist, &F,
         &B, &sys)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
+        err_CO("F");
+    if (strncmp(descr, "CHOLMOD FACTOR", 14))
+        PY_ERR_TYPE("F is not a CHOLMOD factor");
+    L = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     descr = PyCObject_GetDesc(F);
     if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
         PY_ERR_TYPE("F is not a CHOLMOD factor");
     L = (cholmod_factor *) PyCObject_AsVoidPtr(F);
+#endif
     if (L->xtype == CHOLMOD_PATTERN)
         PY_ERR(PyExc_ValueError, "called with symbolic factor");
     n = L->n;
@@ -589,13 +676,22 @@ static PyObject* linsolve(PyObject *self, PyObject *args,
     cholmod_factor *L=NULL;
     cholmod_dense *x=NULL, *b=NULL;
     void *b_old;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
     char uplo='L';
     char *kwlist[] = {"A", "B", "p", "uplo", "nrhs", "ldB", "offsetB",
         NULL};
 
     if (!set_options()) return NULL;
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OCiii", kwlist,
+        &A,  &B, &P, &uplo_, &nrhs, &ldB, &oB)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ociii", kwlist,
         &A,  &B, &P, &uplo, &nrhs, &ldB, &oB)) return NULL;
+#endif
 
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A is not a sparse matrix");
@@ -731,12 +827,21 @@ static PyObject* splinsolve(PyObject *self, PyObject *args,
     int n, nnz;
     cholmod_sparse *Ac=NULL, *Bc=NULL, *Xc=NULL;
     cholmod_factor *L=NULL;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_='L';
+#endif
     char uplo='L';
     char *kwlist[] = {"A", "B", "p", "uplo", NULL};
 
     if (!set_options()) return NULL;
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OC", kwlist, &A,
+        &B, &P, &uplo_)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Oc", kwlist, &A,
         &B, &P, &uplo)) return NULL;
+#endif
 
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A is not a square sparse matrix");
@@ -764,10 +869,11 @@ static PyObject* splinsolve(PyObject *self, PyObject *args,
         CHOL(free_sparse)(&Ac, &Common);
         if (Common.status == CHOLMOD_OUT_OF_MEMORY)
             return PyErr_NoMemory();
-        else
+        else {
             PyErr_SetString(PyExc_ValueError, "symbolic factorization "
                 "failed");
             return NULL;
+        }
     }
 
     CHOL(factorize) (Ac, L, &Common);
@@ -851,17 +957,29 @@ static PyObject* diag(PyObject *self, PyObject *args)
     PyObject *F;
     matrix *d=NULL;
     cholmod_factor *L;
+#if PY_MAJOR_VERSION >= 3
+    const char *descr;
+#else
     char *descr;
+#endif
     int k, strt, incx=1, incy, nrows, ncols;
 
     if (!set_options()) return NULL;
     if (!PyArg_ParseTuple(args, "O", &F)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
+        err_CO("F");
+    if (strncmp(descr, "CHOLMOD FACTOR", 14))
+        PY_ERR_TYPE("F is not a CHOLMOD factor");
+    L = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     descr = PyCObject_GetDesc(F);
     if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
         PY_ERR_TYPE("F is not a CHOLMOD factor");
     L = (cholmod_factor *) PyCObject_AsVoidPtr(F);
+#endif
 
     /* Check factorization */
     if (L->xtype == CHOLMOD_PATTERN  || L->minor<L->n || !L->is_ll
@@ -898,16 +1016,28 @@ static PyObject* getfactor(PyObject *self, PyObject *args)
     PyObject *F;
     cholmod_factor *Lf;
     cholmod_sparse *Ls;
+#if PY_MAJOR_VERSION >= 3
+    const char *descr;
+#else
     char *descr;
+#endif
 
     if (!set_options()) return NULL;
     if (!PyArg_ParseTuple(args, "O", &F)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
+        err_CO("F");
+    if (strncmp(descr, "CHOLMOD FACTOR", 14))
+        PY_ERR_TYPE("F is not a CHOLMOD factor");
+    Lf = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     descr = PyCObject_GetDesc(F);
     if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
         PY_ERR_TYPE("F is not a CHOLMOD factor");
     Lf = (cholmod_factor *) PyCObject_AsVoidPtr(F);
+#endif
 
     /* Check factorization */
     if (Lf->xtype == CHOLMOD_PATTERN)
@@ -951,12 +1081,35 @@ static PyMethodDef cholmod_functions[] = {
   {NULL}  /* Sentinel */
 };
 
-PyMODINIT_FUNC initcholmod(void)
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef cholmod_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "cholmod",
+    cholmod__doc__,
+    -1,
+    cholmod_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_cholmod(void)
 {
     CHOL(start) (&Common);
+    if (!(cholmod_module = PyModule_Create(&cholmod_module_def)))
+        return NULL;
+    PyModule_AddObject(cholmod_module, "options", PyDict_New());
+    if (import_cvxopt() < 0) return NULL;
+    return cholmod_module;
+}
+
+#else 
 
+PyMODINIT_FUNC initcholmod(void)
+{
+    CHOL(start) (&Common);
     cholmod_module = Py_InitModule3("cvxopt.cholmod", cholmod_functions,
         cholmod__doc__);
     PyModule_AddObject(cholmod_module, "options", PyDict_New());
     if (import_cvxopt() < 0) return;
 }
+#endif
diff --git a/src/C/cvxopt.h b/src/C/cvxopt.h
index 22c60af..6802bcb 100644
--- a/src/C/cvxopt.h
+++ b/src/C/cvxopt.h
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,18 +34,6 @@
 #ifndef __CVXOPT__
 #define __CVXOPT__
 
-/*
-static void * malloc_aligned(size_t size) {
-  void *p = NULL;
-  if (!posix_memalign(&p, 16, size))
-    return p;
-  else
-    return NULL;
-}
-
-#define malloc(size) malloc_aligned(size)
-*/
-
 #define INT       0
 #define DOUBLE    1
 #define COMPLEX   2
@@ -55,7 +43,14 @@ static void * malloc_aligned(size_t size) {
 typedef struct {
   PyObject_HEAD
   void *buffer;          /* in column-major-mode array of type 'id' */
+#if PY_MAJOR_VERSION >= 3
+  int nrows, ncols;      /* number of rows and columns */
+  int_t shape[2];
+  int_t strides[2];
+  int_t ob_exports;
+#else
   int_t nrows, ncols;    /* number of rows and columns */
+#endif
   int   id;              /* DOUBLE, INT, COMPLEX */
 } matrix;
 
@@ -74,8 +69,8 @@ typedef struct {
 
 #ifdef BASE_MODULE
 
-#define Matrix_Check(v) ((v)->ob_type == &matrix_tp)
-#define SpMatrix_Check(v) ((v)->ob_type == &spmatrix_tp)
+#define Matrix_Check(self) PyObject_TypeCheck(self, &matrix_tp)
+#define SpMatrix_Check(self) PyObject_TypeCheck(self, &spmatrix_tp)
 
 #else
 
@@ -102,10 +97,15 @@ import_cvxopt(void)
 
   if (module != NULL) {
     PyObject *c_api_object = PyObject_GetAttrString(module, "_C_API");
-    if (c_api_object == NULL)
-      return -1;
-    if (PyCObject_Check(c_api_object))
-      cvxopt_API = (void **)PyCObject_AsVoidPtr(c_api_object);
+#if PY_MAJOR_VERSION >= 3
+    if (!c_api_object || !PyCapsule_IsValid(c_api_object, "base_API"))
+        return -1;
+    cvxopt_API = (void **) PyCapsule_GetPointer(c_api_object, "base_API");
+#else
+    if (!c_api_object || !(PyCObject_Check(c_api_object)))
+        return -1;
+    cvxopt_API = (void **) PyCObject_AsVoidPtr(c_api_object);
+#endif
     Py_DECREF(c_api_object);
   }
   return 0;
diff --git a/src/C/dense.c b/src/C/dense.c
index d443472..b8d65f7 100644
--- a/src/C/dense.c
+++ b/src/C/dense.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 
 #include <complexobject.h>
 
+#if PY_MAJOR_VERSION < 3
 /* NumPy array protocol */
 typedef struct {
   int version;
@@ -37,6 +38,7 @@ typedef struct {
   int_t *strides;
   void *data;
 } PyArrayInterface;
+#endif
 
 static const char PY_ARRAY_TC[3] = { 'i', 'f', 'c' };
 
@@ -145,7 +147,11 @@ matrix * Matrix_New(int_t nrows, int_t ncols, int id)
 
   a->id = id; a->nrows = nrows; a->ncols = ncols;
   if (!(a->buffer =  calloc(nrows*ncols,E_SIZE[id]))) {
+#if PY_MAJOR_VERSION >= 3
+    Py_TYPE(a)->tp_free((PyObject*)a);
+#else
     a->ob_type->tp_free((PyObject*)a);
+#endif
     return (matrix *)PyErr_NoMemory();
   }
 
@@ -172,6 +178,7 @@ matrix *Matrix_NewFromMatrix(matrix *src, int id)
   return a;
 }
 
+#if PY_MAJOR_VERSION < 3
 /*
   Creates a matrix from a PyArrayInterface.
  */
@@ -186,6 +193,7 @@ matrix *Matrix_NewFromArrayStruct(PyObject *obj, int id, int_t *ndim)
   if (src->nd != 1 && src->nd != 2)
     PY_ERR(PyExc_TypeError, "imported array must have 1 or 2 dimensions");
 
+
   int src_id;
   switch (src->typekind) {
   case 'i' : src_id = INT; break;
@@ -256,6 +264,7 @@ matrix *Matrix_NewFromArrayStruct(PyObject *obj, int id, int_t *ndim)
   Py_DECREF(cobj);
   return a;
 }
+#endif
 
 /*
   Generates a matrix with all entries equal.
@@ -284,6 +293,7 @@ matrix * Matrix_NewFromSequence(PyObject *x, int id)
   PyObject *seq = PySequence_Fast(x, "list is not iterable");
   if (!seq) return NULL;
 
+
   if (id == -1) {
     for (i=0; i<len; i++) {
       PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
@@ -442,7 +452,11 @@ static void
 matrix_dealloc(matrix* self)
 {
   free(self->buffer);
+#if PY_MAJOR_VERSION >= 3
+  Py_TYPE(self)->tp_free((PyObject*)self);
+#else
   self->ob_type->tp_free((PyObject*)self);
+#endif
 }
 
 static PyObject *
@@ -454,8 +468,13 @@ matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
   int_t nrows=0, ncols=0;
   char tc = 0;
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOC:matrix", kwlist,
+      &Objx, &size, &tc))
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOc:matrix", kwlist,
       &Objx, &size, &tc))
+#endif
     return NULL;
 
   if (size && !PyArg_ParseTuple(size, "ll", &nrows, &ncols))
@@ -494,11 +513,13 @@ matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     }
   }
 
+#if PY_MAJOR_VERSION < 3
   /* PyArrayStructure */
   else if (PyObject_HasAttrString(Objx,"__array_struct__")) {
     int_t ndim = 0;
     ret = Matrix_NewFromArrayStruct(Objx, id, &ndim);
   }
+#endif
 
   /* x is a list */
   else if (PyList_Check(Objx)) {
@@ -585,8 +606,13 @@ matrix * create_indexlist(int_t dim, PyObject *A)
   int_t i, j;
 
   /* integer */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A)) {
+    i = PyLong_AS_LONG(A);
+#else
   if (PyInt_Check(A)) {
     i = PyInt_AS_LONG(A);
+#endif
     if (OUT_RNG(i,dim)) PY_ERR(PyExc_IndexError, "index out of range");
 
     if ((x = Matrix_New(1,1,INT))) MAT_BUFI(x)[0] = i;
@@ -596,8 +622,13 @@ matrix * create_indexlist(int_t dim, PyObject *A)
   else if (PySlice_Check(A)) {
     int_t start, stop, step, lgt;
 
+#if PY_MAJOR_VERSION >= 3
+    if (PySlice_GetIndicesEx(A, dim, &start, &stop, &step, &lgt) < 0) 
+        return NULL;
+#else
     if (PySlice_GetIndicesEx((PySliceObject*)A, dim,
         &start, &stop, &step, &lgt) < 0) return NULL;
+#endif
 
     if ((x = Matrix_New(lgt, 1, INT)))
       for (i=start, j=0; j<lgt; i += step, j++) MAT_BUFI(x)[j] = i;
@@ -635,8 +666,14 @@ static PyObject *
 matrix_subscr(matrix* self, PyObject* args)
 {
   matrix *Il = NULL, *Jl = NULL, *ret;
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(args)) {
+    int_t i = PyLong_AS_LONG(args);
+#else
   if (PyInt_Check(args)) {
     int_t i = PyInt_AS_LONG(args);
+#endif
+
     if (OUT_RNG(i,MAT_LGT(self)))
       PY_ERR(PyExc_IndexError, "index out of range");
 
@@ -659,15 +696,19 @@ matrix_subscr(matrix* self, PyObject* args)
     free_lists_exit(args,(PyObject *)NULL,Il,(PyObject *)NULL,(PyObject *)ret);
   }
 
-  /* remainding cases are different two argument indexing */
+  /* remaining cases are different two argument indexing */
   PyObject *argI = NULL, *argJ = NULL;
   if (!PyArg_ParseTuple(args, "OO", &argI,&argJ))
     PY_ERR_TYPE("invalid index arguments");
 
   /* handle normal subscripts (two integers) separately */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(argI) && PyLong_Check(argJ)) {
+    int i = PyLong_AS_LONG(argI), j = PyLong_AS_LONG(argJ);
+#else
   if (PyInt_Check(argI) && PyInt_Check(argJ)) {
-
     int i = PyInt_AS_LONG(argI), j = PyInt_AS_LONG(argJ);
+#endif
     if ( OUT_RNG(i, self->nrows) || OUT_RNG(j, self->ncols))
       PY_ERR(PyExc_IndexError, "index out of range");
 
@@ -680,10 +721,17 @@ matrix_subscr(matrix* self, PyObject* args)
     int_t rowstart, rowstop, rowstep, rowlgt;
     int_t colstart, colstop, colstep, collgt;
 
+#if PY_MAJOR_VERSION >= 3
+    if ( (PySlice_GetIndicesEx(argI, MAT_NROWS(self), &rowstart, &rowstop,
+        &rowstep, &rowlgt) < 0) || 
+        (PySlice_GetIndicesEx(argJ, MAT_NCOLS(self), &colstart, &colstop, 
+        &colstep, &collgt) < 0)) return NULL;
+#else
     if ( (PySlice_GetIndicesEx((PySliceObject*)argI, MAT_NROWS(self),
         &rowstart, &rowstop, &rowstep, &rowlgt) < 0) ||
         (PySlice_GetIndicesEx((PySliceObject*)argJ, MAT_NCOLS(self),
-            &colstart, &colstop, &colstep, &collgt) < 0)) return NULL;
+        &colstart, &colstop, &colstep, &collgt) < 0)) return NULL;
+#endif
 
     if (!(ret = Matrix_New(rowlgt, collgt, self->id)))
       return PyErr_NoMemory();
@@ -742,10 +790,14 @@ matrix_ass_subscr(matrix* self, PyObject* args, PyObject* val)
 
   if (!(PY_NUMBER(val) || Matrix_Check(val) || SpMatrix_Check(val))) {
 
+#if PY_MAJOR_VERSION >= 3
+    val = (PyObject *)Matrix_NewFromSequence(val, MAT_ID(self));
+#else
     if (PyObject_HasAttrString(val,"__array_struct__"))
       val = (PyObject *)Matrix_NewFromArrayStruct(val, -1, &arraystruct_nd);
     else
       val = (PyObject *)Matrix_NewFromSequence(val, MAT_ID(self));
+#endif
 
     if (!val)
       PY_ERR_INT(PyExc_NotImplementedError, "invalid type in assignment");
@@ -756,7 +808,11 @@ matrix_ass_subscr(matrix* self, PyObject* args, PyObject* val)
   if (get_id(val, (PY_NUMBER(val) ? 1 : 0)) > id)
     PY_ERR_INT(PyExc_TypeError, "invalid type in assignment");
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(args) || PyList_Check(args) ||
+#else
   if (PyInt_Check(args) || PyList_Check(args) ||
+#endif
       Matrix_Check(args) || PySlice_Check(args)) {
 
     if (!(Il = create_indexlist(MAT_LGT(self), args))) {
@@ -805,7 +861,7 @@ matrix_ass_subscr(matrix* self, PyObject* args, PyObject* val)
     free_lists_exit(args,(PyObject *)NULL,Il,(PyObject *)NULL,0);
   }
 
-  /* remainding cases are different two argument indexing */
+  /* remaining cases are different two argument indexing */
   PyObject *argI = NULL, *argJ = NULL;
   if (!PyArg_ParseTuple(args, "OO", &argI,&argJ))
     PY_ERR_INT(PyExc_TypeError, "invalid index arguments");
@@ -817,10 +873,17 @@ matrix_ass_subscr(matrix* self, PyObject* args, PyObject* val)
     int_t rowstart, rowstop, rowstep, rowlgt;
     int_t colstart, colstop, colstep, collgt;
 
+#if PY_MAJOR_VERSION >= 3
+    if ( (PySlice_GetIndicesEx(argI, MAT_NROWS(self), &rowstart, &rowstop,
+         &rowstep, &rowlgt) < 0) || 
+         (PySlice_GetIndicesEx(argJ, MAT_NCOLS(self), &colstart, &colstop,
+         &colstep, &collgt) < 0)) return -1;
+#else
     if ( (PySlice_GetIndicesEx((PySliceObject*)argI, MAT_NROWS(self),
         &rowstart, &rowstop, &rowstep, &rowlgt) < 0) ||
         (PySlice_GetIndicesEx((PySliceObject*)argJ, MAT_NCOLS(self),
             &colstart, &colstop, &colstep, &collgt) < 0)) return -1;
+#endif
 
     if (decref_val && MAT_LGT(val) == rowlgt*collgt) {
       MAT_NROWS(val) = rowlgt; MAT_NCOLS(val) = collgt;
@@ -985,10 +1048,41 @@ static PyObject * matrix_imag(matrix *self) {
   return (PyObject *)ret;
 }
 
+#if PY_MAJOR_VERSION >= 3
+
 static char doc_tofile[] =
     "Writes a matrix to file\n\n"
     "ARGUMENTS\n"
-    "fo          a Python file object prevously obtained by open()\n\n";
+    "s          a Python stream object, for example obtained by open()\n\n";
+static PyObject *
+matrix_tofile(matrix *self, PyObject *args, PyObject *kwrds)
+{
+  PyObject *f, *bytes, *res;
+  char *kwlist[] = {"s", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O:fromfile", kwlist, &f))
+    return NULL;
+
+  bytes = PyBytes_FromStringAndSize(self->buffer, E_SIZE[MAT_ID(self)]*MAT_LGT(self));
+
+  if (bytes == NULL)
+    return NULL;
+
+  res = PyObject_CallMethod(f, "write", "O", bytes);
+  Py_DECREF(bytes);
+  if (res == NULL)
+    return NULL;
+  Py_DECREF(res);
+
+  return Py_BuildValue("");
+}
+
+#else
+
+static char doc_tofile[] =
+    "Writes a matrix to file\n\n"
+    "ARGUMENTS\n"
+    "fo          a Python file object previously obtained by open()\n\n";
 static PyObject *
 matrix_tofile(matrix *self, PyObject *args, PyObject *kwrds)
 {
@@ -1009,6 +1103,54 @@ matrix_tofile(matrix *self, PyObject *args, PyObject *kwrds)
   return Py_BuildValue("");
 }
 
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+
+static char doc_fromfile[] =
+	"Reads a matrix from file\n\n"
+	"ARGUMENTS\n"
+	"s          a Python stream object, for example obtained by open()\n\n";
+static PyObject *
+matrix_fromfile(matrix *self, PyObject *args, PyObject *kwrds)
+{
+  PyObject *f, *b;
+  char *kwlist[] = {"s", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O:fromfile", kwlist, &f))
+    return NULL;
+
+  b = PyObject_CallMethod(f, "read", "n", E_SIZE[self->id]*MAT_LGT(self));
+  if (b == NULL)
+    return NULL;
+
+  if (!PyBytes_Check(b)) {
+    PyErr_SetString(PyExc_TypeError,
+        "read() didn't return bytes");
+    Py_DECREF(b);
+    return NULL;
+  }
+
+  if (PyBytes_GET_SIZE(b) != E_SIZE[self->id]*MAT_LGT(self)) {
+    PyErr_SetString(PyExc_EOFError,
+        "read() didn't return enough bytes");
+    Py_DECREF(b);
+    return NULL;
+  }
+
+  Py_buffer view;
+  PyObject_GetBuffer(b, &view, PyBUF_SIMPLE);
+  memcpy(self->buffer, view.buf, E_SIZE[self->id]*MAT_LGT(self));
+
+  PyBuffer_Release(&view);
+  Py_DECREF(b);
+
+  return Py_BuildValue("");
+}
+
+#else
+
 static char doc_fromfile[] =
     "Reads a matrix from file\n\n"
     "ARGUMENTS\n"
@@ -1035,6 +1177,8 @@ matrix_fromfile(matrix *self, PyObject *args, PyObject *kwrds)
   return Py_BuildValue("");
 }
 
+#endif
+
 static PyObject *
 matrix_getstate(matrix *self)
 {
@@ -1044,8 +1188,13 @@ matrix_getstate(matrix *self)
     Py_XDECREF(list); Py_XDECREF(size); return NULL;
   }
 
+#if PY_MAJOR_VERSION >= 3
+  PyTuple_SET_ITEM(size, 0, PyLong_FromLong(MAT_NROWS(self)));
+  PyTuple_SET_ITEM(size, 1, PyLong_FromLong(MAT_NCOLS(self)));
+#else
   PyTuple_SET_ITEM(size, 0, PyInt_FromLong(MAT_NROWS(self)));
   PyTuple_SET_ITEM(size, 1, PyInt_FromLong(MAT_NCOLS(self)));
+#endif
 
   int i;
   for (i=0; i<MAT_LGT(self); i++) {
@@ -1058,22 +1207,26 @@ matrix_getstate(matrix *self)
 static PyObject *
 matrix_reduce(matrix* self)
 {
+#if PY_MAJOR_VERSION >= 3
+  return Py_BuildValue("ON", Py_TYPE(self), matrix_getstate(self));
+#else
   return Py_BuildValue("ON", self->ob_type, matrix_getstate(self));
+#endif
 }
 
 static PyMethodDef matrix_methods[] = {
     {"trans", (PyCFunction)matrix_transpose, METH_NOARGS,
         "Returns the matrix transpose"},
-        {"ctrans", (PyCFunction)matrix_ctranspose, METH_NOARGS,
-            "Returns the matrix conjugate transpose"},
-            {"real", (PyCFunction)matrix_real, METH_NOARGS,
-                "Returns real part of matrix"},
-                {"imag", (PyCFunction)matrix_imag, METH_NOARGS,
-                    "Returns imaginary part of matrix"},
-                    {"tofile", (PyCFunction)matrix_tofile, METH_VARARGS|METH_KEYWORDS, doc_tofile},
-                    {"fromfile", (PyCFunction)matrix_fromfile, METH_VARARGS|METH_KEYWORDS, doc_fromfile},
-                    {"__reduce__", (PyCFunction)matrix_reduce, METH_NOARGS, "__reduce__() -> (cls, state)"},
-                    {NULL}  /* Sentinel */
+    {"ctrans", (PyCFunction)matrix_ctranspose, METH_NOARGS,
+        "Returns the matrix conjugate transpose"},
+    {"real", (PyCFunction)matrix_real, METH_NOARGS,
+        "Returns real part of matrix"},
+    {"imag", (PyCFunction)matrix_imag, METH_NOARGS,
+        "Returns imaginary part of matrix"},
+    {"tofile", (PyCFunction)matrix_tofile, METH_VARARGS|METH_KEYWORDS, doc_tofile},
+    {"fromfile", (PyCFunction)matrix_fromfile, METH_VARARGS|METH_KEYWORDS, doc_fromfile},
+    {"__reduce__", (PyCFunction)matrix_reduce, METH_NOARGS, "__reduce__() -> (cls, state)"},
+    {NULL}  /* Sentinel */
 };
 
 static PyObject *
@@ -1081,8 +1234,13 @@ matrix_get_size(matrix *self, void *closure)
 {
   PyObject *t = PyTuple_New(2);
 
+#if PY_MAJOR_VERSION >= 3
+  PyTuple_SET_ITEM(t, 0, PyLong_FromLong(self->nrows));
+  PyTuple_SET_ITEM(t, 1, PyLong_FromLong(self->ncols));
+#else
   PyTuple_SET_ITEM(t, 0, PyInt_FromLong(self->nrows));
   PyTuple_SET_ITEM(t, 1, PyInt_FromLong(self->ncols));
+#endif
 
   return t;
 }
@@ -1096,12 +1254,22 @@ matrix_set_size(matrix *self, PyObject *value, void *closure)
   if (!PyTuple_Check(value) || PyTuple_Size(value) != 2)
     PY_ERR_INT(PyExc_TypeError, "can only assign a 2-tuple to size");
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyLong_Check(PyTuple_GET_ITEM(value, 0)) ||
+      !PyLong_Check(PyTuple_GET_ITEM(value, 1)))
+
+      PY_ERR_INT(PyExc_TypeError, "invalid size tuple");
+
+  int m = PyLong_AS_LONG(PyTuple_GET_ITEM(value, 0));
+  int n = PyLong_AS_LONG(PyTuple_GET_ITEM(value, 1));
+#else
   if (!PyInt_Check(PyTuple_GET_ITEM(value, 0)) ||
       !PyInt_Check(PyTuple_GET_ITEM(value, 1)))
-    PY_ERR_INT(PyExc_TypeError, "invalid size tuple");
+      PY_ERR_INT(PyExc_TypeError, "invalid size tuple");
 
   int m = PyInt_AS_LONG(PyTuple_GET_ITEM(value, 0));
   int n = PyInt_AS_LONG(PyTuple_GET_ITEM(value, 1));
+#endif
 
   if (m<0 || n<0)
     PY_ERR_INT(PyExc_TypeError, "dimensions must be non-negative");
@@ -1117,9 +1285,57 @@ matrix_set_size(matrix *self, PyObject *value, void *closure)
 
 static PyObject * matrix_get_typecode(matrix *self, void *closure)
 {
+#if PY_MAJOR_VERSION >= 3
+  return PyUnicode_FromStringAndSize(TC_CHAR[self->id], 1);
+#else
   return PyString_FromStringAndSize(TC_CHAR[self->id], 1);
+#endif
+}
+
+#if PY_MAJOR_VERSION >= 3
+
+static int
+matrix_buffer_getbuf(matrix *self, Py_buffer *view, int flags)
+{
+
+  if (view==NULL) return 0;
+
+  view->buf = self->buffer;
+  view->len = MAT_LGT(self)*E_SIZE[self->id];
+  view->readonly = 0;
+  view->format = NULL; //FIXME
+  view->ndim = 2;
+
+  view->obj = (PyObject*)self;
+  Py_INCREF(self);
+
+  view->itemsize = E_SIZE[self->id];
+  view->suboffsets = NULL;
+  self->shape[0] = self->nrows; self->shape[1] = self->ncols;
+  view->shape = self->shape;
+
+  self->strides[0] = view->itemsize;
+  self->strides[1] = self->nrows*view->itemsize;
+  view->strides = self->strides;
+
+  view->internal = NULL;
+  self->ob_exports++;
+  return 0;
 }
 
+static void
+matrix_buffer_relbuf(matrix *self, Py_buffer *view)
+{
+  self->ob_exports--;
+}
+
+static PyBufferProcs matrix_as_buffer = {
+    (getbufferproc)matrix_buffer_getbuf,
+    (releasebufferproc)matrix_buffer_relbuf
+};
+
+
+#else
 
 static void matrix_free_array_struct(void *a_struct, void *descr)
 {
@@ -1155,6 +1371,7 @@ static PyObject * matrix_array_struct(matrix *self, void *closure) {
       "CVXOPT ARRAY STRUCT", matrix_free_array_struct);
 
 }
+#endif
 
 static PyObject * matrix_get_T(matrix *self, void *closure)
 {
@@ -1169,56 +1386,67 @@ static PyObject * matrix_get_H(matrix *self, void *closure)
 static PyGetSetDef matrix_getsets[] = {
     {"size", (getter) matrix_get_size, (setter) matrix_set_size,
         "matrix dimensions"},
-        {"typecode", (getter) matrix_get_typecode, NULL, "typecode character"},
-        {"__array_struct__", (getter) matrix_array_struct, NULL,
-            "C object implementing the NumPy array protocol"},
-            {"T", (getter) matrix_get_T, NULL, "transpose"},
-            {"H", (getter) matrix_get_H, NULL, "conjugate transpose"},
-            {NULL}  /* Sentinel */
+    {"typecode", (getter) matrix_get_typecode, NULL, "typecode character"},
+#if PY_MAJOR_VERSION <3
+    {"__array_struct__", (getter) matrix_array_struct, NULL,
+        "C object implementing the NumPy array protocol"},
+#endif
+    {"T", (getter) matrix_get_T, NULL, "transpose"},
+    {"H", (getter) matrix_get_H, NULL, "conjugate transpose"},
+    {NULL}  /* Sentinel */
 };
 
 PyTypeObject matrix_tp = {
+#if PY_MAJOR_VERSION >= 3
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
     PyObject_HEAD_INIT(NULL)
     0,
+#endif
     "cvxopt.base.matrix",
     sizeof(matrix),
     0,
-    (destructor)matrix_dealloc,	        /* tp_dealloc */
-    0,	               	                /* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    (reprfunc)matrix_repr,	                /* tp_repr */
-    &matrix_as_number,			/* tp_as_number */
-    0,	                                /* tp_as_sequence */
-    &matrix_as_mapping,   	                /* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    (reprfunc)matrix_str,			/* tp_str */
-    0,		                        /* tp_getattro */
-    0,			                /* tp_setattro */
-    0,			                /* tp_as_buffer */
+    (destructor)matrix_dealloc,	 /* tp_dealloc */
+    0,                           /* tp_print */
+    0,                           /* tp_getattr */
+    0,                           /* tp_setattr */
+    0,                           /* tp_compare */
+    (reprfunc)matrix_repr,       /* tp_repr */
+    &matrix_as_number,           /* tp_as_number */
+    0,                           /* tp_as_sequence */
+    &matrix_as_mapping,          /* tp_as_mapping */
+    0,                           /* tp_hash */
+    0,                           /* tp_call */
+    (reprfunc)matrix_str,        /* tp_str */
+    0,                           /* tp_getattro */
+    0,                           /* tp_setattro */
+#if PY_MAJOR_VERSION >= 3
+    &matrix_as_buffer,           /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+#else
+    0,                           /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-    Py_TPFLAGS_CHECKTYPES,                  /* tp_flags */
-    0,					/* tp_doc */
-    0,					/* tp_traverse */
-    0,					/* tp_clear */
-    (richcmpfunc)matrix_richcompare,        /* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    (getiterfunc)matrix_iter,		/* tp_iter */
-    0,	       	                        /* tp_iternext */
-    matrix_methods,		                /* tp_methods */
-    0,			        	/* tp_members */
-    matrix_getsets,			        /* tp_getset */
-    0,		                        /* tp_base */
-    0,					/* tp_dict */
-    0,					/* tp_descr_get */
-    0,					/* tp_descr_set */
-    0,					/* tp_dictoffset */
-    0,                                      /* tp_init */
-    0,              			/* tp_alloc */
-    matrix_new,				/* tp_new */
-    0,           				/* tp_free */
+    Py_TPFLAGS_CHECKTYPES,       /* tp_flags */
+#endif
+    0,                           /* tp_doc */
+    0,                           /* tp_traverse */
+    0,                           /* tp_clear */
+    (richcmpfunc)matrix_richcompare,  /* tp_richcompare */
+    0,                          /* tp_weaklistoffset */
+    (getiterfunc)matrix_iter,   /* tp_iter */
+    0,                          /* tp_iternext */
+    matrix_methods,             /* tp_methods */
+    0,                          /* tp_members */
+    matrix_getsets,             /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    0,                          /* tp_dictoffset */
+    0,                          /* tp_init */
+    0,                          /* tp_alloc */
+    matrix_new,                 /* tp_new */
+    0,                          /* tp_free */
 };
 
 /**************************************************************************/
@@ -1555,7 +1783,11 @@ matrix_div_generic(PyObject *self, PyObject *other, int inplace)
 
   int id_self = get_id(self, (Matrix_Check(self) ? 0 : 1));
   int id_other = get_id(other, (Matrix_Check(other) ? 0 : 1));
+#if PY_MAJOR_VERSION >= 3
+  int id = MAX(DOUBLE, MAX(id_self,id_other));
+#else
   int id = MAX(id_self,id_other);
+#endif
 
   number n;
   convert_num[id](&n,other,(Matrix_Check(other) ? 0 : 1),0);
@@ -1713,44 +1945,60 @@ static int matrix_nonzero(matrix *self)
 }
 
 static PyNumberMethods matrix_as_number = {
-    (binaryfunc)matrix_add,	/*nb_add*/
-    (binaryfunc)matrix_sub,	/*nb_subtract*/
-    (binaryfunc)matrix_mul,	/*nb_multiply*/
-    (binaryfunc)matrix_div, /*nb_divide*/
-    (binaryfunc)matrix_rem, /*nb_remainder*/
-    0,	                /*nb_divmod*/
-    (ternaryfunc)matrix_pow, /*nb_power*/
-    (unaryfunc)matrix_neg,	/*nb_negative*/
-    (unaryfunc)matrix_pos,	/*nb_positive*/
-    (unaryfunc)matrix_abs,	/*nb_absolute*/
-    (inquiry)matrix_nonzero,/*nb_nonzero*/
-    0,	                /*nb_invert*/
-    0,	                /*nb_lshift*/
-    0,	                /*nb_rshift*/
-    0,	                /*nb_and*/
-    0,	                /*nb_xor*/
-    0,	                /*nb_or*/
-    0,		        /*nb_coerce*/
-    0,	                /*nb_int*/
-    0,	                /*nb_long*/
-    0,                      /*nb_float*/
-    0,	                /*nb_oct*/
-    0, 	                /*nb_hex*/
-    (binaryfunc)matrix_iadd,/*nb_inplace_add*/
-    (binaryfunc)matrix_isub,/*nb_inplace_subtract*/
-    (binaryfunc)matrix_imul,/*nb_inplace_multiply*/
-    (binaryfunc)matrix_idiv,/*nb_inplace_divide*/
-    (binaryfunc)matrix_irem,/*nb_inplace_remainder*/
-    0,			/*nb_inplace_power*/
-    0,			/*nb_inplace_lshift*/
-    0,			/*nb_inplace_rshift*/
-    0,			/*nb_inplace_and*/
-    0,			/*nb_inplace_xor*/
-    0,			/*nb_inplace_or*/
-    0,	                /*nb_floor_divide*/
-    0,	                /*nb_true_divide*/
-    0,			/*nb_inplace_floor_divide*/
-    0,			/*nb_inplace_true_divide*/
+    (binaryfunc)matrix_add,    /*nb_add*/
+    (binaryfunc)matrix_sub,    /*nb_subtract*/
+    (binaryfunc)matrix_mul,    /*nb_multiply*/
+#if PY_MAJOR_VERSION < 3
+    (binaryfunc)matrix_div,    /*nb_divide*/
+#endif
+    (binaryfunc)matrix_rem,    /*nb_remainder*/
+    0,                         /*nb_divmod*/
+    (ternaryfunc)matrix_pow,   /*nb_power*/
+    (unaryfunc)matrix_neg,     /*nb_negative*/
+    (unaryfunc)matrix_pos,     /*nb_positive*/
+    (unaryfunc)matrix_abs,     /*nb_absolute*/
+    (inquiry)matrix_nonzero,   /*nb_nonzero*/
+    0,                         /*nb_invert*/
+    0,	                       /*nb_lshift*/
+    0,                         /*nb_rshift*/
+    0,                         /*nb_and*/
+    0,                         /*nb_xor*/
+    0,                         /*nb_or*/
+#if PY_MAJOR_VERSION < 3
+    0,                         /*nb_coerce*/
+#endif
+    0,	                       /*nb_int*/
+    0,                         /*nb_long*/
+    0,                         /*nb_float*/
+#if PY_MAJOR_VERSION < 3
+    0,                         /*nb_oct*/
+    0,                         /*nb_hex*/
+#endif
+    (binaryfunc)matrix_iadd,   /*nb_inplace_add*/
+    (binaryfunc)matrix_isub,   /*nb_inplace_subtract*/
+    (binaryfunc)matrix_imul,   /*nb_inplace_multiply*/
+#if PY_MAJOR_VERSION < 3
+    (binaryfunc)matrix_idiv,   /*nb_inplace_divide*/
+#endif
+    (binaryfunc)matrix_irem,   /*nb_inplace_remainder*/
+    0,                         /*nb_inplace_power*/
+    0,                         /*nb_inplace_lshift*/
+    0,                         /*nb_inplace_rshift*/
+    0,                         /*nb_inplace_and*/
+    0,                         /*nb_inplace_xor*/
+    0,                         /*nb_inplace_or*/
+    0,                         /*nb_floor_divide*/
+#if PY_MAJOR_VERSION < 3
+    0,                         /*nb_true_divide*/
+#else
+    (binaryfunc)matrix_div,    /*nb_true_divide*/
+#endif
+    0,                         /*nb_inplace_floor_divide*/
+#if PY_MAJOR_VERSION < 3
+    0,                         /*nb_inplace_true_divide*/
+#else
+    (binaryfunc)matrix_idiv    /*nb_inplace_true_divide*/
+#endif
 };
 
 
@@ -1818,35 +2066,39 @@ matrixiter_next(matrixiter *it)
 }
 
 static PyTypeObject matrixiter_tp = {
+#if PY_MAJOR_VERSION >= 3
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
     PyObject_HEAD_INIT(NULL)
-    0,					/* ob_size */
-    "matrixiter",			        /* tp_name */
-    sizeof(matrixiter),      		/* tp_basicsize */
-    0,					/* tp_itemsize */
-    (destructor)matrixiter_dealloc,		/* tp_dealloc */
-    0,					/* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    0,					/* tp_repr */
-    0,					/* tp_as_number */
-    0,					/* tp_as_sequence */
-    0,					/* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    0,					/* tp_str */
-    0,                      		/* tp_getattro */
-    0,					/* tp_setattro */
-    0,					/* tp_as_buffer */
+    0,                                  /* ob_size */
+#endif
+    "matrixiter",                       /* tp_name */
+    sizeof(matrixiter),                 /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    (destructor)matrixiter_dealloc,     /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_compare */
+    0,                                  /* tp_repr */
+    0,                                  /* tp_as_number */
+    0,                                  /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    0,                                  /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,	                                /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
-    0,					/* tp_doc */
-    (traverseproc)matrixiter_traverse,	/* tp_traverse */
-    0,					/* tp_clear */
-    0,					/* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    0,                  			/* tp_iter */
-    (iternextfunc)matrixiter_next,		/* tp_iternext */
-    0,					/* tp_methods */
+    0,                                  /* tp_doc */
+    (traverseproc)matrixiter_traverse,  /* tp_traverse */
+    0,                                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    0,                                  /* tp_iter */
+    (iternextfunc)matrixiter_next,      /* tp_iternext */
+    0,                                  /* tp_methods */
 };
 
 
@@ -1857,7 +2109,11 @@ PyObject * matrix_log(matrix *self, PyObject *args, PyObject *kwrds)
 
   if (!PyArg_ParseTuple(args, "O", &A)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A) || PyFloat_Check(A)) {
+#else
   if (PyInt_Check(A) || PyFloat_Check(A)) {
+#endif
     double f = PyFloat_AsDouble(A);
     if (f>0.0)
       return Py_BuildValue("d",log(f));
@@ -1924,7 +2180,11 @@ PyObject * matrix_exp(matrix *self, PyObject *args, PyObject *kwrds)
 
   if (!PyArg_ParseTuple(args, "O", &A)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A) || PyFloat_Check(A))
+#else
   if (PyInt_Check(A) || PyFloat_Check(A))
+#endif
     return Py_BuildValue("d",exp(PyFloat_AsDouble(A)));
 
   else if (PyComplex_Check(A)) {
@@ -1959,7 +2219,11 @@ PyObject * matrix_sqrt(matrix *self, PyObject *args, PyObject *kwrds)
 
   if (!PyArg_ParseTuple(args, "O", &A)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A) || PyFloat_Check(A)) {
+#else
   if (PyInt_Check(A) || PyFloat_Check(A)) {
+#endif
     double f = PyFloat_AsDouble(A);
     if (f >= 0.0)
       return Py_BuildValue("d",sqrt(f));
@@ -2017,7 +2281,11 @@ PyObject * matrix_cos(matrix *self, PyObject *args, PyObject *kwrds)
 
   if (!PyArg_ParseTuple(args, "O", &A)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A) || PyFloat_Check(A))
+#else
   if (PyInt_Check(A) || PyFloat_Check(A))
+#endif
     return Py_BuildValue("d",cos(PyFloat_AsDouble(A)));
 
   else if (PyComplex_Check(A)) {
@@ -2052,7 +2320,11 @@ PyObject * matrix_sin(matrix *self, PyObject *args, PyObject *kwrds)
 
   if (!PyArg_ParseTuple(args, "O", &A)) return NULL;
 
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(A) || PyFloat_Check(A))
+#else
   if (PyInt_Check(A) || PyFloat_Check(A))
+#endif
     return Py_BuildValue("d",sin(PyFloat_AsDouble(A)));
 
   else if (PyComplex_Check(A)) {
@@ -2080,5 +2352,3 @@ PyObject * matrix_sin(matrix *self, PyObject *args, PyObject *kwrds)
   }
   else PY_ERR_TYPE("argument must a be a number or dense matrix");
 }
-
-
diff --git a/src/C/dsdp.c b/src/C/dsdp.c
index b6a0be9..3f1428c 100644
--- a/src/C/dsdp.c
+++ b/src/C/dsdp.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -121,15 +121,18 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
     SDPCone sdpcone;
     DSDPTerminationReason info;
     DSDPSolutionType status;
-    char *keystr, err_str[100];
+    char err_str[100];
+#if PY_MAJOR_VERSION >= 3
+    const char *keystr; 
+#else
+    char *keystr; 
+#endif
     char *kwlist[] = {"c", "Gl", "hl", "Gs", "hs", "gamma", "beta",
         NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|OOOOdd", kwlist,
         &c, &Gl, &hl, &Gs, &hs, &gamma, &beta)) return NULL;
 
-
-
     if (!Matrix_Check(c) || MAT_NCOLS(c) != 1 || MAT_ID(c) != DOUBLE)
         PY_ERR_TYPE("c must be a dense 'd' matrix with one column");
     n = MAT_NROWS(c);
@@ -171,51 +174,68 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
 
     if (!(param = PyObject_GetAttrString(dsdp_module, "options")) ||
         !PyDict_Check(param)){
-	PyErr_SetString(PyExc_AttributeError, "missing dsdp.options "
+        PyErr_SetString(PyExc_AttributeError, "missing dsdp.options "
             " dictionary");
-	t = NULL;
-	goto done;
+        t = NULL;
+        goto done;
     }
     while (PyDict_Next(param, &pos, &key, &value))
-	if ((keystr = PyString_AsString(key))){
-	    if (!strcmp(keystr, "DSDP_Monitor")){
-		if (!PyInt_Check(value)) {
+#if PY_MAJOR_VERSION >= 3
+	if (PyUnicode_Check(key)) {
+	    keystr = _PyUnicode_AsString(key);
+#else
+        if ((keystr = PyString_AsString(key))){
+#endif
+            if (!strcmp(keystr, "DSDP_Monitor")){
+#if PY_MAJOR_VERSION >= 3
+                if (!PyLong_Check(value)) {
+#else
+                if (!PyInt_Check(value)) {
+#endif
                     sprintf(err_str, "invalid value for integer "
-			"DSDP parameter: DSDP_Monitor");
-		    PyErr_SetString(PyExc_ValueError, err_str);
-		    t = NULL;
-		    Py_DECREF(param);
-		    goto done;
-		}
-		else
-		    DSDPSetStandardMonitor(sdp, PyInt_AsLong(value));
-	    }
-	    if (!strcmp(keystr, "DSDP_MaxIts")){
-		if (!PyInt_Check(value) ||
-                    (k = PyInt_AsLong(value)) < 0) {
+                        "DSDP parameter: DSDP_Monitor");
+                    PyErr_SetString(PyExc_ValueError, err_str);
+                    t = NULL;
+                    Py_DECREF(param);
+                    goto done;
+                }
+#if PY_MAJOR_VERSION >= 3
+                else DSDPSetStandardMonitor(sdp, PyLong_AsLong(value));
+#else
+                else DSDPSetStandardMonitor(sdp, PyInt_AsLong(value));
+#endif
+            }
+            if (!strcmp(keystr, "DSDP_MaxIts")){
+#if PY_MAJOR_VERSION >= 3
+                if (!PyLong_Check(value) || (k = PyLong_AsLong(value)) < 0){
+#else
+                if (!PyInt_Check(value) || (k = PyInt_AsLong(value)) < 0){
+#endif
                     sprintf(err_str, "invalid value for nonnegative "
                         "integer DSDP parameter: DSDP_MaxIts");
-		    PyErr_SetString(PyExc_ValueError, err_str);
-		    t = NULL;
-		    Py_DECREF(param);
-		    goto done;
-		}
-		else
-		    DSDPSetMaxIts(sdp, k);
+                    PyErr_SetString(PyExc_ValueError, err_str);
+                    t = NULL;
+                    Py_DECREF(param);
+                    goto done;
+                }
+		else DSDPSetMaxIts(sdp, k);
             }
-	    if (!strcmp(keystr, "DSDP_GapTolerance")){
-		if ((!PyFloat_Check(value) && !PyInt_Check(value)) ||
+            if (!strcmp(keystr, "DSDP_GapTolerance")){
+#if PY_MAJOR_VERSION >= 3
+                if ((!PyFloat_Check(value) && !PyLong_Check(value)) ||
+#else
+                if ((!PyFloat_Check(value) && !PyInt_Check(value)) ||
+#endif
                     (tol = PyFloat_AsDouble(value)) <= 0.0) {
                     sprintf(err_str, "invalid value for float "
                         "DSDP parameter: DSDP_GapTolerance");
-		    PyErr_SetString(PyExc_ValueError, err_str);
-		    t = NULL;
-		    Py_DECREF(param);
-		    goto done;
-		}
-		else
-		    DSDPSetGapTolerance(sdp, tol);
-           }
+                    PyErr_SetString(PyExc_ValueError, err_str);
+                    t = NULL;
+                    Py_DECREF(param);
+                    goto done;
+                }
+                else DSDPSetGapTolerance(sdp, tol);
+            }
         }
     Py_DECREF(param);
 
@@ -289,7 +309,7 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
         lmis[k][0].ind = NULL;
         lmis[k][0].nnz = mk*(mk+1)/2;
         for (j=0; j<mk; j++){
-	    lngth = j+1;  incx = mk;  incy = 1;
+            lngth = j+1;  incx = mk;  incy = 1;
             dcopy_(&lngth, MAT_BUFD(hk)+j, &incx,
                 lmis[k][0].val+j*(j+1)/2, &incy);
         }
@@ -356,9 +376,9 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
 
     DSDPSetup(sdp);
     if (DSDPSolve(sdp)){
-	PyErr_SetString(PyExc_ArithmeticError, "DSDP error");
+        PyErr_SetString(PyExc_ArithmeticError, "DSDP error");
         t = NULL;
-	goto done;
+        goto done;
     }
     DSDPStopReason(sdp, &info);
     if (info != DSDP_CONVERGED && info != DSDP_SMALL_STEPS &&
@@ -383,24 +403,44 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
         switch (status){
             case DSDP_PDFEASIBLE:
                 PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                    PyUnicode_FromString("DSDP_PDFEASIBLE"));
+#else
                     PyString_FromString("DSDP_PDFEASIBLE"));
-	        break;
+#endif
+                break;
             case DSDP_UNBOUNDED:
                 PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                    PyUnicode_FromString("DSDP_UNBOUNDED"));
+#else
                     PyString_FromString("DSDP_UNBOUNDED"));
-	        break;
+#endif
+                break;
             case DSDP_INFEASIBLE:
                 PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                    PyUnicode_FromString("DSDP_INFEASIBLE"));
+#else
                     PyString_FromString("DSDP_INFEASIBLE"));
-	        break;
+#endif
+                break;
             case DSDP_PDUNKNOWN:
                 PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                    PyUnicode_FromString("DSDP_UNKNOWN"));
+#else
                     PyString_FromString("DSDP_UNKNOWN"));
-	        break;
+#endif
+                break;
         }
     } else {
         PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+        PyUnicode_FromString("DSDP_UNKNOWN"));
+#else
         PyString_FromString("DSDP_UNKNOWN"));
+#endif
     }
 
     DSDPGetY(sdp, MAT_BUFD(x), n);
@@ -446,10 +486,32 @@ static PyObject* solvesdp(PyObject *self, PyObject *args,
 }
 
 static PyMethodDef dsdp_functions[] = {
-  {"sdp", (PyCFunction) solvesdp, METH_VARARGS|METH_KEYWORDS, doc_dsdp},
-  {NULL}  /* Sentinel */
+    {"sdp", (PyCFunction) solvesdp, METH_VARARGS|METH_KEYWORDS, doc_dsdp},
+    {NULL}  /* Sentinel */
+};
+
+
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef dsdp_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "dsdp",
+    dsdp__doc__,
+    -1,
+    dsdp_functions,
+    NULL, NULL, NULL, NULL
 };
 
+PyMODINIT_FUNC PyInit_dsdp(void)
+{
+  if (!(dsdp_module = PyModule_Create(&dsdp_module_def))) return NULL;
+  PyModule_AddObject(dsdp_module, "options", PyDict_New());
+  if (import_cvxopt() < 0) return NULL;
+  return dsdp_module;
+}
+
+#else
+
 PyMODINIT_FUNC initdsdp(void)
 {
     dsdp_module = Py_InitModule3("cvxopt.dsdp", dsdp_functions,
@@ -457,3 +519,5 @@ PyMODINIT_FUNC initdsdp(void)
     PyModule_AddObject(dsdp_module, "options", PyDict_New());
     if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/fftw.c b/src/C/fftw.c
index 15c6640..37c1589 100644
--- a/src/C/fftw.c
+++ b/src/C/fftw.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,8 +22,7 @@
 #include "misc.h"
 #include <fftw3.h>
 
-PyDoc_STRVAR(fftw__doc__,
-    "Interface to the FFTW3 library.\n");
+PyDoc_STRVAR(fftw__doc__, "Interface to the FFTW3 library.\n");
 
 extern void zscal_(int *n, complex *alpha, complex *x, int *incx);
 extern void dscal_(int *n, double *alpha, double *x, int *incx);
@@ -92,8 +91,13 @@ static PyObject *dftn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -115,14 +119,22 @@ static PyObject *dftn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
       free(dimarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
@@ -217,8 +229,8 @@ static PyObject *idftn(PyObject *self, PyObject *args, PyObject *kwrds)
   int *dimarr;
   int free_dims = 0;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|O:idftn",
-	  kwlist, &X, &dims))
+  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|O:idftn", 
+      kwlist, &X, &dims))
     return NULL;
 
   if (!(Matrix_Check(X) && MAT_ID(X) == COMPLEX))
@@ -228,8 +240,13 @@ static PyObject *idftn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -249,14 +266,22 @@ static PyObject *idftn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
       free(dimarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
@@ -370,7 +395,7 @@ static PyObject *dctn(PyObject *self, PyObject *args, PyObject *kwrds)
   int free_dims = 0;
 
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|OO:dctn", kwlist,
-	  &X, &dims, &type))
+      &X, &dims, &type))
     return NULL;
 
   if (!(Matrix_Check(X) && MAT_ID(X) == DOUBLE))
@@ -380,8 +405,13 @@ static PyObject *dctn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -418,14 +448,22 @@ static PyObject *dctn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
       free(dimarr); free(kindarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
@@ -461,29 +499,37 @@ static PyObject *dctn(PyObject *self, PyObject *args, PyObject *kwrds)
     for (i=0; i<len; i++) {
       PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+      if (!PyLong_Check(item)) {
+#else
       if (!PyInt_Check(item)) {
-	Py_DECREF(seq);
-	free(dimarr); free(kindarr);
-	PY_ERR_TYPE("non-integer in type tuple");
+#endif
+        Py_DECREF(seq);
+        free(dimarr); free(kindarr);
+        PY_ERR_TYPE("non-integer in type tuple");
       }
 
+#if PY_MAJOR_VERSION >= 3
+      switch(PyLong_AS_LONG(item)) {
+#else
       switch(PyInt_AS_LONG(item)) {
+#endif
       case 1:
-	kindarr[len-i-1] = FFTW_REDFT00;
-	if (dimarr[len-i-1] <= 1) {
-	  Py_DECREF(seq);
-	  free(dimarr); free(kindarr);
-	  PY_ERR(PyExc_ValueError,
-	      "dimension must be greater than 1 for DCT-I");
-	}
-	break;
+          kindarr[len-i-1] = FFTW_REDFT00;
+          if (dimarr[len-i-1] <= 1) {
+              Py_DECREF(seq);
+              free(dimarr); free(kindarr);
+              PY_ERR(PyExc_ValueError, 
+                  "dimension must be greater than 1 for DCT-I");
+          }
+          break;
       case 2: kindarr[len-i-1] = FFTW_REDFT10; break;
       case 3: kindarr[len-i-1] = FFTW_REDFT01; break;
       case 4: kindarr[len-i-1] = FFTW_REDFT11; break;
       default:
-	Py_DECREF(seq);
-	free(dimarr); free(kindarr);
-	PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
+          Py_DECREF(seq);
+          free(dimarr); free(kindarr);
+          PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
       }
     }
 
@@ -528,18 +574,17 @@ static PyObject *idct(PyObject *self, PyObject *args, PyObject *kwrds)
 
   fftw_r2r_kind kind;
   switch(type) {
-  case 1: kind = FFTW_REDFT00;
-    if (m <= 1) PY_ERR(PyExc_ValueError, "m must be greater than 1 for DCT-I");
-    break;
-  case 2: kind = FFTW_REDFT01; break;
-  case 3: kind = FFTW_REDFT10; break;
-  case 4: kind = FFTW_REDFT11; break;
-  default: PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
+      case 1: kind = FFTW_REDFT00;
+          if (m <= 1) 
+            PY_ERR(PyExc_ValueError, "m must be greater than 1 for DCT-I");
+          break;
+      case 2: kind = FFTW_REDFT01; break;
+      case 3: kind = FFTW_REDFT10; break;
+      case 4: kind = FFTW_REDFT11; break;
+      default: PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
   }
-  fftw_plan p = fftw_plan_many_r2r(1, &m, n,
-      X->buffer, &m, 1, m,
-      X->buffer, &m, 1, m,
-      &kind, FFTW_ESTIMATE);
+  fftw_plan p = fftw_plan_many_r2r(1, &m, n, X->buffer, &m, 1, m,
+      X->buffer, &m, 1, m, &kind, FFTW_ESTIMATE);
 
   Py_BEGIN_ALLOW_THREADS
   fftw_execute(p);
@@ -578,7 +623,7 @@ static PyObject *idctn(PyObject *self, PyObject *args, PyObject *kwrds)
   int free_dims = 0;
 
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|OO:idctn", kwlist,
-	  &X, &dims, &type))
+      &X, &dims, &type))
     return NULL;
 
   if (!(Matrix_Check(X) && MAT_ID(X) == DOUBLE))
@@ -588,8 +633,13 @@ static PyObject *idctn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -626,14 +676,22 @@ static PyObject *idctn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
       free(dimarr); free(kindarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       Py_DECREF(seq);
@@ -667,29 +725,37 @@ static PyObject *idctn(PyObject *self, PyObject *args, PyObject *kwrds)
     for (i=0; i<len; i++) {
       PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+      if (!PyLong_Check(item)) {
+#else
       if (!PyInt_Check(item)) {
-	Py_DECREF(seq);
-	free(dimarr); free(kindarr);
-	PY_ERR_TYPE("non-integer in type tuple");
+#endif
+        Py_DECREF(seq);
+        free(dimarr); free(kindarr);
+        PY_ERR_TYPE("non-integer in type tuple");
       }
 
+#if PY_MAJOR_VERSION >= 3
+      switch(PyLong_AS_LONG(item)) {
+#else
       switch(PyInt_AS_LONG(item)) {
+#endif
       case 1:
-	kindarr[len-i-1] = FFTW_REDFT00;
-	if (dimarr[len-i-1] <= 1) {
-	  Py_DECREF(seq);
-	  free(dimarr); free(kindarr);
-	  PY_ERR(PyExc_ValueError,
-	      "dimension must be greater than 1 for DCT-I");
-	}
-	break;
+          kindarr[len-i-1] = FFTW_REDFT00;
+          if (dimarr[len-i-1] <= 1) {
+              Py_DECREF(seq);
+              free(dimarr); free(kindarr);
+              PY_ERR(PyExc_ValueError,
+                  "dimension must be greater than 1 for DCT-I");
+          }
+          break;
       case 2: kindarr[len-i-1] = FFTW_REDFT01; break;
       case 3: kindarr[len-i-1] = FFTW_REDFT10; break;
       case 4: kindarr[len-i-1] = FFTW_REDFT11; break;
       default:
-	Py_DECREF(seq);
-	free(dimarr); free(kindarr);
-	PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
+          Py_DECREF(seq);
+          free(dimarr); free(kindarr);
+          PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
       }
     }
 
@@ -794,8 +860,13 @@ static PyObject *dstn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -828,13 +899,21 @@ static PyObject *dstn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       free(dimarr); free(kindarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       free(dimarr); free(kindarr);
@@ -865,19 +944,27 @@ static PyObject *dstn(PyObject *self, PyObject *args, PyObject *kwrds)
     for (i=0; i<len; i++) {
       PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+      if (!PyLong_Check(item)) {
+#else
       if (!PyInt_Check(item)) {
+#endif
 	free(dimarr); free(kindarr);
 	PY_ERR_TYPE("non-integer in type tuple");
       }
 
+#if PY_MAJOR_VERSION >= 3
+      switch(PyLong_AS_LONG(item)) {
+#else
       switch(PyInt_AS_LONG(item)) {
+#endif
       case 1: kindarr[len-i-1] = FFTW_RODFT00; break;
       case 2: kindarr[len-i-1] = FFTW_RODFT10; break;
       case 3: kindarr[len-i-1] = FFTW_RODFT01; break;
       case 4: kindarr[len-i-1] = FFTW_RODFT11; break;
       default:
-	free(dimarr); free(kindarr);
-	PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
+          free(dimarr); free(kindarr);
+          PY_ERR(PyExc_ValueError, "type must be between 1 and 4");
       }
     }
   }
@@ -978,8 +1065,13 @@ static PyObject *idstn(PyObject *self, PyObject *args, PyObject *kwrds)
     dims = PyTuple_New(2);
     if (!dims) return PyErr_NoMemory();
 
+#if PY_MAJOR_VERSION >= 3
+    PyTuple_SET_ITEM(dims, 0, PyLong_FromLong(MAT_NCOLS(X)));
+    PyTuple_SET_ITEM(dims, 1, PyLong_FromLong(MAT_NROWS(X)));
+#else
     PyTuple_SET_ITEM(dims, 0, PyInt_FromLong(MAT_NCOLS(X)));
     PyTuple_SET_ITEM(dims, 1, PyInt_FromLong(MAT_NROWS(X)));
+#endif
     free_dims = 1;
   }
 
@@ -1014,13 +1106,21 @@ static PyObject *idstn(PyObject *self, PyObject *args, PyObject *kwrds)
   for (i=0; i<len; i++) {
     PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyLong_Check(item)) {
+#else
     if (!PyInt_Check(item)) {
+#endif
       if (free_dims) { Py_DECREF(dims); }
       free(dimarr); free(kindarr);
       PY_ERR_TYPE("non-integer in dimension tuple");
     }
 
+#if PY_MAJOR_VERSION >= 3
+    dimarr[len-i-1] = PyLong_AS_LONG(item);
+#else
     dimarr[len-i-1] = PyInt_AS_LONG(item);
+#endif
     if (dimarr[len-i-1] < 0) {
       if (free_dims) { Py_DECREF(dims); }
       free(dimarr); free(kindarr);
@@ -1051,12 +1151,20 @@ static PyObject *idstn(PyObject *self, PyObject *args, PyObject *kwrds)
     for (i=0; i<len; i++) {
       PyObject *item = PySequence_Fast_GET_ITEM(seq, i);
 
+#if PY_MAJOR_VERSION >= 3
+      if (!PyLong_Check(item)) {
+#else
       if (!PyInt_Check(item)) {
+#endif
 	free(dimarr); free(kindarr);
 	PY_ERR_TYPE("non-integer in type tuple");
       }
 
+#if PY_MAJOR_VERSION >= 3
+      switch(PyLong_AS_LONG(item)) {
+#else
       switch(PyInt_AS_LONG(item)) {
+#endif
       case 1: kindarr[len-i-1] = FFTW_RODFT00; break;
       case 2: kindarr[len-i-1] = FFTW_RODFT10; break;
       case 3: kindarr[len-i-1] = FFTW_RODFT01; break;
@@ -1103,12 +1211,32 @@ static PyMethodDef fftw_functions[] = {
     {NULL}  /* Sentinel */
 };
 
+#if PY_MAJOR_VERSION >= 3
 
-PyMODINIT_FUNC initfftw(void)
+static PyModuleDef fftw_module = {
+    PyModuleDef_HEAD_INIT,
+    "fftw",
+    fftw__doc__,
+    -1,
+    fftw_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_fftw(void)
 {
   PyObject *m;
+  if (!(m = PyModule_Create(&fftw_module))) return NULL;
+  if (import_cvxopt() < 0) return NULL;
+  return m;
+}
 
-  m = Py_InitModule3("cvxopt.fftw", fftw_functions, fftw__doc__);
+#else
 
+PyMODINIT_FUNC initfftw(void)
+{
+  PyObject *m;
+  m = Py_InitModule3("cvxopt.fftw", fftw_functions, fftw__doc__);
   if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/glpk.c b/src/C/glpk.c
index 4b8a76b..c74e4fa 100644
--- a/src/C/glpk.c
+++ b/src/C/glpk.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 #include "glpk.h"
 
 PyDoc_STRVAR(glpk__doc__,
-    "Interface to the simplex algorithm in GLPK.\n\n"
+    "Interface to the simplex and mixed integer LP algorithms in GLPK.\n\n"
     "The GLPK control parameters have the default values listed in \n"
     "the GLPK documentation, except for 'LPX_K_PRESOL', which is set\n"
     "to 1 and cannot be modified.  The other parameters can be\n"
@@ -42,38 +42,42 @@ typedef struct {
 }   param_tuple;
 
 static const param_tuple GLPK_PARAM_LIST[] = {
-    {"LPX_K_MSGLEV", 300, 'i'},
-    {"LPX_K_SCALE",  301, 'i'},
-    {"LPX_K_DUAL",   302, 'i'},
-    {"LPX_K_PRICE",  303, 'i'},
-    {"LPX_K_RELAX",  304, 'f'},
-    {"LPX_K_TOLBND", 305, 'f'},
-    {"LPX_K_TOLDJ",  306, 'f'},
-    {"LPX_K_TOLPIV", 307, 'f'},
-    {"LPX_K_ROUND",  308, 'i'},
-    {"LPX_K_OBJLL",  309, 'f'},
-    {"LPX_K_OBJUL",  310, 'f'},
-    {"LPX_K_ITLIM",  311, 'i'},
-    {"LPX_K_ITCNT",  312, 'i'},
-    {"LPX_K_TMLIM",  313, 'f'},
-    {"LPX_K_OUTFRQ", 314, 'i'},
-    {"LPX_K_OUTDLY", 315, 'f'},
-    {"LPX_K_BRANCH", 316, 'i'},
-    {"LPX_K_BTRACK", 317, 'i'},
-    {"LPX_K_TOLINT", 318, 'f'},
-    {"LPX_K_TOLOBJ", 319, 'f'},
-    {"LPX_K_MPSINFO",320, 'i'},
-    {"LPX_K_MPSOBJ", 321, 'i'},
-    {"LPX_K_MPSORIG",322, 'i'},
-    {"LPX_K_MPSWIDE",323, 'i'},
-    {"LPX_K_MPSFREE",324, 'i'},
-    {"LPX_K_MPSSKIP",325, 'i'},
-    {"LPX_K_LPTORIG",326, 'i'},
-    {"LPX_K_PRESOL", 327, 'i'}
+    {"LPX_K_MSGLEV",    LPX_K_MSGLEV,   'i'}, 
+    {"LPX_K_SCALE",     LPX_K_SCALE,    'i'},
+    {"LPX_K_DUAL",      LPX_K_DUAL,     'i'},
+    {"LPX_K_PRICE",     LPX_K_PRICE,    'i'},
+    {"LPX_K_RELAX",     LPX_K_RELAX,    'f'},
+    {"LPX_K_TOLBND",    LPX_K_TOLBND,   'f'},
+    {"LPX_K_TOLDJ",     LPX_K_TOLDJ,    'f'},
+    {"LPX_K_TOLPIV",    LPX_K_TOLPIV,   'f'},
+    {"LPX_K_ROUND",     LPX_K_ROUND,    'i'},
+    {"LPX_K_OBJLL",     LPX_K_OBJLL,    'f'},
+    {"LPX_K_OBJUL",     LPX_K_OBJUL,    'f'},
+    {"LPX_K_ITLIM",     LPX_K_ITLIM,    'i'},
+    {"LPX_K_ITCNT",     LPX_K_ITCNT,    'i'}, 
+    {"LPX_K_TMLIM",     LPX_K_TMLIM,    'f'},
+    {"LPX_K_OUTFRQ",    LPX_K_OUTFRQ,   'i'},
+    {"LPX_K_OUTDLY",    LPX_K_OUTDLY,   'f'},
+    {"LPX_K_BRANCH",    LPX_K_BRANCH,   'i'},
+    {"LPX_K_BTRACK",    LPX_K_BTRACK,   'i'},
+    {"LPX_K_TOLINT",    LPX_K_TOLINT,   'f'},
+    {"LPX_K_TOLOBJ",    LPX_K_TOLOBJ,   'f'},
+    {"LPX_K_MPSINFO",   LPX_K_MPSINFO,  'i'},
+    {"LPX_K_MPSOBJ",    LPX_K_MPSOBJ,   'i'},
+    {"LPX_K_MPSORIG",   LPX_K_MPSORIG,  'i'},
+    {"LPX_K_MPSWIDE",   LPX_K_MPSWIDE,  'i'},
+    {"LPX_K_MPSFREE",   LPX_K_MPSFREE,  'i'},
+    {"LPX_K_MPSSKIP",   LPX_K_MPSSKIP,  'i'},
+    {"LPX_K_LPTORIG",   LPX_K_LPTORIG,  'i'},
+    {"LPX_K_PRESOL",    LPX_K_PRESOL,   'i'},
 }; /* 28 paramaters */
 
 
+#if PY_MAJOR_VERSION >= 3
+static int get_param_idx(const char *str, int *idx, char *type)
+#else
 static int get_param_idx(char *str, int *idx, char *type)
+#endif
 {
     int i;
 
@@ -126,7 +130,12 @@ static PyObject *simplex(PyObject *self, PyObject *args,
     int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL, param_id;
     int_t pos=0;
     double *a=NULL, val;
-    char param_type, err_str[100], *keystr;
+    char param_type, err_str[100]; 
+#if PY_MAJOR_VERSION >= 3
+    const char *keystr;
+#else
+    char *keystr;
+#endif
     char *kwlist[] = {"c", "G", "h", "A", "b", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OO", kwlist, &c,
@@ -249,10 +258,21 @@ static PyObject *simplex(PyObject *self, PyObject *args,
     }
 
     while (PyDict_Next(param, &pos, &key, &value))
+#if PY_MAJOR_VERSION >= 3
+        if ((PyUnicode_Check(key)) && 
+            get_param_idx(_PyUnicode_AsString(key), &param_id, 
+            &param_type)){
+            keystr = _PyUnicode_AsString(key);
+#else
         if ((keystr = PyString_AsString(key)) && get_param_idx(keystr,
             &param_id, &param_type)){
+#endif
 	    if (param_type == 'i'){
+#if PY_MAJOR_VERSION >= 3
+	        if (!PyLong_Check(value)){
+#else
 	        if (!PyInt_Check(value)){
+#endif
                     sprintf(err_str, "invalid value for integer "
                         "GLPK parameter: %-.20s", keystr);
                     PyErr_SetString(PyExc_ValueError, err_str);
@@ -261,15 +281,27 @@ static PyObject *simplex(PyObject *self, PyObject *args,
                     return NULL;
 	        }
                 if (!strcmp("LPX_K_PRESOL", keystr) &&
+#if PY_MAJOR_VERSION >= 3
+                    PyLong_AS_LONG(value) != 1){
+#else
                     PyInt_AS_LONG(value) != 1){
+#endif
                     PyErr_Warn(PyExc_UserWarning, "ignoring value of "
                         "GLPK parameter 'LPX_K_PRESOL'");
                 }
                 else lpx_set_int_parm(lp, param_id,
+#if PY_MAJOR_VERSION >= 3
+                    PyLong_AS_LONG(value));
+#else
                     PyInt_AS_LONG(value));
+#endif
 	    }
 	    else {
+#if PY_MAJOR_VERSION >= 3
+	        if (!PyLong_Check(value) && !PyFloat_Check(value)){
+#else
 	        if (!PyInt_Check(value) && !PyFloat_Check(value)){
+#endif
                     sprintf(err_str, "invalid value for floating point "
                         "GLPK parameter: %-.20s", keystr);
                     PyErr_SetString(PyExc_ValueError, err_str);
@@ -301,7 +333,11 @@ static PyObject *simplex(PyObject *self, PyObject *args,
             }
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("optimal"));
+#else
                 PyString_FromString("optimal"));
+#endif
 
             for (i=0; i<n; i++)
                 MAT_BUFD(x)[i] = lpx_get_col_prim(lp, i+1);
@@ -323,19 +359,31 @@ static PyObject *simplex(PyObject *self, PyObject *args,
         case LPX_E_NOPFS:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("primal infeasible"));
+#else
                 PyString_FromString("primal infeasible"));
+#endif
             break;
 
         case LPX_E_NODFS:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("dual infeasible"));
+#else
                 PyString_FromString("dual infeasible"));
+#endif
             break;
 
         default:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("unknown"));
+#else
                 PyString_FromString("unknown"));
+#endif
     }
 
     lpx_delete_prob(lp);
@@ -383,7 +431,12 @@ static PyObject *integer(PyObject *self, PyObject *args,
     int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL, param_id;
     int_t pos=0;
     double *a=NULL, val;
-    char param_type, err_str[100], *keystr;
+    char param_type, err_str[100]; 
+#if PY_MAJOR_VERSION >= 3
+    const char *keystr;
+#else
+    char *keystr;
+#endif
     char *kwlist[] = {"c", "G", "h", "A", "b", "I", "B", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOOO", kwlist, &c,
@@ -512,10 +565,19 @@ static PyObject *integer(PyObject *self, PyObject *args,
     }
 
     while (PyDict_Next(param, &pos, &key, &value))
+#if PY_MAJOR_VERSION >= 3
+        if ((PyUnicode_Check(key)) && (keystr = PyUnicode_AS_DATA(key)) 
+            && get_param_idx(keystr, &param_id, &param_type)){
+#else
         if ((keystr = PyString_AsString(key)) && get_param_idx(keystr,
             &param_id, &param_type)){
+#endif
 	    if (param_type == 'i'){
+#if PY_MAJOR_VERSION >= 3
+	        if (!PyLong_Check(value)){
+#else
 	        if (!PyInt_Check(value)){
+#endif
                     sprintf(err_str, "invalid value for integer "
                         "GLPK parameter: %-.20s", keystr);
                     PyErr_SetString(PyExc_ValueError, err_str);
@@ -524,15 +586,27 @@ static PyObject *integer(PyObject *self, PyObject *args,
                     return NULL;
 	        }
                 if (!strcmp("LPX_K_PRESOL", keystr) &&
+#if PY_MAJOR_VERSION >= 3
+                    PyLong_AS_LONG(value) != 1){
+#else
                     PyInt_AS_LONG(value) != 1){
+#endif
                     PyErr_Warn(PyExc_UserWarning, "ignoring value of "
                         "GLPK parameter 'LPX_K_PRESOL'");
                 }
-                else lpx_set_int_parm(lp, param_id,
-                    PyInt_AS_LONG(value));
+                else 
+#if PY_MAJOR_VERSION >= 3
+                    lpx_set_int_parm(lp, param_id, PyLong_AS_LONG(value));
+#else
+                    lpx_set_int_parm(lp, param_id, PyInt_AS_LONG(value));
+#endif
 	    }
 	    else {
+#if PY_MAJOR_VERSION >= 3
+	        if (!PyLong_Check(value) && !PyFloat_Check(value)){
+#else
 	        if (!PyInt_Check(value) && !PyFloat_Check(value)){
+#endif
                     sprintf(err_str, "invalid value for floating point "
                         "GLPK parameter: %-.20s", keystr);
                     PyErr_SetString(PyExc_ValueError, err_str);
@@ -553,12 +627,20 @@ static PyObject *integer(PyObject *self, PyObject *args,
       for (i=0; i<PySet_GET_SIZE(IntSet); i++) {
 
 	PyObject *tmp = PySequence_Fast_GET_ITEM(iter, i);
+#if PY_MAJOR_VERSION >= 3
+	if (!PyLong_Check(tmp)) {
+#else
 	if (!PyInt_Check(tmp)) {
+#endif
 	  lpx_delete_prob(lp);
 	  Py_DECREF(iter);
 	  PY_ERR_TYPE("non-integer element in I");
 	}
+#if PY_MAJOR_VERSION >= 3
+	int k = PyLong_AS_LONG(tmp);
+#else
 	int k = PyInt_AS_LONG(tmp);
+#endif
 	if ((k < 0) || (k >= n)) {
 	  lpx_delete_prob(lp);
 	  Py_DECREF(iter);
@@ -576,12 +658,20 @@ static PyObject *integer(PyObject *self, PyObject *args,
       for (i=0; i<PySet_GET_SIZE(BinSet); i++) {
 
 	PyObject *tmp = PySequence_Fast_GET_ITEM(iter, i);
+#if PY_MAJOR_VERSION >= 3
+	if (!PyLong_Check(tmp)) {
+#else
 	if (!PyInt_Check(tmp)) {
+#endif
 	  lpx_delete_prob(lp);
 	  Py_DECREF(iter);
 	  PY_ERR_TYPE("non-binary element in I");
 	}
+#if PY_MAJOR_VERSION >= 3
+	int k = PyLong_AS_LONG(tmp);
+#else
 	int k = PyInt_AS_LONG(tmp);
+#endif
 	if ((k < 0) || (k >= n)) {
 	  lpx_delete_prob(lp);
 	  Py_DECREF(iter);
@@ -607,7 +697,11 @@ static PyObject *integer(PyObject *self, PyObject *args,
                 return PyErr_NoMemory();
             }
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("optimal"));
+#else
                 PyString_FromString("optimal"));
+#endif
 
             for (i=0; i<n; i++)
                 MAT_BUFD(x)[i] = lpx_mip_col_val(lp, i+1);
@@ -618,36 +712,64 @@ static PyObject *integer(PyObject *self, PyObject *args,
 
         case LPX_E_FAULT:
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("invalid MIP formulation"));
+#else
                 PyString_FromString("invalid MIP formulation"));
+#endif
 
 	case LPX_E_NOPFS:
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("primal infeasible"));
+#else
                 PyString_FromString("primal infeasible"));
+#endif
 
 	case LPX_E_NODFS:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("dual infeasible"));
+#else
                 PyString_FromString("dual infeasible"));
+#endif
 
         case LPX_E_ITLIM:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("maxiters exceeded"));
+#else
                 PyString_FromString("maxiters exceeded"));
+#endif
 
         case LPX_E_TMLIM:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("time limit exceeded"));
+#else
                 PyString_FromString("time limit exceeded"));
+#endif
 
 	case LPX_E_SING:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("singular or ill-conditioned basis"));
+#else
                 PyString_FromString("singular or ill-conditioned basis"));
+#endif
 
         default:
 
             PyTuple_SET_ITEM(t, 0, (PyObject *)
+#if PY_MAJOR_VERSION >= 3
+                PyUnicode_FromString("unknown"));
+#else
                 PyString_FromString("unknown"));
+#endif
     }
 
     lpx_delete_prob(lp);
@@ -665,13 +787,33 @@ static PyMethodDef glpk_functions[] = {
     {NULL}  /* Sentinel */
 };
 
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef glpk_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "glpk",
+    glpk__doc__,
+    -1,
+    glpk_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_glpk(void)
+{
+  if (!(glpk_module = PyModule_Create(&glpk_module_def))) return NULL;
+  PyModule_AddObject(glpk_module, "options", PyDict_New());
+  if (import_cvxopt() < 0) return NULL;
+  return glpk_module;
+}
+
+#else
 
 PyMODINIT_FUNC initglpk(void)
 {
-    glpk_module = Py_InitModule3("cvxopt.glpk", glpk_functions,
+    glpk_module = Py_InitModule3("cvxopt.glpk", glpk_functions, 
         glpk__doc__);
-
     PyModule_AddObject(glpk_module, "options", PyDict_New());
-
     if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/gsl.c b/src/C/gsl.c
index 86fc392..8286bb8 100644
--- a/src/C/gsl.c
+++ b/src/C/gsl.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -164,20 +164,39 @@ uniform(PyObject *self, PyObject *args, PyObject *kwrds)
 }
 
 static PyMethodDef gsl_functions[] = {
-  {"getseed", (PyCFunction)getseed, METH_VARARGS|METH_KEYWORDS, doc_getseed},
-  {"setseed", (PyCFunction)setseed, METH_VARARGS|METH_KEYWORDS, doc_setseed},
-  {"normal", (PyCFunction)normal, METH_VARARGS|METH_KEYWORDS, doc_normal},
-  {"uniform", (PyCFunction)uniform, METH_VARARGS|METH_KEYWORDS, doc_uniform},
-  {NULL}  /* Sentinel */
+{"getseed", (PyCFunction)getseed, METH_VARARGS|METH_KEYWORDS, doc_getseed},
+{"setseed", (PyCFunction)setseed, METH_VARARGS|METH_KEYWORDS, doc_setseed},
+{"normal", (PyCFunction)normal, METH_VARARGS|METH_KEYWORDS, doc_normal},
+{"uniform", (PyCFunction)uniform, METH_VARARGS|METH_KEYWORDS, doc_uniform},
+{NULL}  /* Sentinel */
 };
 
-PyMODINIT_FUNC
-initgsl(void)
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef gsl_module = {
+    PyModuleDef_HEAD_INIT,
+    "gsl",
+    gsl__doc__,
+    -1,
+    gsl_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_gsl(void)
 {
   PyObject *m;
+  if (!(m = PyModule_Create(&gsl_module))) return NULL;
+  if (import_cvxopt() < 0) return NULL;
+  return m;
+}
 
-  m = Py_InitModule3("cvxopt.gsl", gsl_functions, gsl__doc__);
+#else
 
-  if (import_cvxopt() < 0)
-    return;
+PyMODINIT_FUNC initgsl(void)
+{
+  PyObject *m;
+  m = Py_InitModule3("cvxopt.gsl", gsl_functions, gsl__doc__);
+  if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/lapack.c b/src/C/lapack.c
index 466d3bf..dc185ac 100644
--- a/src/C/lapack.c
+++ b/src/C/lapack.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -392,13 +392,23 @@ static PyObject* getrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B, *ipiv;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
+    char trans = 'N';
     char *kwlist[] = {"A", "ipiv", "B", "trans", "n", "nrhs", "ldA",
         "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|Ciiiiii", kwlist,
+        &A, &ipiv, &B, &trans_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    trans = trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ciiiiii", kwlist,
         &A, &ipiv, &B, &trans, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -832,13 +842,25 @@ static PyObject* gbtrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B, *ipiv;
     int kl, n=-1, ku=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
+    char trans = 'N';
     char *kwlist[] = {"A", "kl", "ipiv", "B", "trans", "n", "ku", "nrhs",
         "ldA", "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OiOO|Ciiiiiii", kwlist,
+        &A, &kl, &ipiv, &B, &trans_, &n, &ku, &nrhs, &ldA, &ldB, &oA,
+        &oB)) 
+        return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OiOO|ciiiiiii", kwlist,
         &A, &kl, &ipiv, &B, &trans, &n, &ku, &nrhs, &ldA, &ldB, &oA,
-        &oB)) return NULL;
+        &oB)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -1186,15 +1208,25 @@ static char doc_gttrs[] =
 static PyObject* gttrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *dl, *d, *du, *du2, *ipiv, *B;
-    char trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
+    char trans = 'N';
     int n=-1, nrhs=-1, ldB=0, odl=0, od=0, odu=0, oB=0, info;
     static char *kwlist[] = {"dl", "d", "du", "du2", "ipiv", "B", "trans",
         "n", "nrhs", "ldB", "offsetdl", "offsetd", "offsetdu", "offsetB",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOOOOO|ciiiiiii",
+        kwlist, &dl, &d, &du, &du2, &ipiv, &B, &trans, &n, &nrhs, &ldB,
+        &odl, &od, &odu, &oB)) return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOOOOO|ciiiiiii",
         kwlist, &dl, &d, &du, &du2, &ipiv, &B, &trans, &n, &nrhs, &ldB,
         &odl, &od, &odu, &oB)) return NULL;
+#endif
 
     if (!Matrix_Check(dl)) err_mtrx("dl");
     if (!Matrix_Check(d)) err_mtrx("d");
@@ -1374,12 +1406,20 @@ static PyObject* potrf(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A;
     int n=-1, ldA=0, oA=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|Ciii", kwlist, &A,
+        &uplo_, &n, &ldA, &oA)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|ciii", kwlist, &A,
-        &uplo, &n, &ldA, &oA))
-        return NULL;
+        &uplo, &n, &ldA, &oA)) return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (n < 0){
@@ -1448,13 +1488,21 @@ static PyObject* potrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "uplo", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiii", kwlist,
+        &A, &B, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiii", kwlist,
-        &A, &B, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
-        return NULL;
+        &A, &B, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB)) return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -1517,11 +1565,20 @@ static PyObject* potri(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A;
     int n=-1, ldA=0, oA=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|Ciii", kwlist,
+        &A, &uplo_, &n, &ldA, &oA)) return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|ciii", kwlist,
         &A, &uplo, &n, &ldA, &oA)) return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (uplo != 'L' && uplo != 'U') err_char("uplo", "'L', 'U'");
@@ -1531,6 +1588,8 @@ static PyObject* potri(PyObject *self, PyObject *args, PyObject *kwrds)
     if (ldA < MAX(1,n)) err_ld("ldA");
     if (oA < 0) err_nn_int("offsetA");
     if (oA + (n-1)*ldA + n > len(A)) err_buf_len("A");
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|ciii", kwlist,
+        &A, &uplo, &n, &ldA, &oA)) return NULL;
 
     switch (MAT_ID(A)){
         case DOUBLE:
@@ -1584,13 +1643,23 @@ static PyObject* posv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "uplo", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiii", kwlist,
+        &A, &B, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiii", kwlist,
         &A, &B, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -1658,12 +1727,22 @@ static PyObject* pbtrf(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A;
     int n=-1, kd=-1, ldA=0, oA=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "uplo", "n", "kd", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|Ciiii", kwlist, &A,
+        &uplo_, &n, &kd, &ldA, &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|ciiii", kwlist, &A,
         &uplo, &n, &kd, &ldA, &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (n < 0) n = A->ncols;
@@ -1731,13 +1810,23 @@ static PyObject* pbtrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int n=-1, kd=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "uplo", "n", "kd", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiiii", kwlist,
+        &A, &B, &uplo_, &n, &kd, &nrhs, &ldA, &ldB, &oA, oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiiii", kwlist,
         &A, &B, &uplo, &n, &kd, &nrhs, &ldA, &ldB, &oA, oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -1815,13 +1904,23 @@ static PyObject* pbsv(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int n=-1, kd=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "uplo", "n", "kd", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiiii", kwlist,
+        &A, &B, &uplo_, &n, &kd, &nrhs, &ldA, &ldB, &oA, oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiiii", kwlist,
         &A, &B, &uplo, &n, &kd, &nrhs, &ldA, &ldB, &oA, oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -1957,13 +2056,24 @@ static char doc_pttrs[] =
 static PyObject* pttrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *d, *e, *B;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     int n=-1, nrhs=-1, ldB=0, od=0, oe=0, oB=0, info;
     static char *kwlist[] = {"d", "e", "B", "uplo", "n", "nrhs", "ldB",
         "offsetd", "offsete", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|Ciiiiii", kwlist,
+        &d, &e, &B, &uplo_, &n, &nrhs, &ldB, &od, &oe, &oB)) 
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ciiiiii", kwlist,
-        &d, &e, &B, &uplo, &n, &nrhs, &ldB, &od, &oe, &oB)) return NULL;
+        &d, &e, &B, &uplo, &n, &nrhs, &ldB, &od, &oe, &oB)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(d)) err_mtrx("d");
     if (MAT_ID(d) != DOUBLE) err_type("d");
@@ -2109,11 +2219,22 @@ static PyObject* sytrf(PyObject *self, PyObject *args, PyObject *kwrds)
     void *work;
     number wl;
     int n=-1, ldA=0, oA=0, info, lwork;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "ipiv", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
+        &A, &ipiv, &uplo_, &n, &ldA, &oA)) 
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
-        &A, &ipiv, &uplo, &n, &ldA, &oA)) return NULL;
+        &A, &ipiv, &uplo, &n, &ldA, &oA)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2218,11 +2339,22 @@ static PyObject* hetrf(PyObject *self, PyObject *args, PyObject *kwrds)
     void *work;
     number wl;
     int n=-1, ldA=0, oA=0, info, lwork;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "ipiv", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
+        &A, &ipiv, &uplo_, &n, &ldA, &oA)) 
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
-        &A, &ipiv, &uplo, &n, &ldA, &oA)) return NULL;
+        &A, &ipiv, &uplo, &n, &ldA, &oA)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2334,13 +2466,23 @@ static PyObject* sytrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B, *ipiv;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "ipiv", "B", "uplo", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|Ciiiiii", kwlist,
+        &A, &ipiv, &B, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ciiiiii", kwlist,
         &A, &ipiv, &B, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2436,13 +2578,23 @@ static PyObject* hetrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B, *ipiv;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ ='L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "ipiv", "B", "uplo", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|Ciiiiii", kwlist,
+        &A, &ipiv, &B, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ciiiiii", kwlist,
         &A, &ipiv, &B, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2529,13 +2681,23 @@ static PyObject* sytri(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *ipiv;
     int n=-1, ldA=0, oA=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     void *work;
     char *kwlist[] = {"A", "ipiv", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
+        &A, &ipiv, &uplo_, &n, &ldA, &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
         &A, &ipiv, &uplo, &n, &ldA, &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2629,13 +2791,23 @@ static PyObject* hetri(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *ipiv;
     int n=-1, ldA=0, oA=0, info;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     void *work;
     char *kwlist[] = {"A", "ipiv", "uplo", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
+        &A, &ipiv, &uplo_, &n, &ldA, &oA))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
         &A, &ipiv, &uplo, &n, &ldA, &oA))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(ipiv) || ipiv->id != INT) err_int_mtrx("ipiv");
@@ -2740,13 +2912,23 @@ static PyObject* sysv(PyObject *self, PyObject *args, PyObject *kwrds)
         *ipivc=NULL;
     void *work=NULL, *Ac=NULL;
     number wl;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "ipiv", "uplo", "n", "nrhs", "ldA",
         "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OCiiiiii", kwlist,
+        &A, &B, &ipiv, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ociiiiii", kwlist,
         &A, &B, &ipiv, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -2911,13 +3093,23 @@ static PyObject* hesv(PyObject *self, PyObject *args, PyObject *kwrds)
         *ipivc=NULL;
     void *work=NULL, *Ac=NULL;
     number wl;
-    char uplo='L';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L';
+#endif
+    char uplo = 'L';
     char *kwlist[] = {"A", "B", "ipiv", "uplo", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OCiiiiii", kwlist,
+        &A, &B, &ipiv, &uplo_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ociiiiii", kwlist,
         &A, &B, &ipiv, &uplo, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3077,13 +3269,25 @@ static PyObject* trtrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
-    char uplo='L', trans='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
+    char uplo = 'L', trans = 'N', diag = 'N';
     char *kwlist[] = {"A", "B", "uplo", "trans", "diag", "n", "nrhs",
         "ldA", "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiiii", kwlist,
+        &A, &B, &uplo_, &trans_, &diag_, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiiii", kwlist,
         &A, &B, &uplo, &trans, &diag, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3156,11 +3360,21 @@ static PyObject* trtri(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A;
     int n=-1, ldA=0, oA=0, info;
-    char uplo='L', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', diag_ = 'N';
+#endif
+    char uplo = 'L', diag = 'N';
     char *kwlist[] = {"A", "uplo", "diag", "n", "ldA", "offsetA", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|CCiii", kwlist,
+        &A, &uplo_, &diag_, &n, &ldA, &oA)) return NULL;
+    uplo = (char) uplo_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|cciii", kwlist,
         &A, &uplo, &diag, &n, &ldA, &oA)) return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (uplo != 'L' && uplo != 'U') err_char("uplo", "'L', 'U'");
@@ -3234,15 +3448,28 @@ static char doc_tbtrs[] =
 static PyObject* tbtrs(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
-    char uplo='L', trans='N', diag='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', trans_ = 'N', diag_ = 'N';
+#endif
+    char uplo = 'L', trans = 'N', diag = 'N';
     int n=-1, kd=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info;
     char *kwlist[] = {"A", "B", "uplo", "trans", "diag", "n", "kd", "nrhs",
         "ldA", "ldB", "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCiiiiiii", kwlist,
+        &A, &B, &uplo_, &trans_, &diag_, &n, &kd, &nrhs, &ldA, &ldB, &oA,
+        &oB))
+        return NULL;
+    uplo = (char) uplo_;
+    trans = (char) trans_;
+    diag = (char) diag_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccciiiiiii", kwlist,
         &A, &B, &uplo, &trans, &diag, &n, &kd, &nrhs, &ldA, &ldB, &oA,
         &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3331,13 +3558,23 @@ static PyObject* gels(PyObject *self, PyObject *args, PyObject *kwrds)
     int m=-1, n=-1, nrhs=-1, ldA=0, ldB=0, oA=0, oB=0, info, lwork;
     void *work;
     number wl;
-    char trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
+    char trans = 'N';
     char *kwlist[] = {"A", "B", "trans", "m", "n", "nrhs", "ldA", "ldB",
         "offsetA", "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiiii",
+        kwlist, &A, &B, &trans_, &m, &n, &nrhs, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiiii",
         kwlist, &A, &B, &trans, &m, &n, &nrhs, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -3529,13 +3766,26 @@ static PyObject* ormqr(PyObject *self, PyObject *args, PyObject *kwrds)
     int m=-1, n=-1, k=-1, ldA=0, ldC=0, oA=0, oC=0, info, lwork;
     void *work;
     number wl;
-    char side='L', trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', trans_ = 'N';
+#endif
+    char side = 'L', trans = 'N';
     char *kwlist[] = {"A", "tau", "C", "side", "trans", "m", "n", "k",
         "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCiiiiiii",
+        kwlist, &A, &tau, &C, &side_, &trans_, &m, &n, &k, &ldA, &ldC,
+        &oA, &oC)) 
+        return NULL;
+    side = (char) side_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cciiiiiii",
         kwlist, &A, &tau, &C, &side, &trans, &m, &n, &k, &ldA, &ldC,
-        &oA, &oC)) return NULL;
+        &oA, &oC)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(tau)) err_mtrx("tau");
@@ -3628,13 +3878,26 @@ static PyObject* unmqr(PyObject *self, PyObject *args, PyObject *kwrds)
     int m=-1, n=-1, k=-1, ldA=0, ldC=0, oA=0, oC=0, info, lwork;
     void *work;
     number wl;
-    char side='L', trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', trans_ = 'N';
+#endif
+    char side = 'L', trans = 'N';
     char *kwlist[] = {"A", "tau", "C", "side", "trans", "m", "n", "k",
         "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCiiiiiii",
+        kwlist, &A, &tau, &C, &side_, &trans_, &m, &n, &k, &ldA, &ldC,
+        &oA, &oC)) 
+        return NULL;
+    side = (char) side_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cciiiiiii",
         kwlist, &A, &tau, &C, &side, &trans, &m, &n, &k, &ldA, &ldC,
-        &oA, &oC)) return NULL;
+        &oA, &oC)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(tau)) err_mtrx("tau");
@@ -3991,13 +4254,26 @@ static PyObject* ormlq(PyObject *self, PyObject *args, PyObject *kwrds)
     int m=-1, n=-1, k=-1, ldA=0, ldC=0, oA=0, oC=0, info, lwork;
     void *work;
     number wl;
-    char side='L', trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', trans_ = 'N';
+#endif
+    char side = 'L', trans = 'N';
     char *kwlist[] = {"A", "tau", "C", "side", "trans", "m", "n", "k",
         "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCiiiiiii",
+        kwlist, &A, &tau, &C, &side_, &trans_, &m, &n, &k, &ldA, &ldC,
+        &oA, &oC)) 
+        return NULL;
+    side = (char) side_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cciiiiiii",
         kwlist, &A, &tau, &C, &side, &trans, &m, &n, &k, &ldA, &ldC,
-        &oA, &oC)) return NULL;
+        &oA, &oC)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(tau)) err_mtrx("tau");
@@ -4089,13 +4365,26 @@ static PyObject* unmlq(PyObject *self, PyObject *args, PyObject *kwrds)
     int m=-1, n=-1, k=-1, ldA=0, ldC=0, oA=0, oC=0, info, lwork;
     void *work;
     number wl;
-    char side='L', trans='N';
+#if PY_MAJOR_VERSION >= 3
+    int side_ = 'L', trans_ = 'N';
+#endif
+    char side = 'L', trans = 'N';
     char *kwlist[] = {"A", "tau", "C", "side", "trans", "m", "n", "k",
         "ldA", "ldC", "offsetA", "offsetC", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|CCiiiiiii",
+        kwlist, &A, &tau, &C, &side_, &trans_, &m, &n, &k, &ldA, &ldC,
+        &oA, &oC)) 
+        return NULL;
+    side = (char) side_;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|cciiiiiii",
         kwlist, &A, &tau, &C, &side, &trans, &m, &n, &k, &ldA, &ldC,
-        &oA, &oC)) return NULL;
+        &oA, &oC)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(tau)) err_mtrx("tau");
@@ -4472,12 +4761,24 @@ static PyObject* syev(PyObject *self, PyObject *args, PyObject *kwrds)
     int n=-1, ldA=0, oA=0, oW=0, info, lwork;
     double *work;
     number wl;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "W", "jobz", "uplo", "n", "ldA", "offsetA",
         "offsetW", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCiiii", kwlist,
+        &A, &W, &jobz_, &uplo_, &n, &ldA, &oA, &oW)) 
+        return NULL;
+    jobz = (char) jobz_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cciiii", kwlist,
-        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) return NULL;
+        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -4554,12 +4855,24 @@ static PyObject* heev(PyObject *self, PyObject *args, PyObject *kwrds)
     double *rwork=NULL;
     void *work=NULL;
     number wl;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "W", "jobz", "uplo", "n", "ldA", "offsetA",
         "offsetW", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCiiii", kwlist,
+        &A, &W, &jobz_, &uplo_, &n, &ldA, &oA, &oW)) 
+        return NULL;
+    jobz = (char) jobz_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cciiii", kwlist,
-        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) return NULL;
+        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -4679,14 +4992,28 @@ static PyObject* syevx(PyObject *self, PyObject *args, PyObject *kwrds)
         *iwork, m, *ifail=NULL;
     double *work, vl=0.0, vu=0.0, abstol=0.0;
     double wl;
-    char uplo='L', jobz='N', range='A';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N', range_ = 'A';
+#endif
+    char uplo = 'L', jobz = 'N', range = 'A';
     char *kwlist[] = {"A", "W", "jobz", "range", "uplo", "vl", "vu",
 	"il", "iu", "Z", "n", "ldA", "ldZ", "abstol", "offsetA",
         "offsetW", "offsetZ", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCddiiOiiidiii",
+        kwlist, &A, &W, &jobz_, &range_, &uplo_, &vl, &vu, &il, &iu, &Z,
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+    jobz = (char) jobz_;
+    range = (char) range_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cccddiiOiiidiii",
         kwlist, &A, &W, &jobz, &range, &uplo, &vl, &vu, &il, &iu, &Z,
-	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) return NULL;
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -4819,14 +5146,28 @@ static PyObject* heevx(PyObject *self, PyObject *args, PyObject *kwrds)
     double vl=0.0, vu=0.0, abstol=0.0, *rwork;
     number wl;
     void *work;
-    char uplo='L', jobz='N', range='A';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N', range_ = 'A';
+#endif
+    char uplo = 'L', jobz = 'N', range = 'A';
     char *kwlist[] = {"A", "W", "jobz", "range", "uplo", "vl", "vu",
 	"il", "iu", "Z", "n", "ldA", "ldZ", "abstol", "offsetA",
         "offsetW", "offsetZ", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCddiiOiiidiii",
+        kwlist, &A, &W, &jobz_, &range_, &uplo_, &vl, &vu, &il, &iu, &Z,
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+    jobz = (char) jobz_;
+    range = (char) range_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cccddiiOiiidiii",
         kwlist, &A, &W, &jobz, &range, &uplo, &vl, &vu, &il, &iu, &Z,
-	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) return NULL;
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -4958,12 +5299,24 @@ static PyObject* syevd(PyObject *self, PyObject *args, PyObject *kwrds)
     matrix *A, *W;
     int n=-1, ldA=0, oA=0, oW=0, info, lwork, liwork, *iwork, iwl;
     double *work=NULL, wl;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "W", "jobz", "uplo", "n", "ldA", "offsetA",
         "offsetW", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCiiii", kwlist,
+        &A, &W, &jobz_, &uplo_, &n, &ldA, &oA, &oW)) 
+        return NULL;
+    uplo = (char) uplo_;
+    jobz = (char) jobz_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cciiii", kwlist,
-        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) return NULL;
+        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || W->id != DOUBLE) err_dbl_mtrx("W");
@@ -5048,12 +5401,24 @@ static PyObject* heevd(PyObject *self, PyObject *args, PyObject *kwrds)
     double *rwork, rwl;
     number wl;
     void *work;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "W", "jobz", "uplo", "n", "ldA", "offsetA",
         "offsetW", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCiiii", kwlist,
+        &A, &W, &jobz_, &uplo_, &n, &ldA, &oA, &oW)) 
+        return NULL;
+    jobz = (char) jobz_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cciiii", kwlist,
-        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) return NULL;
+        &A, &W, &jobz, &uplo, &n, &ldA, &oA, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || W->id != DOUBLE) err_dbl_mtrx("W");
@@ -5188,14 +5553,28 @@ static PyObject* syevr(PyObject *self, PyObject *args, PyObject *kwrds)
     int n=-1, ldA=0, ldZ=0, il=1, iu=1, oA=0, oW=0, oZ=0, info, lwork,
         *iwork=NULL, liwork, m, *isuppz=NULL, iwl;
     double *work=NULL, vl=0.0, vu=0.0, abstol=0.0, wl;
-    char uplo='L', jobz='N', range='A';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N', range_ = 'A';
+#endif
+    char uplo = 'L', jobz = 'N', range = 'A';
     char *kwlist[] = {"A", "W", "jobz", "range", "uplo", "vl", "vu",
 	"il", "iu", "Z", "n", "ldA", "ldZ", "abstol", "offsetA",
         "offsetW", "offsetZ", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCddiiOiiidiii",
+        kwlist, &A, &W, &jobz_, &range_, &uplo_, &vl, &vu, &il, &iu, &Z,
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+    jobz = (char) jobz_;
+    range = (char) range_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cccddiiOiiidiii",
         kwlist, &A, &W, &jobz, &range, &uplo, &vl, &vu, &il, &iu, &Z,
-	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) return NULL;
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -5336,14 +5715,28 @@ static PyObject* heevr(PyObject *self, PyObject *args, PyObject *kwrds)
     double vl=0.0, vu=0.0, abstol=0.0, *rwork, rwl;
     void *work;
     number wl;
-    char uplo='L', jobz='N', range='A';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N', range_ = 'A';
+#endif
+    char uplo = 'L', jobz = 'N', range = 'A';
     char *kwlist[] = {"A", "W", "jobz", "range", "uplo", "vl", "vu",
 	"il", "iu", "Z", "n", "ldA", "ldZ", "abstol", "offsetA",
         "offsetW", "offsetZ", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCCddiiOiiidiii",
+        kwlist, &A, &W, &jobz_, &range_, &uplo_, &vl, &vu, &il, &iu, &Z,
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+    jobz = (char) jobz_;
+    range = (char) range_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cccddiiOiiidiii",
         kwlist, &A, &W, &jobz, &range, &uplo, &vl, &vu, &il, &iu, &Z,
-	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) return NULL;
+	&n, &ldA, &ldZ, &abstol, &oA, &oW, &oZ)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(W) || MAT_ID(W) != DOUBLE) err_dbl_mtrx("W");
@@ -5504,13 +5897,26 @@ static PyObject* sygv(PyObject *self, PyObject *args, PyObject *kwrds)
     int n=-1, itype=1, ldA=0, ldB=0, oA=0, oB=0, oW=0, info, lwork;
     double *work;
     number wl;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "B", "W", "itype", "jobz", "uplo", "n",
         "ldA", "ldB", "offsetA", "offsetB", "offsetW", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|iCCiiiiii",
+        kwlist, &A, &B, &W, &itype, &jobz_, &uplo_, &n, &ldA, &ldB, &oA,
+        &oB, &oW)) 
+        return NULL;
+    jobz = (char) jobz_;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|icciiiiii",
         kwlist, &A, &B, &W, &itype, &jobz, &uplo, &n, &ldA, &ldB, &oA,
-        &oB, &oW)) return NULL;
+        &oB, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B) || MAT_ID(B) != MAT_ID(A)) err_conflicting_ids;
@@ -5614,15 +6020,30 @@ static PyObject* hegv(PyObject *self, PyObject *args, PyObject *kwrds)
     double *rwork=NULL;
     void *work=NULL;
     number wl;
-    char uplo='L', jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'L', jobz_ = 'N';
+#endif
+    char uplo = 'L', jobz = 'N';
     char *kwlist[] = {"A", "B", "W", "itype", "jobz", "uplo", "n",
         "ldA", "offsetA", "offsetB", "offsetW", NULL};
+#if 0
     int ispec=1, n2=-1, n3=-1, n4=-1;
     char *name = "zhetrd", *uplol = "L", *uplou = "U";
+#endif
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|iCCiiiii",
+        kwlist, &A, &B, &W, &itype, &jobz_, &uplo_, &n, &ldA, &ldB, &oA,
+        &oB, &oW)) 
+        return NULL;
+    uplo = (char) uplo_;
+    jobz = (char) jobz_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|icciiiii",
         kwlist, &A, &B, &W, &itype, &jobz, &uplo, &n, &ldA, &ldB, &oA,
-        &oB, &oW)) return NULL;
+        &oB, &oW)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B) || MAT_ID(B) != MAT_ID(A)) err_conflicting_ids;
@@ -5674,8 +6095,7 @@ static PyObject* hegv(PyObject *self, PyObject *args, PyObject *kwrds)
             break;
 
         case COMPLEX:
-#if 0
-            /* zhegv does not handle lwork=-1 correctly */
+#if 1
             lwork=-1;
             Py_BEGIN_ALLOW_THREADS
             zhegv_(&itype, &jobz, &uplo, &n, NULL, &n, NULL, &n, NULL,
@@ -5683,9 +6103,12 @@ static PyObject* hegv(PyObject *self, PyObject *args, PyObject *kwrds)
             Py_END_ALLOW_THREADS
             lwork = (int) creal(wl.z);
 #endif
-            /* replaces call to zhegv with lwork=-1 */
+#if 0
+            /* zhegv used to handle lwork=-1 incorrectly.
+               The following replaces the call to zhegv with lwork=-1 */
             lwork = n * (1 + ilaenv_(&ispec, &name, (uplo == 'L') ?
                 &uplol : &uplou, &n, &n2, &n3, &n4));
+#endif
 
             work = (void *) calloc(lwork, sizeof(complex));
             rwork = (double *) calloc(3*n-2, sizeof(double));
@@ -5788,14 +6211,27 @@ static PyObject* gesvd(PyObject *self, PyObject *args, PyObject *kwrds)
     double *rwork=NULL;
     void *work=NULL;
     number wl;
-    char jobu='N', jobvt='N';
+#if PY_MAJOR_VERSION >= 3
+    int jobu_ = 'N', jobvt_ = 'N';
+#endif
+    char jobu = 'N', jobvt = 'N';
     char *kwlist[] = {"A", "S", "jobu", "jobvt", "U", "Vt", "m", "n",
 	"ldA", "ldU", "ldVt", "offsetA", "offsetS", "offsetU",
         "offsetVt", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CCOOiiiiiiiii",
+        kwlist, &A, &S, &jobu_, &jobvt_, &U, &Vt, &m, &n, &ldA, &ldU,
+        &ldVt, &oA, &oS, &oU, &oVt)) 
+        return NULL;
+    jobu = (char) jobu_;
+    jobvt = (char) jobvt_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccOOiiiiiiiii",
         kwlist, &A, &S, &jobu, &jobvt, &U, &Vt, &m, &n, &ldA, &ldU,
-        &ldVt, &oA, &oS, &oU, &oVt)) return NULL;
+        &ldVt, &oA, &oS, &oU, &oVt)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(S) || MAT_ID(S) != DOUBLE) err_dbl_mtrx("S");
@@ -5976,14 +6412,26 @@ static PyObject* gesdd(PyObject *self, PyObject *args, PyObject *kwrds)
     double *rwork=NULL;
     void *work=NULL;
     number wl;
-    char jobz='N';
+#if PY_MAJOR_VERSION >= 3
+    int jobz_ = 'N';
+#endif
+    char jobz = 'N';
     char *kwlist[] = {"A", "S", "jobz", "U", "Vt", "m", "n", "ldA",
 	"ldU", "ldVt", "offsetA", "offsetS", "offsetU", "offsetVt",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|COOiiiiiiiii",
+        kwlist, &A, &S, &jobz_, &U, &Vt, &m, &n, &ldA, &ldU, &ldVt, &oA,
+       	&oS, &oU, &oVt)) 
+        return NULL;
+    jobz = (char) jobz_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cOOiiiiiiiii",
         kwlist, &A, &S, &jobz, &U, &Vt, &m, &n, &ldA, &ldU, &ldVt, &oA,
-       	&oS, &oU, &oVt)) return NULL;
+       	&oS, &oU, &oVt)) 
+        return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(S) || MAT_ID(S) != DOUBLE) err_dbl_mtrx("S");
@@ -6140,8 +6588,11 @@ extern int fselect_c(complex *w)
         Py_XDECREF(wpy);
         return -1;
     }
-    if PyInt_Check(result)
-        a = (int) PyInt_AsLong(result);
+#if PY_MAJOR_VERSION >= 3
+    if PyLong_Check(result) a = (int) PyLong_AsLong(result);
+#else
+    if PyInt_Check(result) a = (int) PyInt_AsLong(result);
+#endif
     else
         PyErr_SetString(PyExc_TypeError, "select() must return an integer "
             "argument");
@@ -6159,8 +6610,11 @@ extern int fselect_r(double *wr, double *wi)
         Py_XDECREF(wpy);
         return -1;
     }
-    if PyInt_Check(result)
-        a = (int) PyInt_AsLong(result);
+#if PY_MAJOR_VERSION >= 3
+    if PyLong_Check(result) a = (int) PyLong_AsLong(result);
+#else
+    if PyInt_Check(result) a = (int) PyInt_AsLong(result);
+#endif
     else
         PyErr_SetString(PyExc_TypeError, "select() must return an integer "
            "argument");
@@ -6351,8 +6805,11 @@ extern int fselect_gc(complex *w, double *v)
        Py_XDECREF(wpy); Py_XDECREF(vpy);
        return -1;
    }
-   if PyInt_Check(result)
-       a = (int) PyInt_AsLong(result);
+#if PY_MAJOR_VERSION >= 3
+   if PyLong_Check(result) a = (int) PyLong_AsLong(result);
+#else
+   if PyInt_Check(result) a = (int) PyInt_AsLong(result);
+#endif
    else
        PyErr_SetString(PyExc_TypeError, "select() must return an integer "
            "argument");
@@ -6372,8 +6829,11 @@ extern int fselect_gr(double *wr, double *wi, double *v)
        Py_XDECREF(wpy); Py_XDECREF(vpy);
        return -1;
    }
-   if PyInt_Check(result)
-       a = (int) PyInt_AsLong(result);
+#if PY_MAJOR_VERSION >= 3
+   if PyLong_Check(result) a = (int) PyLong_AsLong(result);
+#else
+   if PyInt_Check(result) a = (int) PyInt_AsLong(result);
+#endif
    else
        PyErr_SetString(PyExc_TypeError, "select() must return an integer "
            "argument");
@@ -6569,13 +7029,23 @@ static PyObject* lacpy(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *A, *B;
     int m = -1, n = -1, ldA = 0, ldB = 0, oA = 0, oB = 0;
+#if PY_MAJOR_VERSION >= 3
+    int uplo_ = 'N';
+#endif
     char uplo = 'N';
     char *kwlist[] = {"A", "B", "uplo", "m", "n", "ldA", "ldB", "offsetA",
         "offsetB", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciiiiii", kwlist,
+        &A, &B, &uplo_, &m, &n, &ldA, &ldB, &oA, &oB))
+        return NULL;
+    uplo = (char) uplo_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciiiiii", kwlist,
         &A, &B, &uplo, &m, &n, &ldA, &ldB, &oA, &oB))
         return NULL;
+#endif
 
     if (!Matrix_Check(A)) err_mtrx("A");
     if (!Matrix_Check(B)) err_mtrx("B");
@@ -6674,11 +7144,33 @@ static PyMethodDef lapack_functions[] = {
 {NULL}  /* Sentinel */
 };
 
-PyMODINIT_FUNC initlapack(void)
+
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef lapack_module = {
+    PyModuleDef_HEAD_INIT,
+    "lapack",
+    lapack__doc__,
+    -1,
+    lapack_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_lapack(void)
 {
-  PyObject *m;
+    PyObject *m;
+    if (!(m = PyModule_Create(&lapack_module))) return NULL;
+    if (import_cvxopt() < 0) return NULL;
+    return m;
+}
 
-  m = Py_InitModule3("cvxopt.lapack", lapack_functions, lapack__doc__);
+#else
 
-  if (import_cvxopt() < 0) return;
+PyMODINIT_FUNC initlapack(void)
+{
+    PyObject *m;
+    m = Py_InitModule3("cvxopt.lapack", lapack_functions, lapack__doc__);
+    if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/misc.h b/src/C/misc.h
index 6df7a9f..68292b4 100644
--- a/src/C/misc.h
+++ b/src/C/misc.h
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,11 @@
 #ifndef __MISC__
 #define __MISC__
 
+#if PY_MAJOR_VERSION >= 3
+#define PY_NUMBER(O) (PyLong_Check(O) || PyFloat_Check(O) || PyComplex_Check(O))
+#else
 #define PY_NUMBER(O) (PyInt_Check(O) || PyFloat_Check(O) || PyComplex_Check(O))
+#endif
 
 #ifndef NO_ANSI99_COMPLEX
 typedef union {
@@ -52,9 +56,16 @@ typedef union {
 #define X_NCOLS(O) (Matrix_Check(O) ? MAT_NCOLS(O) : SP_NCOLS(O))
 #define X_Matrix_Check(O) (Matrix_Check(O) || SpMatrix_Check(O))
 
+#if PY_MAJOR_VERSION >= 3
+#define TypeCheck_Capsule(O,str,errstr) { \
+    if (!PyCapsule_CheckExact(O)) PY_ERR(PyExc_TypeError, errstr); \
+    const char *descr = PyCapsule_GetName(O);  \
+    if (!descr || strcmp(descr,str)) PY_ERR(PyExc_TypeError,errstr); }
+#else
 #define TypeCheck_CObject(O,str,errstr) { \
     char *descr = PyCObject_GetDesc(O);   \
     if (!descr || strcmp(descr,str)) PY_ERR(PyExc_TypeError,errstr); }
+#endif
 
 
 #define len(x) (Matrix_Check(x) ? MAT_LGT(x) : SP_LGT(x))
@@ -92,7 +103,11 @@ typedef union {
 #define err_dbl_mtrx(s) { \
     PY_ERR_TYPE(s " must be a matrix with typecode 'd'") }
 
+#if PY_MAJOR_VERSION >= 3
+#define err_CO(s) PY_ERR_TYPE(s " is not a Capsule")
+#else
 #define err_CO(s) PY_ERR_TYPE(s " is not a CObject")
+#endif
 
 
 #define err_msk_noparam "missing options dictionary"
diff --git a/src/C/misc_solvers.c b/src/C/misc_solvers.c
index 1f5df02..11d6633 100644
--- a/src/C/misc_solvers.c
+++ b/src/C/misc_solvers.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -85,15 +85,24 @@ static PyObject* scale(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *x, *d, *vk, *rk;
     PyObject *W, *v, *beta, *r, *betak;
+#if PY_MAJOR_VERSION >= 3
+    int trans = 'N', inverse = 'N';
+#else
     char trans = 'N', inverse = 'N';
+#endif
     int m, n, xr, xc, ind = 0, int0 = 0, int1 = 1, i, k, inc, len, ld, 
         maxn, N;
     double b, dbl0 = 0.0, dbl1 = 1.0, dblm1 = -1.0, dbl2 = 2.0, dbl5 = 0.5,
         *wrk;
     char *kwlist[] = {"x", "W", "trans", "inverse", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|CC", kwlist,
+        &x, &W, &trans, &inverse)) return NULL;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|cc", kwlist,
         &x, &W, &trans, &inverse)) return NULL;
+#endif
 
     xr = x->nrows;
     xc = x->ncols;
@@ -247,13 +256,22 @@ static PyObject* scale2(PyObject *self, PyObject *args, PyObject *kwrds)
 {
     matrix *lmbda, *x;
     PyObject *dims, *O, *Ok;
+#if PY_MAJOR_VERSION >= 3
+    int inverse = 'N';
+#else
     char inverse = 'N';
+#endif
     double a, lx, x0, b, *c = NULL, *sql = NULL;
     int m = 0, mk, i, j, len, int0 = 0, int1 = 1, maxn = 0, ind2;
     char *kwlist[] = {"lmbda", "x", "dims", "mnl", "inverse", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|iC", kwlist, &lmbda,
+        &x, &dims, &m, &inverse)) return NULL;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ic", kwlist, &lmbda,
         &x, &dims, &m, &inverse)) return NULL;
+#endif
 
 
     /*
@@ -266,7 +284,11 @@ static PyObject* scale2(PyObject *self, PyObject *args, PyObject *kwrds)
      */
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    m += (int) PyLong_AsLong(O);
+#else
     m += (int) PyInt_AsLong(O);
+#endif
     if (inverse == 'N')
         dtbsv_("L", "N", "N", &m, &int0, MAT_BUFD(lmbda), &int1,
              MAT_BUFD(x), &int1);
@@ -292,7 +314,11 @@ static PyObject* scale2(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         len = mk - 1;
         a = dnrm2_(&len, MAT_BUFD(lmbda) + m + 1, &int1);
         a = sqrt(MAT_BUFD(lmbda)[m] + a) * sqrt(MAT_BUFD(lmbda)[m] - a);
@@ -333,7 +359,11 @@ static PyObject* scale2(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "s");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        maxn = MAX(maxn, (int) PyLong_AsLong(Ok));
+#else
         maxn = MAX(maxn, (int) PyInt_AsLong(Ok));
+#endif
     }
     if (!(c = (double *) calloc(maxn, sizeof(double))) ||
         !(sql = (double *) calloc(maxn, sizeof(double)))){
@@ -343,7 +373,11 @@ static PyObject* scale2(PyObject *self, PyObject *args, PyObject *kwrds)
     ind2 = m;
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         for (j = 0; j < mk; j++)
             sql[j] = sqrt(MAT_BUFD(lmbda)[ind2 + j]);
         for (j = 0; j < mk; j++){
@@ -386,12 +420,20 @@ static PyObject* pack(PyObject *self, PyObject *args, PyObject *kwrds)
         &y, &dims, &nlq, &ox, &oy)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    nlq += (int) PyLong_AsLong(O);
+#else
     nlq += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        nlq += (int) PyLong_AsLong(Ok);
+#else
         nlq += (int) PyInt_AsLong(Ok);
+#endif
     }
     dcopy_(&nlq, MAT_BUFD(x) + ox, &int1, MAT_BUFD(y) + oy, &int1);
 
@@ -399,7 +441,11 @@ static PyObject* pack(PyObject *self, PyObject *args, PyObject *kwrds)
     for (i = 0, np = 0, iu = ox + nlq, ip = oy + nlq; i < (int)
         PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        n = (int) PyLong_AsLong(Ok);
+#else
         n = (int) PyInt_AsLong(Ok);
+#endif
         for (k = 0; k < n; k++){
             len = n-k;
             dcopy_(&len, MAT_BUFD(x) + iu + k*(n+1), &int1,  MAT_BUFD(y) +
@@ -441,18 +487,30 @@ static PyObject* pack2(PyObject *self, PyObject *args, PyObject *kwrds)
     xc = x->ncols;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    nlq += (int) PyLong_AsLong(O);
+#else
     nlq += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        nlq += (int) PyLong_AsLong(Ok);
+#else
         nlq += (int) PyInt_AsLong(Ok);
+#endif
     }
 
     O = PyDict_GetItemString(dims, "s");
     for (i = 0, maxn = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        maxn = MAX(maxn, (int) PyLong_AsLong(Ok));
+#else
         maxn = MAX(maxn, (int) PyInt_AsLong(Ok));
+#endif
     }
     if (!maxn) return Py_BuildValue("");
     if (!(wrk = (double *) calloc(maxn * xc, sizeof(double))))
@@ -460,7 +518,11 @@ static PyObject* pack2(PyObject *self, PyObject *args, PyObject *kwrds)
 
     for (i = 0, iu = nlq, ip = nlq; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        n = (int) PyLong_AsLong(Ok);
+#else
         n = (int) PyInt_AsLong(Ok);
+#endif
         for (k = 0; k < n; k++){
             len = n-k;
             dlacpy_(" ", &len, &xc, MAT_BUFD(x) + iu + k*(n+1), &xr, wrk, 
@@ -498,19 +560,31 @@ static PyObject* unpack(PyObject *self, PyObject *args, PyObject *kwrds)
         &y, &dims, &m, &ox, &oy)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    m += (int) PyLong_AsLong(O);
+#else
     m += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        m += (int) PyLong_AsLong(Ok);
+#else
         m += (int) PyInt_AsLong(Ok);
+#endif
     }
     dcopy_(&m, MAT_BUFD(x) + ox, &int1, MAT_BUFD(y) + oy, &int1);
 
     O = PyDict_GetItemString(dims, "s");
     for (i = 0, ip = ox + m, iu = oy + m; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        n = (int) PyLong_AsLong(Ok);
+#else
         n = (int) PyInt_AsLong(Ok);
+#endif
         for (k = 0; k < n; k++){
             len = n-k;
             dcopy_(&len, MAT_BUFD(x) + ip, &int1, MAT_BUFD(y) + iu +
@@ -562,11 +636,20 @@ static PyObject* sprod(PyObject *self, PyObject *args, PyObject *kwrds)
     PyObject *dims, *O, *Ok;
     int i, j, k, mk, len, maxn, ind = 0, ind2, int0 = 0, int1 = 1, ld;
     double a, *A = NULL, dbl2 = 0.5, dbl0 = 0.0;
+#if PY_MAJOR_VERSION >= 3
+    int diag = 'N';
+#else
     char diag = 'N';
+#endif
     char *kwlist[] = {"x", "y", "dims", "mnl", "diag", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|iC", kwlist, &x, &y,
+        &dims, &ind, &diag)) return NULL;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ic", kwlist, &x, &y,
         &dims, &ind, &diag)) return NULL;
+#endif
 
 
     /*
@@ -576,7 +659,11 @@ static PyObject* sprod(PyObject *self, PyObject *args, PyObject *kwrds)
      */
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    ind += (int) PyLong_AsLong(O);
+#else
     ind += (int) PyInt_AsLong(O);
+#endif
     dtbmv_("L", "N", "N", &ind, &int0, MAT_BUFD(y), &int1, MAT_BUFD(x),
         &int1);
 
@@ -594,7 +681,11 @@ static PyObject* sprod(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         a = ddot_(&mk, MAT_BUFD(y) + ind, &int1, MAT_BUFD(x) + ind, &int1);
         len = mk - 1;
         dscal_(&len, MAT_BUFD(y) + ind, MAT_BUFD(x) + ind + 1, &int1);
@@ -616,14 +707,22 @@ static PyObject* sprod(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "s");
     for (i = 0, maxn = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        maxn = MAX(maxn, (int) PyLong_AsLong(Ok));
+#else
         maxn = MAX(maxn, (int) PyInt_AsLong(Ok));
+#endif
     }
     if (diag == 'N'){
         if (!(A = (double *) calloc(maxn * maxn, sizeof(double))))
             return PyErr_NoMemory();
         for (i = 0; i < (int) PyList_Size(O); ind += mk*mk, i++){
             Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+            mk = (int) PyLong_AsLong(Ok);
+#else
             mk = (int) PyInt_AsLong(Ok);
+#endif
             len = mk*mk;
             dcopy_(&len, MAT_BUFD(x) + ind, &int1, A, &int1);
 
@@ -646,7 +745,11 @@ static PyObject* sprod(PyObject *self, PyObject *args, PyObject *kwrds)
         for (i = 0, ind2 = ind; i < (int) PyList_Size(O); ind += mk*mk,
             ind2 += mk, i++){
             Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+            mk = (int) PyLong_AsLong(Ok);
+#else
             mk = (int) PyInt_AsLong(Ok);
+#endif
             for (k = 0; k < mk; k++){
                 len = mk - k;
                 dcopy_(&len, MAT_BUFD(y) + ind2 + k, &int1, A, &int1);
@@ -687,7 +790,11 @@ static PyObject* sinv(PyObject *self, PyObject *args, PyObject *kwrds)
      */
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    ind += (int) PyLong_AsLong(O);
+#else
     ind += (int) PyInt_AsLong(O);
+#endif
     dtbsv_("L", "N", "N", &ind, &int0, MAT_BUFD(y), &int1, MAT_BUFD(x),
         &int1);
 
@@ -705,7 +812,11 @@ static PyObject* sinv(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         len = mk - 1;
         a = dnrm2_(&len, MAT_BUFD(y) + ind + 1, &int1);
         a = (MAT_BUFD(y)[ind] + a) * (MAT_BUFD(y)[ind] - a);
@@ -735,14 +846,22 @@ static PyObject* sinv(PyObject *self, PyObject *args, PyObject *kwrds)
     O = PyDict_GetItemString(dims, "s");
     for (i = 0, maxn = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        maxn = MAX(maxn, (int) PyLong_AsLong(Ok));
+#else
         maxn = MAX(maxn, (int) PyInt_AsLong(Ok));
+#endif
     }
     if (!(A = (double *) calloc(maxn, sizeof(double))))
         return PyErr_NoMemory();
     for (i = 0, ind2 = ind; i < (int) PyList_Size(O); ind += mk*mk,
         ind2 += mk, i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         for (k = 0; k < mk; k++){
             len = mk - k;
             dcopy_(&len, MAT_BUFD(y) + ind2 + k, &int1, A, &int1);
@@ -776,18 +895,30 @@ static PyObject* trisc(PyObject *self, PyObject *args, PyObject *kwrds)
         &dims, &ox)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    ox += (int) PyLong_AsLong(O);
+#else
     ox += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        ox += (int) PyLong_AsLong(Ok);
+#else
         ox += (int) PyInt_AsLong(Ok);
+#endif
     }
 
     O = PyDict_GetItemString(dims, "s");
     for (k = 0; k < (int) PyList_Size(O); k++){
         Ok = PyList_GetItem(O, (Py_ssize_t) k);
+#if PY_MAJOR_VERSION >= 3
+        nk = (int) PyLong_AsLong(Ok);
+#else
         nk = (int) PyInt_AsLong(Ok);
+#endif
         for (i = 1; i < nk; i++){
             len = nk - i;
             dscal_(&len, &dbl0, MAT_BUFD(x) + ox + i*(nk+1) - 1, &nk);
@@ -817,18 +948,30 @@ static PyObject* triusc(PyObject *self, PyObject *args, PyObject *kwrds)
         &dims, &ox)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    ox += (int) PyLong_AsLong(O);
+#else
     ox += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        ox += (int) PyLong_AsLong(Ok);
+#else
         ox += (int) PyInt_AsLong(Ok);
+#endif
     }
 
     O = PyDict_GetItemString(dims, "s");
     for (k = 0; k < (int) PyList_Size(O); k++){
         Ok = PyList_GetItem(O, (Py_ssize_t) k);
+#if PY_MAJOR_VERSION >= 3
+        nk = (int) PyLong_AsLong(Ok);
+#else
         nk = (int) PyInt_AsLong(Ok);
+#endif
         for (i = 1; i < nk; i++){
             len = nk - i;
             dscal_(&len, &dbl5, MAT_BUFD(x) + ox + nk*(i-1) + i, &int1);
@@ -856,19 +999,31 @@ static PyObject* sdot(PyObject *self, PyObject *args, PyObject *kwrds)
         &dims, &m)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    m += (int) PyLong_AsLong(O);
+#else
     m += (int) PyInt_AsLong(O);
+#endif
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        m += (int) PyLong_AsLong(Ok);
+#else
         m += (int) PyInt_AsLong(Ok);
+#endif
     }
     a = ddot_(&m, MAT_BUFD(x), &int1, MAT_BUFD(y), &int1);
 
     O = PyDict_GetItemString(dims, "s");
     for (k = 0; k < (int) PyList_Size(O); k++){
         Ok = PyList_GetItem(O, (Py_ssize_t) k);
+#if PY_MAJOR_VERSION >= 3
+        nk = (int) PyLong_AsLong(Ok);
+#else
         nk = (int) PyInt_AsLong(Ok);
+#endif
         inc = nk+1;
         a += ddot_(&nk, MAT_BUFD(x) + m, &inc, MAT_BUFD(y) + m, &inc);
         for (i = 1; i < nk; i++){
@@ -907,13 +1062,21 @@ static PyObject* max_step(PyObject *self, PyObject *args, PyObject *kwrds)
         &dims, &ind, &sigma)) return NULL;
 
     O = PyDict_GetItemString(dims, "l");
+#if PY_MAJOR_VERSION >= 3
+    ind += (int) PyLong_AsLong(O);
+#else
     ind += (int) PyInt_AsLong(O);
+#endif
     for (i = 0; i < ind; i++) t = MAX(t, -MAT_BUFD(x)[i]);
 
     O = PyDict_GetItemString(dims, "q");
     for (i = 0; i < (int) PyList_Size(O); i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         len = mk - 1;
         t = MAX(t, dnrm2_(&len, MAT_BUFD(x) + ind + 1, &int1) -
             MAT_BUFD(x)[ind]);
@@ -924,7 +1087,11 @@ static PyObject* max_step(PyObject *self, PyObject *args, PyObject *kwrds)
     Ns = (int) PyList_Size(O);
     for (i = 0, maxn = 0; i < Ns; i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        maxn = MAX(maxn, (int) PyLong_AsLong(Ok));
+#else
         maxn = MAX(maxn, (int) PyInt_AsLong(Ok));
+#endif
     }
     if (!maxn) return Py_BuildValue("d", (ind) ? t : 0.0);
 
@@ -954,7 +1121,11 @@ static PyObject* max_step(PyObject *self, PyObject *args, PyObject *kwrds)
     }
     for (i = 0, ind2 = 0; i < Ns; i++){
         Ok = PyList_GetItem(O, (Py_ssize_t) i);
+#if PY_MAJOR_VERSION >= 3
+        mk = (int) PyLong_AsLong(Ok);
+#else
         mk = (int) PyInt_AsLong(Ok);
+#endif
         if (mk){
             if (sigma){
                 dsyevd_("V", "L", &mk, MAT_BUFD(x) + ind, &mk,
@@ -980,7 +1151,7 @@ static PyObject* max_step(PyObject *self, PyObject *args, PyObject *kwrds)
     return Py_BuildValue("d", (ind) ? t : 0.0);
 }
 
-static PyMethodDef misc_solvers__functions[] = {
+static PyMethodDef misc_solvers_functions[] = {
     {"scale", (PyCFunction) scale, METH_VARARGS|METH_KEYWORDS, doc_scale},
     {"scale2", (PyCFunction) scale2, METH_VARARGS|METH_KEYWORDS,
         doc_scale2},
@@ -1000,12 +1171,33 @@ static PyMethodDef misc_solvers__functions[] = {
     {NULL}  /* Sentinel */
 };
 
-PyMODINIT_FUNC initmisc_solvers(void)
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef misc_solvers_module = {
+    PyModuleDef_HEAD_INIT,
+    "misc_solvers",
+    misc_solvers__doc__,
+    -1,
+    misc_solvers_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_misc_solvers(void)
 {
   PyObject *m;
+  if (!(m = PyModule_Create(&misc_solvers_module))) return NULL;
+  if (import_cvxopt() < 0) return NULL;
+  return m;
+}
 
-  m = Py_InitModule3("cvxopt.misc_solvers", misc_solvers__functions,
-      misc_solvers__doc__);
+#else
 
+PyMODINIT_FUNC initmisc_solvers(void)
+{
+  PyObject *m;
+  m = Py_InitModule3("cvxopt.misc_solvers", misc_solvers_functions,
+      misc_solvers__doc__);
   if (import_cvxopt() < 0) return;
 }
+
+#endif
diff --git a/src/C/sparse.c b/src/C/sparse.c
index ebbacd5..93be88d 100644
--- a/src/C/sparse.c
+++ b/src/C/sparse.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,7 +45,9 @@ extern int get_id(void *, int ) ;
 extern PyTypeObject matrix_tp ;
 extern matrix * Matrix_NewFromMatrix(matrix *, int) ;
 extern matrix * Matrix_NewFromSequence(PyObject *, int) ;
+#if PY_MAJOR_VERSION < 3
 extern matrix * Matrix_NewFromArrayStruct(PyObject *, int, int_t *) ;
+#endif
 extern matrix * Matrix_NewFromNumber(int_t , int_t , int_t , void *, int ) ;
 extern matrix * create_indexlist(int, PyObject *) ;
 extern matrix * Matrix_New(int_t, int_t, int) ;
@@ -1052,8 +1054,8 @@ int sp_zsymv(char uplo, int n, number alpha, ccs *A, int oA, void *x, int ix,
 }
 
 static int sp_dgemm(char tA, char tB, number alpha, void *a, void *b,
-    number beta, void *c, int sp_a, int sp_b, int sp_c, int partial, void **z,
-    int m, int n, int k)
+    number beta, void *c, int sp_a, int sp_b, int sp_c, int partial, 
+    void **z, int m, int n, int k)
 {
 
   if (sp_a && sp_b && sp_c && partial) {
@@ -2242,7 +2244,11 @@ static void spmatrix_dealloc(spmatrix* self)
   free(self->obj->colptr);
   free(self->obj->rowind);
   free(self->obj);
+#if PY_MAJOR_VERSION >= 3
+  Py_TYPE(self)->tp_free((PyObject*)self);
+#else
   self->ob_type->tp_free((PyObject*)self);
+#endif
 }
 
 static PyObject *
@@ -2255,8 +2261,13 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
   static char *kwlist[] = { "V", "I", "J", "size","tc", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|OC:spmatrix", kwlist,
+      &V, &Il, &Jl, &size, &tc))
+#else
   if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|Oc:spmatrix", kwlist,
       &V, &Il, &Jl, &size, &tc))
+#endif
     return NULL;
 
   if (!(PySequence_Check((PyObject *)V) || Matrix_Check(V) || PY_NUMBER(V))) {
@@ -2272,14 +2283,18 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
   if (tc && !(VALID_TC_SP(tc))) PY_ERR_TYPE("tc must be 'd' or 'z'");
   int id = (tc ? TC2ID(tc) : -1);
 
+#if PY_MAJOR_VERSION < 3
   int_t ndim = 0;
+#endif
   /* convert lists to matrices */
   if (Matrix_Check(Il))
     Py_INCREF(Il);
+#if PY_MAJOR_VERSION < 3
   else if (PyObject_HasAttrString((PyObject *)Il,"__array_struct__")) {
     if (!(Il = Matrix_NewFromArrayStruct((PyObject *)Il, INT, &ndim)))
       return NULL;
   }
+#endif
   else if (PySequence_Check((PyObject *)Il)) {
     if (!(Il = Matrix_NewFromSequence((PyObject *)Il, INT)))
       return NULL;
@@ -2288,12 +2303,14 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
   if (Matrix_Check(Jl))
     Py_INCREF(Jl);
+#if PY_MAJOR_VERSION < 3
   else if (PyObject_HasAttrString((PyObject *)Jl,"__array_struct__")) {
     if (!(Jl = Matrix_NewFromArrayStruct((PyObject *)Jl, INT, &ndim))) {
       Py_DECREF(Il);
       return NULL;
     }
   }
+#endif
   else if (PySequence_Check((PyObject *)Jl)) {
     if (!(Jl = Matrix_NewFromSequence((PyObject *)Jl, INT))) {
       Py_DECREF(Il);
@@ -2307,6 +2324,7 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
   if (Matrix_Check(V))
     Py_INCREF(V);
+#if PY_MAJOR_VERSION < 3
   else if (PyObject_HasAttrString((PyObject *)V,"__array_struct__")) {
     int_t ndim = 0;
     if (!(V = Matrix_NewFromArrayStruct((PyObject *)V, id, &ndim))) {
@@ -2315,6 +2333,7 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
       return NULL;
     }
   }
+#endif
   else if (PySequence_Check((PyObject *)V))
     {
     if (!(V = Matrix_NewFromSequence((PyObject *)V, id))) {
@@ -2399,8 +2418,13 @@ static PyObject * spmatrix_get_size(spmatrix *self, void *closure)
 {
   PyObject *t = PyTuple_New(2);
 
+#if PY_MAJOR_VERSION >= 3
+  PyTuple_SET_ITEM(t, 0, PyLong_FromLong(SP_NROWS(self)));
+  PyTuple_SET_ITEM(t, 1, PyLong_FromLong(SP_NCOLS(self)));
+#else
   PyTuple_SET_ITEM(t, 0, PyInt_FromLong(SP_NROWS(self)));
   PyTuple_SET_ITEM(t, 1, PyInt_FromLong(SP_NCOLS(self)));
+#endif
 
   return t;
 }
@@ -2412,12 +2436,22 @@ static int spmatrix_set_size(spmatrix *self, PyObject *value, void *closure)
   if (!PyTuple_Check(value) || PyTuple_Size(value) != 2)
     PY_ERR_INT(PyExc_TypeError, "can only assign a 2-tuple to size");
 
+#if PY_MAJOR_VERSION >= 3
+  if (!PyLong_Check(PyTuple_GET_ITEM(value, 0)) ||
+      !PyLong_Check(PyTuple_GET_ITEM(value, 1)))
+#else
   if (!PyInt_Check(PyTuple_GET_ITEM(value, 0)) ||
       !PyInt_Check(PyTuple_GET_ITEM(value, 1)))
+#endif
     PY_ERR_INT(PyExc_TypeError, "invalid size tuple");
 
+#if PY_MAJOR_VERSION >= 3
+  int m = PyLong_AS_LONG(PyTuple_GET_ITEM(value, 0));
+  int n = PyLong_AS_LONG(PyTuple_GET_ITEM(value, 1));
+#else
   int m = PyInt_AS_LONG(PyTuple_GET_ITEM(value, 0));
   int n = PyInt_AS_LONG(PyTuple_GET_ITEM(value, 1));
+#endif
 
   if (m<0 || n<0)
     PY_ERR_INT(PyExc_TypeError, "dimensions must be non-negative");
@@ -2450,7 +2484,11 @@ static int spmatrix_set_size(spmatrix *self, PyObject *value, void *closure)
 
 static PyObject * spmatrix_get_typecode(matrix *self, void *closure)
 {
+#if PY_MAJOR_VERSION >= 3
+  return PyUnicode_FromStringAndSize(TC_CHAR[SP_ID(self)], 1);
+#else
   return PyString_FromStringAndSize(TC_CHAR[SP_ID(self)], 1);
+#endif
 }
 
 static PyObject *
@@ -2574,8 +2612,13 @@ spmatrix_getstate(spmatrix *self)
     return NULL;
   }
 
+#if PY_MAJOR_VERSION >= 3
+  PyTuple_SET_ITEM(size, 0, PyLong_FromLong(SP_NROWS(self)));
+  PyTuple_SET_ITEM(size, 1, PyLong_FromLong(SP_NCOLS(self)));
+#else
   PyTuple_SET_ITEM(size, 0, PyInt_FromLong(SP_NROWS(self)));
   PyTuple_SET_ITEM(size, 1, PyInt_FromLong(SP_NCOLS(self)));
+#endif
 
   return Py_BuildValue("NNNNs", V, Il, Jl, size, TC_CHAR[SP_ID(self)]);
 
@@ -2633,21 +2676,25 @@ static PyObject * spmatrix_imag(spmatrix *self) {
 static PyObject *
 spmatrix_reduce(spmatrix* self)
 {
+#if PY_MAJOR_VERSION >= 3
+  return Py_BuildValue("ON", Py_TYPE(self), spmatrix_getstate(self));
+#else
   return Py_BuildValue("ON", self->ob_type, spmatrix_getstate(self));
+#endif
 }
 
 static PyMethodDef spmatrix_methods[] = {
     {"real", (PyCFunction)spmatrix_real, METH_NOARGS,
         "Returns real part of sparse matrix"},
-        {"imag", (PyCFunction)spmatrix_imag, METH_NOARGS,
-            "Returns imaginary part of sparse matrix"},
-            {"trans", (PyCFunction)spmatrix_trans, METH_NOARGS,
-                "Returns the matrix transpose"},
-                {"ctrans", (PyCFunction)spmatrix_ctrans, METH_NOARGS,
-                    "Returns the matrix conjugate transpose"},
-                    {"__reduce__", (PyCFunction)spmatrix_reduce, METH_NOARGS,
-                        "__reduce__() -> (cls, state)"},
-                        {NULL}  /* Sentinel */
+    {"imag", (PyCFunction)spmatrix_imag, METH_NOARGS,
+        "Returns imaginary part of sparse matrix"},
+    {"trans", (PyCFunction)spmatrix_trans, METH_NOARGS,
+        "Returns the matrix transpose"},
+    {"ctrans", (PyCFunction)spmatrix_ctrans, METH_NOARGS,
+        "Returns the matrix conjugate transpose"},
+    {"__reduce__", (PyCFunction)spmatrix_reduce, METH_NOARGS,
+        "__reduce__() -> (cls, state)"},
+    {NULL}  /* Sentinel */
 };
 
 
@@ -2743,8 +2790,13 @@ spmatrix_subscr(spmatrix* self, PyObject* args)
   matrix *Il = NULL, *Jl = NULL;
 
   /* single integer */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(args)) {
+    i = PyLong_AS_LONG(args);
+#else
   if (PyInt_Check(args)) {
     i = PyInt_AS_LONG(args);
+#endif
     if ( i<-SP_LGT(self) || i >= SP_LGT(self) )
       PY_ERR(PyExc_IndexError, "index out of range");
 
@@ -2789,8 +2841,13 @@ spmatrix_subscr(spmatrix* self, PyObject* args)
     PY_ERR(PyExc_TypeError, "invalid index sets I or J");
 
   /* two integers, subscript form, handle separately */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(argI) && PyLong_Check(argJ)) {
+    i = PyLong_AS_LONG(argI); j = PyLong_AS_LONG(argJ);
+#else
   if (PyInt_Check(argI) && PyInt_Check(argJ)) {
     i = PyInt_AS_LONG(argI); j = PyInt_AS_LONG(argJ);
+#endif
     if ( OUT_RNG(i, SP_NROWS(self)) || OUT_RNG(j, SP_NCOLS(self)) )
       PY_ERR(PyExc_IndexError, "index out of range");
 
@@ -2802,30 +2859,48 @@ spmatrix_subscr(spmatrix* self, PyObject* args)
 
   if (PySlice_Check(argI)) {
     int_t rowstart, rowstop, rowstep, rowlgt, rowcnt;
-
+   
+#if PY_MAJOR_VERSION >= 3
+    if (PySlice_GetIndicesEx(argI, SP_NROWS(self), &rowstart, &rowstop, 
+        &rowstep, &rowlgt) < 0) return NULL;
+#else
     if (PySlice_GetIndicesEx((PySliceObject*)argI, SP_NROWS(self),
         &rowstart, &rowstop, &rowstep, &rowlgt) < 0) return NULL;
+#endif
 
     int_t colstart, colstop, colstep, collgt, colcnt;
-    if (PySlice_Check(argJ))
-      {
+    if (PySlice_Check(argJ)) {
+#if PY_MAJOR_VERSION >= 3
+      if (PySlice_GetIndicesEx(argJ, SP_NCOLS(self), &colstart, &colstop, 
+          &colstep, &collgt) < 0) return NULL;
+#else
       if (PySlice_GetIndicesEx((PySliceObject*)argJ, SP_NCOLS(self),
-          &colstart, &colstop, &colstep, &collgt) < 0)
-        return NULL;
-      }
-    else if (PyInt_Check(argJ))
-      {
+          &colstart, &colstop, &colstep, &collgt) < 0) return NULL;
+#endif
+    }
+#if PY_MAJOR_VERSION >= 3
+    else if (PyLong_Check(argJ)){
+      j = PyLong_AS_LONG(argJ);
+#else
+    else if (PyInt_Check(argJ)){
       j = PyInt_AS_LONG(argJ);
+#endif
       if ( OUT_RNG(j, SP_NCOLS(self)) )
-        PY_ERR(PyExc_IndexError, "index out of range");
-      colstart = 	CWRAP(j,SP_NCOLS(self)); colstop = colstart; collgt = 1; colstep = 1;
-      }
+          PY_ERR(PyExc_IndexError, "index out of range");
+      colstart = CWRAP(j,SP_NCOLS(self)); 
+      colstop = colstart; 
+      collgt = 1; 
+      colstep = 1;
+    }
     else if (PyList_Check(argJ) || Matrix_Check(argJ)) {
-      if (!(Jl = create_indexlist(SP_NCOLS(self), argJ)))
+      if (!(Jl = create_indexlist(SP_NCOLS(self), argJ))) 
         return NULL;
-
-      colstart = 0; colstop = MAT_LGT(Jl)-1; collgt = MAT_LGT(Jl); colstep = 1;
+      colstart = 0; 
+      colstop = MAT_LGT(Jl)-1; 
+      collgt = MAT_LGT(Jl); 
+      colstep = 1;
     }
+    else PY_ERR_TYPE("invalid index argument");
 
     int_t *colptr = calloc(collgt+1, sizeof(int_t));
     if (!colptr) {
@@ -3014,11 +3089,13 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
   if (!value) PY_ERR_INT(PyExc_NotImplementedError,
       "cannot delete matrix entries");
 
-  if (!(PY_NUMBER(value) || Matrix_Check(value) || SpMatrix_Check(value))) {
+  if (!(PY_NUMBER(value) || Matrix_Check(value) || SpMatrix_Check(value))){
+#if PY_MAJOR_VERSION < 3
     if (PyObject_HasAttrString(value,"__array_struct__"))
       value = (PyObject *)Matrix_NewFromArrayStruct(value, -1,
           &arraystruct_nd);
     else
+#endif
       value = (PyObject *)Matrix_NewFromSequence(value, SP_ID(self));
 
     if (!value)
@@ -3047,11 +3124,19 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     itype = 's';
 
   /* single integer */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(args)) {
+#else
   if (PyInt_Check(args)) {
+#endif
     if (itype != 'n')
       PY_ERR_INT(PyExc_IndexError, "incompatible sizes in assignment");
 
+#if PY_MAJOR_VERSION >= 3
+    i = PyLong_AsLong(args);
+#else
     i = PyInt_AsLong(args);
+#endif
     if ( i<-SP_LGT(self) || i >= SP_LGT(self) )
       PY_ERR_INT(PyExc_IndexError, "index out of range");
 
@@ -3289,12 +3374,20 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     PY_ERR_INT(PyExc_TypeError, "invalid index arguments");
 
   /* two integers, subscript form, handle separately */
+#if PY_MAJOR_VERSION >= 3
+  if (PyLong_Check(argI) && PyLong_Check(argJ)) {
+#else
   if (PyInt_Check(argI) && PyInt_Check(argJ)) {
+#endif
 
     if (itype != 'n')
       PY_ERR_INT(PyExc_TypeError, "argument has wrong size");
 
+#if PY_MAJOR_VERSION >= 3
+    i = PyLong_AS_LONG(argI); j = PyLong_AS_LONG(argJ);
+#else
     i = PyInt_AS_LONG(argI); j = PyInt_AS_LONG(argJ);
+#endif
     if ( OUT_RNG(i, SP_NROWS(self)) || OUT_RNG(j, SP_NCOLS(self)) )
       PY_ERR_INT(PyExc_IndexError, "index out of range");
 
@@ -3796,9 +3889,9 @@ spmatrix_mul(PyObject *self, PyObject *other)
 
   int id = MAX(get_id(self, PY_NUMBER(self)),get_id(other, PY_NUMBER(other)));
   if (PY_NUMBER(self) || (Matrix_Check(self) && MAT_LGT(self) == 1 &&
-      !(SpMatrix_Check(other) && SP_NCOLS(other) == 1)) ||
+      !(SpMatrix_Check(other) && SP_NROWS(other) == 1)) ||
       PY_NUMBER(other) || (Matrix_Check(other) && MAT_LGT(other) == 1 &&
-          !(SpMatrix_Check(self) && SP_NROWS(self) == 1)) )
+          !(SpMatrix_Check(self) && SP_NCOLS(self) == 1)) )
     {
 
     spmatrix *ret = SpMatrix_NewFromSpMatrix((spmatrix *)
@@ -3939,44 +4032,65 @@ static int spmatrix_nonzero(matrix *self)
 
 
 static PyNumberMethods spmatrix_as_number = {
-    (binaryfunc)spmatrix_add, /*nb_add*/
-    (binaryfunc)spmatrix_sub, /*nb_subtract*/
-    (binaryfunc)spmatrix_mul, /*nb_multiply*/
-    (binaryfunc)spmatrix_div, /*nb_divide*/
-    0,                      /*nb_remainder*/
-    0,	                /*nb_divmod*/
-    0,	                /*nb_power*/
-    (unaryfunc)spmatrix_neg,/*nb_negative*/
-    (unaryfunc)spmatrix_pos,/*nb_positive*/
-    (unaryfunc)spmatrix_abs,/*nb_absolute*/
-    (inquiry)spmatrix_nonzero,/*nb_nonzero*/
-    0,	                /*nb_invert*/
-    0,	                /*nb_lshift*/
-    0,	                /*nb_rshift*/
-    0,	                /*nb_and*/
-    0,	                /*nb_xor*/
-    0,	                /*nb_or*/
-    0,		        /*nb_coerce*/
-    0,	                /*nb_int*/
-    0,	                /*nb_long*/
-    0,	                /*nb_float*/
-    0,	                /*nb_oct*/
-    0, 	                /*nb_hex*/
-    (binaryfunc)spmatrix_iadd,/*nb_inplace_add*/
-    (binaryfunc)spmatrix_isub,/*nb_inplace_subtract*/
-    (binaryfunc)spmatrix_imul,/*nb_inplace_multiply*/
-    (binaryfunc)spmatrix_idiv,/*nb_inplace_divide*/
-    0,                      /*nb_inplace_remainder*/
-    0,			/*nb_inplace_power*/
-    0,			/*nb_inplace_lshift*/
-    0,			/*nb_inplace_rshift*/
-    0,			/*nb_inplace_and*/
-    0,			/*nb_inplace_xor*/
-    0,			/*nb_inplace_or*/
-    0,	                /* nb_floor_divide */
-    0,	                /* nb_true_divide */
-    0,			/* nb_inplace_floor_divide */
-    0,			/* nb_inplace_true_divide */
+    (binaryfunc)spmatrix_add,    /*nb_add*/
+    (binaryfunc)spmatrix_sub,    /*nb_subtract*/
+    (binaryfunc)spmatrix_mul,    /*nb_multiply*/
+#if PY_MAJOR_VERSION < 3
+    (binaryfunc)spmatrix_div,    /*nb_divide*/
+#endif
+    0,                           /*nb_remainder*/
+    0,                           /*nb_divmod*/
+    0,                           /*nb_power*/
+    (unaryfunc)spmatrix_neg,     /*nb_negative*/
+    (unaryfunc)spmatrix_pos,     /*nb_positive*/
+    (unaryfunc)spmatrix_abs,     /*nb_absolute*/
+    (inquiry)spmatrix_nonzero,   /*nb_nonzero*/
+    0,                           /*nb_invert*/
+    0,                           /*nb_lshift*/
+    0,                           /*nb_rshift*/
+    0,                           /*nb_and*/
+    0,                           /*nb_xor*/
+    0,                           /*nb_or*/
+#if PY_MAJOR_VERSION < 3
+    0,                           /*nb_coerce*/
+#endif
+    0,                           /*nb_int*/
+#if PY_MAJOR_VERSION >= 3
+    0,                           /*nb_reserved*/
+#else
+    0,                           /*nb_long*/
+#endif
+    0,                           /*nb_float*/
+#if PY_MAJOR_VERSION < 3
+    0,                           /*nb_oct*/
+    0,                           /*nb_hex*/
+#endif
+    (binaryfunc)spmatrix_iadd,   /*nb_inplace_add*/
+    (binaryfunc)spmatrix_isub,   /*nb_inplace_subtract*/
+    (binaryfunc)spmatrix_imul,   /*nb_inplace_multiply*/
+#if PY_MAJOR_VERSION < 3
+    (binaryfunc)spmatrix_idiv,   /*nb_inplace_divide*/
+#endif
+    0,                           /*nb_inplace_remainder*/
+    0,                           /*nb_inplace_power*/
+    0,                           /*nb_inplace_lshift*/
+    0,                           /*nb_inplace_rshift*/
+    0,                           /*nb_inplace_and*/
+    0,                           /*nb_inplace_xor*/
+    0,                           /*nb_inplace_or*/
+    0,                           /*nb_floor_divide */
+#if PY_MAJOR_VERSION >= 3
+    (binaryfunc)spmatrix_div,    /* nb_true_divide */
+#else
+    0,                           /* nb_true_divide */
+#endif
+    0,                           /* nb_inplace_floor_divide */
+#if PY_MAJOR_VERSION >= 3
+    (binaryfunc)spmatrix_idiv,   /* nb_inplace_true_divide */
+    0,                           /* nb_index */
+#else
+    0,                           /* nb_inplace_true_divide */
+#endif
 };
 
 
@@ -4045,77 +4159,89 @@ spmatrixiter_next(spmatrixiter *it)
 }
 
 static PyTypeObject spmatrixiter_tp = {
+#if PY_MAJOR_VERSION >= 3
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
     PyObject_HEAD_INIT(NULL)
-    0,					/* ob_size */
-    "spmatrixiter", 			/* tp_name */
-    sizeof(spmatrixiter),           	/* tp_basicsize */
-    0,					/* tp_itemsize */
-    (destructor)spmatrixiter_dealloc,	/* tp_dealloc */
-    0,					/* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    0,					/* tp_repr */
-    0,					/* tp_as_number */
-    0,					/* tp_as_sequence */
-    0,					/* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    0,					/* tp_str */
-    0,       		                /* tp_getattro */
-    0, 		                        /* tp_setattro */
-    0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
-    0,					/* tp_doc */
-    (traverseproc)spmatrixiter_traverse,	/* tp_traverse */
-    0,					/* tp_clear */
-    0,					/* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    0,              			/* tp_iter */
-    (iternextfunc)spmatrixiter_next,	/* tp_iternext */
-    0,					/* tp_methods */
+    0,                                        /* ob_size */
+#endif
+    "spmatrixiter",                           /* tp_name */
+    sizeof(spmatrixiter),                     /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)spmatrixiter_dealloc,         /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compar */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,  /* tp_flags */
+    0,                                        /* tp_doc */
+    (traverseproc)spmatrixiter_traverse,      /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    (iternextfunc)spmatrixiter_next,          /* tp_iternext */
+    0,                                        /* tp_methods */
 };
 
 
 PyTypeObject spmatrix_tp = {
+#if PY_MAJOR_VERSION >= 3
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
     PyObject_HEAD_INIT(NULL)
     0,
+#endif
     "cvxopt.base.spmatrix",
     sizeof(spmatrix),
     0,
-    (destructor)spmatrix_dealloc,	        /* tp_dealloc */
-    0,	               	                /* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    (reprfunc)spmatrix_repr,                /* tp_repr */
-    &spmatrix_as_number,			/* tp_as_number */
-    0,	                                /* tp_as_sequence */
-    &spmatrix_as_mapping,                   /* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    (reprfunc)spmatrix_str, 		/* tp_str */
-    0,					/* tp_getattro */
-    0,			                /* tp_setattro */
-    0,			                /* tp_as_buffer */
+    (destructor)spmatrix_dealloc,              /* tp_dealloc */
+    0,                                         /* tp_print */
+    0,                                         /* tp_getattr */
+    0,                                         /* tp_setattr */
+    0,                                         /* tp_compare */
+    (reprfunc)spmatrix_repr,                   /* tp_repr */
+    &spmatrix_as_number,                       /* tp_as_number */
+    0,                                         /* tp_as_sequence */
+    &spmatrix_as_mapping,                      /* tp_as_mapping */
+    0,                                         /* tp_hash */
+    0,                                         /* tp_call */
+    (reprfunc)spmatrix_str,                    /* tp_str */
+    0,                                         /* tp_getattro */
+    0,                                         /* tp_setattro */
+    0,                                         /* tp_as_buffer */
+#if PY_MAJOR_VERSION >= 3
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /* tp_flags */
+#else
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
-    Py_TPFLAGS_CHECKTYPES,                  /* tp_flags */
-    0,					/* tp_doc */
-    0,					/* tp_traverse */
-    0,					/* tp_clear */
-    (richcmpfunc)spmatrix_richcompare,      /* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    (getiterfunc)spmatrix_iter,		/* tp_iter */
-    0,	       	                        /* tp_iternext */
-    spmatrix_methods,                       /* tp_methods */
-    0,				        /* tp_members */
-    spmatrix_getsets,      		        /* tp_getset */
-    0,		                        /* tp_base */
-    0,					/* tp_dict */
-    0,	       			        /* tp_descr_get */
-    0,					/* tp_descr_set */
-    0,					/* tp_dictoffset */
-    0,                                      /* tp_init */
-    0,               			/* tp_alloc */
-    spmatrix_new,				/* tp_new */
+    Py_TPFLAGS_CHECKTYPES,                     /* tp_flags */
+#endif
+    0,                                         /* tp_doc */
+    0,                                         /* tp_traverse */
+    0,                                         /* tp_clear */
+    (richcmpfunc)spmatrix_richcompare,         /* tp_richcompare */
+    0,                                         /* tp_weaklistoffset */
+    (getiterfunc)spmatrix_iter,                /* tp_iter */
+    0,                                         /* tp_iternext */
+    spmatrix_methods,                          /* tp_methods */
+    0,                                         /* tp_members */
+    spmatrix_getsets,                          /* tp_getset */
+    0,                                         /* tp_base */
+    0,                                         /* tp_dict */
+    0,                                         /* tp_descr_get */
+    0,                                         /* tp_descr_set */
+    0,                                         /* tp_dictoffset */
+    0,                                         /* tp_init */
+    0,                                         /* tp_alloc */
+    spmatrix_new,                              /* tp_new */
 };
diff --git a/src/C/umfpack.c b/src/C/umfpack.c
index 5abb802..44f202c 100644
--- a/src/C/umfpack.c
+++ b/src/C/umfpack.c
@@ -1,8 +1,8 @@
 /*
- * Copyright 2010 L. Vandenberghe.
+ * Copyright 2010-2011 L. Vandenberghe.
  * Copyright 2004-2009 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 1.1.3.
+ * This file is part of CVXOPT version 1.1.4.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,25 +40,58 @@ PyDoc_STRVAR(umfpack__doc__,"Interface to the UMFPACK library.\n\n"
     "The default control settings of UMPFACK are used.\n\n"
     "See also http://www.cise.ufl.edu/research/sparse/umfpack.");
 
+#if PY_MAJOR_VERSION >= 3
+static void free_umfpack_d_symbolic(void *F)
+{
+    void *Fptr = PyCapsule_GetPointer(F, PyCapsule_GetName(F));
+    UMFD(free_symbolic)(&Fptr);
+}
+#else
 static void free_umfpack_d_symbolic(void *F, void *descr)
 {
     UMFD(free_symbolic)(&F);
 }
+#endif
 
+#if PY_MAJOR_VERSION >= 3
+static void free_umfpack_z_symbolic(void *F)
+{
+    void *Fptr = PyCapsule_GetPointer(F, PyCapsule_GetName(F));
+    UMFZ(free_symbolic)(&Fptr);
+}
+#else
 static void free_umfpack_z_symbolic(void *F, void *descr)
 {
     UMFZ(free_symbolic)(&F);
 }
+#endif
 
+#if PY_MAJOR_VERSION >= 3
+static void free_umfpack_d_numeric(void *F)
+{
+    void *Fptr = PyCapsule_GetPointer(F, PyCapsule_GetName(F));
+    UMFD(free_numeric)(&Fptr);
+}
+#else
 static void free_umfpack_d_numeric(void *F, void *descr)
 {
     UMFD(free_numeric)(&F);
 }
+#endif
 
+#if PY_MAJOR_VERSION >= 3
+static void free_umfpack_z_numeric(void *F)
+{
+    void *Fptr = PyCapsule_GetPointer(F, PyCapsule_GetName(F));
+    UMFZ(free_numeric)(&Fptr);
+}
+#else
 static void free_umfpack_z_numeric(void *F, void *descr)
 {
     UMFZ(free_numeric)(&F);
 }
+#endif
+
 
 static char doc_linsolve[] =
     "Solves a sparse set of linear equations.\n\n"
@@ -85,6 +118,9 @@ static PyObject* linsolve(PyObject *self, PyObject *args,
 {
     spmatrix *A;
     matrix *B;
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+#endif
     char trans='N';
     double info[UMFPACK_INFO];
     int oB=0, n, nrhs=-1, ldB=0, k;
@@ -92,8 +128,14 @@ static PyObject* linsolve(PyObject *self, PyObject *args,
     char *kwlist[] = {"A", "B", "trans", "nrhs", "ldB", "offsetB",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
+        &A, &B, &trans_, &nrhs, &ldB, &oB)) return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
         &A, &B, &trans, &nrhs, &ldB, &oB)) return NULL;
+#endif
 
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A must be a square sparse matrix");
@@ -240,9 +282,15 @@ static PyObject* symbolic(PyObject *self, PyObject *args)
             UMFD(symbolic)(SP_NROWS(A), SP_NCOLS(A), SP_COL(A),
                 SP_ROW(A), SP_VAL(A), &symbolic, NULL, info);
             if (info[UMFPACK_STATUS] == UMFPACK_OK)
+#if PY_MAJOR_VERSION >= 3
+                return (PyObject *) PyCapsule_New( (void *) symbolic, 
+                    "UMFPACK SYM D FACTOR", 
+                    (PyCapsule_Destructor) &free_umfpack_d_symbolic);  
+#else
                 return (PyObject *) PyCObject_FromVoidPtrAndDesc(
                     (void *) symbolic, "UMFPACK SYM D FACTOR",
                     free_umfpack_d_symbolic);
+#endif
             else
                 UMFD(free_symbolic)(&symbolic);
             break;
@@ -251,9 +299,15 @@ static PyObject* symbolic(PyObject *self, PyObject *args)
             UMFZ(symbolic)(SP_NROWS(A), SP_NCOLS(A), SP_COL(A),
                 SP_ROW(A), SP_VAL(A), NULL, &symbolic, NULL, info);
             if (info[UMFPACK_STATUS] == UMFPACK_OK)
+#if PY_MAJOR_VERSION >= 3
+                return (PyObject *) PyCapsule_New(
+                    (void *) symbolic, "UMFPACK SYM Z FACTOR",
+                    (PyCapsule_Destructor) &free_umfpack_z_symbolic);
+#else
                 return (PyObject *) PyCObject_FromVoidPtrAndDesc(
                     (void *) symbolic, "UMFPACK SYM Z FACTOR",
-                free_umfpack_z_symbolic);
+                    free_umfpack_z_symbolic);
+#endif
             else
                 UMFZ(free_symbolic)(&symbolic);
             break;
@@ -288,36 +342,74 @@ static PyObject* numeric(PyObject *self, PyObject *args)
     PyObject *Fs;
     double info[UMFPACK_INFO];
     void *numeric;
+#if PY_MAJOR_VERSION >= 3
+    void *Fsptr;
+    const char *descrd = "UMFPACK SYM D FACTOR";
+    const char *descrz = "UMFPACK SYM Z FACTOR";
+#endif
 
     if (!PyArg_ParseTuple(args, "OO", &A, &Fs)) return NULL;
 
     if (!SpMatrix_Check(A)) PY_ERR_TYPE("A must be a sparse matrix");
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(Fs)) err_CO("Fs");
+#else
     if (!PyCObject_Check(Fs)) err_CO("Fs");
+#endif
 
     switch (SP_ID(A)) {
 	case DOUBLE:
+#if PY_MAJOR_VERSION >= 3
+            TypeCheck_Capsule(Fs, descrd, "Fs is not the UMFPACK symbolic "
+                "factor of a 'd' matrix");
+            if (!(Fsptr = (void *) PyCapsule_GetPointer(Fs, descrd)))
+                err_CO("Fs");
+            UMFD(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A), Fsptr, &numeric,
+                NULL, info);
+#else
             TypeCheck_CObject(Fs, "UMFPACK SYM D FACTOR", "Fs is not "
                 "the UMFPACK symbolic factor of a 'd' matrix");
             UMFD(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A),
 	        (void *) PyCObject_AsVoidPtr(Fs), &numeric, NULL, info);
+#endif
             if (info[UMFPACK_STATUS] == UMFPACK_OK)
+#if PY_MAJOR_VERSION >= 3
+                return (PyObject *) PyCapsule_New(
+                    (void *) numeric, "UMFPACK NUM D FACTOR",
+                    (PyCapsule_Destructor) &free_umfpack_d_numeric);
+#else
                 return (PyObject *) PyCObject_FromVoidPtrAndDesc(
                     (void *) numeric, "UMFPACK NUM D FACTOR",
                     free_umfpack_d_numeric);
+#endif
             else
                 UMFD(free_numeric)(&numeric);
 	    break;
 
         case COMPLEX:
+#if PY_MAJOR_VERSION >= 3
+            TypeCheck_Capsule(Fs, descrz, "Fs is not the UMFPACK symbolic "
+                "factor of a 'z' matrix");
+            if (!(Fsptr = (void *) PyCapsule_GetPointer(Fs, descrz)))
+                err_CO("Fs");
+            UMFZ(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A), NULL, Fsptr, 
+                &numeric, NULL, info);
+#else
             TypeCheck_CObject(Fs, "UMFPACK SYM Z FACTOR", "Fs is not "
                 "the UMFPACK symbolic factor of a 'z' matrix");
             UMFZ(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A), NULL,
-	         (void *) PyCObject_AsVoidPtr(Fs), &numeric, NULL,
-		 info);
+	         (void *) PyCObject_AsVoidPtr(Fs), &numeric, NULL, info);
+#endif
             if (info[UMFPACK_STATUS] == UMFPACK_OK)
+#if PY_MAJOR_VERSION >= 3
+                return (PyObject *) PyCapsule_New(
+                    (void *) numeric, "UMFPACK NUM Z FACTOR",
+                    (PyCapsule_Destructor) &free_umfpack_z_numeric);
+#else
                 return (PyObject *) PyCObject_FromVoidPtrAndDesc(
                     (void *) numeric, "UMFPACK NUM Z FACTOR",
                     free_umfpack_z_numeric);
+#endif
 	    else
                  UMFZ(free_numeric)(&numeric);
 	    break;
@@ -366,19 +458,41 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
     spmatrix *A;
     PyObject *F;
     matrix *B;
+#if PY_MAJOR_VERSION >= 3
+    int trans_ = 'N';
+    const char *descrd = "UMFPACK NUM D FACTOR"; 
+    const char *descrz = "UMFPACK NUM Z FACTOR"; 
+#endif
     char trans='N';
     double *x, info[UMFPACK_INFO];
     int oB=0, n, ldB=0, nrhs=-1, k;
     char *kwlist[] = {"A", "F", "B", "trans", "nrhs", "ldB", "offsetB",
         NULL};
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|Ciii", kwlist,
+        &A, &F, &B, &trans_, &nrhs, &ldB, &oB)) return NULL;
+    trans = (char) trans_;
+#else
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|ciii", kwlist,
         &A, &F, &B, &trans, &nrhs, &ldB, &oB)) return NULL;
+#endif
 
     if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
         PY_ERR_TYPE("A must a square sparse matrix");
     n = SP_NROWS(A);
 
+#if PY_MAJOR_VERSION >= 3
+    if (!PyCapsule_CheckExact(F)) err_CO("F");
+    if (SP_ID(A) == DOUBLE) {
+        TypeCheck_Capsule(F, descrd, "F is not the UMFPACK numeric factor "
+            "of a 'd' matrix");
+    }
+    else  {
+        TypeCheck_Capsule(F, descrz, "F is not the UMFPACK numeric factor "
+            "of a 'z' matrix");
+    }
+#else
     if (!PyCObject_Check(F)) err_CO("F");
     if (SP_ID(A) == DOUBLE) {
         TypeCheck_CObject(F, "UMFPACK NUM D FACTOR", "F is not the "
@@ -388,6 +502,7 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
         TypeCheck_CObject(F, "UMFPACK NUM Z FACTOR", "F is not the "
             "UMFPACK numeric factor of a 'z' matrix");
     }
+#endif
 
     if (!Matrix_Check(B) || MAT_ID(B) != SP_ID(A))
         PY_ERR_TYPE("B must a dense matrix of the same numeric type "
@@ -406,16 +521,31 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
 
     for (k=0; k<nrhs; k++) {
         if (SP_ID(A) == DOUBLE)
+#if PY_MAJOR_VERSION >= 3
+            UMFD(solve)(trans == 'N' ? UMFPACK_A : UMFPACK_Aat,
+                SP_COL(A), SP_ROW(A), SP_VAL(A), x,
+                MAT_BUFD(B) + k*ldB + oB,
+                (void *) PyCapsule_GetPointer(F, descrd), NULL, info);
+#else
             UMFD(solve)(trans == 'N' ? UMFPACK_A : UMFPACK_Aat,
                 SP_COL(A), SP_ROW(A), SP_VAL(A), x,
                 MAT_BUFD(B) + k*ldB + oB,
                 (void *) PyCObject_AsVoidPtr(F), NULL, info);
+#endif
         else
+#if PY_MAJOR_VERSION >= 3
+            UMFZ(solve)(trans == 'N' ? UMFPACK_A : trans == 'C' ?
+                UMFPACK_At : UMFPACK_Aat, SP_COL(A), SP_ROW(A),
+                SP_VAL(A), NULL, x, NULL,
+                (double *)(MAT_BUFZ(B) + k*ldB + oB), NULL,
+                (void *) PyCapsule_GetPointer(F, descrz), NULL, info);
+#else
             UMFZ(solve)(trans == 'N' ? UMFPACK_A : trans == 'C' ?
                 UMFPACK_At : UMFPACK_Aat, SP_COL(A), SP_ROW(A),
                 SP_VAL(A), NULL, x, NULL,
                 (double *)(MAT_BUFZ(B) + k*ldB + oB), NULL,
                 (void *) PyCObject_AsVoidPtr(F), NULL, info);
+#endif
         if (info[UMFPACK_STATUS] == UMFPACK_OK)
             memcpy(B->buffer + (k*ldB + oB)*E_SIZE[SP_ID(A)], x,
                 n*E_SIZE[SP_ID(A)]);
@@ -444,20 +574,39 @@ static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
 }
 
 static PyMethodDef umfpack_functions[] = {
-{"linsolve", (PyCFunction) linsolve, METH_VARARGS|METH_KEYWORDS,
-    doc_linsolve},
-{"symbolic", (PyCFunction) symbolic, METH_VARARGS, doc_symbolic},
-{"numeric", (PyCFunction) numeric, METH_VARARGS, doc_numeric},
-{"solve", (PyCFunction) solve, METH_VARARGS|METH_KEYWORDS, doc_solve},
-{NULL}  /* Sentinel */
+    {"linsolve", (PyCFunction) linsolve, METH_VARARGS|METH_KEYWORDS,
+        doc_linsolve},
+    {"symbolic", (PyCFunction) symbolic, METH_VARARGS, doc_symbolic},
+    {"numeric", (PyCFunction) numeric, METH_VARARGS, doc_numeric},
+    {"solve", (PyCFunction) solve, METH_VARARGS|METH_KEYWORDS, doc_solve},
+    {NULL}  /* Sentinel */
 };
 
-PyMODINIT_FUNC initumfpack(void)
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef umfpack_module = {
+    PyModuleDef_HEAD_INIT,
+    "umfpack",
+    umfpack__doc__,
+    -1,
+    umfpack_functions,
+    NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_umfpack(void)
 {
   PyObject *m;
+  if (!(m = PyModule_Create(&umfpack_module))) return NULL;
+  if (import_cvxopt() < 0) return NULL;
+  return m;
+}
 
-  m = Py_InitModule3("cvxopt.umfpack", umfpack_functions,
-      umfpack__doc__);
+#else
 
+PyMODINIT_FUNC initumfpack(void)
+{
+  PyObject *m;
+  m = Py_InitModule3("cvxopt.umfpack", umfpack_functions, umfpack__doc__);
   if (import_cvxopt() < 0) return;
 }
+#endif
diff --git a/src/python/__init__.py b/src/python/__init__.py
index 3c0f9bc..df40b41 100644
--- a/src/python/__init__.py
+++ b/src/python/__init__.py
@@ -11,10 +11,10 @@ library and on the strengths of Python as a high-level programming
 language.
 """ 
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@ language.
 # 
 # You should have received a copy of the GNU General Public License
 
-import base
+import cvxopt.base
 
 def normal(nrows, ncols=1, mean=0.0, std=1.0):
     '''
@@ -55,7 +55,7 @@ def normal(nrows, ncols=1, mean=0.0, std=1.0):
     except:
         from cvxopt.base import matrix
         from random import gauss
-        return matrix([gauss(mean, std) for k in xrange(nrows*ncols)],
+        return matrix([gauss(mean, std) for k in range(nrows*ncols)],
                       (nrows,ncols), 'd' )
         
     return gsl.normal(nrows, ncols, mean, std)
@@ -86,7 +86,7 @@ def uniform(nrows, ncols=1, a=0, b=1):
     except:
         from cvxopt.base import matrix
         from random import uniform
-        return matrix([uniform(a, b) for k in xrange(nrows*ncols)],
+        return matrix([uniform(a, b) for k in range(nrows*ncols)],
                       (nrows,ncols), 'd' )
 
     return gsl.uniform(nrows, ncols, a, b)
@@ -122,13 +122,19 @@ def getseed():
         from cvxopt import gsl
         return gsl.getseed()
     except:
-        raise NotImplementedError, "getseed() not installed (requires GSL) "
+        raise NotImplementedError("getseed() not installed (requires GSL)")
     
 
+import sys
+if sys.version_info.major < 3:
+    import __builtin__
+    omax = __builtin__.max
+    omin = __builtin__.min
+else:
+    omax = max
+    omin = min
+    from functools import reduce
 
-import __builtin__
-omax = __builtin__.max
-omin = __builtin__.min
 
 def max(*args):
     ''' 
@@ -146,7 +152,7 @@ def max(*args):
     '''    
     
     if len(args) == 1 and type(args[0]).__name__ in \
-            ['list', 'tuple', 'xrange', 'generator']: 
+            ['list', 'tuple', 'xrange', 'range', 'generator']: 
         return +reduce(base.emax, *args)
     elif len(args) == 1 and type(args[0]) is base.matrix:
         return omax(args[0])
@@ -175,7 +181,7 @@ def min(*args):
     '''
 
     if len(args) == 1 and type(args[0]).__name__ in \
-            ['list', 'tuple', 'xrange', 'generator']: 
+            ['list', 'tuple', 'xrange', 'range', 'generator']: 
         return +reduce(base.emin, *args)
     elif len(args) == 1 and type(args[0]) is base.matrix:
         return omin(args[0])
@@ -204,7 +210,7 @@ def mul(*args):
     '''
 
     if len(args) == 1 and type(args[0]).__name__ in \
-            ['list', 'tuple', 'xrange', 'generator']: 
+            ['list', 'tuple', 'xrange', 'range', 'generator']: 
         return +reduce(base.emul, *args)
     else:
         return +reduce(base.emul, args)
@@ -226,7 +232,7 @@ def div(*args):
     '''
 
     if len(args) == 1 and type(args[0]).__name__ in \
-            ['list', 'tuple', 'xrange', 'generator']: 
+            ['list', 'tuple', 'xrange', 'range', 'generator']: 
         return +reduce(base.ediv, *args)
     else:
         return +reduce(base.ediv, args)
diff --git a/src/python/coneprog.py b/src/python/coneprog.py
index 03bd1ef..9e85282 100644
--- a/src/python/coneprog.py
+++ b/src/python/coneprog.py
@@ -2,10 +2,10 @@
 Solver for linear and quadratic cone programs. 
 """
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -860,7 +860,7 @@ def conelp(c, G, h, dims = None, A = None, b = None, primalstart = None,
 
     gap = misc.sdot(s, z, dims) 
 
-    for iters in xrange(MAXITERS+1):
+    for iters in range(MAXITERS+1):
 
         # hrx = -A'*y - G'*z 
         Af(y, hrx, alpha = -1.0, trans = 'T') 
@@ -1221,7 +1221,7 @@ def conelp(c, G, h, dims = None, A = None, b = None, primalstart = None,
                 blas.copy(s, ws)
                 wkappa[0] = kappa[0]
             f6_no_ir(x, y, z, tau, s, kappa)
-            for i in xrange(refinement):
+            for i in range(refinement):
                 xcopy(wx, wx2)
                 ycopy(wy, wy2)
                 blas.copy(wz, wz2)
@@ -1383,9 +1383,9 @@ def conelp(c, G, h, dims = None, A = None, b = None, primalstart = None,
         # dsk := Ls = dsk * sqrt(sigs).  
         # dzk := Lz = dzk * sqrt(sigz).
         ind2, ind3 = dims['l'] + sum(dims['q']), 0
-        for k in xrange(len(dims['s'])):
+        for k in range(len(dims['s'])):
             m = dims['s'][k]
-            for i in xrange(m):
+            for i in range(m):
                 blas.scal(math.sqrt(sigs[ind3+i]), ds, offset = ind2 + m*i,
                     n = m)
                 blas.scal(math.sqrt(sigz[ind3+i]), dz, offset = ind2 + m*i,
@@ -2178,7 +2178,7 @@ def coneqp(P, q, G = None, h = None, dims = None, A = None, b = None,
 
     gap = misc.sdot(s, z, dims) 
 
-    for iters in xrange(MAXITERS + 1):
+    for iters in range(MAXITERS + 1):
 
         # f0 = (1/2)*x'*P*x + q'*x + r and  rx = P*x + q + A'*y + G'*z.
         xcopy(q, rx)
@@ -2347,7 +2347,7 @@ def coneqp(P, q, G = None, h = None, dims = None, A = None, b = None,
                 blas.copy(z, wz)        
                 blas.copy(s, ws)        
             f4_no_ir(x, y, z, s)        
-            for i in xrange(refinement):
+            for i in range(refinement):
                 xcopy(wx, wx2)        
                 ycopy(wy, wy2)        
                 blas.copy(wz, wz2)        
@@ -2516,9 +2516,9 @@ def coneqp(P, q, G = None, h = None, dims = None, A = None, b = None,
         # dsk := Ls = dsk * sqrt(sigs).
         # dzk := Lz = dzk * sqrt(sigz).
         ind2, ind3 = dims['l'] + sum(dims['q']), 0
-        for k in xrange(len(dims['s'])):
+        for k in range(len(dims['s'])):
             m = dims['s'][k]
-            for i in xrange(m):
+            for i in range(m):
                 blas.scal(math.sqrt(sigs[ind3+i]), ds, offset = ind2 + m*i,
                     n = m)
                 blas.scal(math.sqrt(sigz[ind3+i]), dz, offset = ind2 + m*i,
@@ -3314,7 +3314,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         raise TypeError("'Gq' must be a list of sparse or dense 'd' "\
             "matrices with %d columns" %n)
     mq = [ G.size[0] for G in Gq ]
-    a = [ k for k in xrange(len(mq)) if mq[k] == 0 ] 
+    a = [ k for k in range(len(mq)) if mq[k] == 0 ] 
     if a: raise TypeError("the number of rows of Gq[%d] is zero" %a[0])
     if hq is None: hq = []
     if type(hq) is not list or len(hq) != len(mq) or [ h for h in hq if
@@ -3322,7 +3322,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         h.typecode != 'd' ]: 
         raise TypeError("'hq' must be a list of %d dense or sparse "\
             "'d' matrices" %len(mq))
-    a = [ k for k in xrange(len(mq)) if hq[k].size != (mq[k], 1) ]
+    a = [ k for k in range(len(mq)) if hq[k].size != (mq[k], 1) ]
     if a:
         k = a[0]
         raise TypeError("'hq[%d]' has size (%d,%d).  Expected size "\
@@ -3367,16 +3367,16 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             y = matrix(0.0, (0,1))
             pcost = blas.dot(c,x)
             dcost = -blas.dot(hl,zl) - \
-                sum([ blas.dot(hq[k],zq[k]) for k in xrange(len(mq))]) 
+                sum([ blas.dot(hq[k],zq[k]) for k in range(len(mq))]) 
 
             sl = matrix(hl)
             base.gemv(Gl, x, sl, alpha = -1.0, beta = 1.0)
             sq = [ +hqk for hqk in hq ]
-            for k in xrange(len(Gq)):
+            for k in range(len(Gq)):
                 base.gemv(Gq[k], x, sq[k], alpha = -1.0, beta = 1.0)
 
             gap = blas.dot(sl, zl) + \
-                sum([blas.dot(zq[k],sq[k]) for k in xrange(len(mq))]) 
+                sum([blas.dot(zq[k],sq[k]) for k in range(len(mq))]) 
             if pcost < 0.0:
                 relgap = gap / -pcost
             elif dcost > 0.0:
@@ -3387,7 +3387,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             # rx = c + G'*z 
             rx = matrix(c)
             base.gemv(Gl, zl, rx, beta = 1.0, trans = 'T') 
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 base.gemv(Gq[k], zq[k], rx, beta = 1.0, trans = 'T') 
             resx = blas.nrm2(rx) / resx0
 
@@ -3397,7 +3397,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             blas.axpy(sl, rz)
             blas.axpy(hl, rz, alpha = -1.0)
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 base.gemv(Gq[k], x, rz, offsety = ind)
                 blas.axpy(sq[k], rz, offsety = ind)
                 blas.axpy(hq[k], rz, alpha = -1.0, offsety = ind)
@@ -3408,7 +3408,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             blas.copy(sl, s)
             blas.copy(zl, z)
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 blas.copy(zq[k], z, offsety = ind)
                 blas.copy(sq[k], s, offsety = ind)
                 ind += mq[k]
@@ -3422,9 +3422,9 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             status = 'primal infeasible'
             y = matrix(0.0, (0,1))
             hz = blas.dot(hl, zl) + sum([blas.dot(hq[k],zq[k]) for k 
-                in xrange(len(mq))]) 
+                in range(len(mq))]) 
             blas.scal(1.0 / -hz, zl)
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 blas.scal(1.0 / -hz, zq[k])
 
             x, sl, sq = None, None, None
@@ -3432,7 +3432,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             # rx = - G'*z 
             rx = matrix(0.0, (n,1)) 
             base.gemv(Gl, zl, rx, alpha = -1.0, beta = 1.0, trans = 'T') 
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 base.gemv(Gq[k], zq[k], rx, beta = 1.0, trans = 'T') 
             pinfres =  blas.nrm2(rx) / resx0 
             dinfres = None
@@ -3440,7 +3440,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             z = matrix(0.0, (N,1))
             blas.copy(zl, z)
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 blas.copy(zq[k], z, offsety = ind)
                 ind += mq[k]
             dslack = -misc.max_step(z, dims)
@@ -3459,14 +3459,14 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             sl = matrix(0.0, (ml,1))
             base.gemv(Gl, x, sl, alpha = -1.0)
             sq = [ matrix(0.0, (mqk,1)) for mqk in mq ]
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 base.gemv(Gq[k], x, sq[k], alpha = -1.0, beta = 1.0)
 
             # rz = s + G*x  
             rz = matrix( [sl] + [sqk for sqk in sq])
             base.gemv(Gl, x, rz, beta = 1.0)
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 base.gemv(Gq[k], x, rz, beta = 1.0, offsety = ind)
                 ind += mq[k]
             resz = blas.nrm2(rz) / resz0
@@ -3475,7 +3475,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
             s = matrix(0.0, (N,1))
             blas.copy(sl, s)
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 blas.copy(sq[k], s, offsety = ind)
                 ind += mq[k]
             pslack = -misc.max_step(s, dims)
@@ -3516,7 +3516,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
     h[:ml] = hl
     G[:ml,:] = Gl
     ind = ml
-    for k in xrange(len(mq)):
+    for k in range(len(mq)):
         h[ind : ind + mq[k]] = hq[k]
         G[ind : ind + mq[k], :] = Gq[k]
         ind += mq[k]
@@ -3528,7 +3528,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         if ml: ps['s'][:ml] = primalstart['sl']
         if mq:
             ind = ml
-            for k in xrange(len(mq)): 
+            for k in range(len(mq)): 
                 ps['s'][ind : ind + mq[k]] = primalstart['sq'][k][:]
                 ind += mq[k]
     else: 
@@ -3541,7 +3541,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         if ml: ds['z'][:ml] = dualstart['zl']
         if mq: 
             ind = ml
-            for k in xrange(len(mq)):
+            for k in range(len(mq)):
                 ds['z'][ind : ind + mq[k]] = dualstart['zq'][k][:]
                 ind += mq[k]
     else: 
@@ -3556,7 +3556,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         sol['sl'] = sol['s'][:ml]  
         sol['sq'] = [ matrix(0.0, (m,1)) for m in mq ] 
         ind = ml
-        for k in xrange(len(mq)):
+        for k in range(len(mq)):
             sol['sq'][k][:] = sol['s'][ind : ind+mq[k]]
             ind += mq[k]
     del sol['s']
@@ -3568,7 +3568,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         sol['zl'] = sol['z'][:ml]
         sol['zq'] = [ matrix(0.0, (m,1)) for m in mq] 
         ind = ml
-        for k in xrange(len(mq)):
+        for k in range(len(mq)):
             sol['zq'][k][:] = sol['z'][ind : ind+mq[k]]
             ind += mq[k]
     del sol['z']
@@ -3877,7 +3877,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         raise TypeError("'Gs' must be a list of sparse or dense 'd' "\
             "matrices with %d columns" %n)
     ms = [ int(math.sqrt(G.size[0])) for G in Gs ]
-    a = [ k for k in xrange(len(ms)) if ms[k]**2 != Gs[k].size[0] ]
+    a = [ k for k in range(len(ms)) if ms[k]**2 != Gs[k].size[0] ]
     if a: raise TypeError("the squareroot of the number of rows in "\
         "'Gs[%d]' is not an integer" %k)
     if hs is None: hs = []
@@ -3886,7 +3886,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         h.typecode != 'd' ]:
         raise TypeError("'hs' must be a list of %d dense or sparse "\
             "'d' matrices" %len(ms))
-    a = [ k for k in xrange(len(ms)) if hs[k].size != (ms[k],ms[k]) ]
+    a = [ k for k in range(len(ms)) if hs[k].size != (ms[k],ms[k]) ]
     if a:
         k = a[0]
         raise TypeError("hs[%d] has size (%d,%d).  Expected size is "\
@@ -3925,15 +3925,15 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             blas.scal(-1.0/cx, x)
             sl = -Gl*x
             ss = [ -matrix(Gs[k]*x, (ms[k], ms[k])) for k in 
-                xrange(len(ms)) ]
-            for k in xrange(len(ms)):  
+                range(len(ms)) ]
+            for k in range(len(ms)):  
                 misc.symm(ss[k], ms[k])
 
             # rz = s + G*x  
             rz = matrix( [sl] + [ssk[:] for ssk in ss])
             base.gemv(Gl, x, rz, beta = 1.0)
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 base.gemv(Gs[k], x, rz, beta = 1.0, offsety = ind)
                 ind += ms[k]**2
             dims = {'l': ml, 's': ms, 'q': []}
@@ -3942,7 +3942,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             s = matrix(0.0, (N,1))
             blas.copy(sl, s)
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.copy(ss[k], s, offsety = ind)
                 ind += ms[k]
             pslack = -misc.max_step(s, dims)
@@ -3959,7 +3959,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             y = matrix(0.0, (0,1))
             hz = blas.dot(hl, zl) + misc.sdot2(hs, zs)
             blas.scal(1.0 / -hz, zl)
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.scal(1.0 / -hz, zs[k])
                 misc.symm(zs[k], ms[k])
 
@@ -3967,9 +3967,9 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             rx = matrix(0.0, (n,1)) 
             base.gemv(Gl, zl, rx, alpha = -1.0, beta = 1.0, trans = 'T') 
             ind = 0
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.scal(0.5, zs[k], inc=ms[k]+1)
-                for j in xrange(ms[k]):
+                for j in range(ms[k]):
                     blas.scal(0.0, zs[k], offset=j+ms[k]*(j+1), inc=ms[k])
                 base.gemv(Gs[k], zs[k], rx, alpha=2.0, beta=1.0, trans='T')
                 blas.scal(2.0, zs[k], inc=ms[k]+1)
@@ -3980,7 +3980,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             z = matrix(0.0, (N,1))
             blas.copy(zl, z)
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.copy(zs[k], z, offsety = ind)
                 ind += ms[k]
             dslack = -misc.max_step(z, dims)
@@ -3999,8 +3999,8 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             y = matrix(0.0, (0,1))
             sl = hl - Gl*x
             ss = [ hs[k] - matrix(Gs[k]*x, (ms[k], ms[k])) for k in 
-                xrange(len(ms)) ]
-            for k in xrange(len(ms)): 
+                range(len(ms)) ]
+            for k in range(len(ms)): 
                 misc.symm(ss[k], ms[k])
                 misc.symm(zs[k], ms[k])
             pcost = blas.dot(c,x)
@@ -4017,9 +4017,9 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             rx = matrix(c)
             base.gemv(Gl, zl, rx, beta = 1.0, trans = 'T') 
             ind = 0
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.scal(0.5, zs[k], inc = ms[k]+1)
-                for j in xrange(ms[k]):
+                for j in range(ms[k]):
                     blas.scal(0.0, zs[k], offset=j+ms[k]*(j+1), inc=ms[k])
                 base.gemv(Gs[k], zs[k], rx, alpha=2.0, beta=1.0, trans='T')
                 blas.scal(2.0, zs[k], inc=ms[k]+1)
@@ -4032,7 +4032,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             blas.axpy(sl, rz)
             blas.axpy(hl, rz, alpha = -1.0)
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 base.gemv(Gs[k], x, rz, offsety = ind)
                 blas.axpy(ss[k], rz, offsety = ind, n = ms[k]**2)
                 blas.axpy(hs[k], rz, alpha = -1.0, offsety = ind, 
@@ -4045,7 +4045,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             blas.copy(sl, s)
             blas.copy(zl, z)
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 blas.copy(ss[k], s, offsety = ind)
                 blas.copy(zs[k], z, offsety = ind)
                 ind += ms[k]
@@ -4059,9 +4059,9 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
                 rx = matrix(0.0, (n,1))
                 base.gemv(Gl, zl, rx, beta = 1.0, trans = 'T') 
                 ind = 0
-                for k in xrange(len(ms)):
+                for k in range(len(ms)):
                     blas.scal(0.5, zs[k], inc = ms[k]+1)
-                    for j in xrange(ms[k]):
+                    for j in range(ms[k]):
                         blas.scal(0.0, zs[k], offset=j+ms[k]*(j+1), 
                             inc=ms[k])
                     base.gemv(Gs[k], zs[k], rx, alpha=2.0, beta=1.0, 
@@ -4078,7 +4078,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
                 base.gemv(Gl, x, rz)
                 blas.axpy(sl, rz)
                 ind = ml
-                for k in xrange(len(ms)):
+                for k in range(len(ms)):
                     base.gemv(Gs[k], x, rz, offsety = ind)
                     blas.axpy(ss[k], rz, offsety = ind, n = ms[k]**2)
                     ind += ms[k]**2
@@ -4101,7 +4101,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
     h[:ml] = hl
     G[:ml,:] = Gl
     ind = ml
-    for k in xrange(len(ms)):
+    for k in range(len(ms)):
         m = ms[k]
         h[ind : ind + m*m] = hs[k][:]
         G[ind : ind + m*m, :] = Gs[k]
@@ -4114,7 +4114,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         if ml: ps['s'][:ml] = primalstart['sl']
         if ms:
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 m = ms[k]
                 ps['s'][ind : ind + m*m] = primalstart['ss'][k][:]
                 ind += m**2
@@ -4128,7 +4128,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         if ml: ds['z'][:ml] = dualstart['zl']
         if ms: 
             ind = ml
-            for k in xrange(len(ms)):
+            for k in range(len(ms)):
                 m = ms[k]
                 ds['z'][ind : ind + m*m] = dualstart['zs'][k][:]
                 ind += m**2
@@ -4144,7 +4144,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         sol['sl'] = sol['s'][:ml]
         sol['ss'] = [ matrix(0.0, (mk, mk)) for mk in ms ]
         ind = ml
-        for k in xrange(len(ms)):
+        for k in range(len(ms)):
             m = ms[k]
             sol['ss'][k][:] = sol['s'][ind:ind+m*m]
             ind += m**2
@@ -4157,7 +4157,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
         sol['zl'] = sol['z'][:ml]
         sol['zs'] = [ matrix(0.0, (mk, mk)) for mk in ms ]
         ind = ml
-        for k in xrange(len(ms)):
+        for k in range(len(ms)):
             m = ms[k]
             sol['zs'][k][:] = sol['z'][ind:ind+m*m]
             ind += m**2
diff --git a/src/python/cvxprog.py b/src/python/cvxprog.py
index 310986f..6b98299 100644
--- a/src/python/cvxprog.py
+++ b/src/python/cvxprog.py
@@ -6,10 +6,10 @@ for quadratic and geometric programming.  Also includes an interface
 to the quadratic programming solver from MOSEK.
 """
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -625,7 +625,7 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
 
 
     relaxed_iters = 0
-    for iters in xrange(MAXITERS + 1):  
+    for iters in range(MAXITERS + 1):  
 
         if refinement or DEBUG:  
             # We need H to compute residuals of KKT equations.
@@ -799,10 +799,10 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
                 blas.copy(W0['dnli'], W['dnli'])
                 blas.copy(W0['d'], W['d'])
                 blas.copy(W0['di'], W['di'])
-                for k in xrange(len(dims['q'])):
+                for k in range(len(dims['q'])):
                     blas.copy(W0['v'][k], W['v'][k])
                     W['beta'][k] = W0['beta'][k]
-                for k in xrange(len(dims['s'])):
+                for k in range(len(dims['s'])):
                     blas.copy(W0['r'][k], W['r'][k])
                     blas.copy(W0['rti'][k], W['rti'][k])
                 xcopy(x0, x); 
@@ -948,7 +948,7 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
                 blas.copy(z, wz)        
                 blas.copy(s, ws)        
             f4_no_ir(x, y, z, s)        
-            for i in xrange(refinement):
+            for i in range(refinement):
                 xcopy(wx, wx2)        
                 ycopy(wy, wy2)        
                 blas.copy(wz, wz2)        
@@ -1198,10 +1198,10 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
                             blas.copy(W['dnli'], W0['dnli'])
                             blas.copy(W['d'], W0['d'])
                             blas.copy(W['di'], W0['di'])
-                            for k in xrange(len(dims['q'])):
+                            for k in range(len(dims['q'])):
                                 blas.copy(W['v'][k], W0['v'][k])
                                 W0['beta'][k] = W['beta'][k]
-                            for k in xrange(len(dims['s'])):
+                            for k in range(len(dims['s'])):
                                 blas.copy(W['r'][k], W0['r'][k])
                                 blas.copy(W['rti'][k], W0['rti'][k])
                             xcopy(x, x0); xcopy(dx, dx0)
@@ -1247,10 +1247,10 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
                             blas.copy(W0['dnli'], W['dnli'])
                             blas.copy(W0['d'], W['d'])
                             blas.copy(W0['di'], W['di'])
-                            for k in xrange(len(dims['q'])):
+                            for k in range(len(dims['q'])):
                                 blas.copy(W0['v'][k], W['v'][k])
                                 W['beta'][k] = W0['beta'][k]
-                            for k in xrange(len(dims['s'])):
+                            for k in range(len(dims['s'])):
                                 blas.copy(W0['r'][k], W['r'][k])
                                 blas.copy(W0['rti'][k], W['rti'][k])
                             xcopy(x0, x); xcopy(dx0, dx);
@@ -1322,9 +1322,9 @@ def cpl(c, F, G = None, h = None, dims = None, A = None, b = None,
         # dsk := Ls = dsk * sqrt(sigs).
         # dzk := Lz = dzk * sqrt(sigz).
         ind2, ind3 = mnl + dims['l'] + sum(dims['q']), 0
-        for k in xrange(len(dims['s'])):
+        for k in range(len(dims['s'])):
             m = dims['s'][k]
-            for i in xrange(m):
+            for i in range(m):
                 blas.scal(math.sqrt(sigs[ind3+i]), ds, offset = ind2 + m*i,
                     n = m)
                 blas.scal(math.sqrt(sigz[ind3+i]), dz, offset = ind2 + m*i,
@@ -2099,9 +2099,9 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
     u = matrix(0.0, (max(K),1))
     Fsc = matrix(0.0, (max(K),n))
 
-    cs1 = [ sum(K[:i]) for i in xrange(mnl+1) ] 
-    cs2 = [ cs1[i] + K[i] for i in xrange(mnl+1) ]
-    ind = zip(range(mnl+1), cs1, cs2)
+    cs1 = [ sum(K[:i]) for i in range(mnl+1) ] 
+    cs2 = [ cs1[i] + K[i] for i in range(mnl+1) ]
+    ind = list(zip(range(mnl+1), cs1, cs2))
 
     def Fgp(x = None, z = None):
 
@@ -2143,7 +2143,7 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
                 #      = diag(yi)^1/2 * (Fi - 1*gradfi')
 
                 Fsc[:K[i], :] = F[start:stop, :] 
-                for k in xrange(start,stop):
+                for k in range(start,stop):
                    blas.axpy(Df, Fsc, n=n, alpha=-1.0, incx=mnl+1,
                        incy=Fsc.size[0], offsetx=i, offsety=k-start)
                    blas.scal(math.sqrt(y[k]), Fsc, inc=Fsc.size[0],
diff --git a/src/python/info.py b/src/python/info.py
index 78c7919..c20846d 100644
--- a/src/python/info.py
+++ b/src/python/info.py
@@ -1,9 +1,9 @@
-version = '1.1.3'
+version = '1.1.4'
 
 def license(): print(
 """
-CVXOPT version 1.1.3. 
-Copyright (c) 2010 L. Vandenberghe.
+CVXOPT version 1.1.4. 
+Copyright (c) 2010-2011 L. Vandenberghe.
 Copyright (c) 2004-2009 J. Dahl and L. Vandenberghe.
 
 This program is free software; you can redistribute it and/or modify
diff --git a/src/python/misc.py b/src/python/misc.py
index 8cac4fb..911f21e 100644
--- a/src/python/misc.py
+++ b/src/python/misc.py
@@ -1,7 +1,7 @@
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -64,7 +64,7 @@ else:
     if 'dnl' in W:
         if inverse == 'N': w = W['dnl']
         else: w = W['dnli']
-        for k in xrange(x.size[1]):
+        for k in range(x.size[1]):
             blas.tbmv(w, x, n = w.size[0], k = 0, ldA = 1, offsetx = 
                 k*x.size[0])
         ind += w.size[0]
@@ -75,7 +75,7 @@ else:
 
     if inverse == 'N': w = W['d']
     else: w = W['di']
-    for k in xrange(x.size[1]):
+    for k in range(x.size[1]):
         blas.tbmv(w, x, n = w.size[0], k = 0, ldA = 1, offsetx = 
             k*x.size[0] + ind)
     ind += w.size[0]
@@ -94,7 +94,7 @@ else:
     #         = 1/beta * (-J) * (2*v*((-J*xk)'*v)' + xk). 
 
     w = matrix(0.0, (x.size[1], 1))
-    for k in xrange(len(W['v'])):
+    for k in range(len(W['v'])):
         v = W['v'][k]
         m = v.size[0]
         if inverse == 'I':  
@@ -109,7 +109,7 @@ else:
             a = 1.0 / W['beta'][k] 
         else:
             a = W['beta'][k] 
-        for i in xrange(x.size[1]):
+        for i in range(x.size[1]):
             blas.scal(a, x, n = m, offset = ind + i*x.size[0])
         ind += m
 
@@ -130,7 +130,7 @@ else:
 
     maxn = max( [0] + [ r.size[0] for r in W['r'] ] )
     a = matrix(0.0, (maxn, maxn))
-    for k in xrange(len(W['r'])):
+    for k in range(len(W['r'])):
 
         if inverse == 'N':
             r = W['r'][k]
@@ -141,7 +141,7 @@ else:
             t = trans
 
         n = r.size[0]
-        for i in xrange(x.size[1]):
+        for i in range(x.size[1]):
 
             # scale diagonal of xk by 0.5
             blas.scal(0.5, x, offset = ind + i*x.size[0], inc = n+1, n = n)
@@ -234,9 +234,9 @@ else:
     # inverse operation will be applied to nonsymmetric matrices.
 
     ind2 = ind
-    for k in xrange(len(dims['s'])):
+    for k in range(len(dims['s'])):
         m = dims['s'][k]
-        for j in xrange(m):
+        for j in range(m):
             c = math.sqrt(lmbda[ind2+j]) * base.sqrt(lmbda[ind2:ind2+m])
             if inverse == 'N':  
                 blas.tbsv(c, x, n = m, k = 0, ldA = 1, offsetx = ind + j*m)
@@ -307,7 +307,7 @@ def compute_scaling(s, z, lmbda, dims, mnl = None):
     W['v'] = [ matrix(0.0, (k,1)) for k in dims['q'] ]
     W['beta'] = len(dims['q']) * [ 0.0 ] 
 
-    for k in xrange(len(dims['q'])):
+    for k in range(len(dims['q'])):
         m = dims['q'][k]
         v = W['v'][k]
 
@@ -377,7 +377,7 @@ def compute_scaling(s, z, lmbda, dims, mnl = None):
     Lz = matrix(0.0, (max( [0] + dims['s'] )**2, 1))
 
     ind2 = ind
-    for k in xrange(len(dims['s'])):
+    for k in range(len(dims['s'])):
         m = dims['s'][k]
         r, rti = W['r'][k], W['rti'][k]
 
@@ -390,7 +390,7 @@ def compute_scaling(s, z, lmbda, dims, mnl = None):
         lapack.potrf(Lz, n = m, ldA = m)
 	 
         # SVD Lz'*Ls = U*diag(lambda_k)*V'.  Keep U in work. 
-        for i in xrange(m): 
+        for i in range(m): 
             blas.scal(0.0, Ls, offset = i*m, n = i)
         blas.copy(Ls, work, n = m**2)
         blas.trmm(Lz, work, transA = 'T', ldA = m, ldB = m, n = m, m = m) 
@@ -407,7 +407,7 @@ def compute_scaling(s, z, lmbda, dims, mnl = None):
 
         # r := r * diag(sqrt(lambda_k))
         # rti := rti * diag(1 ./ sqrt(lambda_k))
-        for i in xrange(m):
+        for i in range(m):
             a = math.sqrt( lmbda[ind+i] )
             blas.scal(a, r, offset = m*i, n = m)
             blas.scal(1.0/a, rti, offset = m*i, n = m)
@@ -500,7 +500,7 @@ def update_scaling(W, lmbda, s, z):
     #        beta[k] *=  sqrt(a/b)
 
     ind = m
-    for k in xrange(len(W['v'])):
+    for k in range(len(W['v'])):
 
         v = W['v'][k]
         m = len(v)
@@ -591,7 +591,7 @@ def update_scaling(W, lmbda, s, z):
     work = matrix(0.0, (max( [0] + [r.size[0] for r in W['r']])**2, 1))
     ind = mnl + ml + sum([ len(v) for v in W['v'] ])
     ind2, ind3 = ind, 0
-    for k in xrange(len(W['r'])):
+    for k in range(len(W['r'])):
         r, rti = W['r'][k], W['rti'][k]
         m = r.size[0]
 
@@ -623,7 +623,7 @@ def update_scaling(W, lmbda, s, z):
         blas.copy(work, rti, n = m**2)
 
         # r := r*lambda^{-1/2}; rti := rti*lambda^{-1/2}
-        for i in xrange(m):    
+        for i in range(m):    
             a = 1.0 / math.sqrt(lmbda[ind+i])
             blas.scal(a, r, offset = m*i, n = m)
             blas.scal(a, rti, offset = m*i, n = m)
@@ -650,12 +650,12 @@ else:
      blas.copy(x, y, n = nlq, offsetx = offsetx, offsety = offsety)
      iu, ip = offsetx + nlq, offsety + nlq
      for n in dims['s']:
-         for k in xrange(n):
+         for k in range(n):
              blas.copy(x, y, n = n-k, offsetx = iu + k*(n+1), offsety = ip)
              y[ip] /= math.sqrt(2)
              ip += n-k
          iu += n**2 
-     np = sum([ n*(n+1)/2 for n in dims['s'] ])
+     np = sum([ int(n*(n+1)/2) for n in dims['s'] ])
      blas.scal(math.sqrt(2.0), y, n = np, offset = offsety+nlq)
      
 
@@ -674,13 +674,13 @@ else:
      iu = mnl + dims['l'] + sum(dims['q'])
      ip = iu
      for n in dims['s']:
-         for k in xrange(n):
+         for k in range(n):
              x[ip, :] = x[iu + (n+1)*k, :]
              x[ip + 1 : ip+n-k, :] = x[iu + (n+1)*k + 1: iu + n*(k+1), :] \
                  * math.sqrt(2.0)
              ip += n - k
          iu += n**2 
-     np = sum([ n*(n+1)/2 for n in dims['s'] ])
+     np = sum([ int(n*(n+1)/2) for n in dims['s'] ])
      
 
 if use_C:
@@ -698,7 +698,7 @@ else:
      blas.copy(x, y, n = nlq, offsetx = offsetx, offsety = offsety)
      iu, ip = offsety+nlq, offsetx+nlq
      for n in dims['s']:
-         for k in xrange(n):
+         for k in range(n):
              blas.copy(x, y, n = n-k, offsetx = ip, offsety = iu+k*(n+1))
              y[iu+k*(n+1)] *= math.sqrt(2)
              ip += n-k
@@ -720,7 +720,7 @@ else:
     for m in dims['s']:
         a += blas.dot(x, y, offsetx = ind, offsety = ind, incx = m+1, 
             incy = m+1, n = m)
-        for j in xrange(1, m):
+        for j in range(1, m):
             a += 2.0 * blas.dot(x, y, incx = m+1, incy = m+1, 
                 offsetx = ind+j, offsety = ind+j, n = m-j)
         ind += m**2
@@ -739,15 +739,15 @@ def sdot2(x, y):
     if type(x) is matrix:
         n = x.size[0]
         a += blas.dot(x, y, incx=n+1, incy=n+1, n=n)
-        for j in xrange(1,n):
+        for j in range(1,n):
             a += 2.0 * blas.dot(x, y, incx=n+1, incy=n+1, offsetx=j,
                 offsety=j, n=n-j)
 
     else:
-        for k in xrange(len(x)):
+        for k in range(len(x)):
             n = x[k].size[0]
             a += blas.dot(x[k], y[k], incx=n+1, incy=n+1, n=n)
-            for j in xrange(1,n):
+            for j in range(1,n):
                 a += 2.0 * blas.dot(x[k], y[k], incx=n+1, incy=n+1, 
                     offsetx=j, offsety=j, n=n-j)
     return a
@@ -773,7 +773,7 @@ else:
     m = dims['l'] + sum(dims['q']) + sum([ k**2 for k in dims['s'] ]) 
     ind = offset + dims['l'] + sum(dims['q'])
     for mk in dims['s']:
-        for j in xrange(1, mk):  
+        for j in range(1, mk):  
             blas.scal(0.0, x, n = mk-j, inc = mk, offset = 
                     ind + j*(mk + 1) - 1) 
             blas.scal(2.0, x, offset = ind + mk*(j-1) + j, n = mk-j) 
@@ -792,7 +792,7 @@ else:
     m = dims['l'] + sum(dims['q']) + sum([ k**2 for k in dims['s'] ]) 
     ind = offset + dims['l'] + sum(dims['q'])
     for mk in dims['s']:
-        for j in xrange(1, mk):  
+        for j in range(1, mk):  
                 blas.scal(0.5, x, offset = ind + mk*(j-1) + j, n = mk-j) 
         ind += mk**2
 
@@ -866,7 +866,7 @@ else:
     """
 
     if n <= 1:  return
-    for i in xrange(n-1):
+    for i in range(n-1):
         blas.copy(x, x, offsetx = offset + i*(n+1) + 1, offsety = 
             offset + (i+1)*(n+1) - 1, incy = n, n = n-i-1)
 
@@ -920,7 +920,7 @@ else:
             blas.copy(x, A, offsetx = ind, n = m*m)
 
             # Write upper triangular part of A and yk.
-            for i in xrange(m-1):
+            for i in range(m-1):
                 symm(A, m)
                 symm(y, m, offset = ind)
 
@@ -933,7 +933,7 @@ else:
     else:
         ind2 = ind
         for m in dims['s']:
-            for j in xrange(m):
+            for j in range(m):
                 u = 0.5 * ( y[ind2+j:ind2+m] + y[ind2+j] )
                 blas.tbmv(u, x, n = m-j, k = 0, ldA = 1, offsetx = 
                     ind + j*(m+1))  
@@ -1003,7 +1003,7 @@ else:
 
     ind2 = ind
     for m in dims['s']:
-        for j in xrange(m):
+        for j in range(m):
             u = 0.5 * ( y[ind2+j:ind2+m] + y[ind2+j] )
             blas.tbsv(u, x, n = m-j, k = 0, ldA = 1, offsetx = ind + 
                 j*(m+1))  
@@ -1074,8 +1074,8 @@ def kkt_ldl(G, dims, A, mnl = 0):
     """
     
     p, n = A.size
-    ldK = n + p + mnl + dims['l'] + sum(dims['q']) + sum([ k*(k+1)/2 for k 
-        in dims['s'] ])
+    ldK = n + p + mnl + dims['l'] + sum(dims['q']) + sum([ int(k*(k+1)/2)
+        for k in dims['s'] ])
     K = matrix(0.0, (ldK, ldK))
     ipiv = matrix(0, (ldK, 1))
     u = matrix(0.0, (ldK, 1))
@@ -1086,7 +1086,7 @@ def kkt_ldl(G, dims, A, mnl = 0):
         blas.scal(0.0, K)
         if H is not None: K[:n, :n] = H
         K[n:n+p, :n] = A
-        for k in xrange(n):
+        for k in range(n):
             if mnl: g[:mnl] = Df[:,k]
             g[mnl:] = G[:,k]
             scale(g, W, trans = 'T', inverse = 'I')
@@ -1155,7 +1155,7 @@ def kkt_ldl2(G, dims, A, mnl = 0):
         blas.scal(0.0, K)
         if H is not None: K[:n, :n] = H
         K[n:,:n] = A
-        for k in xrange(n):
+        for k in range(n):
             if mnl: g[:mnl] = Df[:,k]
             g[mnl:] = G[:,k]
             scale(g, W, trans = 'T', inverse = 'I')
@@ -1234,8 +1234,8 @@ def kkt_chol(G, dims, A, mnl = 0):
     p, n = A.size
     cdim = mnl + dims['l'] + sum(dims['q']) + sum([ k**2 for k in 
         dims['s'] ])
-    cdim_pckd = mnl + dims['l'] + sum(dims['q']) + sum([ k*(k+1)/2 for k 
-        in dims['s'] ])
+    cdim_pckd = mnl + dims['l'] + sum(dims['q']) + sum([ int(k*(k+1)/2)
+        for k in dims['s'] ])
 
     # A' = [Q1, Q2] * [R; 0]  (Q1 is n x p, Q2 is n x n-p).
     if type(A) is matrix: 
@@ -1407,12 +1407,12 @@ def kkt_chol2(G, dims, A, mnl = 0):
                     F['K'] = spmatrix([], [], [], (p,p), 'd')
 
         # Dfs = Wnl^{-1} * Df 
-        if mnl: base.gemm(spmatrix(W['dnli'], range(mnl), range(mnl)), Df, 
-            F['Dfs'], partial = True)
+        if mnl: base.gemm(spmatrix(W['dnli'], list(range(mnl)), 
+            list(range(mnl))), Df, F['Dfs'], partial = True)
 
         # Gs = Wl^{-1} * G.
-        base.gemm(spmatrix(W['di'], range(ml), range(ml)), G, F['Gs'], 
-            partial = True)
+        base.gemm(spmatrix(W['di'], list(range(ml)), list(range(ml))), 
+            G, F['Gs'], partial = True)
 
         if F['firstcall']:
             base.syrk(F['Gs'], F['S'], trans = 'T') 
@@ -1590,7 +1590,7 @@ def kkt_qr(G, dims, A):
  
     p, n = A.size
     cdim = dims['l'] + sum(dims['q']) + sum([ k**2 for k in dims['s'] ])
-    cdim_pckd = dims['l'] + sum(dims['q']) + sum([ k*(k+1)/2 for k in 
+    cdim_pckd = dims['l'] + sum(dims['q']) + sum([ int(k*(k+1)/2) for k in 
         dims['s'] ])
 
     # A' = [Q1, Q2] * [R1; 0]
diff --git a/src/python/modeling.py b/src/python/modeling.py
index 75f270b..3d80997 100644
--- a/src/python/modeling.py
+++ b/src/python/modeling.py
@@ -5,10 +5,10 @@ Routines for specifying and solving convex optimization problems with
 piecewise-linear objective and constraint functions.
 """
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -23,10 +23,13 @@ piecewise-linear objective and constraint functions.
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from string import strip
 from cvxopt.base import matrix, spmatrix
 from cvxopt import blas, solvers 
-import __builtin__
+import sys
+if sys.version_info.major < 3: 
+    import __builtin__ as builtins
+else:
+    import builtins
 
 __all__ = ["variable", "constraint", "op", "min", "max", "sum", "dot"]
  
@@ -181,15 +184,29 @@ class variable(object):
             "implemented for 'variable' objects")
 
 
-    def __div__(self,other):
+    if sys.version_info.major < 3: 
 
-        return (+self).__div__(other)
+        def __div__(self,other):
 
+            return (+self).__div__(other)
 
-    def __idiv__(self,other):
 
-        raise NotImplementedError("in-place division not implemented "\
-            "for 'variable' objects")
+        def __idiv__(self,other):
+
+            raise NotImplementedError("in-place division not implemented "\
+                "for 'variable' objects")
+
+    else:
+    
+        def __truediv__(self,other):
+
+            return (+self).__truediv__(other)
+
+
+        def __itruediv__(self,other):
+
+            raise NotImplementedError("in-place division not implemented "\
+                "for 'variable' objects")
 
 
     def __eq__(self,other):
@@ -222,6 +239,12 @@ class variable(object):
         return (+self).__getitem__(key)
 
 
+    if sys.version_info.major >= 3: 
+
+        def __hash__(self):
+
+            return id(self)
+
 
 class _function(object):
 
@@ -796,17 +819,32 @@ class _function(object):
         else: 
             raise TypeError('incompatible dimensions or types')
 
+    if sys.version_info.major < 3: 
 
-    def __div__(self,other):
+        def __div__(self,other):
 
-        if type(other) is int or type(other) is float:
-            return self.__mul__(1.0/other)
+            if type(other) is int or type(other) is float:
+                return self.__mul__(1.0/other)
 
-        elif _isdmatrix(other) and other.size == (1,1):
-            return self.__mul__(1.0/other[0])
+            elif _isdmatrix(other) and other.size == (1,1):
+                return self.__mul__(1.0/other[0])
+
+            else:
+                return NotImplemented
+
+    else:
+
+        def __truediv__(self,other):
+
+            if type(other) is int or type(other) is float:
+                return self.__mul__(1.0/other)
+
+            elif _isdmatrix(other) and other.size == (1,1):
+                return self.__mul__(1.0/other[0])
+
+            else:
+                return NotImplemented
 
-        else:
-            return NotImplemented
 
 
     def __rdiv__(self,other):
@@ -814,16 +852,31 @@ class _function(object):
         return NotImplemented
 
 
-    def __idiv__(self,other):
+    if sys.version_info.major < 3: 
 
-        if type(other) is int or type(other) is float:
-            return self.__imul__(1.0/other)
+        def __idiv__(self,other):
 
-        elif _isdmatrix(other) and other.size == (1,1):
-            return self.__imul__(1.0/other[0])
+            if type(other) is int or type(other) is float:
+                return self.__imul__(1.0/other)
 
-        else:
-            return NotImplemented
+            elif _isdmatrix(other) and other.size == (1,1):
+                return self.__imul__(1.0/other[0])
+
+            else:
+                return NotImplemented
+
+    else:
+
+        def __itruediv__(self,other):
+
+            if type(other) is int or type(other) is float:
+                return self.__imul__(1.0/other)
+
+            elif _isdmatrix(other) and other.size == (1,1):
+                return self.__imul__(1.0/other[0])
+
+            else:
+                return NotImplemented
         
 
     def __abs__(self):
@@ -945,7 +998,7 @@ def sum(s):
         return f
 
     else:
-        return __builtin__.sum(s)
+        return builtins.sum(s)
 
 
 
@@ -981,7 +1034,7 @@ class _lin(object):
 
     def __len__(self):
     
-        for v,c in self._coeff.iteritems():
+        for v,c in iter(self._coeff.items()):
             if c.size[0] > 1: 
                 return c.size[0]
             elif _isscalar(c) and len(v) > 1: 
@@ -997,7 +1050,7 @@ class _lin(object):
     def __str__(self):
 
         s = repr(self)[1:-1] + '\n'
-        for v,c in self._coeff.iteritems(): 
+        for v,c in iter(self._coeff.items()): 
             s += 'coefficient of ' + repr(v) + ':\n'  + str(c) 
         return s
 
@@ -1005,7 +1058,7 @@ class _lin(object):
     def value(self):
 
         value = matrix(0.0, (len(self),1))
-        for v,c in self._coeff.iteritems():
+        for v,c in iter(self._coeff.items()):
             if v.value is None: 
                 return None
             else: 
@@ -1027,7 +1080,7 @@ class _lin(object):
 
         lg = len(self)
 
-        if self._coeff.has_key(v):
+        if v in self._coeff:
 
             # self := self + a*v with v a variable of self
             #
@@ -1126,13 +1179,13 @@ class _lin(object):
         '''
 
         if type(a) is int or type(a) is float:
-            for v in self._coeff.iterkeys(): self._coeff[v] *= a
+            for v in iter(self._coeff.keys()): self._coeff[v] *= a
 
         elif _ismatrix(a) and a.size == (1,1):
-            for v in self._coeff.iterkeys(): self._coeff[v] *= a[0]
+            for v in iter(self._coeff.keys()): self._coeff[v] *= a[0]
         
         elif len(self) == 1 and _isdmatrix(a) and a.size[1] == 1:
-            for v,c in self._coeff.iteritems(): self._coeff[v] = a*c
+            for v,c in iter(self._coeff.items()): self._coeff[v] = a*c
 
         else: 
             raise TypeError('incompatible dimensions')
@@ -1146,13 +1199,13 @@ class _lin(object):
 
         lg = len(self)
         if _isscalar(a):
-            for v in self._coeff.iterkeys(): self._coeff[v] *= a
+            for v in iter(self._coeff.keys()): self._coeff[v] *= a
         
         elif lg == 1 and _ismatrix(a) and a.size[1] == 1:
-            for v,c in self._coeff.iteritems(): self._coeff[v] = a*c
+            for v,c in iter(self._coeff.items()): self._coeff[v] = a*c
 
         elif _ismatrix(a) and a.size[1] == lg: 
-            for v,c in self._coeff.iteritems():
+            for v,c in iter(self._coeff.items()):
                 if c.size == (1,len(v)):
                     self._coeff[v] = a*c[lg*[0],:]
                 else: 
@@ -1165,14 +1218,14 @@ class _lin(object):
     def __pos__(self):
 
         f = _lin()
-        for v,c in self._coeff.iteritems(): f._coeff[v] = +c
+        for v,c in iter(self._coeff.items()): f._coeff[v] = +c
         return f
 
 
     def __neg__(self):
 
         f = _lin()
-        for v,c in self._coeff.iteritems(): f._coeff[v] = -c
+        for v,c in iter(self._coeff.items()): f._coeff[v] = -c
         return f
 
 
@@ -1191,7 +1244,7 @@ class _lin(object):
             f._addterm(1.0, other)
 
         elif type(other) is _lin:
-            for v,c in other._coeff.iteritems(): f._addterm(c,v)
+            for v,c in iter(other._coeff.items()): f._addterm(c,v)
 
         else: return NotImplemented
 
@@ -1219,7 +1272,7 @@ class _lin(object):
 
         elif type(other) is _lin and (len(other) == 1 or 
             len(other) == lg): 
-            for v,c in other._coeff.iteritems(): self._addterm(c,v)
+            for v,c in iter(other._coeff.items()): self._addterm(c,v)
 
         else: 
             raise NotImplementedError('in-place addition must result '\
@@ -1235,7 +1288,7 @@ class _lin(object):
         if type(other) is variable:
             f._addterm(-1.0, other)
         elif type(other) is _lin:
-            for v,c in other._coeff.iteritems(): f._addterm(-c,v)
+            for v,c in iter(other._coeff.items()): f._addterm(-c,v)
         else: 
             return NotImplemented
         
@@ -1249,7 +1302,7 @@ class _lin(object):
         if type(other) is variable:
             f._addterm(1.0, other)
         elif type(other) is _lin:
-            for v,c in other._coeff.iteritems(): f._addterm(c,v)
+            for v,c in iter(other._coeff.items()): f._addterm(c,v)
         else: 
             return NotImplemented
         
@@ -1272,7 +1325,7 @@ class _lin(object):
 
         elif type(other) is _lin and (len(other) == 1 or 
             len(other) == lg):
-            for v,c in other._coeff.iteritems(): self._addterm(-c,v)
+            for v,c in iter(other._coeff.items()): self._addterm(-c,v)
 
         else: 
             raise NotImplementedError('in-place subtraction must '\
@@ -1328,7 +1381,7 @@ class _lin(object):
         if not l: raise ValueError('empty index set')
 
         f = _lin()
-        for v,c in self._coeff.iteritems():
+        for v,c in iter(self._coeff.items()):
             if c.size == (len(self), len(v)):  
                 f._coeff[v] = c[l,:]
 
@@ -1337,9 +1390,9 @@ class _lin(object):
 
             elif c.size == (1,1) and len(v) > 1:
                 # create a sparse matrix with 1.0 element in 
-                # position (k,l[k]) for k in xrange(len(l)) 
+                # position (k,l[k]) for k in range(len(l)) 
                 f._coeff[v] = spmatrix([], [], [], (len(l),len(v)), 'd')
-                f._coeff[v][[l[k]*len(l)+k for k in xrange(len(l))]] \
+                f._coeff[v][[l[k]*len(l)+k for k in range(len(l))]] \
                     = c[0]
 
             else:  # c is 1 by len(v)
@@ -1457,7 +1510,7 @@ class _minmax(object):
         if len(self._flist) == 1:
             s += '\n' + repr(self._flist[0])[1:-1]
         else:
-            for k in xrange(len(self._flist)):
+            for k in range(len(self._flist)):
                 s += "\nfunction %d: " %k + repr(self._flist[k])[1:-1]
         return s
 
@@ -1587,7 +1640,7 @@ def max(*s):
     Does not work with generators (Python 2.4).
     """
 
-    try: return __builtin__.max(*s)
+    try: return builtins.max(*s)
     except NotImplementedError:
         f = _function()
         try: 
@@ -1626,7 +1679,7 @@ def min(*s):
     Does not work with generators (Python 2.4).
     """
 
-    try: return __builtin__.min(*s)
+    try: return builtins.min(*s)
     except NotImplementedError:
         f = _function()
         try: 
@@ -1697,7 +1750,7 @@ class _sum_minmax(_minmax):
     def __str__(self):
 
         s = repr(self)[1:-1] 
-        for k in xrange(len(self._flist)):
+        for k in range(len(self._flist)):
             s += "\nfunction %d: " %k + repr(self._flist[k])[1:-1]
         return s
 
@@ -1958,7 +2011,7 @@ class constraint(object):
 
                 else:
                     # write as vector + f0[k] <= 0 for all k
-                    for k in xrange(len(f0)):
+                    for k in range(len(f0)):
                         c = faff + f0[k] <= 0
                         c.name = self.name + '(%d)' %k 
                         c, caux, newvars = c._aslinearineq()
@@ -1968,7 +2021,7 @@ class constraint(object):
 
             else:
                 # constraint of the form f = faff + max(f0,f1,...) <= 0
-                for k in xrange(len(cvxterms[0]._flist)):
+                for k in range(len(cvxterms[0]._flist)):
                     c = faff + cvxterms[0]._flist[k] <= 0
                     c.name = self.name + '(%d)' %k 
                     c, caux, newvars = c._aslinearineq()
@@ -1983,7 +2036,7 @@ class constraint(object):
 
             sumt = _function()
 
-            for k in xrange(len(cvxterms)):
+            for k in range(len(cvxterms)):
                 if type(cvxterms[k]) is _minmax:
                     # gk is max(f0,f1,...)
 
@@ -2005,7 +2058,7 @@ class constraint(object):
                     else:
                         # add constraint gk = max(f0,f1, ... ) <= tk
 
-                        for j in xrange(len(cvxterms[k]._flist)):
+                        for j in range(len(cvxterms[k]._flist)):
                             fj = cvxterms[k]._flist[j]
                             c = fj <= tk
                             c.name = self.name + '[%d](%d)' %(k,j)
@@ -2022,7 +2075,7 @@ class constraint(object):
                     sumt = sumt + sum(tk)
 
                     # add contraint max(f0,f1, ... ) <= tk
-                    for j in xrange(len(cvxterms[k]._flist)):
+                    for j in range(len(cvxterms[k]._flist)):
                         fj = cvxterms[k]._flist[j]
                         c = fj <= tk
                         c.name = self.name + '[%d](%d)' %(k,j)
@@ -2119,14 +2172,14 @@ class op(object):
 
         for c in self._inequalities:
             for v in c.variables():
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['i'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [c], 'e': []}
 
         for c in self._equalities:
             for v in c.variables():
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['e'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [], 'e': [c]}
@@ -2169,7 +2222,7 @@ class op(object):
 
             # update _variables
             for v in self.objective.variables():
-                if not self._variables.has_key(v):
+                if v not in self._variables:
                     self._variables[v] = {'o': True, 'i': [], 'e': []}
                 else:
                     self._variables[v]['o'] = True
@@ -2257,12 +2310,12 @@ class op(object):
         if c.type() == '=': self._equalities += [c]             
         for v in c.variables():
             if c.type() == '<':
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['i'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [c], 'e': []}
             else:
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['e'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [], 'e': [c]}
@@ -2366,7 +2419,7 @@ class op(object):
             newobj._constant = +objective._constant
             newobj._linear = +objective._linear
 
-            for k in xrange(len(objective._cvxterms)):
+            for k in range(len(objective._cvxterms)):
                 fk = objective._cvxterms[k]
                 
                 if type(fk) is _minmax:
@@ -2379,7 +2432,7 @@ class op(object):
 
                 aux_variables += [tk]
 
-                for j in xrange(len(fk._flist)):
+                for j in range(len(fk._flist)):
                     c = fk._flist[j] <= tk
                     if len(fk._flist) > 1:
                         c.name = self.name + '[%d](%d)' %(k,j)
@@ -2407,7 +2460,7 @@ class op(object):
             vslc[v] = slice(n, n+len(v))
             n += len(v)
         c = matrix(0.0, (1,n))
-        for v,cf in objective._linear._coeff.iteritems():
+        for v,cf in iter(objective._linear._coeff.items()):
             if _isscalar(cf): 
                 c[vslc[v]] = cf[0]
             elif _isdmatrix(cf):  
@@ -2443,7 +2496,7 @@ class op(object):
 
         for i in islc:
             lg = len(i)
-            for v,cf in i._f._linear._coeff.iteritems():
+            for v,cf in iter(i._f._linear._coeff.items()):
                 if cf.size == (lg, len(v)):
                     if _isspmatrix(cf) and _isdmatrix(G):
                         G[islc[i], vslc[v]] = matrix(cf, tc='d')
@@ -2479,7 +2532,7 @@ class op(object):
 
         for e in equalities:
             lg = len(e)
-            for v,cf in e._f._linear._coeff.iteritems():
+            for v,cf in iter(e._f._linear._coeff.items()):
                 if cf.size == (lg,len(v)):
                     if _isspmatrix(cf) and _isdmatrix(A):
                         A[eslc[e], vslc[v]] = matrix(cf, tc='d')
@@ -2580,8 +2633,8 @@ class op(object):
 
         self.status = sol['status']
         if type(t) is tuple:
-            for v,f in vmap.iteritems(): v.value = f.value()
-            for c,f in mmap.iteritems(): c.multiplier.value = f.value()
+            for v,f in iter(vmap.items()): v.value = f.value()
+            for c,f in iter(mmap.items()): c.multiplier.value = f.value()
          
 
 
@@ -2605,9 +2658,9 @@ class op(object):
 
         f.write('ROWS\n') 
         f.write(' N  %8s\n' %'cost')
-        for k in xrange(len(constraints)):
+        for k in range(len(constraints)):
             c = constraints[k]
-            for i in xrange(len(c)):
+            for i in range(len(c)):
                 if c._type == '<':
                     f.write(' L  ')
                 else:
@@ -2621,32 +2674,32 @@ class op(object):
                 f.write('\n')
 
         f.write('COLUMNS\n') 
-        for k in xrange(len(variables)):
+        for k in range(len(variables)):
             v = variables[k]
-            for i in xrange(len(v)):
+            for i in range(len(v)):
                 if v.name: 
                     varname = v.name
                 else:
                     varname = str(k)
                 varname = varname[:(7-len(str(i)))] + '_' + str(i)
 
-                if self.objective._linear._coeff.has_key(v):
+                if v in self.objective._linear._coeff:
                     cf = self.objective._linear._coeff[v]
                     if cf[i] != 0.0:
                         f.write(4*' ' + varname[:8].rjust(8))
                         f.write(2*' ' + '%8s' %'cost')
                         f.write(2*' ' + '% 7.5E\n' %cf[i])
 
-                for j in xrange(len(constraints)):
+                for j in range(len(constraints)):
                      c = constraints[j]
                      if c.name:
                          cname = c.name 
                      else:
                          cname = str(j) 
-                     if c._f._linear._coeff.has_key(v):
+                     if v in c._f._linear._coeff:
                          cf = c._f._linear._coeff[v]
                          if cf.size == (len(c),len(v)):
-                             nz = [k for k in xrange(cf.size[0]) 
+                             nz = [k for k in range(cf.size[0]) 
                                  if cf[k,i] != 0.0]
                              for l in nz:
                                  conname = cname[:(7-len(str(l)))] \
@@ -2656,7 +2709,7 @@ class op(object):
                                  f.write(2*' ' + '% 7.5E\n' %cf[l,i])
                          elif cf.size == (1,len(v)):
                              if cf[0,i] != 0.0:
-                                 for l in xrange(len(c)):
+                                 for l in range(len(c)):
                                      conname = cname[:(7-len(str(l)))] \
                                          + '_' + str(l)
                                      f.write(4*' ' + 
@@ -2673,14 +2726,14 @@ class op(object):
                                  f.write(2*' ' + '% 7.5E\n' %cf[0,0])
                         
         f.write('RHS\n') 
-        for j in xrange(len(constraints)):
+        for j in range(len(constraints)):
             c = constraints[j]
             if c.name:
                 cname = c.name 
             else:
                 cname = str(j) 
             const = -c._f._constant
-            for l in xrange(len(c)):
+            for l in range(len(c)):
                  conname = cname[:(7-len(str(l)))] + '_' + str(l)
                  f.write(14*' ' + conname[:8].rjust(8))
                  if const.size[0] == len(c):
@@ -2691,9 +2744,9 @@ class op(object):
         f.write('RANGES\n') 
 
         f.write('BOUNDS\n') 
-        for k in xrange(len(variables)):
+        for k in range(len(variables)):
             v = variables[k]
-            for i in xrange(len(v)):
+            for i in range(len(v)):
                 if v.name:
                     varname = v.name
                 else:
@@ -2731,7 +2784,7 @@ class op(object):
             if not s: 
                 raise SyntaxError("EOF reached before 'NAME' section "\
                     "was found")
-        self.name = strip(s[14:22])
+        self.name = s[14:22].strip()
 
         s = f.readline()
         while s[:4] != 'ROWS': 
@@ -2748,19 +2801,19 @@ class op(object):
         foundobj = False     # first occurrence of 'N' counts
         while s[:7] != 'COLUMNS': 
             if not s: raise SyntaxError("file has no 'COLUMNS' section")
-            if len(strip(s)) == 0 or s[0] == '*': 
+            if len(s.strip()) == 0 or s[0] == '*': 
                 pass
-            elif strip(s[1:3]) in ['E','L','G']:
-                rowlabel = strip(s[4:12])
+            elif s[1:3].strip() in ['E','L','G']:
+                rowlabel = s[4:12].strip()
                 functions[rowlabel] = _function()
-                rowtypes[rowlabel] = strip(s[1:3])
-            elif strip(s[1:3]) == 'N':
-                rowlabel = strip(s[4:12])
+                rowtypes[rowlabel] = s[1:3].strip()
+            elif s[1:3].strip() == 'N':
+                rowlabel = s[4:12].strip()
                 if not foundobj:
                     functions[rowlabel] = self.objective
                     foundobj = True
             else: 
-                raise ValueError("unknown row type '%s'" %strip(s[1:3]))
+                raise ValueError("unknown row type '%s'" %s[1:3].strip())
             s = f.readline()
         s = f.readline()
 
@@ -2771,21 +2824,21 @@ class op(object):
             if not s: 
                 raise SyntaxError("EOF reached before 'RHS' section "\
                     "was found")
-            if len(strip(s)) == 0 or s[0] == '*': 
+            if len(s.strip()) == 0 or s[0] == '*': 
                 pass
             else:
-                if strip(s[4:12]): collabel = strip(s[4:12])
-                if not variables.has_key(collabel):
+                if s[4:12].strip(): collabel = s[4:12].strip()
+                if collabel not in variables:
                     variables[collabel] = variable(1,collabel)
                 v = variables[collabel]
-                rowlabel = strip(s[14:22])
-                if not functions.has_key(rowlabel):
+                rowlabel = s[14:22].strip()
+                if rowlabel not in functions:
                     raise KeyError("no row label '%s'" %rowlabel)
                 functions[rowlabel]._linear._coeff[v] = \
                     matrix(float(s[24:36]), tc='d')
-                rowlabel = strip(s[39:47])
+                rowlabel = s[39:47].strip()
                 if rowlabel:
-                    if not functions.has_key(rowlabel):
+                    if rowlabel not in functions:
                         raise KeyError("no row label '%s'" %rowlabel)
                     functions[rowlabel]._linear._coeff[v] =  \
                         matrix(float(s[49:61]), tc='d')
@@ -2803,23 +2856,23 @@ class op(object):
             s[:6] != 'ENDATA':
             if not s: raise SyntaxError( \
                  "EOF reached before 'ENDATA' was found")
-            if len(strip(s)) == 0 or s[0] == '*': 
+            if len(s.strip()) == 0 or s[0] == '*': 
                 pass
             else:
-                if None != rhslabel != strip(s[4:12]):
+                if None != rhslabel != s[4:12].strip():
                     # skip if rhslabel is different from 1st rhs label
                     # encountered
                     pass  
                 else:
-                    if rhslabel is None: rhslabel = strip(s[4:12])
-                    rowlabel = strip(s[14:22])
-                    if not functions.has_key(rowlabel):
+                    if rhslabel is None: rhslabel = s[4:12].strip()
+                    rowlabel = s[14:22].strip()
+                    if rowlabel not in functions:
                         raise KeyError("no row label '%s'" %rowlabel)
                     functions[rowlabel]._constant = \
                         matrix(-float(s[24:36]), tc='d')
-                    rowlabel = strip(s[39:47])
+                    rowlabel = s[39:47].strip()
                     if rowlabel:
-                        if not functions.has_key(rowlabel):
+                        if rowlabel not in functions:
                             raise KeyError("no row label '%s'" \
                                 %rowlabel)
                         functions[rowlabel]._constant = \
@@ -2833,7 +2886,7 @@ class op(object):
         # We read in only one vector, the one with the first range label
         # encountered.
         ranges = dict()
-        for l in rowtypes.iterkeys(): 
+        for l in iter(rowtypes.keys()): 
             ranges[l] = None   # {rowlabel: range value}
         rangeslabel = None
         if s[:6] == 'RANGES':
@@ -2841,21 +2894,21 @@ class op(object):
             while s[:6] != 'BOUNDS' and s[:6] != 'ENDATA':
                 if not s: raise SyntaxError( \
                     "EOF reached before 'ENDATA' was found")
-                if len(strip(s)) == 0 or s[0] == '*': 
+                if len(s.strip()) == 0 or s[0] == '*': 
                     pass
                 else:
-                    if None != rangeslabel != strip(s[4:12]):
+                    if None != rangeslabel != s[4:12].strip():
                         pass  
                     else:
                         if rangeslabel == None: 
-                            rangeslabel = strip(s[4:12])
-                        rowlabel = strip(s[14:22])
-                        if not rowtypes.has_key(rowlabel):
+                            rangeslabel = s[4:12].strip()
+                        rowlabel = s[14:22].strip()
+                        if rowlabel not in rowtypes:
                             raise KeyError("no row label '%s'"%rowlabel)
                         ranges[rowlabel] = float(s[24:36])
-                        rowlabel = strip(s[39:47])
+                        rowlabel = s[39:47].strip()
                         if rowlabel != '':
-                            if not functions.has_key(rowlabel):
+                            if rowlabel not in functions:
                                 raise KeyError("no row label '%s'" \
                                     %rowlabel)
                             ranges[rowlabel] =  float(s[49:61])
@@ -2869,62 +2922,62 @@ class op(object):
         # label encountered.
         boundslabel = None
         bounds = dict()
-        for v in variables.iterkeys():  
+        for v in iter(variables.keys()):  
             bounds[v] = [0.0, None] #{column label: [l.bound, u. bound]}
         if s[:6] == 'BOUNDS':
             s = f.readline()
             while s[:6] != 'ENDATA':
                 if not s: raise SyntaxError( \
                     "EOF reached before 'ENDATA' was found")
-                if len(strip(s)) == 0 or s[0] == '*': 
+                if len(s.strip()) == 0 or s[0] == '*': 
                     pass
                 else:
-                    if None != boundslabel != strip(s[4:12]):
+                    if None != boundslabel != s[4:12].strip():
                         pass  
                     else:
                         if boundslabel is None: 
-                            boundslabel = strip(s[4:12])
-                        collabel = strip(s[14:22])
-                        if not variables.has_key(collabel):
+                            boundslabel = s[4:12].strip()
+                        collabel = s[14:22].strip()
+                        if collabel not in variables:
                             raise ValueError('unknown column label ' \
                                 + "'%s'" %collabel)
-                        if strip(s[1:3]) == 'LO': 
+                        if s[1:3].strip() == 'LO': 
                             if bounds[collabel][0] != 0.0:
                                 raise ValueError("repeated lower "\
                                     "bound for variable '%s'" %collabel)
                             bounds[collabel][0] = float(s[24:36])
-                        elif strip(s[1:3]) == 'UP': 
+                        elif s[1:3].strip() == 'UP': 
                             if bounds[collabel][1] != None:
                                 raise ValueError("repeated upper "\
                                     "bound for variable '%s'" %collabel)
                             bounds[collabel][1] = float(s[24:36])
-                        elif strip(s[1:3]) == 'FX': 
+                        elif s[1:3].strip() == 'FX': 
                             if bounds[collabel] != [0, None]:
                                 raise ValueError("repeated bounds "\
                                     "for variable '%s'" %collabel)
                             bounds[collabel][0] = float(s[24:36])
                             bounds[collabel][1] = float(s[24:36])
-                        elif strip(s[1:3]) == 'FR': 
+                        elif s[1:3].strip() == 'FR': 
                             if bounds[collabel] != [0, None]:
                                 raise ValueError("repeated bounds "\
                                     "for variable '%s'" %collabel)
                             bounds[collabel][0] = None
                             bounds[collabel][1] = None
-                        elif strip(s[1:3]) == 'MI': 
+                        elif s[1:3].strip() == 'MI': 
                             if bounds[collabel][0] != 0.0:
                                 raise ValueError("repeated lower " \
                                     "bound for variable '%s'" %collabel)
                             bounds[collabel][0] = None
-                        elif strip(s[1:3]) == 'PL': 
+                        elif s[1:3].strip() == 'PL': 
                             if bounds[collabel][1] != None:
                                 raise ValueError("repeated upper " \
                                     "bound for variable '%s'" %collabel)
                         else:
                             raise ValueError("unknown bound type '%s'"\
-                                %strip(s[1:3]))
+                                %s[1:3].strip())
                 s = f.readline()
 
-        for l, type in rowtypes.iteritems():
+        for l, type in iter(rowtypes.items()):
 
             if type == 'L':   
                 c = functions[l] <= 0.0
@@ -2962,7 +3015,7 @@ class op(object):
                     c.name = l + '_lb'
                     self._inequalities += [c]
 
-        for l,bnds in bounds.iteritems():
+        for l,bnds in iter(bounds.items()):
             v = variables[l]
             if None != bnds[0] != bnds[1]:
                 c = v >= bnds[0]
@@ -2996,13 +3049,13 @@ class op(object):
             self._variables[v] = {'o': True, 'i': [], 'e': []}
         for c in self._inequalities:
             for v in c._f._linear._coeff.keys():
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['i'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [c], 'e': []}
         for c in self._equalities:
             for v in c._f._linear._coeff.keys():
-                if self._variables.has_key(v):
+                if v in self._variables:
                     self._variables[v]['e'] += [c]
                 else:
                     self._variables[v] = {'o': False, 'i': [], 'e': [c]}
@@ -3104,13 +3157,13 @@ def _keytolist(key,n):
         l = [k for k in key if -n <= k < n]
         if len(l) != len(key):
             raise IndexError('variable index out of range')
-        for i in xrange(len(l)): 
+        for i in range(len(l)): 
             if l[i] < 0: l[i] += n
         
     elif type(key) is slice:
             
         ind = key.indices(n)
-        l = range(ind[0],ind[1],ind[2])
+        l = list(range(ind[0],ind[1],ind[2]))
 
     else: 
         raise TypeError('invalid key')
@@ -3128,7 +3181,7 @@ class varlist(list):
 
     def __contains__(self,item):
             
-        for k in xrange(len(self)): 
+        for k in range(len(self)): 
             if self[k] is item: return True
         return False
 
@@ -3172,7 +3225,7 @@ def _vecmax(*s):
             val = matrix([max(c[0],x) for x in val], tc='d')
 
         elif len(val) == len(c):
-            val = matrix( [max(val[k],c[k]) for k in xrange(len(c))], 
+            val = matrix( [max(val[k],c[k]) for k in range(len(c))], 
                 tc='d' )
     
         else: 
@@ -3220,7 +3273,7 @@ def _vecmin(*s):
             val = matrix( [min(c[0],x) for x in val], tc='d' )
 
         elif len(val) == len(c):
-            val = matrix( [min(val[k],c[k]) for k in xrange(len(c))], 
+            val = matrix( [min(val[k],c[k]) for k in range(len(c))], 
                 tc='d' )
     
         else: 
diff --git a/src/python/msk.py b/src/python/msk.py
index e324a59..6773ccc 100644
--- a/src/python/msk.py
+++ b/src/python/msk.py
@@ -2,10 +2,10 @@
 CVXOPT interface for MOSEK 6.0
 """
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -348,7 +348,7 @@ def conelp(c, G, h, dims = None):
 
     task.putobjsense(mosek.objsense.maximize)
 
-    for k in xrange(len(mq)):
+    for k in range(len(mq)):
         task.appendcone(mosek.conetype.quad, 0.0, 
                         array(range(ml+sum(mq[:k]),ml+sum(mq[:k+1]))))
     task.optimize()
@@ -455,7 +455,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None):
         raise TypeError("'Gq' must be a list of sparse or dense 'd' "\
             "matrices with %d columns" %n)
     mq = [ G.size[0] for G in Gq ]
-    a = [ k for k in xrange(len(mq)) if mq[k] == 0 ] 
+    a = [ k for k in range(len(mq)) if mq[k] == 0 ] 
     if a: raise TypeError("the number of rows of Gq[%d] is zero" %a[0])
     if hq is None: hq = []
     if type(hq) is not list or len(hq) != len(mq) or [ h for h in hq if
@@ -463,7 +463,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None):
         h.typecode != 'd' ]: 
             raise TypeError("'hq' must be a list of %d dense or sparse "\
                 "'d' matrices" %len(mq))
-    a = [ k for k in xrange(len(mq)) if hq[k].size != (mq[k], 1) ]
+    a = [ k for k in range(len(mq)) if hq[k].size != (mq[k], 1) ]
     if a:
         k = a[0]
         raise TypeError("'hq[%d]' has size (%d,%d).  Expected size "\
@@ -478,7 +478,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None):
     h[:ml] = hl
     G[:ml,:] = Gl
     ind = ml
-    for k in xrange(len(mq)):
+    for k in range(len(mq)):
         h[ind : ind + mq[k]] = hq[k]
         G[ind : ind + mq[k], :] = Gq[k]
         ind += mq[k]
@@ -527,7 +527,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None):
 
     task.putobjsense(mosek.objsense.maximize)
 
-    for k in xrange(len(mq)):
+    for k in range(len(mq)):
         task.appendcone(mosek.conetype.quad, 0.0, 
                         array(range(ml+sum(mq[:k]),ml+sum(mq[:k+1]))))
     task.optimize()
@@ -542,7 +542,7 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None):
     task.getsolutionslice(mosek.soltype.itr, mosek.solitem.xx, ml, N, zq) 
     x = matrix(xu-xl)
 
-    zq = [ matrix(zq[sum(mq[:k]):sum(mq[:k+1])]) for k in xrange(len(mq)) ]
+    zq = [ matrix(zq[sum(mq[:k]):sum(mq[:k+1])]) for k in range(len(mq)) ]
     
     if ml:
         zl = zeros(ml, float)
@@ -680,7 +680,7 @@ def qp(P, q, G=None, h=None, A=None, b=None):
 
     Ps = sparse(P)
     I, J = Ps.I, Ps.J
-    tril = [ k for k in xrange(len(I)) if I[k] >= J[k] ]
+    tril = [ k for k in range(len(I)) if I[k] >= J[k] ]
     task.putqobj(array(I[tril]), array(J[tril]), array(Ps.V[tril]))
     
     task.putobjsense(mosek.objsense.minimize)
diff --git a/src/python/printing.py b/src/python/printing.py
index 29cb462..78d3e6c 100644
--- a/src/python/printing.py
+++ b/src/python/printing.py
@@ -1,7 +1,7 @@
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -23,9 +23,8 @@ options = {'dformat' : '% .2e',
 
 def matrix_str_default(X):
 
-    from sys import maxint
-    from string import rjust, center
-    from printing import options
+    from sys import maxsize
+    from cvxopt.printing import options
 
     width, height = options['width'], options['height']
     iformat, dformat = options['iformat'], options['dformat']
@@ -37,8 +36,8 @@ def matrix_str_default(X):
 
     s = ""
     m, n   = X.size
-    if width < 0: width = maxint
-    if height < 0: height = maxint
+    if width < 0: width = maxsize
+    if height < 0: height = maxsize
 
     if width*height is 0: return ""
     if len(X) is 0: return ""
@@ -59,10 +58,10 @@ def matrix_str_default(X):
         for j in clist:
 
             if X.typecode == 'z':
-                s += rjust(fmt % X[i,j].real + sgn[X[i,j].imag>0] + 'j' + \
-                               (fmt % abs(X[i,j].imag)).lstrip(),twidth) 
+                s += format(fmt % X[i,j].real + sgn[X[i,j].imag>0] + 'j' +\
+                          (fmt % abs(X[i,j].imag)).lstrip(), '>%i' %twidth)
             else:
-                s += rjust(fmt % X[i,j],twidth)
+                s += format(fmt % X[i,j], '>%i' %twidth)
 
             s += ' '
         
@@ -82,9 +81,8 @@ def matrix_repr_default(X):
 
 def spmatrix_str_default(X):
 
-    from sys import maxint
-    from string import rjust, center
-    from printing import options
+    from sys import maxsize
+    from cvxopt.printing import options
 
     width, height = options['width'], options['height']
     iformat, dformat = options['iformat'], options['dformat']
@@ -96,17 +94,16 @@ def spmatrix_str_default(X):
 
     s = ""
     m, n   = X.size
-    if width < 0: width = maxint
-    if height < 0: height = maxint
+    if width < 0: width = maxsize
+    if height < 0: height = maxsize
 
     if width*height is 0: return ""
  
-    rlist = xrange(0,min(m,height))
-    clist = xrange(0,min(n,width))
+    rlist = range(0,min(m,height))
+    clist = range(0,min(n,width))
 
     Xr = X[:min(m,height),:min(n,width)]
-    Idx = zip(*(Xr.I,Xr.J))
-    Zero = '0'
+    Idx = list(zip(*(Xr.I,Xr.J)))
     
     if len(Idx) > 0:
         if X.typecode == 'z':
@@ -116,7 +113,7 @@ def spmatrix_str_default(X):
         else:
             twidth = max([ len(fmt % X[i,j]) for i in rlist for j in clist ])
     else:
-        twidth = len(Zero)
+        twidth = 1
 
     for i in rlist:
         s += '['
@@ -125,12 +122,12 @@ def spmatrix_str_default(X):
 
             if (i,j) in Idx:
                 if X.typecode == 'z':
-                    s += rjust(fmt % X[i,j].real + sgn[X[i,j].imag>0] + 'j' + \
-                                   (fmt % abs(X[i,j].imag)).lstrip(),twidth)
+                    s +=  format(fmt % X[i,j].real + sgn[X[i,j].imag>0] + 'j' + \
+                                 (fmt % abs(X[i,j].imag)).lstrip(), '>%i' %twidth)
                 else:
-                    s += rjust(fmt % X[i,j],twidth)
+                    s += format(fmt % X[i,j], '>%i' %twidth)
             else: 
-                s += center(Zero, twidth)
+                s += format(0, '^%i' %twidth)
                 
             s += ' '
         
@@ -138,7 +135,7 @@ def spmatrix_str_default(X):
         else: s = s[:-1] + "]\n"
            
     if height < m: 
-        s += "[" + min(n,width)*(center(':',twidth)+' ')
+        s += "[" + min(n,width)*(format(':', '^%i' %twidth)+' ')
 
         if width < n: s += '   ]\n'
         else: s = s[:-1] + ']\n'
@@ -148,8 +145,7 @@ def spmatrix_str_default(X):
 
 def spmatrix_str_triplet(X):
 
-    from string import rjust
-    from printing import options
+    from cvxopt.printing import options
 
     iformat, dformat = options['iformat'], options['dformat']
 
@@ -174,17 +170,17 @@ def spmatrix_str_triplet(X):
     else:
         twidth = 0 
 
-    for k in xrange(len(X)):
+    for k in range(len(X)):
         s += "(" 
-        s += rjust(str(X.I[k]),imax) + "," + rjust(str(X.J[k]),jmax) 
+        s += format(X.I[k], '>%i' %imax)  + "," + \
+            format(X.J[k], '>%i' %jmax) 
         s += ") "
 
-        if X.typecode is 'z':
-            s += rjust(fmt % X.V[k].real + sgn[X.V[k].imag>0] + 'j' + \
-                           (fmt % abs(X.V[k].imag)).lstrip(),twidth)
+        if X.typecode=='z':
+            s +=  format(fmt % X.V[k].real + sgn[X.V[k].imag>0] + 'j' + \
+                         (fmt % abs(X.V[k].imag)).lstrip(), '>%i' %twidth)
         else:
-            s += rjust(fmt % X.V[k],twidth)
-        
+            s += format(fmt % X.V[k], '>%i' %twidth)
         s += "\n"
                 
     return s
diff --git a/src/python/solvers.py b/src/python/solvers.py
index aefc2a6..38b8326 100644
--- a/src/python/solvers.py
+++ b/src/python/solvers.py
@@ -13,10 +13,10 @@ socp:     solves second-order cone programs.
 options:  dictionary with customizable algorithm parameters.
 """
 
-# Copyright 2010 L. Vandenberghe.
+# Copyright 2010-2011 L. Vandenberghe.
 # Copyright 2004-2009 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 1.1.3.
+# This file is part of CVXOPT version 1.1.4.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/setup.py b/src/setup.py
index 4704b39..d231863 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -114,7 +114,7 @@ umfpack = Extension('umfpack',
 
 # Build for int or long? 
 import sys
-if sys.maxint > 2**31: MACROS += [('DLONG','')]
+if sys.maxsize > 2**31: MACROS += [('DLONG','')]
 
 cholmod = Extension('cholmod',
     library_dirs = [ ATLAS_LIB_DIR ],
@@ -148,7 +148,7 @@ extmods += [base, blas, lapack, umfpack, cholmod, amd, misc_solvers]
 
 setup (name = 'cvxopt', 
     description = 'Convex optimization package',
-    version = '1.1.3', 
+    version = '1.1.4', 
     long_description = '''
 CVXOPT is a free software package for convex optimization based on the 
 Python programming language. It can be used with the interactive Python 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/cvxopt.git



More information about the debian-science-commits mailing list