[cvxopt] 08/64: Imported Upstream version 0.9.1

Andreas Tille tille at debian.org
Wed Jul 20 11:23:48 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 18b4afea6908f74dccb6e259daebafe599a8a749
Author: Andreas Tille <tille at debian.org>
Date:   Wed Jul 20 08:26:50 2016 +0200

    Imported Upstream version 0.9.1
---
 INSTALL                                            |   52 +-
 LICENSE                                            |   38 +-
 doc/.latex2html-init                               |  198 --
 doc/Makefile                                       |   17 +-
 doc/base.tex                                       |   76 +-
 doc/base_sparse.tex                                |   71 +-
 doc/blas.tex                                       |  126 +-
 doc/c-api.tex                                      |    2 +-
 doc/coneprog.tex                                   |  105 +-
 doc/cvxopt.tex                                     |   76 +-
 doc/cvxopt/WARNINGS                                |    1 -
 doc/cvxopt/cvxopt.css                              |   38 -
 doc/cvxopt/images.aux                              |    1 -
 doc/cvxopt/images.log                              | 1281 ---------
 doc/cvxopt/images.pl                               | 1932 -------------
 doc/cvxopt/images.tex                              | 2523 -----------------
 doc/cvxopt/internals.pl                            |  218 --
 doc/cvxopt/labels.pl                               |  437 ---
 doc/fftw.tex                                       |    3 +-
 doc/intro.tex                                      |    8 +-
 doc/lapack.tex                                     |  293 +-
 doc/modeling.tex                                   |   33 +-
 doc/solvers.tex                                    |  719 +++--
 doc/spsolvers.tex                                  |   72 +-
 examples/book/README                               |    2 +-
 examples/book/chap4/portfolio                      |    8 +-
 examples/book/chap4/rls                            |    2 +-
 examples/book/chap6/basispursuit                   |   83 +-
 examples/book/chap6/consumerpref                   |   14 +-
 examples/book/chap6/old/README                     |    2 -
 examples/book/chap6/old/smoothrec                  |   91 -
 examples/book/chap6/old/smoothrec_new              |  102 -
 examples/book/chap6/old/tv                         |  293 --
 examples/book/chap6/old/tv_new                     |  291 --
 examples/book/chap6/penalties                      |    7 +-
 examples/book/chap6/regsel                         |    4 +-
 examples/book/chap6/smoothrec                      |    2 +-
 examples/book/chap6/tv                             |   60 +-
 examples/book/chap7/expdesign                      |   20 +-
 examples/book/chap7/logreg                         |    4 +-
 examples/book/chap7/maxent                         |    8 +-
 examples/book/chap7/probbounds                     |    6 +-
 examples/book/chap8/centers                        |   12 +-
 examples/book/chap8/ellipsoids                     |    8 +-
 examples/book/chap8/floorplan                      |   27 +-
 examples/book/chap8/linsep                         |   10 +-
 examples/book/chap8/placement                      |    6 +-
 examples/doc/chap10/l1svc                          |   19 +
 examples/doc/chap10/lp                             |   36 +
 examples/doc/{ => chap10}/normappr                 |    2 +-
 examples/doc/chap10/roblp                          |   21 +
 examples/doc/{ => chap4}/acent                     |    0
 examples/doc/{ => chap7}/covsel                    |    0
 examples/doc/{ => chap7}/covsel.bin                |    0
 examples/doc/{ => chap8}/l1                        |    4 +-
 examples/doc/chap8/lp                              |   11 +
 examples/doc/{ => chap8}/mcsdp                     |    0
 examples/doc/{ => chap8}/qcl1                      |    0
 examples/doc/chap8/sdp                             |   19 +
 examples/doc/chap8/socp                            |   14 +
 examples/doc/chap9/acent                           |   45 +
 examples/doc/chap9/acent2                          |   27 +
 examples/doc/chap9/floorplan                       |  186 ++
 examples/doc/chap9/gp                              |   22 +
 examples/doc/chap9/l1regls                         |  155 ++
 examples/{book/chap4 => doc/chap9}/portfolio       |   11 +-
 examples/doc/chap9/robls                           |   58 +
 src/C/SuiteSparse/CHOLMOD/Check/cholmod_write.c    |   18 +-
 .../CHOLMOD/Cholesky/cholmod_resymbol.c            |    9 +-
 .../CHOLMOD/Cholesky/cholmod_rowcolcounts.c        |    4 +-
 .../SuiteSparse/CHOLMOD/Cholesky/cholmod_rowfac.c  |    4 +-
 .../SuiteSparse/CHOLMOD/Cholesky/cholmod_spsolve.c |   56 +-
 .../CHOLMOD/Cholesky/t_cholmod_rowfac.c            |    4 +-
 src/C/SuiteSparse/CHOLMOD/Core/cholmod_aat.c       |    4 +-
 src/C/SuiteSparse/CHOLMOD/Core/cholmod_add.c       |    8 +-
 src/C/SuiteSparse/CHOLMOD/Core/cholmod_common.c    |    2 +-
 src/C/SuiteSparse/CHOLMOD/Core/cholmod_factor.c    |    2 +-
 src/C/SuiteSparse/CHOLMOD/Core/cholmod_memory.c    |    2 -
 src/C/SuiteSparse/CHOLMOD/Doc/ChangeLog            |   25 +
 src/C/SuiteSparse/CHOLMOD/Doc/UserGuide.tex        |    2 +-
 src/C/SuiteSparse/CHOLMOD/Include/cholmod_blas.h   |    2 +-
 src/C/SuiteSparse/CHOLMOD/Include/cholmod_core.h   |   15 +-
 .../SuiteSparse/CHOLMOD/Include/cholmod_internal.h |   17 +-
 src/C/SuiteSparse/CHOLMOD/README.txt               |   15 +-
 .../CHOLMOD/Supernodal/cholmod_super_numeric.c     |    3 +-
 .../CHOLMOD/Supernodal/cholmod_super_symbolic.c    |   10 +-
 src/C/SuiteSparse/COLAMD/Demo/colamd_example.out   |    4 +-
 src/C/SuiteSparse/COLAMD/Demo/colamd_l_example.out |    4 +-
 src/C/SuiteSparse/COLAMD/Include/colamd.h          |    4 +-
 src/C/SuiteSparse/COLAMD/MATLAB/Contents.m         |   19 -
 src/C/SuiteSparse/COLAMD/MATLAB/Makefile           |   35 -
 src/C/SuiteSparse/COLAMD/MATLAB/colamd2.m          |   87 -
 src/C/SuiteSparse/COLAMD/MATLAB/colamd_demo.m      |  179 --
 src/C/SuiteSparse/COLAMD/MATLAB/colamd_install.m   |   18 -
 src/C/SuiteSparse/COLAMD/MATLAB/colamd_make.m      |   29 -
 src/C/SuiteSparse/COLAMD/MATLAB/colamd_test.m      |  511 ----
 src/C/SuiteSparse/COLAMD/MATLAB/colamdmex.c        |  220 --
 src/C/SuiteSparse/COLAMD/MATLAB/colamdtestmex.c    |  577 ----
 src/C/SuiteSparse/COLAMD/MATLAB/luflops.m          |   34 -
 src/C/SuiteSparse/COLAMD/MATLAB/symamd2.m          |   86 -
 src/C/SuiteSparse/COLAMD/MATLAB/symamdmex.c        |  201 --
 src/C/SuiteSparse/COLAMD/MATLAB/symamdtestmex.c    |  543 ----
 src/C/SuiteSparse/Contents.m                       |   10 +-
 src/C/SuiteSparse/Makefile                         |   15 +-
 src/C/SuiteSparse/README.txt                       |   84 +-
 src/C/SuiteSparse/README_cvxopt                    |   12 +-
 src/C/SuiteSparse/SuiteSparse_demo.m               |  113 -
 src/C/SuiteSparse/UFconfig/README.txt              |   10 +-
 src/C/SuiteSparse/UFconfig/UFconfig.h              |   32 +-
 src/C/SuiteSparse/UFconfig/UFconfig.mk             |   16 +-
 src/C/SuiteSparse/UMFPACK/Doc/ChangeLog            |   11 +
 src/C/SuiteSparse/UMFPACK/Doc/License              |   12 +-
 src/C/SuiteSparse/UMFPACK/Doc/QuickStart.tex       |   10 +-
 src/C/SuiteSparse/UMFPACK/Doc/UserGuide.stex       |   49 +-
 src/C/SuiteSparse/UMFPACK/Doc/gpl.txt              |  340 +++
 src/C/SuiteSparse/UMFPACK/Doc/lesser.txt           |  504 ----
 src/C/SuiteSparse/UMFPACK/Include/umfpack.h        |   16 +-
 src/C/SuiteSparse/UMFPACK/Makefile                 |    5 +
 src/C/SuiteSparse/UMFPACK/README.txt               |   14 +-
 src/C/SuiteSparse/UMFPACK/Source/cholmod_blas.h    |    4 +-
 src/C/SuiteSparse/UMFPACK/Source/umf_2by2.c        |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_analyze.c     |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_apply_order.c |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_assemble.c    |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_blas3_update.c  |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_build_tuples.c  |    1 +
 .../UMFPACK/Source/umf_create_element.c            |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_extend_front.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_free.c        |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_fsize.c       |    1 +
 .../UMFPACK/Source/umf_garbage_collection.c        |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_get_memory.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_grow_front.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_init_front.c  |    1 +
 .../UMFPACK/Source/umf_is_permutation.c            |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_kernel.c      |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_kernel_init.c |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_kernel_wrapup.c |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_local_search.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_lsolve.c      |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_ltsolve.c     |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_malloc.c      |    1 +
 .../UMFPACK/Source/umf_mem_alloc_element.c         |    1 +
 .../UMFPACK/Source/umf_mem_alloc_head_block.c      |    1 +
 .../UMFPACK/Source/umf_mem_alloc_tail_block.c      |    1 +
 .../UMFPACK/Source/umf_mem_free_tail_block.c       |    1 +
 .../UMFPACK/Source/umf_mem_init_memoryspace.c      |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_realloc.c     |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_report_perm.c |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_report_vector.c |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_scale.c       |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_scale_column.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_set_stats.c   |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_singletons.c  |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_solve.c       |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_start_front.c |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_store_lu.c    |    1 +
 .../UMFPACK/Source/umf_symbolic_usage.c            |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_transpose.c   |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_triplet.c     |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_tuple_lengths.c |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_usolve.c      |    1 +
 src/C/SuiteSparse/UMFPACK/Source/umf_utsolve.c     |    1 +
 .../SuiteSparse/UMFPACK/Source/umf_valid_numeric.c |    1 +
 .../UMFPACK/Source/umf_valid_symbolic.c            |    1 +
 .../UMFPACK/Source/umfpack_load_numeric.c          |    2 +-
 .../UMFPACK/Source/umfpack_load_symbolic.c         |    2 +-
 .../UMFPACK/Source/umfpack_save_numeric.c          |    2 +-
 .../UMFPACK/Source/umfpack_save_symbolic.c         |    2 +-
 src/C/SuiteSparse/UMFPACK/Source/umfpack_timer.c   |    2 +
 src/C/amd.c                                        |    2 +-
 src/C/base.c                                       |  137 +-
 src/C/blas.c                                       |    6 +-
 src/C/cholmod.c                                    |    2 +-
 src/C/cvxopt.h                                     |    4 +-
 src/C/dense.c                                      |    6 +-
 src/C/dsdp.c                                       |    2 +-
 src/C/fftw.c                                       |    2 +-
 src/C/glpk.c                                       |    2 +-
 src/C/lapack.c                                     |    2 +-
 src/C/misc.h                                       |    2 +-
 src/C/mosek.c                                      |  792 ------
 src/C/random.c                                     |  132 +-
 src/C/rngs/README.cvxopt                           |    3 -
 src/C/rngs/rngs.c                                  |  179 --
 src/C/rngs/rngs.h                                  |   19 -
 src/C/rngs/rvgs.c                                  |  218 --
 src/C/rngs/rvgs.h                                  |   28 -
 src/C/sparse.c                                     |  183 +-
 src/C/umfpack.c                                    |    2 +-
 src/python/__init__.py                             |    4 +-
 src/python/coneprog.py                             |  124 +-
 src/python/cvxprog.py                              | 2865 ++++++++++++++++----
 src/python/info.py                                 |   47 +-
 src/python/misc.py                                 |  914 ++++---
 src/python/modeling.py                             |    2 +-
 src/python/mosek.py                                |  706 +++++
 src/python/solvers.py                              |   24 +-
 src/setup.py                                       |   56 +-
 199 files changed, 6466 insertions(+), 14076 deletions(-)

diff --git a/INSTALL b/INSTALL
index 73352f8..ed21677 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-Installation instructions for CVXOPT Version 0.9.
+Installation instructions for CVXOPT Version 0.9.1.
 
 The package requires version 2.3 or newer of Python, and is built 
 from source, so the header files and libraries for Python must be 
@@ -11,15 +11,17 @@ Both header files and libraries must be installed.
 
 The following software libraries are optional.  
 
-1) FFTW (www.fftw.org) is a C library for discrete Fourier transforms.
+1) The GNU Scientific Library GSL (www.gnu.org/software/gsl).
 
-1) GLPK (www.gnu.org/software/glpk/glpk.html) is a linear programming 
+2) FFTW (www.fftw.org) is a C library for discrete Fourier transforms.
+
+3) GLPK (www.gnu.org/software/glpk/glpk.html) is a linear programming 
 package.  
 
-2) MOSEK version 4 (www.mosek.com) is a commercial library of convex 
+4) MOSEK version 5 (www.mosek.com) is a commercial library of convex 
 optimization solvers.  
 
-3) DSDP5.8 (www-unix.mcs.anl.gov/DSDP) is a semidefinite programming
+5) DSDP5.8 (www-unix.mcs.anl.gov/DSDP) is a semidefinite programming
 solver. 
 
 
@@ -27,23 +29,31 @@ Configuration script:
 ---------------------
 Edit src/setup.py and update the following variables:
 
-- ATLAS_LIB_DIR: the directory containing the lapack and blas libraries
+- ATLAS_LIB_DIR: the directory containing the lapack and blas libraries.
+
+- BUILD_GSL: set this variableto 1 to install the cvxopt.random module,
+  which is based on the random number generators of the GSL library. 
+- GSL_LIB_DIR: the directory containing the libgsl.
+- GSL_iNC_DIR: the directory containing the GSL header files. 
 
-- BUILD_FFTW: set this variable to 1 to enable FFTW support
-- FFTW_LIB_DIR: the directory containing the libfftw3
-- FFTW_INC_DIR: the directory containing fftw.h
+- BUILD_FFTW: set this variable to 1 to install the cvxopt.fftw module,
+  which is an interface to FFTW.
+- FFTW_LIB_DIR: the directory containing the libfftw3.
+- FFTW_INC_DIR: the directory containing fftw.h.
 
-- BUILD_GLPK: set this variable to 1 to enable GLPK support
-- GLPK_LIB_DIR: the directory containing libglpk
-- GLPK_INC_DIR: the directory containing glpk.h 
+- BUILD_GLPK: set this variable to 1 to enable support for the linear
+  programming solver in GLPK.  
+- GLPK_LIB_DIR: the directory containing libglpk.
+- GLPK_INC_DIR: the directory containing glpk.h. 
 
-- BUILD_MOSEK: set this variable to 1 to enable MOSEK support
-- MOSEK_LIB_DIR: the directory containing libmosek
-- MOSEK_INC_DIR: the directory containing mosek.h
+- BUILD_DSDP: set this variable to 1 to enable support for the semidefinite
+  programming solver in DSDP.
+- DSDP_LIB_DIR: the directory containing libdsdp.
+- DSDP_INC_DIR: the directory containing dsdp5.h.
 
-- BUILD_DSDP: set this variable to 1 to enable DSDP support
-- DSDP_LIB_DIR: the directory containing libdsdp
-- DSDP_INC_DIR: the directory containing dsdp5.h
+Support for the linear, second-order cone, and quadratic programming 
+solvers in MOSEK is automatically enabled if the MOSEK Python interface
+pymosek.so is found in the user's PYTHONPATH.
 
 
 Compilation:
@@ -60,7 +70,7 @@ It can also be installed locally in the home directory by typing:
 This will install the libraries in /home/username/lib/python. In this
 case PYTHONPATH must be updated, e.g., under Bash write
 
-    export PYTHONPATH=$PYTHONPATH:/home/username/lib/python
+    export PYTHONPATH = $PYTHONPATH:/home/username/lib/python
 
 
 Test it:
@@ -68,7 +78,7 @@ Test it:
 To test that the installation was successful, go to the examples
 directory and try one of the examples, for example,
 
-    $ cd examples/doc
-    $ python acent
+    $ cd examples/doc/chap8
+    $ python lp
 
 If Python does not issue an error message installation was successful.
diff --git a/LICENSE b/LICENSE
index ebaf7d6..e7fda90 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-CVXOPT version 0.9.  Copyright (c) 2004-2007 J. Dahl and L. Vandenberghe.
+CVXOPT version 0.9.1.  Copyright (c) 2004-2007 J. Dahl and L. Vandenberghe.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -14,30 +14,24 @@ A copy of the GNU General Public License is included below.
 For further information, see <http://www.gnu.org/licenses/>.
 ---------------------------------------------------------------------------
 
-The CVXOPT distribution includes source code for the following software 
-libraries. 
+The CVXOPT distribution includes source code for a subset of the 
+SuiteSparse suite of sparse matrix algorithms, including:
 
-1. Part of the SuiteSparse suite of sparse matrix algorithms, including:
-   - AMD Version 2.1. Copyright (c) 2007 by Timothy A. Davis, Patrick R. 
-     Amestoy, and Iain S. Duff.
-   - CHOLMOD Version 1.5. Copyright (c) 2005-2007 by University of Florida,
-     Timothy A. Davis and W. Hager.
-   - COLAMD version 2.7. Copyright (c) 1998-2007 by Timothy A. Davis.
-   - UMFPACK Version 5.0.2. Copyright (c) 1995-2006 by Timothy A. Davis.
+- AMD Version 2.2.0. Copyright (c) 2007 by Timothy A. Davis, Patrick R. 
+  Amestoy, and Iain S. Duff.
+- CHOLMOD Version 1.6.0 Copyright (c) 2005-2007 by University of Florida,
+  Timothy A. Davis and W. Hager.
+- COLAMD version 2.7.0. Copyright (c) 1998-2007 by Timothy A. Davis.
+- UMFPACK Version 5.2.0. Copyright (c) 1995-2006 by Timothy A. Davis.
 
-   These packages are licensed under the terms of the GNU Lesser General 
-   Public License, version 2.1 or higher (UMFPACK, parts of CHOLMOD, AMD, 
-   COLAMD) and the GNU General Public License, version 2 or higher 
-   (the Supernodal module of CHOLMOD). For copyright and license details, 
-   consult the README files in the source directories or the website 
-   listed below.
+These packages are licensed under the terms of the GNU General Public 
+License, version 2 or higher (UMFPACK, the Supernodal module of CHOLMOD)
+and the GNU Lesser General Public License, version 2.1 or higher 
+(the other CHOLMOD modules, AMD, COLAMD).  For copyright and license 
+details, consult the README files in the source directories or the website 
+listed below.
 
-   Availability: www.cise.ufl.edu/research/sparse. 
-
-2. RNGS Random Number Generation -- Multiple Streams (Sep. 22, 1998) by 
-   Steve Park & Dave Geyer.
-
-   Availability: www.cs.wm.edu/~va/software/park/park.html. 
+Availability: www.cise.ufl.edu/research/sparse. 
 ----------------------------------------------------------------------------
 
                     GNU GENERAL PUBLIC LICENSE
diff --git a/doc/.latex2html-init b/doc/.latex2html-init
deleted file mode 100644
index 8345f62..0000000
--- a/doc/.latex2html-init
+++ /dev/null
@@ -1,198 +0,0 @@
-#LaTeX2HTML Version 96.1 : dot.latex2html-init
-#
-### Command Line Argument Defaults #######################################
-
-$IMAGE_TYPE  = $IMAGE_TYPES[1];  # use gif (see /etc/latex2html.conf)
-
-$MAX_SPLIT_DEPTH = 8;	# Stop making separate files at this depth
-
-$MAX_LINK_DEPTH = 4;    # Stop showing child nodes at this depth   
-
-$NOLATEX = 0;           # 1 = do not pass unknown environments to Latex
-
-$EXTERNAL_IMAGES = 0;   # 1 = leave the images outside the document 
-
-$ASCII_MODE = 0;        # 1 = do not use any icons or internal images
-
-# 1 =  use links to external postscript images rather than inlined bitmap
-# images.
-$PS_IMAGES = 0;
-
-$TITLE = $default_title;      # The default is "No Title" 
-
-$DESTDIR = '';         # Put the result in this directory 
-
-# When this is set, the generated HTML files will be placed in the 
-# current directory. If set to 0 the default behaviour is to create (or reuse)
-# another file directory.
-$NO_SUBDIR = 0;
-
-
-# Supply your own string if you don't like the default <Name> <Date>
-## $ADDRESS = "<I>$address_data[0] <BR>\n$address_data[1]</I>";
-$ADDRESS = "";
-
-$NO_NAVIGATION = 0;	# 1 = do not put a navigation panel at the top of each page
-
-# Put navigation links at the top of each  page.  If  the page  exceeds
-# $WORDS_IN_PAGE  number of words then put one at the bottom of the page.
-$AUTO_NAVIGATION = 1;
-
-# Put a link to the index page in  the  navigation  panel
-$INDEX_IN_NAVIGATION = 1;
-
-# Put a link to the table of contents  in  the  navigation  panel
-$CONTENTS_IN_NAVIGATION = 1;
-
-# Put a link to the next logical page  in  the  navigation  panel
-$NEXT_PAGE_IN_NAVIGATION = 1;
-
-# Put a link to the previous logical page  in  the  navigation  panel
-$PREVIOUS_PAGE_IN_NAVIGATION = 1;
-
-$INFO = 0;              # 0 = do not make a "About this document..." section 
-
-# Reuse images generated during previous runs
-$REUSE = 2;
-
-# When this is 1, the section numbers are shown. The section numbers should 
-# then match those that would have bee produced by LaTeX.
-# The correct section numbers are obtained from the $FILE.aux file generated 
-# by LaTeX.
-# Hiding the seciton numbers encourages use of particular sections 
-# as standalone documents. In this case the cross reference to a section 
-# is shown using the default symbol rather than the section number.
-$SHOW_SECTION_NUMBERS = 1;
-
-### Other global variables ###############################################
-$CHILDLINE = "<BR> <HR>\n";
-
-# This is the line width measured in pixels and it is used to right justify
-# equations and equation arrays; 
-$LINE_WIDTH = 500;		
-
-# Used in conjunction with AUTO_NAVIGATION
-$WORDS_IN_PAGE = 300;	
-
-# Affects ONLY the way accents are processed 
-$default_language = 'english';	
-
-# The value of this variable determines how many words to use in each 
-# title that is added to the navigation panel (see below)
-# 
-$WORDS_IN_NAVIGATION_PANEL_TITLES = 4;
-
-# This number will determine the size of the equations, special characters,
-# and anything which will be converted into an inlined image
-# *except* "image generating environments" such as "figure", "table" 
-# or "minipage".
-# Effective values are those greater than 0.
-# Sensible values are between 0.1 - 4.
-$MATH_SCALE_FACTOR = 1.6;
-
-# This number will determine the size of 
-# image generating environments such as "figure", "table" or "minipage".
-# Effective values are those greater than 0.
-# Sensible values are between 0.1 - 4.
-$FIGURE_SCALE_FACTOR = 1.6;
-
-
-#  If this is set then intermediate files are left for later inspection.
-#  This includes $$_images.tex and $$_images.log created during image
-#  conversion.
-#  Caution: Intermediate files can be *enormous*.
-$DEBUG = 0;
-
-#  If both of the following two variables are set then the "Up" button
-#  of the navigation panel in the first node/page of a converted document
-#  will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set
-#  to some text which describes this external link.
-$EXTERNAL_UP_LINK = "";
-$EXTERNAL_UP_TITLE = "";
-
-# If this is set then the resulting HTML will look marginally better if viewed 
-# with Netscape.
-$NETSCAPE_HTML = 0;
-
-# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0"
-# Paper sizes has no effect other than in the time it takes to create inlined
-# images and in whether large images can be created at all ie
-#  - larger paper sizes *MAY* help with large image problems 
-#  - smaller paper sizes are quicker to handle
-$PAPERSIZE = "a4";
-
-# Replace "english" with another language in order to tell LaTeX2HTML that you 
-# want some generated section titles (eg "Table of Contents" or "References")
-# to appear in a different language. Currently only "english" and "french"
-# is supported but it is very easy to add your own. See the example in the
-# file "latex2html.config" 
-$TITLES_LANGUAGE = "english";
-
-### Navigation Panel ##########################################################
-#
-# The navigation panel is constructed out of buttons and section titles.
-# These can be configured in any combination with arbitrary text and 
-# HTML tags interspersed between them. 
-# The buttons available are:
-# $PREVIOUS - points to the previous section
-# $UP  - points up to the "parent" section
-# $NEXT - points to the next section
-# $NEXT_GROUP - points to the next "group" section
-# $PREVIOUS_GROUP - points to the previous "group" section
-# $CONTENTS - points to the contents page if there is one
-# $INDEX - points to the index page if there is one
-#
-# If the corresponding section exists the button will contain an
-# active link to that section. If the corresponding section does
-# not exist the button will be inactive.
-#
-# Also for each of the $PREVIOUS $UP $NEXT $NEXT_GROUP and $PREVIOUS_GROUP
-# buttons there are equivalent $PREVIOUS_TITLE, $UP_TITLE, etc variables
-# which contain the titles of their corresponding sections. 
-# Each title is empty if there is no corresponding section.
-#
-# The subroutine below constructs the navigation panels in each page.
-# Feel free to mix and match buttons, titles, your own text, your logos,
-# and arbitrary HTML (the "." is the Perl concatenation operator).
-sub top_navigation_panel {
-
-    # Now add a few buttons with a space between them
-#    "$NEXT $UP $PREVIOUS $CONTENTS $INDEX $CUSTOM_BUTTONS" .
-    
-#    "<BR>\n" .		# Line break
-	
-    # If ``next'' section exists, add its title to the navigation panel
-    ($NEXT_TITLE ? "<B> Next:</B> $NEXT_TITLE\n" : undef) . 
-    
-    # Similarly with the ``up'' title ...
-    ($UP_TITLE ? "<B>Up:</B> $UP_TITLE\n" : undef) . 
- 
-    # ... and the ``previous'' title
-    ($PREVIOUS_TITLE ? "<B> Previous:</B> $PREVIOUS_TITLE\n" : undef) .
-   
-    #  Line Break, horizontal rule (3-d dividing line) and new paragraph  
-    "<BR> <P>\n"		
-}
-
-sub bot_navigation_panel {
-
-    #  Start with a horizontal rule (3-d dividing line)
-    "<HR>".			
-    
-    # Now add a few buttons with a space between them
-#    "$NEXT $UP $PREVIOUS $CONTENTS $INDEX $CUSTOM_BUTTONS" .
-    
-    "<BR>\n" .		# Line break
-	
-    # If ``next'' section exists, add its title to the navigation panel
-    ($NEXT_TITLE ? "<B> Next:</B> $NEXT_TITLE\n" : undef) . 
-    
-    # Similarly with the ``up'' title ...
-    ($UP_TITLE ? "<B>Up:</B> $UP_TITLE\n" : undef) . 
- 
-    # ... and the ``previous'' title
-    ($PREVIOUS_TITLE ? "<B> Previous:</B> $PREVIOUS_TITLE\n" : undef) 
-   
-}
-
-1;	# This must be the last line
diff --git a/doc/Makefile b/doc/Makefile
index 26e9576..9792ae7 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,15 +1,16 @@
 SOURCES	= cvxopt.tex intro.tex base.tex blas.tex lapack.tex \
-	spsolvers.tex modeling.tex coneprog.tex solvers.tex c-api.tex 
+	spsolvers.tex modeling.tex solvers.tex coneprog.tex c-api.tex 
 
 all: html 
 
-latex: Makefile $(SOURCES) 
-	latex cvxopt.tex
-
 html: Makefile $(SOURCES) 
-	latex cvxopt.tex
-	latex2html -ps_images cvxopt
-	rm -rf *.dvi *.idx *.ind *.l2h *.log *.toc *.aux *~ 
+	htlatex cvxopt.tex "html,3,info" 
+	tex4ht -f/cvxopt  -i/usr/share/texmf/tex4ht/ht-fonts/ \
+            -e/usr/share/texmf/tex4ht/tex4ht.env
+	t4ht -dhtml/ -f/cvxopt.tex -e/usr/share/texmf/tex4ht/tex4ht.env
+	rm -rf *.html *.4ct *.4tc *.css *.dvi *.idv *.tmp log *.toc *.aux \
+            *.lg *.xref *.png *.log
 
 clean:	
-	rm -rf *.dvi *.idx *.ind *.l2h *.log *.toc *.aux *~ *.ps cvxopt
+	rm -rf *.html *.4ct *.4tc *.css *.dvi *.idv *.tmp *.log *.toc \
+            *.aux *.lg *.xref *.png *.log html/* 
diff --git a/doc/base.tex b/doc/base.tex
index 450a299..eff0a8b 100644
--- a/doc/base.tex
+++ b/doc/base.tex
@@ -4,6 +4,7 @@ The \module{cvxopt.base} module defines two new Python types:
 \mtrx\ objects, used for dense matrix computations, and 
 \spmtrx\ objects, used for sparse matrix computations.
 In this chapter we describe the dense \mtrx\ object.
+Sparse matrices are discussed in chapter~\ref{chap:spmatrix}.
 
 \section{Creating Matrices}\label{s-creating-matrices}
 A \mtrx\ object is created by calling the function \function{matrix()}. 
@@ -24,7 +25,7 @@ lists of matrices and numbers.
 \item If \var{x} is a number (Python \intgr, \flt\ or \cmplx), a matrix
 is created with the dimensions specified by \var{size} and with all the 
 coefficients equal to \var{x}.  
-The default value of \var{size} is (1,1), and the default value
+The default value of \var{size} is $(1,1)$, and the default value
 of \var{tc} is the type of \var{x}.
 If necessary, the type of \var{x} is converted (from integer to double
 when used to create a matrix of type \dtc, and from integer or
@@ -164,22 +165,22 @@ A \ctype{char}, either \itc, \dtc, or \ztc, for integer, real
 and complex matrices, respectively.  A read-only attribute.
 \end{memberdesc} 
 
-\begin{methoddesc}{matrix}{trans}
+\begin{methoddesc}{trans}
 Returns the transpose of the matrix as a new matrix.
 One can also use \code{A.T} instead of \code{A.trans()}.
 \end{methoddesc}
 
-\begin{methoddesc}{matrix}{ctrans}
+\begin{methoddesc}{ctrans}
 Returns the conjugate transpose of the matrix as a new matrix.
 One can also use \code{A.H} instead of \code{A.ctrans()}.
 \end{methoddesc}
 
-\begin{methoddesc}{matrix}{real}
+\begin{methoddesc}{real}
 For complex matrices, returns the real part as a real matrix.
 For integer and real matrices, returns a copy of the matrix.
 \end{methoddesc}
 
-\begin{methoddesc}{matrix}{imag}
+\begin{methoddesc}{imag}
 For complex matrices, returns the imaginary part as a real matrix.
 For integer and real matrices, returns an integer or real zero matrix.
 \end{methoddesc}
@@ -231,16 +232,17 @@ or a dense 1 by 1 matrix), and \var{d} is a Python number.
 
 \begin{center}
 \begin{tabular}{l|l}
-Unary plus/minus & \code{+\var{A}}, \code{-\var{A}} \\
+\hline
+Unary plus/minus & \code{+\var{A}}, \code{-\var{A}} \\ \hline 
 Addition & \code{\var{A}+\var{B}}, \code{\var{A}+\var{c}}, 
-    \code{\var{c}+\var{A}}\\
+    \code{\var{c}+\var{A}}\\ \hline 
 Subtraction & \code{\var{A}-\var{B}}, \code{\var{A}-\var{c}}, 
-    \code{\var{c}-\var{A}}\\
-Matrix multiplication & \code{{\var{A}*\var{B}}} \\
+    \code{\var{c}-\var{A}}\\ \hline 
+Matrix multiplication & \code{{\var{A}*\var{B}}} \\ \hline
 Scalar multiplication and division & \code{\var{c}*\var{A}}, 
-    \code{\var{A}*\var{c}}, \code{\var{A}/\var{c}} \\
-Remainder after division & \code{\var{A}\%\var{c}} \\
-Elementwise exponentiation  & \code{\var{A}**\var{d}}
+    \code{\var{A}*\var{c}}, \code{\var{A}/\var{c}} \\ \hline 
+Remainder after division & \code{\var{A}\%\var{c}} \\ \hline 
+Elementwise exponentiation  & \code{\var{A}**\var{d}} \\ \hline 
 \end{tabular}
 \end{center}
 
@@ -283,14 +285,14 @@ infinity.
 
 The following in-place operations are also defined, but only if 
 they do not change the type or the size of the matrix \var{A}: 
-\begin{center}\begin{tabular}{l|l}
+\begin{center}\begin{tabular}{l|l} \hline
  In-place addition & 
-    \code{\var{A}+=\var{B}}, \code{\var{A}+=\var{c}} \\
+    \code{\var{A}+=\var{B}}, \code{\var{A}+=\var{c}} \\ \hline
  In-place subtraction & 
-    \code{\var{A}-=\var{B}}, \code{\var{A}-=\var{c}} \\    
+    \code{\var{A}-=\var{B}}, \code{\var{A}-=\var{c}} \\ \hline   
  In-place scalar multiplication and division & 
-    \code{\var{A}*=\var{c}}, \code{\var{A}/=\var{c}} \\
- In-place remainder & \code{\var{A}\%=\var{c}} 
+    \code{\var{A}*=\var{c}}, \code{\var{A}/=\var{c}} \\ \hline
+ In-place remainder & \code{\var{A}\%=\var{c}} \\ \hline
 \end{tabular}\end{center}
 
 For example, if \var{A} has type \itc, then \code{\var{A}+=\var{B}} 
@@ -647,27 +649,21 @@ The two matrices must have the same size and type.
 \end{funcdesc}
 
 
-\section{Randomly Generated Matrices} \label{s-random}
+\section{Randomly Generated Matrices (\module{cvxopt.random})} 
+\label{s-random}
 The module \module{cvxopt.random} provides functions for generating
-random matrices.  Two types of random matrices are defined:
-matrices with normally distributed entries and matrices with uniformly 
-distributed entries.   
-
-The pseudo-random number generators used to 
-generate the random matrices are from the package described in the 
-references below.  
-\begin{seealso}
-\item \seelink{http://www.cs.wm.edu/\~{}va/software/park/park.html}
-{S. Park, Random Number Generators.}{} 
-\item \seetext{S. Park, D. Geyer, Random Number Generators: Good Ones Are 
-Hard To Find,
-Communications of the ACM, October 1988.}
-\end{seealso}
+random matrices, using the pseudo-random number generators in the 
+\ulink{GNU Scientific Library (GSL)}{http://www.gnu.org/software/gsl}.
+This module is optional, and only installed when the GSL library is 
+available during the CVXOPT installation.
 
+Two types of random matrices are defined: matrices with normally 
+distributed entries and matrices with uniformly 
+distributed entries.   
 \begin{funcdesc}{normal}{nrows\optional{, ncols\optional{, 
  mean\optional{, std}}}}
 Returns a type \dtc\ matrix of size \var{nrows} by 
-\var{ncols} with random elements chosen from a normal distribution 
+\var{ncols} with elements chosen from a normal distribution 
 with mean \var{mean} and standard deviation \var{std}.
 The default values for the optional arguments are 
 \var{ncols}=1, \var{mean}=0.0, \var{std}=1.0.
@@ -676,23 +672,23 @@ The default values for the optional arguments are
 \begin{funcdesc}{uniform}{nrows\optional{, ncols\optional{, 
   a\optional{, b}}}}
 Returns a type \dtc\ matrix of size \var{nrows} by 
-\var{ncols} matrix with random elements, uniformly distributed 
+\var{ncols} matrix with elements uniformly distributed 
 between \var{a} and \var{b}.
 The default values for the optional arguments are 
 \var{ncols}=1, \var{a}=0.0, \var{b}=1.0.
 \end{funcdesc}
 
 \begin{funcdesc}{getseed}{}
-Returns the current seed value (the state of the random number 
-generator).
+Returns the current seed value (the state of the random number generator).
 \end{funcdesc}
 
 \begin{funcdesc}{setseed}{\optional{value}}
-Sets the seed value.  \var{value} must be a nonnegative integer.
+Sets the seed value.  \var{value} must be an integer.
 If \var{value} is absent or equal to zero, the seed value is taken 
 from the system clock.  
 \end{funcdesc}
 
+
 \section{The NumPy Array Interface} \label{s-array-interface}
 
 The CVXOPT \mtrx\ object is compatible with the \program{NumPy} Array 
@@ -701,12 +697,12 @@ which allows Python objects that represent multidimensional
 arrays to exchange data using information stored in the 
 attribute \code{\_\_array\_struct\_\_}.  
 
-\begin{seealso}
+\textbf{See also:}
+\BIT
 \item \seelink{http://numpy.scipy.org/array_interface.shtml}
 {NumPy Array Interface Specification}{}
-
 \item \seelink{http://numpy.scipy.org}{NumPy home page}{}
-\end{seealso}
+\EIT
 
 As already mentioned in section~\ref{s-creating-matrices},
 a two-dimensional array object (for example, a \program{NumPy} matrix or
diff --git a/doc/base_sparse.tex b/doc/base_sparse.tex
index a14961f..b50a35b 100644
--- a/doc/base_sparse.tex
+++ b/doc/base_sparse.tex
@@ -54,10 +54,10 @@ dimensions of the matrix.
 The \var{size} argument is only needed when creating a matrix with 
 a zero last row or last column.  If \var{size} is not specified, it 
 is determined from \var{I} and \var{J}:
-the default value for \code{\var{size}[0]} is \code{max(\var{I})+1} 
+the default value for \code{\var{size}[0]} is max(\var{I})+1 
 if \var{I} is nonempty and zero otherwise.  
 The default value for \code{\var{size}[1]} is 
-\code{max(\var{J})+1} if \var{J} is nonempty and zero otherwise.
+max(\var{J})+1 if \var{J} is nonempty and zero otherwise.
 
 \var{tc} is the typecode, \dtc\ or \ztc, for double and complex 
 matrices, respectively.   Integer sparse matrices are not implemented.
@@ -181,7 +181,39 @@ SIZE: (6,3)
 (5, 2)  5.0000e+00
 \end{verbatim}
 \EIT
+\end{funcdesc}
+
 
+The function \function{spdiag()} constructs a block-diagonal
+sparse matrix from a list of matrices.
+   
+\begin{funcdesc}{spdiag}{x}
+\var{x} is a matrix with a single row or column, or a list of square
+dense or sparse matrices or scalars.  
+If \var{x} is matrix, a sparse diagonal matrix is returned with 
+the entries of \var{x} on its diagonal.
+If \var{x} is list, a sparse block-diagonal matrix is returned with
+the element in the list as its diagonal blocks.
+  
+The following example shows how to construct a sparse block-diagonal matrix.
+\begin{verbatim}
+>>> from cvxopt.base import matrix, spmatrix, spdiag
+>>> A = 3.0
+>>> B = matrix([[1,-2],[-2,1]])
+>>> C = spmatrix([1,1,1,1,1],[0,1,2,0,0,],[0,0,0,1,2])
+>>> print spdiag([A, B, C])
+SIZE: (6,6)
+(0, 0)  3.0000e+00
+(1, 1)  1.0000e+00
+(2, 1) -2.0000e+00
+(1, 2) -2.0000e+00
+(2, 2)  1.0000e+00
+(3, 3)  1.0000e+00
+(4, 3)  1.0000e+00
+(5, 3)  1.0000e+00
+(3, 4)  1.0000e+00
+(3, 5)  1.0000e+00
+\end{verbatim}
 \end{funcdesc}
 
 \section{Attributes and Methods}
@@ -216,12 +248,19 @@ in \code{V}.  A read-only attribute.
 A tuple with the dimensions of the matrix.  A read-only attribute.
 \end{memberdesc} 
 
-\begin{methoddesc}{spmatrix}{trans}
+\begin{memberdesc}{CCS}
+A triplet (colptr, rowind, values) with the compressed-column-storage 
+representation of the matrix.  A read-only attribute.  This attribute
+can be used to export sparse matrices to other packages such as MOSEK.
+\end{memberdesc} 
+
+
+\begin{methoddesc}{trans}
 Returns the transpose of a sparse matrix as a new sparse matrix.
 One can also use \code{A.T} instead of \code{A.trans()}.
 \end{methoddesc}
 
-\begin{methoddesc}{spmatrix}{ctrans}
+\begin{methoddesc}{ctrans}
 Returns the complex conjugate transpose of a sparse matrix as a 
 new sparse matrix.
 One can also use \code{A.H} instead of \code{A.ctrans()}. 
@@ -331,16 +370,16 @@ In the following table, \var{A} is a sparse matrix,
 Python number or a 1 by 1 dense matrix.
 
 \begin{center}
-\begin{tabular}{l|l}
- Unary plus/minus & \code{+\var{A}}, \code{-\var{A}} \\
+\begin{tabular}{l|l} \hline
+ Unary plus/minus & \code{+\var{A}}, \code{-\var{A}} \\ \hline
  Addition & \code{\var{A}+\var{B}}, \code{\var{B}+\var{A}}, 
-   \code{\var{A}+\var{c}}, \code{\var{c}+\var{A}}\\
+   \code{\var{A}+\var{c}}, \code{\var{c}+\var{A}}\\ \hline
  Subtraction & \code{\var{A}-\var{B}}, \code{\var{B}-\var{A}}, 
-    \code{\var{A}-\var{c}}, \code{\var{c}-\var{A}}\\
+    \code{\var{A}-\var{c}}, \code{\var{c}-\var{A}}\\ \hline
  Matrix multiplication & \code{\var{A}*\var{B}}, 
-  \code{\var{B}*\var{A}} \\
+  \code{\var{B}*\var{A}} \\ \hline
  Scalar multiplication and division & \code{\var{c}*\var{A}}, 
-   \code{\var{A}*\var{c}}, \code{\var{A}/\var{c}}
+   \code{\var{A}*\var{c}}, \code{\var{A}/\var{c}} \\\hline
  \end{tabular}
 \end{center}
 
@@ -393,13 +432,13 @@ or with  \code{1.0/\var{c}[0]} if \var{c} is a 1 by 1 dense matrix.
 The following in-place operations are defined for a sparse matrix 
 \var{A} if they do not change the dimensions or type of \var{A}.
 \begin{center}
-  \begin{tabular}{l|l}
+  \begin{tabular}{l|l} \hline
   In-place addition & \code{\var{A}+=\var{B}}, 
-    \code{\var{A}+=\var{c}} \\    
+    \code{\var{A}+=\var{c}} \\ \hline   
   In-place subtraction & \code{\var{A}-=\var{B}}, 
-    \code{\var{A}-=\var{c}} \\    
+    \code{\var{A}-=\var{c}} \\ \hline   
   In-place scalar multiplication and division & 
-    \code{\var{A}*=\var{c}}, \code{\var{A}/=\var{c}} 
+    \code{\var{A}*=\var{c}}, \code{\var{A}/=\var{c}}  \\ \hline
   \end{tabular}
 \end{center}
 
@@ -639,7 +678,7 @@ from that of the matrix product.
 \begin{funcdesc}{syrk}{A, C\optional{, uplo='L'\optional{, 
 trans='N'\optional{, alpha=1.0\optional{, beta=0.0\optional{, 
 partial=False}}}}}}
-Rank-{\it k} update of a sparse or dense real or complex symmetric
+Rank-$k$ update of a sparse or dense real or complex symmetric
 matrix:
 \[
  C := \alpha AA^T + \beta C \quad (\mathrm{trans} = \mathrm{'N'}), 
@@ -688,7 +727,7 @@ SIZE: (3,3)
 (0, 2)  2.0000e+00
 (2, 2)  2.0000e+00
 \end{verbatim}
-Now suppose we want to replace {\it C}  with
+Now suppose we want to replace \var{C}  with
 \[
 C = A^TD, \qquad 
 D = \left[ \begin{array}{ccc}
diff --git a/doc/blas.tex b/doc/blas.tex
index 0dc383f..4408b6f 100644
--- a/doc/blas.tex
+++ b/doc/blas.tex
@@ -26,7 +26,8 @@ matrices.  Thus they can be viewed as generalizations of the in-place
 matrix addition and scalar multiplication of 
 section~\ref{s-arithmetic} to more complicated operations.
 
-\begin{seealso}
+\textbf{See also:}
+\BIT
 \item \seetext{C. L. Lawson, R. J. Hanson, D. R. Kincaid, F. T. Krogh, 
 Basic Linear Algebra Subprograms for Fortran Use,
 ACM Transactions on Mathematical Software, 5(3), 309-323, 1975.}
@@ -36,7 +37,7 @@ ACM Transactions on Mathematical Software, 14(1), 1-17, 1988.}
 \item \seetext{J. J. Dongarra, J. Du Croz, S. Hammarling, I. Duff,
 A Set of Level 3 Basic Linear Algebra Subprograms,
 ACM Transactions on Mathematical Software, 16(1), 1-17, 1990.}
-\end{seealso}
+\EIT
 
 \section{Matrix Classes} \label{s-conventions}
 
@@ -47,17 +48,17 @@ arguments that specify the structure.
 
 \begin{description}
 \item[Vector] 
-A real or complex {\it n}-vector is represented by a \mtrx\ of type 
-\dtc\ or \ztc\ and length {\it n}, with the entries of the vector 
-stored in column-major order. 
+A real or complex $n$-vector is represented by a \mtrx\ of type 
+\dtc\ or \ztc\ and length $n$, with the entries of the vector stored in 
+column-major order. 
 
 \item[General matrix]
-A general real or complex {\it m} by {\it n} matrix is represented by 
-a real or complex \mtrx\ of size ({\it m}, {\it n}).
+A general real or complex $m$ by $n$ matrix is represented by 
+a real or complex \mtrx\ of size ($m$, $n$).
 
 \item[Symmetric matrix]
-A real or complex symmetric matrix of order {\it n} is represented
-by a real or complex \mtrx\ of size ({\it n}, {\it n}), and a character 
+A real or complex symmetric matrix of order $n$ is represented
+by a real or complex \mtrx\ of size ($n$, $n$), and a character 
 argument \var{uplo} with two possible values:  
 \code{'L'} and \code{'U'}.
 If \var{uplo} is \code{'L'}, the lower triangular part of the
@@ -83,12 +84,12 @@ X[0,n-1] & X[1,n-1] & X[2,n-1] & \cdots & X[n-1,n-1]
 \EEAS
 
 \item[Complex Hermitian matrix]
-A complex Hermitian matrix of order {\it n} is represented
-by a \mtrx\ of type \ztc\ and size ({\it n}, {\it n}), and
+A complex Hermitian matrix of order $n$ is represented
+by a \mtrx\ of type \ztc\ and size ($n$, $n$), and
 a character argument \var{uplo} with the same meaning as for symmetric 
 matrices.
-A complex \mtrx\ {\var X} of size ({\it n}, {\it n}) can 
-represent the Hermitian  matrices
+A complex \mtrx\ {\var X} of size ($n$, $n$) can represent the Hermitian  
+matrices
 \BEAS
 &
 \left[\begin{array}{ccccc}
@@ -108,14 +109,14 @@ X[n-1,0] & X[n-1,1] & X[n-1,2] & \cdots & \Re X[n-1,n-1]
 \EEAS
 
 \item[Triangular matrix]
-A real or complex triangular matrix of order {\it n} is represented
-by a real or complex \mtrx\ of size ({\it n}, {\it n}), and two 
+A real or complex triangular matrix of order $n$ is represented
+by a real or complex \mtrx\ of size ($n$, $n$), and two 
 character arguments: an argument \var{uplo} with possible values 
 \code{'L'} and \code{'U'} to distinguish between lower and upper 
 triangular matrices, and an argument \var{diag} with possible values 
 \code{'U'} and \code{'N'} to distinguish between unit and non-unit 
 triangular matrices.  A square \mtrx\ {\var X} of size 
-({\it n}, {\it n}) can represent the triangular matrices
+($n$, $n$) can represent the triangular matrices
 \BEAS
 & \left[\begin{array}{ccccc}
 X[0,0]   & 0        & 0        & \cdots & 0 \\
@@ -148,16 +149,16 @@ X[0,0]   & X[0,1]   & X[0,2]   & \cdots & X[0,n-1] \\
 \EEAS
 
 \item[General band matrix]
-A general real or complex {\it m} by {\it n} band matrix  with {\it kl}
-subdiagonals and {\it ku} superdiagonals is represented by a real or 
-complex \mtrx\ \var{X} of size ({\it kl+ku+1}, {\it n}), and the two 
-integers {\it m} and {\it kl}.   
+A general real or complex $m$ by $n$ band matrix  with $k_l$
+subdiagonals and $k_u$ superdiagonals is represented by a real or 
+complex \mtrx\ \var{X} of size ($k_l+k_u+1$, $n$), and the two 
+integers $m$ and $k_l$.   
 The diagonals of the band matrix are stored in the rows of \var{X}, 
 starting at the top diagonal, and shifted horizontally so that the 
 entries of the 
-{\it k}th column of the band matrix are stored in column {\it k} of 
-{\var X}.  A \mtrx\ {\var X} of size ({\it kl+ku+1}, {\it n}) therefore
-represents the {\it m} by {\it n} band matrix
+$k$th column of the band matrix are stored in column $k$ of 
+{\var X}.  A \mtrx\ {\var X} of size ($k_l+k_u+1$, $n$) therefore
+represents the $m$ by $n$ band matrix
 \[
 \left[ \begin{array}{ccccccc}
 X[k_u,0]     & X[k_u-1,1]     & X[k_u-2,2]     & \cdots & X[0,k_u] & 0               & \cdots \\
@@ -171,17 +172,17 @@ X[k_u+k_l,0] & X[k_u+k_l-1,1] & X[k_u+k_l-2,2] & \cdots &  &  & \\
 \]
 
 \item[Symmetric band matrix]
-A real or complex symmetric band matrix of order {\it n} with {\it k}
+A real or complex symmetric band matrix of order $n$ with $k$
 subdiagonals, is represented by a real or complex matrix \var{X} of 
-size ({\it k}+1, {\it n}), and an argument {\it uplo} to indicate 
+size ($k+1$, $n$), and an argument {\it uplo} to indicate 
 whether the subdiagonals ({\it uplo} is \code{'L'}) or superdiagonals 
 ({\it uplo} is \code{'U'}) are stored.
-The {\it k}+1 diagonals are stored as rows of \var{X}, starting at the top 
+The $k+1$ diagonals are stored as rows of \var{X}, starting at the top 
 diagonal (\ie, the main diagonal if {\it uplo} is \code{'L'},  or
-the {\it k}th superdiagonal if {\it uplo} is \code{'U'}) and shifted
+the $k$th superdiagonal if {\it uplo} is \code{'U'}) and shifted
 horizontally so that the entries of the 
-{\it k}th column of the band matrix are stored in column {\it k} of 
-{\var X}.  A \mtrx\ {\it X} of size ({\it k}+1, {\it n}) can therefore
+$k$th column of the band matrix are stored in column $k$ of 
+{\var X}.  A \mtrx\ \var{X} of size ($k+1$, $n$) can therefore
 represent the band matrices 
 \BEAS
 & \left[ \begin{array}{ccccccc}
@@ -206,10 +207,10 @@ X[0,k]   & X[1,k]   & X[2,k]   & \cdots &  &  & \\
 \EEAS
 
 \item[Hermitian  band matrix]
-A complex Hermitian band matrix of order {\it n} with {\it k} 
+A complex Hermitian band matrix of order $n$ with $k$ 
 subdiagonals is represented by a complex matrix of size 
-({\it k+1}, {\it n}) and an argument \var{uplo}.  
-A \mtrx\ {\it X} of size ({\it k}+1, {\it n}) can represent the band
+($k+1$, $n$) and an argument \var{uplo}.  
+A \mtrx\ \var{X} of size ($k+1$, $n$) can represent the band
 matrices 
 \BEAS
 & \left[ \begin{array}{ccccccc}
@@ -234,11 +235,11 @@ X[k,0] & X[k-1,1] & X[k-2,2] & \cdots &  &  & \\
 \EEAS
 
 \item[Triangular band matrix]
-A triangular band matrix of order {\it n} with {\it k} subdiagonals or
+A triangular band matrix of order $n$ with $k$ subdiagonals or
 superdiagonals is represented by a real complex matrix of size 
-({\it k+1}, {\it n}) and two character arguments \var{uplo} and 
+($k+1$, $n$) and two character arguments \var{uplo} and 
 \var{diag}.  
-A \mtrx\ {\it X} of size ({\it k}+1, {\it n}) can represent the band
+A \mtrx\ \var{X} of size ($k+1$, $n$) can represent the band
 matrices 
 \BEAS
 & \left[ \begin{array}{cccc}
@@ -316,7 +317,7 @@ Returns
  \mbox{($x$ complex)}. 
 \]
 If more than one coefficient achieves the maximum, the index of the 
-first {\it k} is returned.  
+first $k$ is returned.  
 \end{funcdesc}
 
 \begin{funcdesc}{swap}{x, y}
@@ -390,7 +391,7 @@ Matrix-vector  product with a real symmetric matrix:
 \[
    y := \alpha A x + \beta y,
 \]
-where {\it A} is a real symmetric matrix.  
+where $A$ is a real symmetric matrix.  
 The arguments \var{A}, \var{x} and {\var y} must have 
 type \dtc\ and \var{alpha} and \var{beta} must be real.
 \end{funcdesc}
@@ -402,7 +403,7 @@ matrix:
 \[
    y := \alpha A x + \beta y,
 \]
-where {\it A} is real symmetric or complex Hermitian.
+where $A$ is real symmetric or complex Hermitian.
 The arguments \var{A}, \var{x} and {\var y} must have the same
 type (\dtc\ or \ztc).  
 Complex values of \var{alpha} and \var{beta} are only
@@ -417,9 +418,8 @@ x := Ax \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
 x := A^T x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad
 x := A^H x \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} is square and triangular.
-The arguments \var{A} and \var{x} must have the same type 
-(\dtc\ or \ztc).
+where $A$ is square and triangular.
+The arguments \var{A} and \var{x} must have the same type (\dtc\ or \ztc).
 \end{funcdesc}
 
 \begin{funcdesc}{trsv}{A, x\optional{, uplo='L'\optional{, 
@@ -430,7 +430,7 @@ x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
 x := A^{-T}x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
 x := A^{-H}x \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} is square and triangular with nonzero diagonal 
+where $A$ is square and triangular with nonzero diagonal 
 elements.  The arguments \var{A} and \var{x} must have the same type 
 (\dtc\ or \ztc).
 \end{funcdesc}
@@ -444,8 +444,8 @@ y := \alpha A^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}),
 \qquad 
 y := \alpha A^H x + \beta y \quad (\mathrm{trans} = \mathrm{'C'}),
 \]
-where  {\it A} is a rectangular band matrix with \var{m} rows and 
-\var{kl} subdiagonals.
+where  $A$ is a rectangular band matrix with $m$ rows and 
+$k_l$ subdiagonals.
 The arguments \var{A}, \var{x} and {\var y} must have the same
 type (\dtc\ or \ztc).
 Complex values of \var{alpha} and \var{beta} are only allowed if \var{A} is
@@ -458,7 +458,7 @@ Matrix-vector  product with a real symmetric band matrix:
 \[
  y := \alpha Ax + \beta y,
 \]
-where {\it A} is a real symmetric band matrix.
+where $A$ is a real symmetric band matrix.
 The arguments \var{A}, \var{x} and {\var y} must have type \dtc\ and 
 \var{alpha} and \var{beta} must be real.
 \end{funcdesc}
@@ -470,7 +470,7 @@ band matrix:
 \[
  y := \alpha Ax + \beta y,
 \]
-where {\it A} is a real symmetric or complex Hermitian band matrix.
+where $A$ is a real symmetric or complex Hermitian band matrix.
 The arguments \var{A}, \var{x} and {\var y} must have the same type
 (\dtc\ or \ztc).  
 Complex values of \var{alpha} and \var{beta} are only allowed if 
@@ -497,7 +497,7 @@ x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
 x := A^{-T} x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad
 x := A^{-H} x \quad (\mathrm{trans} = \mathrm{'T'}), 
 \]
-where {\it A} is a triangular band matrix of with nonzero diagonal 
+where $A$ is a triangular band matrix of with nonzero diagonal 
 elements.
 The arguments \var{A} and \var{x} must have the same type 
 (\dtc\ or \ztc).  
@@ -508,7 +508,7 @@ General rank-1 update:
 \[ 
 A := A + \alpha x y^H,
 \]
-where {\it A} is a general matrix.
+where $A$ is a general matrix.
 The arguments \var{A}, \var{x} and \var{y} must have the same type 
 (\dtc\ or \ztc).  
 Complex values of \var{alpha} are only allowed if \var{A} is complex.
@@ -519,7 +519,7 @@ General rank-1 update:
 \[ 
 A := A + \alpha x y^T, 
 \]
-where {\it A} is a general matrix.
+where $A$ is a general matrix.
 The arguments \var{A}, \var{x} and \var{y} must have the same type 
 (\dtc\ or \ztc).  
 Complex values of \var{alpha} are only allowed if \var{A} is complex.
@@ -530,7 +530,7 @@ Symmetric rank-1 update:
 \[
  A := A + \alpha xx^T,
 \]
-where {\it A} is a real symmetric matrix.
+where $A$ is a real symmetric matrix.
 The arguments \var{A} and \var{x} must have type \dtc.  
 \var{alpha} must be a real number.
 \end{funcdesc}
@@ -540,7 +540,7 @@ Hermitian rank-1 update:
 \[
  A := A + \alpha xx^H, 
 \]
-where {\it A} is a real symmetric or complex Hermitian matrix.
+where $A$ is a real symmetric or complex Hermitian matrix.
 The arguments \var{A} and \var{x} must have the same type 
 (\dtc\ or \ztc).  
 \var{alpha} must be a real number.
@@ -552,7 +552,7 @@ Symmetric rank-2  update:
 \[
  A := A + \alpha (xy^T + yx^T),
 \]
-where {\it A} is a real symmetric matrix.
+where $A$ is a real symmetric matrix.
 The arguments \var{A}, \var{x} and \var{y} must have type \dtc.  
 \var{alpha} must be real.
 \end{funcdesc}
@@ -563,7 +563,7 @@ Symmetric rank-2  update:
 \[
  A := A + \alpha xy^H + \bar \alpha yx^H,
 \]
-where {\it A} is a a real symmetric or complex Hermitian matrix.
+where $A$ is a a real symmetric or complex Hermitian matrix.
 The arguments \var{A}, \var{x} and \var{y} must have the same type  
 (\dtc\ or \ztc).  
 Complex values of \var{alpha} are only allowed if \var{A} is complex.
@@ -635,8 +635,8 @@ if \var{A} is complex.
 
 \begin{funcdesc}{symm}{A, B, C\optional{, side='L'\optional{, 
 uplo='L'\optional{, alpha=1.0\optional{,  beta=0.0}}}}}
-Product of a real or complex symmetric matrix {\it A} and a general 
-matrix {\it B}:
+Product of a real or complex symmetric matrix $A$ and a general 
+matrix $B$:
 \[
  C := \alpha AB + \beta C \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
  C := \alpha BA + \beta C \quad (\mathrm{side} = \mathrm{'R'}). 
@@ -689,7 +689,7 @@ Solution of a nonsingular triangular system of equations:
  A^T & \mathrm{transA} = \mathrm{'T'} \\
  A^H & \mathrm{transA} = \mathrm{'C'}, \end{array} \right.
 \]
-where {\it A} is triangular and {\it B} is a general matrix.
+where $A$ is triangular and $B$ is a general matrix.
 The arguments \var{A} and \var{B} must have the same type (\dtc\ or 
 \ztc).   Complex values of \var{alpha} are only allowed if \var{A} is 
 complex.
@@ -703,7 +703,7 @@ Rank-{\it k} update of a real or complex symmetric matrix {\it C}:
  \qquad 
  C := \alpha A^TA + \beta C \quad (\mathrm{trans} = \mathrm{'T'}), 
 \]
-where {\it A} is a general matrix.
+where $A$ is a general matrix.
 The arguments \var{A} and \var{C} must have the same type (\dtc\ or 
 \ztc).  Complex values of \var{alpha} and \var{beta} are only allowed 
 if \var{A} is complex.
@@ -711,14 +711,13 @@ if \var{A} is complex.
 
 \begin{funcdesc}{herk}{A, C\optional{, uplo='L'\optional{, 
 trans='N'\optional{, alpha=1.0\optional{, beta=0.0}}}}}
-Rank-{\it k} update of a real symmetric or complex Hermitian matrix
-{\it C}:
+Rank-$k$ update of a real symmetric or complex Hermitian matrix $C$:
 \[
  C := \alpha AA^H + \beta C \quad (\mathrm{trans} = \mathrm{'N'}), 
  \qquad 
  C := \alpha A^HA + \beta C \quad (\mathrm{trans} = \mathrm{'C'}),
 \]
-where {\it A} is a general matrix.
+where $A$ is a general matrix.
 The arguments \var{A} and \var{C} must have the same type (\dtc\ or
 \ztc).  \var{alpha} and \var{beta} must be real.
 \end{funcdesc}
@@ -732,7 +731,7 @@ Rank-{\it 2k} update of a real or complex symmetric matrix {\it C}:
  C := \alpha (A^TB + B^TA) + \beta C \quad 
   (\mathrm{trans} = \mathrm{'T'}). 
 \]
-{\it A} and {\it B} are general real or complex matrices.
+$A$ and $B$ are general real or complex matrices.
 The arguments \var{A}, \var{B} and \var{C} must have the same
 type.  Complex values of \var{alpha} and \var{beta} are only 
 allowed if \var{A} is complex.
@@ -740,15 +739,14 @@ allowed if \var{A} is complex.
 
 \begin{funcdesc}{her2k}{A, B, C\optional{, uplo='L'\optional{, 
 trans='N'\optional{, alpha=1.0\optional{ beta=0.0}}}}}
-Rank-{\it 2k} update of a real symmetric or complex Hermitian matrix
-{\it C}:
+Rank-$2k$ update of a real symmetric or complex Hermitian matrix $C$:
 \[
  C := \alpha AB^H + \bar \alpha BA^H + \beta C \quad 
   (\mathrm{trans} = \mathrm{'N'}), \qquad 
  C := \alpha A^HB + \bar\alpha B^HA + \beta C \quad 
   (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} and {\it B} are general matrices.
+where $A$ and $B$ are general matrices.
 The arguments \var{A}, \var{B} and \var{C} must have the same type 
 (\dtc\ or \ztc).  Complex values of \var{alpha} are only allowed if 
 \var{A} is complex.  \var{beta} must be real.
diff --git a/doc/c-api.tex b/doc/c-api.tex
index b25b5b7..bd24774 100644
--- a/doc/c-api.tex
+++ b/doc/c-api.tex
@@ -100,7 +100,7 @@ for each column of the matrix the index of the first element in
 \code{\var{colptr}[0]} is \code{0}, and for 
 \code{\var{k} = 0, 1, \ldots, \var{ncols}-1},
 \code{\var{colptr}[k+1]} is equal to \code{\var{colptr}[k]} plus the 
-number of nonzeros in column \var{k} of the matrix.
+number of nonzeros in column $k$ of the matrix.
 Thus, \code{\var{colptr}[\var{ncols}]} is equal to \var{nnz}, the 
 number of nonzero entries.
 \end{description}
diff --git a/doc/coneprog.tex b/doc/coneprog.tex
index 64d23c7..63d93ce 100644
--- a/doc/coneprog.tex
+++ b/doc/coneprog.tex
@@ -32,15 +32,15 @@ Solves a pair of primal and dual cone programs
  \mbox{minimize} & c^T x \\
  \mbox{subject to} & G x + s = h \\ & Ax = b \\ & s \succeq 0
  \end{array}
- \qquad\qquad\qquad\qquad
+\qquad\qquad\qquad\qquad
  \begin{array}[t]{ll}
  \mbox{maximize} & -h^T z - b^T y \\
  \mbox{subject to} & G^T z + A^T y + c = 0 \\
    & z \succeq 0.
  \end{array}
 \EEQ
-The primal variables are {\it x} and the slack variable {\it s}.  
-The dual variables are {\it y} and {\it z}.  The inequalities are 
+The primal variables are $x$ and the slack variable $s$.  
+The dual variables are $y$ and $z$.  The inequalities are 
 interpreted as $s \in C$, $z\in C$, where $C$ is a cone defined as a 
 Cartesian product of a nonnegative orthant, a number of second-order 
 cones, and a number of positive semidefinite cones:
@@ -57,7 +57,7 @@ C_{k+1} = \{ (u_0, u_1) \in \reals \times \reals^{q_{k}-1} \; | \;
 C_{k+M+1} = \left\{ \svec(u) \; | \;
   u \in \symm^{p_k}_+ \right\}, \quad k=0,\ldots,N-1.
 \]
-Here $\svec(u)$ denotes a symmetric matrix {\it u} stored as a vector 
+Here $\svec(u)$ denotes a symmetric matrix $u$ stored as a vector 
 in column major order.  
 
 The arguments \var{c}, \var{h} and \var{b} are real single-column dense 
@@ -74,9 +74,9 @@ The columns of \var{G} and \var{h} are vectors in
 \reals^{q_{M-1}} \times \reals^{p_0^2}  \times \cdots \times 
 \reals^{p_{N-1}^2},
 \]
-where the last {\it N} components represent symmetric matrices stored in 
+where the last $N$ components represent symmetric matrices stored in 
 column major order.  The strictly upper triangular entries of these 
-matrices are not accessed ({\it i.e.},  the symmetric matrices are stored
+matrices are not accessed (i.e.,  the symmetric matrices are stored
 in the 'L'-type column major order used in the \module{blas} and
 \module{lapack} modules).
 
@@ -85,10 +85,9 @@ cones.  It has three fields.
 \begin{description}
 \item[\var{dims['l']}:] $l$, the dimension of the nonnegative orthant
  (a nonnegative integer).
-\item[\var{dims['q']}:] \code{[q\_0, \ldots, q\_\{M-1\}]}, 
+\item[\var{dims['q']}:] $[q_0, \ldots, q_{M-1}]$, 
 a list with the dimensions of the second-order cones (positive integers).
-\item[\var{dims['s']}:] 
-\code{[p\_0, \ldots, p\_\{N-1\}]}, 
+\item[\var{dims['s']}:] $[p_0, \ldots, p_{N-1}]$, 
 a list with the dimensions of the positive semidefinite cones
 (nonnegative integers).
 \end{description}
@@ -97,7 +96,7 @@ a list with the dimensions of the positive semidefinite cones
 used as an optional primal starting point.   
 \code{primalstart['x']} and 
 \code{primalstart['s']} are real dense matrices of size
-\code{(n,1)} and \code{(K,1)}, respectively, where {\it n} is the
+$(n,1)$ and $(K,1)$, respectively, where $n$ is the
 length of \var{c}.
 The vector \code{primalstart['s']} must be strictly positive with respect
 to the cone $C$.
@@ -106,7 +105,7 @@ to the cone $C$.
 used as an optional dual starting point.
 \code{dualstart['y']} and 
 \code{dualstart['z']} are real dense matrices of size
-\code{(p,1)} and \code{(K,1)}, respectively, where {\it p} is the 
+$(p,1)$ and $(K,1)$, respectively, where $p$ is the 
 number of rows in \var{A}.
 The vector \code{dualstart['s']} must be strictly positive with respect
 to the cone $C$.
@@ -154,8 +153,8 @@ It is required that
 \Rank(A) = p, \qquad 
 \Rank(\left[\begin{array}{c} G \\ A \end{array}\right]) = n,
 \]
-where {\it p} is the number or rows of \var{A} and {\it n}
-is the number of columns of \var{G} and \var{A}.
+where $p$ is the number or rows of $A$ and $n$ is the number of columns 
+of $G$ and $A$.
 \end{funcdesc}
 
 As an example we solve the problem
@@ -232,8 +231,8 @@ obtain the same result if we define \var{G} and \var{h} as below.
 
 \section{Linear Programming} \label{s-lpsolver}
 The function \function{lp()} is an interface to \function{conelp()} for 
-linear programs.  It also provides the option of using the linear programming
-solvers from GLPK or MOSEK.
+linear programs.  It also provides the option of using the linear 
+programming solvers from GLPK or MOSEK.
 
 \begin{funcdesc}{lp}{c, G, h\optional{, A, b\optional{, 
 solver\optional{, primalstart\optional{, dualstart}}}}}
@@ -293,7 +292,7 @@ The function \function{socp()} is a simpler interface to
 constraints.
 
 \begin{funcdesc}{socp}{c\optional{, Gl, hl\optional{, Gq, hq\optional{, 
- A, b\optional{, primalstart\optional{, dualstart}}}}}}
+ A, b\optional{, solver\optional{, primalstart\optional{, dualstart}}}}}}}
 Solves the pair of primal and dual second-order cone programs
 \[
  \begin{array}[t]{ll}
@@ -323,7 +322,6 @@ as
  s_k = (s_{k0}, s_{k1}) \in\reals\times\reals^{q_{k}-1}, \qquad 
  z_k = (z_{k0}, z_{k1}) \in\reals\times\reals^{q_{k}-1}.
 \]
-
 The input argument \var{c} is a real single-column dense matrix.
 The arguments \var{Gl} and \var{hl} are the coefficient matrix $G_0$
 and the righthand side $h_0$ of the componentwise inequalities.
@@ -332,9 +330,9 @@ dense matrix.   The default values for \var{Gl} and \var{hl} are matrices
 with zero rows.
 
 The argument \var{Gq} is a list of $M$ dense or sparse matrices 
-\var{G\_1}, \ldots, \var{G\_M}. 
+$G_1$, \ldots, $G_M$. 
 The argument \var{hq} is a list of $M$ dense single-column matrices 
-\var{h\_1}, \ldots, \var{h\_M}.  
+$h_1$, \ldots, $h_M$.  
 The elements of \var{Gq} and \var{hq} must have at least one row.
 The default values of \var{Gq} and \var{hq} are empty lists.
 
@@ -342,24 +340,35 @@ The default values of \var{Gq} and \var{hq} are empty lists.
 matrix.  The default values for \var{A} and \var{b} are matrices with 
 zero rows. 
 
+The \var{solver} argument is used to choose between two
+solvers: the CVXOPT \function{conelp()} solver 
+(used when \var{solver} is absent or
+equal to \None) and the external solver MOSEK 
+(\code{\var{solver}='mosek'}); see section~\ref{s-external}.
+With the \code{'mosek'} option the code does not accept problems with 
+equality constraints.
+
 \var{primalstart} and \var{dualstart} are dictionaries with optional 
 primal, respectively, dual starting points.
 \var{primalstart} has elements \code{'x'}, \code{'sl'}, \code{'sq'}.
 \code{primalstart['x']} and \code{primalstart['sl']} are single-column
-dense matrices with the initial values of {\it x} and {\it s\_0}; 
+ dense matrices with the initial values of $x$ and $s_0$; 
 \code{primalstart['sq']} is a list of single-column matrices with the
-initial values of {\it s\_1}, \ldots, {\it s\_M}.
+initial values of $s_1$, \ldots, $s_M$.
 The initial values must satisfy the inequalities in the primal problem 
 strictly, but not necessarily the equality constraints.
 
 \var{dualstart} has elements \code{'y'}, \code{'zl'}, \code{'zq'}.
 \code{dualstart['y']} and \code{dualstart['zl']} are single-column dense 
-matrices with the initial values of {\it y} and {\it z\_0}.
+matrices with the initial values of $y$ and $z_0$.
 \code{dualstart['zq']} is a list of single-column matrices with the 
-initial values of {\it z\_1}, \ldots, {\it z\_M}.  These values must
+initial values of $z_1$, \ldots, $z_M$.  These values must
 satisfy the dual inequalities strictly, but not necessarily the equality
 constraint.
 
+The arguments \var{primalstart} and \var{dualstart} are ignored when 
+the MOSEK solver is used.
+
 \function{socp()} returns a dictionary with keys \var{'status'},
 \var{'x'}, \var{'sl'}, \var{'sq'}, \var{'y'}, \var{'zl'}, \var{'zq'}.
 The meaning is similar to the output of \function{conelp()}.
@@ -453,7 +462,7 @@ We use the notation $\svec(z)$ to denote a symmetric matrix $z$
 stored in column major order as a column vector.
 
 The input argument \var{c} is a dense real matrix with one column of
-length {\it n}.
+length $n$.
 The arguments \var{Gl} and \var{hl} are the coefficient matrix $G_0$
 and the righthand side $h_0$ of the componentwise inequalities.
 \var{Gl} is a real dense or sparse matrix; \var{hl} is a real single-column
@@ -463,13 +472,13 @@ with zero rows.
 \var{Gs} and \var{hs} are lists of length $N$ that specify the 
 linear matrix inequality constraints.
 \var{Gs} is a list of $N$ dense or sparse real matrices  
-\code{G\_1}, \ldots, \code{G\_M}.
+$G_1$, \ldots, $G_M$.
 The columns of these matrices can be interpreted as 
 symmetric matrices stored in column major order, using the BLAS 'L'-type
 storage (\ie, only the entries corresponding to lower triangular positions
 are accessed). 
-\var{hs} is a list of $N$ dense symmetric matrices \code{h\_1},
-\ldots, \code{h\_N}.
+\var{hs} is a list of $N$ dense symmetric matrices $h_1$,
+\ldots, $h_N$.
 Only the lower triangular elements of these matrices are accessed.
 The default values for \code{Gs} and \code{hs} are empty lists.
 
@@ -489,18 +498,18 @@ The optional argument \var{primalstart} is a dictionary with keys
 \code{'x'}, \code{'sl'}, and \code{'ss'}, used as an optional primal 
 starting point. 
 \code{primalstart['x']} and \code{primalstart['sl']} are single-column
-dense matrices with the initial values of {\it x} and {\it s\_0}; 
+dense matrices with the initial values of $x$ and $s_0$; 
 \code{primalstart['ss']} is a list of square matrices with the
-initial values of {\it s\_1}, \ldots, {\it s\_N}.
+initial values of $s_1$, \ldots, $s_N$.
 The initial values must satisfy the inequalities in the primal problem 
 strictly, but not necessarily the equality constraints.
 
 \var{dualstart} is a dictionary with keys \code{'y'}, \code{'zl'}, 
 \code{'zs'}, used as an optional dual starting point.
 \code{dualstart['y']} and \code{dualstart['zl']} are single-column dense 
-matrices with the initial values of {\it y} and {\it z\_0}.
+matrices with the initial values of $y$ and $z_0$.
 \code{dualstart['zs']} is a list of square matrices with the 
-initial values of {\it z\_1}, \ldots, {\it z\_N}.  These values must
+initial values of $z_1$, \ldots, $z_N$.  These values must
 satisfy the dual inequalities strictly, but not necessarily the equality
 constraint.
 
@@ -592,8 +601,8 @@ triangular entries need to be provided, so in the example \var{h} and
 
 
 \section{Exploiting Structure} \label{s-conelp-struct}
-By default, the \function{conelp()} exploits no problem structure except 
-(to some limited extent) sparsity.  
+By default, the function \function{conelp()} exploits no problem 
+structure except (to some limited extent) sparsity.  
 Two mechanisms are provided for implementing customized solvers that 
 take advantage of problem structure.
 
@@ -619,7 +628,7 @@ We use the notation of~section~\ref{s-conelp}.  Suppose
  u_{\mathrm{q},k} \in\reals^{q_k}, \quad k = 0,\ldots,M-1, \qquad 
  u_{\mathrm{s},k} \in\symm^{p_k},  \quad k = 0,\ldots,N-1.
 \]
-Then {\it W} is a block-diagonal matrix, 
+Then $W$ is a block-diagonal matrix, 
 \[
  Wu = \left( W_\mathrm{l} u_\mathrm{l}, \;
  W_{\mathrm{q},0} u_{\mathrm{q},0}, \; \ldots, \;
@@ -630,7 +639,7 @@ Then {\it W} is a block-diagonal matrix,
 with the following diagonal blocks.
 \BIT
 \item The first block is a \emph{positive diagonal scaling} with a 
- vector {\it d}:
+ vector $d$:
 \[
   W_\mathrm{l} = \diag(d), \qquad W_\mathrm{l}^{-1} = \diag(d)^{-1}.
 \]
@@ -655,7 +664,7 @@ where
 \]
 These transformations are also symmetric:
 \[
-  W_\mathrm{q,k}^T = W_\mathrm{q,k}. 
+  W_{\mathrm{q},k}^T = W_{\mathrm{q},k}. 
 \]
 
 \item The last $N$ blocks are \emph{congruence transformations} with 
@@ -1148,8 +1157,9 @@ libraries.
 the simplex algorithm in 
 \ulink{GLPK (GNU Linear Programming Kit)}{http://www.gnu.org/software/glpk/glpk.html}.   
 
-\item[MOSEK] \function{lp()} with the \code{solver='mosek'} option uses 
-\ulink{MOSEK}{http://www.mosek.com} version 4.  
+\item[MOSEK] \function{lp()} and \function{socp()} with the 
+ \code{solver='mosek'} option use 
+ \ulink{MOSEK}{http://www.mosek.com} version 5.  
 
 \item[DSDP] \function{sdp()} with the \code{solver='dsdp'} option uses 
 the \ulink{DSDP5.8}{http://www-unix.mcs.anl.gov/DSDP} solver.  
@@ -1233,16 +1243,21 @@ parameter.  The command
 turns off the screen output subsequent calls \function{lp()} with 
 the \code{'glpk'} option.
 
-The MOSEK \ulink{control parameters}{http://www.mosek.com/fileadmin/products/3/tools/doc/html/tools/node22.html}
-are set to their default values.
-The corresponding keys in \code{solvers.options} are strings with the 
-name of the MOSEK parameter.  For example the command
+The MOSEK interior-point algorithm parameters are set to their default 
+values.  They can be modified by adding an entry 
+\code{solvers.options['MOSEK']}.  This entry is a dictionary with 
+MOSEK parameter/value pairs, with the parameter names imported from
+\module{pymosek}.  For details see Section 14.1.3 of the 
+\ulink{MOSEK Python API Manual}{http://www.mosek.com/fileadmin/products/5_0/tools/doc/html/pyapi/index.html}.
+
+For example the commands
 \begin{verbatim}
 >>> from cvxopt import solvers 
->>> solvers.options['MSK_IPAR_LOG'] = 0
+>>> import pymosek
+>>> solvers.options['MOSEK'] = {pymosek.iparam.log: 0}
 \end{verbatim}
-turns off the screen output during calls of  \function{lp()} 
-with the \code{'mosek'} option.
+turn off the screen output during calls of  \function{lp()} 
+or \function{socp()} with the \code{'mosek'} option.
 
 The following control parameters affect the DSDP algorithm:
 \begin{description}
diff --git a/doc/cvxopt.tex b/doc/cvxopt.tex
index b6e6bd4..6dcd337 100644
--- a/doc/cvxopt.tex
+++ b/doc/cvxopt.tex
@@ -1,5 +1,9 @@
 \documentclass{book}
-\usepackage{html,graphicx}
+%\usepackage{url,graphicx}
+%\usepackage{html,graphicx}
+\usepackage{graphicx}
+
+\parindent 0pt
 
 \def\BIT{\begin{itemize}}
 \def\EIT{\end{itemize}}
@@ -7,18 +11,19 @@
 \def\EEQ{\end{equation}}
 \def\reals{{\mbox{\bf R}}}
 \def\complex{{\mbox{\bf C}}}
-\newcommand{\eg}{{\em e.g.}}
-\newcommand{\ie}{{\em i.e.}}
+\newcommand{\eg}{{\rm e.g.}}
+\newcommand{\ie}{{\rm i.e.}}
 \newcommand{\BEA}{\begin{eqnarray}}
 \newcommand{\EEA}{\end{eqnarray}}
 \newcommand{\BEAS}{\begin{eqnarray*}}
 \newcommand{\EEAS}{\end{eqnarray*}}
 \newcommand{\Rank}{\mathop{\bf rank}}
 \newcommand{\Tr}{\mathop{\bf tr}}
-\newcommand{\lse}{\mathop{\bf lse}}
+\newcommand{\lse}{\mathop{\mathbf{lse}}}
 \newcommand{\diag}{\mbox{\bf diag}\,}
 \newcommand{\ones}{{\bf 1}}
-\newcommand{\argmax}{\mathop{\rm argmax}}
+\newcommand{\argmax}{\mathop{\mathrm{argmax}}}
+\renewcommand{\Rank}{\mathop{\mathrm{rank}}}
 \newcommand{\symm}{{\mbox{\bf S}}}  
 \newcommand{\op}{\mathop{\mathrm{op}}}
 \newcommand{\svec}{\mathop{\mathbf{vec}}}
@@ -44,13 +49,13 @@
     ({\tt #2})\begin{list}{}{}\item[]}{\end{list}}
 \newenvironment{funcdesc}[2]{\par{\bf #1}%
     ({\tt #2})\begin{list}{}{}\item[]}{\end{list}}
-\newenvironment{memberdesc}[3]{\par{\bf #2}%
+\newenvironment{memberdesc}[1]{\par{\bf #1}%
     \begin{list}{}{}\item[]}{\end{list}}
-\newenvironment{methoddesc}[3]{\par{\bf #2}()%
+\newenvironment{methoddesc}[1]{\par{\bf #1}()%
     \begin{list}{}{}\item[]}{\end{list}}
-\newenvironment{seealso}{\par{\bf See also:}\begin{list}{}{}\item[]}{\end{list}}
-%\renewcommand{\seealso}[1]{#1} 
+%\newenvironment{seealso}{\par{\bf See also:}\begin{itemize}\item}{\end{itemize}}
 \newcommand{\seetext}[1]{#1} 
+\newcommand{\htmladdnormallink}[2]{\Link[#2]{}{}{#1}\EndLink} 
 \newcommand{\ulink}[2]{\htmladdnormallink{#1}{#2}} 
 \newcommand{\seelink}[3]{\htmladdnormallink{#2}{#1}} 
 \newcommand{\citetitle}[2]{\htmladdnormallink{#2}{#1}} 
@@ -72,17 +77,17 @@
 \newcommand{\spmtrx}{\class{spmatrix}}
 
 
-%\title{CVXOPT: A Python Package for Convex Optimization}
 \title{CVXOPT User's Guide} 
 \author{Joachim Dahl \& Lieven Vandenberghe}
-%{\tt joachim at kom.aau.dk}, {\tt vandenbe at ee.ucla.edu}}
-\date{Release 0.9 -- August 10, 2007} 
-%\release{0.8.2}
+\date{Release 0.9.1 -- November 23, 2007} 
 
 \begin{document}
+\Configure{crosslinks*}{next}{prev}{up}{}
+
 \maketitle
 
 \chapter*{Copyright and License}
+
 Copyright \copyright{2004-2007} J. Dahl \& L. Vandenberghe. 
 
 CVXOPT is free software; you can redistribute it and/or modify
@@ -96,32 +101,30 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 See the
 \ulink{GNU General Public License}{http://www.gnu.org/licenses/gpl-3.0.html}
-for more details.
+for more details. \\
 
-\hrule
-The CVXOPT distribution includes source code for the following 
-software libraries.  
-\BIT
-\item Part of the SuiteSparse suite of sparse matrix algorithms, 
- including:
+\hrule 
+
+The CVXOPT distribution includes source code for part of the SuiteSparse 
+suite of sparse matrix algorithms, including:
 \BIT
-\item AMD Version 2.1.  Copyright (c) 2007 by Timothy A.\ Davis, 
- Patrick R.\ Amestoy, and Iain S.\ Duff.  
-\item CHOLMOD Version 1.5.  
+\item AMD Version 2.2.0.  
+ Copyright (c) 2007 by Timothy A.\ Davis, Patrick R.\ Amestoy, and 
+ Iain S.\ Duff.  
+\item CHOLMOD Version 1.6.0.  
  Copyright (c) 2005-2007 by University of Florida, Timothy A. Davis 
  and W. Hager.
-\item COLAMD version 2.7.  Copyright (c) 1998-2007 by Timothy A.\ Davis.
-\item UMFPACK Version 5.0.2. 
- Copyright (c) 1995-2006 by Timothy A.\  Davis.
+\item COLAMD version 2.7.0.  Copyright (c) 1998-2007 by Timothy A.\ Davis.
+\item UMFPACK Version 5.2.0.  Copyright (c) 1995-2006 by Timothy A.\  Davis.
 \EIT
 
 These packages are licensed under the terms of the 
-\ulink{GNU Lesser General Public License, version 2.1 or higher}
-{http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html} 
-(UMFPACK, parts of CHOLMOD, AMD, COLAMD) and the 
 \ulink{GNU General Public License, version 2 or higher}
 {http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} 
-(the Supernodal module of CHOLMOD).
+(UMFPACK, the Supernodal module of CHOLMOD) and the
+\ulink{GNU Lesser General Public License, version 2.1 or higher}
+{http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html} 
+(the other CHOLMOD modules, AMD, COLAMD).
 For copyright and license details, consult the README files in the source 
 directories or the website listed below.
 
@@ -130,18 +133,6 @@ Availability: \ulink{www.cise.ufl.edu/research/sparse}
 {http://www.cise.ufl.edu/research/sparse}.
 \end{quote}
 
-\item RNGS Random Number Generation --- Multiple Streams 
-(Sep. 22, 1998) by Steve Park \& Dave Geyer.
-
-\begin{quote}
-Availability: \ulink{www.cs.wm.edu/\~{}va/software/park/park.html}
-{http://www.cs.wm.edu/\~{}va/software/park/park.html}.
-\end{quote}
-
-\EIT
-
-%\tableofcontents
-
 \input{intro}
 \input{base}
 \input{blas}
@@ -153,5 +144,4 @@ Availability: \ulink{www.cs.wm.edu/\~{}va/software/park/park.html}
 \input{solvers}
 \input{modeling}
 \input{c-api}
-%\input{cvxopt.ind}
 \end{document}
diff --git a/doc/cvxopt/WARNINGS b/doc/cvxopt/WARNINGS
deleted file mode 100644
index 486bcce..0000000
--- a/doc/cvxopt/WARNINGS
+++ /dev/null
@@ -1 +0,0 @@
-No implementation found for style `graphicx'
diff --git a/doc/cvxopt/cvxopt.css b/doc/cvxopt/cvxopt.css
deleted file mode 100644
index b315a6b..0000000
--- a/doc/cvxopt/cvxopt.css
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
-.MATH    { font-family: "Century Schoolbook", serif; }
-.MATH I  { font-family: "Century Schoolbook", serif; font-style: italic }
-.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold }
-
-/* implement both fixed-size and relative sizes */
-SMALL.XTINY		{ font-size : xx-small }
-SMALL.TINY		{ font-size : x-small  }
-SMALL.SCRIPTSIZE	{ font-size : smaller  }
-SMALL.FOOTNOTESIZE	{ font-size : small    }
-SMALL.SMALL		{  }
-BIG.LARGE		{  }
-BIG.XLARGE		{ font-size : large    }
-BIG.XXLARGE		{ font-size : x-large  }
-BIG.HUGE		{ font-size : larger   }
-BIG.XHUGE		{ font-size : xx-large }
-
-/* heading styles */
-H1		{  }
-H2		{  }
-H3		{  }
-H4		{  }
-H5		{  }
-
-/* mathematics styles */
-DIV.displaymath		{ }	/* math displays */
-TD.eqno			{ }	/* equation-number cells */
-
-
-/* document-specific styles come next */
-DIV.navigation		{   }
-DIV.center		{   }
-DIV.quote		{   }
-PRE.preform		{   }
-SPAN.tt		{   }
-SPAN.textit		{ font-style: italic  }
-SPAN.arabic		{   }
-SPAN.textbf		{ font-weight: bold  }
diff --git a/doc/cvxopt/images.aux b/doc/cvxopt/images.aux
deleted file mode 100644
index f23e546..0000000
--- a/doc/cvxopt/images.aux
+++ /dev/null
@@ -1 +0,0 @@
-\relax 
diff --git a/doc/cvxopt/images.log b/doc/cvxopt/images.log
deleted file mode 100644
index 1896ed8..0000000
--- a/doc/cvxopt/images.log
+++ /dev/null
@@ -1,1281 +0,0 @@
-This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) (format=latex 2007.5.8)  9 AUG 2007 12:53
-entering extended mode
-**./images.tex
-(./images.tex
-LaTeX2e <2003/12/01>
-Babel <v3.8d> and hyphenation patterns for american, french, german, ngerman, b
-ahasa, basque, bulgarian, catalan, croatian, czech, danish, dutch, esperanto, e
-stonian, finnish, greek, icelandic, irish, italian, latin, magyar, norsk, polis
-h, portuges, romanian, russian, serbian, slovak, slovene, spanish, swedish, tur
-kish, ukrainian, nohyphenation, loaded.
-
-(/usr/share/texmf-tetex/tex/latex/base/book.cls
-Document Class: book 2004/02/16 v1.4f Standard LaTeX document class
-(/usr/share/texmf-tetex/tex/latex/base/bk10.clo
-File: bk10.clo 2004/02/16 v1.4f Standard LaTeX file (size option)
-)
-\c at part=\count79
-\c at chapter=\count80
-\c at section=\count81
-\c at subsection=\count82
-\c at subsubsection=\count83
-\c at paragraph=\count84
-\c at subparagraph=\count85
-\c at figure=\count86
-\c at table=\count87
-\abovecaptionskip=\skip41
-\belowcaptionskip=\skip42
-\bibindent=\dimen102
-) (/usr/share/texmf-tetex/tex/latex/base/ifthen.sty
-Package: ifthen 2001/05/26 v1.1c Standard LaTeX ifthen package (DPC)
-) (/usr/share/texmf/tex/latex/html/html.sty
-Package: html 1999/07/19 v1.38 hypertext commands for latex2html (nd, hws, rrm)
-
-\c at lpart=\count88
-\c at lchapter=\count89
-\c at lsection=\count90
-\c at lsubsection=\count91
-\c at lsubsubsection=\count92
-\c at lparagraph=\count93
-\c at lsubparagraph=\count94
-\c at lsubsubparagraph=\count95
-\ptrfile=\write3
-) (/usr/share/texmf-tetex/tex/latex/graphics/graphicx.sty
-Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
-(/usr/share/texmf-tetex/tex/latex/graphics/keyval.sty
-Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
-\KV at toks@=\toks14
-) (/usr/share/texmf-tetex/tex/latex/graphics/graphics.sty
-Package: graphics 2001/07/07 v1.0n Standard LaTeX Graphics (DPC,SPQR)
-(/usr/share/texmf-tetex/tex/latex/graphics/trig.sty
-Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
-) (/usr/share/texmf-tetex/tex/latex/graphics/graphics.cfg
-File: graphics.cfg 2005/02/03 v1.3 graphics configuration of teTeX/TeXLive
-)
-Package graphics Info: Driver file: dvips.def on input line 80.
-(/usr/share/texmf-tetex/tex/latex/graphics/dvips.def
-File: dvips.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
-))
-\Gin at req@height=\dimen103
-\Gin at req@width=\dimen104
-) (/usr/share/texmf-tetex/tex/latex/graphics/color.sty
-Package: color 1999/02/16 v1.0i Standard LaTeX Color (DPC)
-(/usr/share/texmf-tetex/tex/latex/graphics/color.cfg
-File: color.cfg 2005/02/03 v1.3 color configuration of teTeX/TeXLive
-)
-Package color Info: Driver file: dvips.def on input line 125.
-(/usr/share/texmf-tetex/tex/latex/graphics/dvipsnam.def
-File: dvipsnam.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
-)) (/usr/share/texmf-tetex/tex/latex/base/inputenc.sty
-Package: inputenc 2004/02/05 v1.0d Input encoding file
-(/usr/share/texmf-tetex/tex/latex/base/latin1.def
-File: latin1.def 2004/02/05 v1.0d Input encoding file
-))
-\sizebox=\box26
-\lthtmlwrite=\write4
-(./images.aux
-
-LaTeX Warning: Label `s-parameters' multiply defined.
-
-)
-\openout1 = `images.aux'.
-
-LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 210.
-LaTeX Font Info:    ... okay on input line 210.
-
-latex2htmlLength hsize=451.0pt
-
-latex2htmlLength vsize=554.0pt
-
-latex2htmlLength hoffset=0.0pt
-
-latex2htmlLength voffset=0.0pt
-
-latex2htmlLength topmargin=0.0pt
-
-latex2htmlLength topskip=0.00003pt
-
-latex2htmlLength headheight=0.0pt
-
-latex2htmlLength headsep=0.0pt
-
-latex2htmlLength parskip=0.0pt plus 1.0pt
-
-latex2htmlLength oddsidemargin=35.0pt
-
-latex2htmlLength evensidemargin=89.0pt
-
-LaTeX Font Info:    External font `cmex10' loaded for size
-(Font)              <7> on input line 247.
-LaTeX Font Info:    External font `cmex10' loaded for size
-(Font)              <5> on input line 247.
-l2hSize :eqnarraystar4063:138.31116pt::0.0pt::451.0pt.
-[1
-
-
-
-]
-l2hSize :eqnarraystar4070:138.31116pt::0.0pt::451.0pt.
-[2
-
-
-]
-l2hSize :eqnarraystar4081:279.62231pt::0.0pt::451.0pt.
-[3
-
-
-]
-l2hSize :displaymath4586:98.31116pt::0.0pt::451.0pt.
-[4
-
-
-]
-l2hSize :eqnarraystar4098:199.62231pt::0.0pt::451.0pt.
-[5
-
-
-]
-l2hSize :eqnarraystar4102:199.62231pt::0.0pt::451.0pt.
-[6
-
-
-]
-Overfull \hbox (3.89575pt too wide) in alignment at lines 393--424
- [][][] []
- []
-
-l2hSize :eqnarraystar4107:316.93347pt::0.0pt::451.0pt.
-[7
-
-
-]
-l2hSize :displaymath4587:12.0pt::0.0pt::451.0pt.
-[8
-
-
-]
-l2hSize :displaymath4588:14.5pt::0.0pt::451.0pt.
-[9
-
-
-]
-l2hSize :displaymath4589:14.5pt::0.0pt::451.0pt.
-[10
-
-
-]
-l2hSize :displaymath4590:22.8333pt::0.0pt::451.0pt.
-[11
-
-
-]
-l2hSize :displaymath4591:13.94444pt::0.0pt::451.0pt.
-[12
-
-
-]
-l2hSize :displaymath4592:13.94444pt::0.0pt::451.0pt.
-[13
-
-
-]
-l2hSize :displaymath4593:13.94444pt::0.0pt::451.0pt.
-[14
-
-
-]
-l2hSize :displaymath4594:13.94444pt::0.0pt::451.0pt.
-[15
-
-
-]
-l2hSize :displaymath4595:13.94444pt::0.0pt::451.0pt.
-[16
-
-
-]
-l2hSize :displaymath4596:14.5pt::0.0pt::451.0pt.
-[17
-
-
-]
-l2hSize :displaymath4597:13.94444pt::0.0pt::451.0pt.
-[18
-
-
-]
-l2hSize :displaymath4599:14.5pt::0.0pt::451.0pt.
-[19
-
-
-]
-l2hSize :displaymath4600:14.5pt::0.0pt::451.0pt.
-[20
-
-
-]
-l2hSize :displaymath4601:14.5pt::0.0pt::451.0pt.
-[21
-
-
-]
-l2hSize :displaymath4604:14.5pt::0.0pt::451.0pt.
-[22
-
-
-]
-l2hSize :displaymath4605:14.5pt::0.0pt::451.0pt.
-[23
-
-
-]
-l2hSize :displaymath4606:13.94444pt::0.0pt::451.0pt.
-[24
-
-
-]
-l2hSize :displaymath4607:13.94444pt::0.0pt::451.0pt.
-[25
-
-
-]
-l2hSize :displaymath4608:13.94444pt::0.0pt::451.0pt.
-[26
-
-
-]
-l2hSize :displaymath4609:13.94444pt::0.0pt::451.0pt.
-[27
-
-
-]
-l2hSize :displaymath4610:14.5pt::0.0pt::451.0pt.
-[28
-
-
-]
-l2hSize :displaymath4611:13.94444pt::0.0pt::451.0pt.
-[29
-
-
-]
-l2hSize :displaymath4612:37.00034pt::0.0pt::451.0pt.
-[30
-
-
-]
-l2hSize :displaymath4613:14.5pt::0.0pt::451.0pt.
-[31
-
-
-]
-l2hSize :displaymath4614:37.0246pt::0.0pt::451.0pt.
-[32
-
-
-]
-l2hSize :displaymath4615:14.5pt::0.0pt::451.0pt.
-[33
-
-
-]
-l2hSize :displaymath4617:37.0246pt::0.0pt::451.0pt.
-[34
-
-
-]
-Overfull \hbox (15.38872pt too wide) detected at line 692
-\OML/cmm/m/it/10 B \OT1/cmr/m/n/10 := \OML/cmm/m/it/10 
 []\OT1/cmr/m/n/10 (\OM
-L/cmm/m/it/10 A\OT1/cmr/m/n/10 )[]\OML/cmm/m/it/10 B \OT1/cmr/m/n/10 ([] = [])\
-OML/cmm/m/it/10 ;  B \OT1/cmr/m/n/10 := \OML/cmm/m/it/10 
B []\OT1/cmr/m/n/10 (
-\OML/cmm/m/it/10 A\OT1/cmr/m/n/10 )[] ([] = [])\OML/cmm/m/it/10 ;  []\OT1/cmr/m
-/n/10 (\OML/cmm/m/it/10 A\OT1/cmr/m/n/10 ) = []
- []
-
-l2hSize :displaymath4618:37.0246pt::0.0pt::451.0pt.
-[35
-
-
-]
-l2hSize :displaymath4619:14.5pt::0.0pt::451.0pt.
-[36
-
-
-]
-l2hSize :displaymath4620:14.5pt::0.0pt::451.0pt.
-[37
-
-
-]
-l2hSize :displaymath4621:14.5pt::0.0pt::451.0pt.
-[38
-
-
-]
-l2hSize :displaymath4622:14.5pt::0.0pt::451.0pt.
-[39
-
-
-]
-l2hSize :tex2html_wrap_inline8374:8.41226pt::0.0pt::6.70839pt.
-[40
-
-
-]
-l2hSize :displaymath8292:13.94444pt::0.0pt::451.0pt.
-[41
-
-
-]
-l2hSize :displaymath8293:12.0pt::0.0pt::451.0pt.
-[42
-
-
-]
-l2hSize :displaymath8294:14.5pt::0.0pt::451.0pt.
-[43
-
-
-]
-l2hSize :displaymath8295:14.5pt::0.0pt::451.0pt.
-[44
-
-
-]
-l2hSize :displaymath8298:49.00046pt::0.0pt::451.0pt.
-[45
-
-
-]
-l2hSize :displaymath8302:12.0pt::0.0pt::451.0pt.
-[46
-
-
-]
-l2hSize :displaymath8303:12.0pt::0.0pt::451.0pt.
-[47
-
-
-]
-l2hSize :displaymath7646:25.0123pt::0.0pt::451.0pt.
-[48
-
-
-]
-l2hSize :displaymath8304:14.5pt::0.0pt::451.0pt.
-[49
-
-
-]
-l2hSize :tex2html_wrap_inline8376:8.41226pt::0.0pt::6.70839pt.
-[50
-
-
-]
-l2hSize :tex2html_wrap_inline8378:8.41226pt::0.0pt::6.90285pt.
-[51
-
-
-]
-l2hSize :displaymath8311:12.0pt::0.0pt::451.0pt.
-[52
-
-
-]
-l2hSize :tex2html_wrap_inline8390:6.83331pt::0.0pt::8.00005pt.
-[53
-
-
-]
-l2hSize :displaymath8314:12.0pt::0.0pt::451.0pt.
-[54
-
-
-]
-l2hSize :displaymath8318:15.5pt::0.0pt::451.0pt.
-[55
-
-
-]
-l2hSize :displaymath8319:25.0pt::0.0pt::451.0pt.
-[56
-
-
-]
-l2hSize :displaymath8320:25.0123pt::0.0pt::451.0pt.
-[57
-
-
-]
-l2hSize :displaymath8321:15.50615pt::0.0pt::451.0pt.
-[58
-
-
-]
-l2hSize :displaymath8322:25.0123pt::0.0pt::451.0pt.
-[59
-
-
-]
-l2hSize :displaymath8323:15.50615pt::0.0pt::451.0pt.
-[60
-
-
-]
-l2hSize :displaymath8324:13.94444pt::0.0pt::451.0pt.
-[61
-
-
-]
-l2hSize :displaymath8325:25.0123pt::0.0pt::451.0pt.
-[62
-
-
-]
-l2hSize :displaymath8326:37.0246pt::0.0pt::451.0pt.
-[63
-
-
-]
-l2hSize :displaymath8327:14.5pt::0.0pt::451.0pt.
-[64
-
-
-]
-l2hSize :displaymath8328:14.5pt::0.0pt::451.0pt.
-[65
-
-
-]
-l2hSize :displaymath8126:14.5pt::0.0pt::451.0pt.
-[66
-
-
-]
-l2hSize :tex2html_wrap_inline8408:6.83331pt::0.0pt::8.58684pt.
-[67
-
-
-]
-l2hSize :displaymath8329:14.5pt::0.0pt::451.0pt.
-[68
-
-
-]
-l2hSize :displaymath8330:13.94444pt::0.0pt::451.0pt.
-[69
-
-
-]
-l2hSize :tex2html_wrap_inline8412:8.41226pt::0.0pt::16.14032pt.
-[70
-
-
-]
-l2hSize :displaymath8331:15.50615pt::0.0pt::451.0pt.
-[71
-
-
-]
-l2hSize :displaymath8332:14.5pt::0.0pt::451.0pt.
-[72
-
-
-]
-l2hSize :tex2html_wrap_inline8414:8.91226pt::8.91226pt::12.08557pt.
-[73
-
-
-]
-l2hSize :displaymath10727:33.1709pt::0.0pt::451.0pt.
-[74
-
-
-]
-l2hSize :displaymath10728:33.1709pt::0.0pt::451.0pt.
-[75
-
-
-]
-Overfull \hbox (9.4698pt too wide) in alignment at lines 1074--1088
- [][][] []
- []
-
-l2hSize :eqnarraystar10717:141.6836pt::0.0pt::451.0pt.
-[76
-
-
-]
-Overfull \hbox (2.62268pt too wide) in alignment at lines 1095--1110
- [][][] []
- []
-
-l2hSize :eqnarraystar10723:141.6836pt::0.0pt::451.0pt.
-[77
-
-
-]
-l2hSize :displaymath11487:49.00046pt::0.0pt::451.0pt.
-[78
-
-
-]
-l2hSize :displaymath12088:14.5pt::0.0pt::451.0pt.
-[79
-
-
-]
-l2hSize :displaymath12089:14.5pt::0.0pt::451.0pt.
-[80
-
-
-]
-l2hSize :displaymath11622:49.00046pt::0.0pt::451.0pt.
-[81
-
-
-]
-l2hSize :displaymath12091:13.94444pt::0.0pt::451.0pt.
-[82
-
-
-]
-l2hSize :displaymath12095:49.00046pt::0.0pt::451.0pt.
-[83
-
-
-]
-l2hSize :displaymath12096:49.00046pt::0.0pt::451.0pt.
-[84
-
-
-]
-l2hSize :displaymath13881:49.00046pt::0.0pt::451.0pt.
-[85
-
-
-]
-l2hSize :displaymath13754:61.00058pt::0.0pt::451.0pt.
-[86
-
-
-]
-l2hSize :displaymath13884:61.00058pt::0.0pt::451.0pt.
-[87
-
-
-]
-l2hSize :displaymath13885:12.0pt::0.0pt::451.0pt.
-[88
-
-
-]
-l2hSize :tex2html_wrap_inline13901:8.41226pt::0.0pt::6.90285pt.
-[89
-
-
-]
-l2hSize :displaymath13792:49.00046pt::0.0pt::451.0pt.
-[90
-
-
-]
-l2hSize :displaymath13816:13.94444pt::0.0pt::451.0pt.
-[91
-
-
-]
-l2hSize :displaymath13818:13.94444pt::0.0pt::451.0pt.
-[92
-
-
-]
-l2hSize :tex2html_wrap_inline13903:6.83331pt::0.0pt::38.4895pt.
-[93
-
-
-]
-l2hSize :tex2html_wrap_inline13905:8.41226pt::0.0pt::59.45723pt.
-[94
-
-
-]
-l2hSize :tex2html_wrap_inline13907:6.83331pt::0.0pt::53.15758pt.
-[95
-
-
-]
-l2hSize :tex2html_wrap_inline13909:8.41226pt::0.0pt::52.65166pt.
-[96
-
-
-]
-l2hSize :tex2html_wrap_inline13911:6.83331pt::0.0pt::37.79506pt.
-[97
-
-
-]
-l2hSize :tex2html_wrap_inline13913:8.41226pt::0.0pt::44.09471pt.
-[98
-
-
-]
-l2hSize :tex2html_wrap_inline13915:6.83331pt::0.0pt::39.54643pt.
-[99
-
-
-]
-l2hSize :tex2html_wrap_inline13917:8.41226pt::0.0pt::45.09818pt.
-[100
-
-
-]
-l2hSize :tex2html_wrap_inline13919:6.83331pt::0.0pt::38.79852pt.
-[101
-
-
-]
-l2hSize :tex2html_wrap_inline13921:8.41226pt::0.0pt::13.60526pt.
-[102
-
-
-]
-l2hSize :tex2html_wrap_inline13923:8.41226pt::0.0pt::14.89034pt.
-[103
-
-
-]
-l2hSize :displaymath13872:25.0pt::0.0pt::451.0pt.
-[104
-
-
-]
-l2hSize :tex2html_wrap_inline13927:6.83331pt::0.0pt::8.52782pt.
-[105
-
-
-]
-l2hSize :tex2html_wrap_inline13929:6.83331pt::0.0pt::7.20834pt.
-[106
-
-
-]
-l2hSize :displaymath13887:14.5pt::0.0pt::451.0pt.
-[107
-
-
-]
-l2hSize :displaymath13888:15.50006pt::0.0pt::451.0pt.
-[108
-
-
-]
-l2hSize :displaymath13889:15.5pt::0.0pt::451.0pt.
-[109
-
-
-]
-l2hSize :eqnarraystar13565:62.91235pt::0.0pt::451.0pt.
-[110
-
-
-]
-l2hSize :displaymath15763:37.0123pt::0.0pt::451.0pt.
-[111
-
-
-]
-l2hSize :displaymath15279:51.60004pt::0.0pt::451.0pt.
-[112
-
-
-]
-l2hSize :tex2html_wrap_inline15841:7.33331pt::7.33331pt::25.27213pt.
-[113
-
-
-]
-l2hSize :tex2html_wrap_inline15843:7.33331pt::7.33331pt::25.67493pt.
-[114
-
-
-]
-l2hSize :tex2html_wrap_inline15845:6.83331pt::0.0pt::8.36252pt.
-[115
-
-
-]
-l2hSize :displaymath15764:14.33333pt::0.0pt::451.0pt.
-[116
-
-
-]
-Overfull \hbox (251.01503pt too wide) detected at line 1487
-\OML/cmm/m/it/10 C[] \OT1/cmr/m/n/10 = \OMS/cmsy/m/n/10 f\OML/cmm/m/it/10 u \OM
-S/cmsy/m/n/10 2 [][] j \OML/cmm/m/it/10 u[] \OMS/cmsy/m/n/10 ^^U \OT1/cmr/m/n/1
-0 0\OML/cmm/m/it/10 ;  k \OT1/cmr/m/n/10 = 1\OML/cmm/m/it/10 ; [] ; l\OMS/cmsy/
-m/n/10 g\OML/cmm/m/it/10 ;  C[] \OT1/cmr/m/n/10 = \OMS/cmsy/m/n/10 f\OT1/cmr/m/
-n/10 (\OML/cmm/m/it/10 u[]; u[]\OT1/cmr/m/n/10 ) \OMS/cmsy/m/n/10 2 [] ^^B [][]
- j \OML/cmm/m/it/10 u[] \OMS/cmsy/m/n/10 ^^U k\OML/cmm/m/it/10 u[]\OMS/cmsy/m/n
-/10 k[]g\OML/cmm/m/it/10 ;  k \OT1/cmr/m/n/10 = 0\OML/cmm/m/it/10 ; [] ; M \OMS
-/cmsy/m/n/10 ^^@ \OT1/cmr/m/n/10 1\OML/cmm/m/it/10 ;  C[] \OT1/cmr/m/n/10 = [] 
-\OML/cmm/m/it/10 ;  k \OT1/cmr/m/n/10 = 0\OML/cmm/m/it/10 ; [] ; N \OMS/cmsy/m/
-n/10 ^^@ \OT1/cmr/m/n/10 1\OML/cmm/m/it/10 :
- []
-
-l2hSize :displaymath15765:15.50006pt::0.0pt::451.0pt.
-[117
-
-
-]
-l2hSize :tex2html_wrap_inline15847:8.0pt::8.0pt::30.13428pt.
-[118
-
-
-]
-l2hSize :displaymath15766:32.3112pt::0.0pt::451.0pt.
-[119
-
-
-]
-l2hSize :displaymath15767:13.94444pt::0.0pt::451.0pt.
-[120
-
-
-]
-l2hSize :tex2html_wrap_inline15849:6.94444pt::0.0pt::3.6806pt.
-[121
-
-
-]
-l2hSize :displaymath15768:13.94444pt::0.0pt::451.0pt.
-[122
-
-
-]
-l2hSize :displaymath15769:13.94444pt::0.0pt::451.0pt.
-[123
-
-
-]
-l2hSize :displaymath15770:13.94444pt::0.0pt::451.0pt.
-[124
-
-
-]
-l2hSize :displaymath15771:25.00023pt::0.0pt::451.0pt.
-[125
-
-
-]
-Overfull \hbox (113.61066pt too wide) detected at line 1576
-[]
- []
-
-l2hSize :displaymath15772:121.88489pt::0.0pt::451.0pt.
-[126
-
-
-]
-l2hSize :displaymath15774:51.60004pt::0.0pt::451.0pt.
-[127
-
-
-]
-l2hSize :displaymath15775:63.60004pt::0.0pt::451.0pt.
-[128
-
-
-]
-l2hSize :displaymath15776:13.94444pt::0.0pt::451.0pt.
-[129
-
-
-]
-l2hSize :displaymath15777:14.5pt::0.0pt::451.0pt.
-[130
-
-
-]
-l2hSize :tex2html_wrap_inline15855:7.33331pt::7.33331pt::12.84865pt.
-[131
-
-
-]
-l2hSize :tex2html_wrap_inline15857:7.44444pt::7.44444pt::10.74774pt.
-[132
-
-
-]
-l2hSize :tex2html_wrap_inline15859:6.83331pt::0.0pt::11.29169pt.
-[133
-
-
-]
-l2hSize :displaymath15778:84.82268pt::0.0pt::451.0pt.
-[134
-
-
-]
-Overfull \hbox (79.73811pt too wide) detected at line 1691
-[]  []
- []
-
-l2hSize :displaymath15779:75.60004pt::0.0pt::451.0pt.
-[135
-
-
-]
-l2hSize :tex2html_wrap_inline15863:8.0pt::8.0pt::29.5pt.
-[136
-
-
-]
-l2hSize :tex2html_wrap_inline15865:6.45831pt::0.0pt::5.59033pt.
-[137
-
-
-]
-l2hSize :tex2html_wrap_inline15871:6.83331pt::0.0pt::9.625pt.
-[138
-
-
-]
-Overfull \hbox (23.82675pt too wide) detected at line 1747
-[]
- []
-
-l2hSize :displaymath15781:73.00056pt::0.0pt::451.0pt.
-[139
-
-
-]
-l2hSize :displaymath15597:37.0246pt::0.0pt::451.0pt.
-[140
-
-
-]
-l2hSize :tex2html_wrap_inline15877:6.83331pt::0.0pt::11.33337pt.
-[141
-
-
-]
-Overfull \hbox (165.61256pt too wide) detected at line 1780
-\OML/cmm/m/it/10 u \OT1/cmr/m/n/10 = [] \OML/cmm/m/it/10 ;  u[] \OMS/cmsy/m/n/1
-0 2 [][]\OML/cmm/m/it/10 ;  u[] \OMS/cmsy/m/n/10 2 [][]\OML/cmm/m/it/10 ;  k \O
-T1/cmr/m/n/10 = 0\OML/cmm/m/it/10 ; [] ; M \OMS/cmsy/m/n/10 ^^@ \OT1/cmr/m/n/10
- 1\OML/cmm/m/it/10 ;  u[] \OMS/cmsy/m/n/10 2 [][]\OML/cmm/m/it/10 ;  k \OT1/cmr
-/m/n/10 = 0\OML/cmm/m/it/10 ; [] ; N \OMS/cmsy/m/n/10 ^^@ \OT1/cmr/m/n/10 1\OML
-/cmm/m/it/10 :
- []
-
-l2hSize :displaymath15782:14.86108pt::0.0pt::451.0pt.
-[142
-
-
-]
-l2hSize :displaymath15783:14.86108pt::0.0pt::451.0pt.
-[143
-
-
-]
-l2hSize :displaymath15784:15.01659pt::0.0pt::451.0pt.
-[144
-
-
-]
-l2hSize :displaymath15785:14.47217pt::0.0pt::451.0pt.
-[145
-
-
-]
-l2hSize :displaymath15786:23.01347pt::0.0pt::451.0pt.
-[146
-
-
-]
-l2hSize :displaymath15787:25.00023pt::0.0pt::451.0pt.
-[147
-
-
-]
-l2hSize :displaymath15788:15.83327pt::0.0pt::451.0pt.
-[148
-
-
-]
-l2hSize :displaymath15789:16.37769pt::0.0pt::451.0pt.
-[149
-
-
-]
-Overfull \hbox (2.37782pt too wide) detected at line 1863
-\OML/cmm/m/it/10 W[] [] [] \OT1/cmr/m/n/10 = [] []\OML/cmm/m/it/10 ;   W[] [] [
-] \OT1/cmr/m/n/10 = [] []\OML/cmm/m/it/10 ;   k \OT1/cmr/m/n/10 = 0\OML/cmm/m/i
-t/10 ; [] ; N \OMS/cmsy/m/n/10 ^^@ \OT1/cmr/m/n/10 1\OML/cmm/m/it/10 :
- []
-
-l2hSize :displaymath15790:16.37769pt::0.0pt::451.0pt.
-[150
-
-
-]
-l2hSize :tex2html_wrap_inline15883:6.83331pt::0.0pt::8.36252pt.
-[151
-
-
-]
-l2hSize :displaymath15791:14.86108pt::0.0pt::451.0pt.
-[152
-
-
-]
-l2hSize :displaymath15792:14.5pt::0.0pt::451.0pt.
-[153
-
-
-]
-l2hSize :displaymath15793:14.5pt::0.0pt::451.0pt.
-[154
-
-
-]
-l2hSize :displaymath15794:15.5pt::0.0pt::451.0pt.
-[155
-
-
-]
-l2hSize :displaymath15795:25.0123pt::0.0pt::451.0pt.
-[156
-
-
-]
-l2hSize :displaymath15796:25.0123pt::0.0pt::451.0pt.
-[157
-
-
-]
-l2hSize :displaymath15797:25.0pt::0.0pt::451.0pt.
-[158
-
-
-]
-Overfull \hbox (17.80594pt too wide) detected at line 1957
-\OML/cmm/m/it/10 s \OMS/cmsy/m/n/10 ^^W \OT1/cmr/m/n/10 0\OML/cmm/m/it/10 ;  z 
-\OMS/cmsy/m/n/10 ^^W \OT1/cmr/m/n/10 0\OML/cmm/m/it/10 ;   [] \OMS/cmsy/m/n/10 
-^^T \OML/cmm/m/it/10 ^^O[];  [] \OMS/cmsy/m/n/10 ^^T \OML/cmm/m/it/10 ^^O[];  [
-] \OMS/cmsy/m/n/10 ^^T \OML/cmm/m/it/10 ^^O[];
- []
-
-l2hSize :displaymath15798:25.53685pt::0.0pt::451.0pt.
-[159
-
-
-]
-l2hSize :displaymath15799:25.67746pt::0.0pt::451.0pt.
-[160
-
-
-]
-l2hSize :displaymath15800:25.53685pt::0.0pt::451.0pt.
-[161
-
-
-]
-l2hSize :displaymath15801:24.62459pt::0.0pt::451.0pt.
-[162
-
-
-]
-l2hSize :displaymath17449:49.0pt::0.0pt::451.0pt.
-[163
-
-
-]
-l2hSize :tex2html_wrap_inline17867:8.0pt::8.0pt::71.67934pt.
-[164
-
-
-]
-l2hSize :displaymath17815:14.5pt::0.0pt::451.0pt.
-[165
-
-
-]
-l2hSize :displaymath17816:14.5pt::0.0pt::451.0pt.
-[166
-
-
-]
-l2hSize :tex2html_wrap_inline17871:9.81749pt::9.81749pt::71.67934pt.
-[167
-
-
-]
-l2hSize :displaymath17817:14.47217pt::0.0pt::451.0pt.
-[168
-
-
-]
-l2hSize :displaymath17818:50.83505pt::0.0pt::451.0pt.
-[169
-
-
-]
-l2hSize :tex2html_wrap_inline17873:7.44444pt::7.44444pt::10.19102pt.
-[170
-
-
-]
-l2hSize :tex2html_wrap_inline17875:7.44444pt::7.44444pt::10.19102pt.
-[171
-
-
-]
-l2hSize :displaymath17819:25.0pt::0.0pt::451.0pt.
-[172
-
-
-]
-l2hSize :displaymath17820:15.5pt::0.0pt::451.0pt.
-[173
-
-
-]
-Overfull \hbox (28.66281pt too wide) detected at line 2115
-[]
- []
-
-l2hSize :displaymath17821:85.0pt::0.0pt::451.0pt.
-[174
-
-
-]
-l2hSize :displaymath17822:13.94444pt::0.0pt::451.0pt.
-[175
-
-
-]
-File: figures/floorplan.eps Graphic file (type eps)
-<figures/floorplan.eps>
-l2hSize :tex2html_wrap22797:320.09381pt::0.0pt::451.0pt.
-[176
-
-
-]
-l2hSize :displaymath17823:37.0123pt::0.0pt::451.0pt.
-[177
-
-
-]
-l2hSize :displaymath17824:13.94444pt::0.0pt::451.0pt.
-[178
-
-
-]
-l2hSize :displaymath17826:13.94444pt::0.0pt::451.0pt.
-[179
-
-
-]
-l2hSize :displaymath17827:25.0246pt::0.0pt::451.0pt.
-[180
-
-
-]
-File: figures/portfolio1.eps Graphic file (type eps)
-<figures/portfolio1.eps>
-l2hSize :tex2html_wrap22809:213.39587pt::0.0pt::451.0pt.
-[181
-
-
-]
-File: figures/portfolio2.eps Graphic file (type eps)
-<figures/portfolio2.eps>
-l2hSize :tex2html_wrap22810:213.39587pt::0.0pt::451.0pt.
-[182
-
-
-]
-l2hSize :displaymath17828:49.0pt::0.0pt::451.0pt.
-[183
-
-
-]
-l2hSize :displaymath17829:25.02782pt::0.0pt::451.0pt.
-[184
-
-
-]
-Overfull \hbox (18.45276pt too wide) detected at line 2220
-\OMS/cmsy/m/n/10 r\OML/cmm/m/it/10 f[]\OT1/cmr/m/n/10 (\OML/cmm/m/it/10 x\OT1/c
-mr/m/n/10 ) + [] \OML/cmm/m/it/10 z[]\OMS/cmsy/m/n/10 r\OML/cmm/m/it/10 f[]\OT1
-/cmr/m/n/10 (\OML/cmm/m/it/10 x\OT1/cmr/m/n/10 ) + \OML/cmm/m/it/10 G[]z[] \OT1
-/cmr/m/n/10 + \OML/cmm/m/it/10 A[]y \OT1/cmr/m/n/10 = 0\OML/cmm/m/it/10 ;  f[]\
-OT1/cmr/m/n/10 (\OML/cmm/m/it/10 x\OT1/cmr/m/n/10 ) + \OML/cmm/m/it/10 s[] \OT1
-/cmr/m/n/10 = 0\OML/cmm/m/it/10 ;  k \OT1/cmr/m/n/10 = 1\OML/cmm/m/it/10 ; [] ;
- m;  Gx \OT1/cmr/m/n/10 + \OML/cmm/m/it/10 s[] \OT1/cmr/m/n/10 = \OML/cmm/m/it/
-10 h;  Ax \OT1/cmr/m/n/10 = \OML/cmm/m/it/10 b
- []
-
-l2hSize :displaymath17830:30.54175pt::0.0pt::451.0pt.
-[185
-
-
-]
-l2hSize :displaymath17832:85.0pt::0.0pt::451.0pt.
-[186
-
-
-]
-l2hSize :eqnarraystar17683:75.22586pt::0.0pt::451.0pt.
-[187
-
-
-]
-l2hSize :displaymath17833:30.54175pt::0.0pt::451.0pt.
-[188
-
-
-]
-l2hSize :displaymath17836:15.5pt::0.0pt::451.0pt.
-[189
-
-
-]
-l2hSize :displaymath17837:25.0123pt::0.0pt::451.0pt.
-[190
-
-
-]
-Overfull \hbox (16.92455pt too wide) detected at line 2299
-[] \OMS/cmsy/m/n/10 ^^T \OML/cmm/m/it/10 ^^O[];  [] \OMS/cmsy/m/n/10 ^^T \OML/c
-mm/m/it/10 ^^O[]
- []
-
-l2hSize :displaymath17838:27.79999pt::0.0pt::451.0pt.
-[191
-
-
-]
-l2hSize :displaymath17839:25.00023pt::0.0pt::451.0pt.
-[192
-
-
-]
-l2hSize :displaymath17840:27.31137pt::0.0pt::451.0pt.
-[193
-
-
-]
-l2hSize :displaymath19892:14.5pt::0.0pt::451.0pt.
-[194
-
-
-]
-l2hSize :eqnarraystar19548:81.00069pt::0.0pt::451.0pt.
-[195
-
-
-]
-l2hSize :displaymath19893:32.3112pt::0.0pt::451.0pt.
-[196
-
-
-]
-l2hSize :displaymath19894:32.3112pt::0.0pt::451.0pt.
-[197
-
-
-]
-l2hSize :displaymath19895:37.00037pt::0.0pt::451.0pt.
-[198
-
-
-]
-l2hSize :displaymath19896:14.5pt::0.0pt::451.0pt.
-[199
-
-
-]
-l2hSize :tex2html_wrap_inline19918:7.44444pt::7.44444pt::6.47229pt.
-[200
-
-
-]
-l2hSize :displaymath19897:13.94444pt::0.0pt::451.0pt.
-[201
-
-
-]
-l2hSize :displaymath19898:49.0pt::0.0pt::451.0pt.
-[202
-
-
-]
-l2hSize :displaymath19899:15.5pt::0.0pt::451.0pt.
-[203
-
-
-]
-l2hSize :displaymath19900:37.00037pt::0.0pt::451.0pt.
-[204
-
-
-]
-File: figures/normappr.eps Graphic file (type eps)
-<figures/normappr.eps>
-l2hSize :tex2html_wrap22898:338.24954pt::0.0pt::451.0pt.
-[205
-
-
-]
-l2hSize :displaymath19901:25.61899pt::0.0pt::451.0pt.
-[206
-
-
-]
-l2hSize :displaymath19902:25.0246pt::0.0pt::451.0pt.
-[207
-
-
-]
-l2hSize :displaymath19903:37.0246pt::0.0pt::451.0pt.
-[208
-
-
-]
-l2hSize :displaymath19904:37.0123pt::0.0pt::451.0pt.
-[209
-
-
-]
-l2hSize :displaymath21247:49.00046pt::0.0pt::451.0pt.
-[210
-
-
-] (./images.aux)
-
-LaTeX Warning: There were multiply-defined labels.
-
- ) 
-Here is how much of TeX's memory you used:
- 1225 strings out of 94501
- 15203 string characters out of 1175812
- 72667 words of memory out of 1000000
- 4432 multiletter control sequences out of 10000+50000
- 4567 words of font info for 17 fonts, out of 500000 for 2000
- 580 hyphenation exceptions out of 8191
- 25i,15n,19p,185b,225s stack positions out of 1500i,500n,5000p,200000b,5000s
-
-Output written on images.dvi (210 pages, 100432 bytes).
diff --git a/doc/cvxopt/images.pl b/doc/cvxopt/images.pl
deleted file mode 100644
index d4d4cbd..0000000
--- a/doc/cvxopt/images.pl
+++ /dev/null
@@ -1,1932 +0,0 @@
-# LaTeX2HTML 2002-2-1 (1.71)
-# Associate images original text with physical files.
-
-
-$key = q/{displaymath}W_{mathrm{q},k}=beta_k(2v_kv_k^T-J),qquadW_{mathrm{q},k}^{-1}=frac{1}{beta_k}(2Jv_kv_k^TJ-J),qquadk=0,ldots,M-1,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="535" HEIGHT="41" BORDER="0"
- SRC="|."$dir".q|img146.gif"
- ALT="\begin{displaymath}
-W_{\mathrm{q},k} = \beta_k ( 2 v_k v_k^T - J),
-\qquad
-W_{...
-...c{1}{\beta_k} ( 2 Jv_k v_k^T J - J),
-\qquad k = 0,\ldots,M-1,
-\end{displaymath}">|; 
-
-$key = q/DL^TX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="87" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img96.gif"
- ALT="$DL^TX=B$">|; 
-
-$key = q/mathrm{{}^H};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="15" HEIGHT="18" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img89.gif"
- ALT="$\mathrm{{}^H}$">|; 
-
-$key = q/{displaymath}PAP^T=LDL^T,qquadPAP^T=LDL^H,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="272" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img92.gif"
- ALT="\begin{displaymath}
-PAP^T = LDL^T, \qquad PAP^T = LDL^H,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}f(x_1,ldots,x_n)=0,qquadf(x_1,ldots,x_n)preceq0,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="283" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img199.gif"
- ALT="\begin{displaymath}
-f(x_1,\ldots,x_n) = 0, \qquad f(x_1,\ldots,x_n) \preceq 0,
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}&left[array{{ccccc}ReX[0,0]&barX[1,0]&barX[2,0]&cdots&barX[n-1,0]Xdots&ReX[n-1,n-1]array{right]&mbox{ifuplo='U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="563" HEIGHT="225" BORDER="0"
- SRC="|."$dir".q|img2.gif"
- ALT="\begin{eqnarray*}
-&
-\left[\begin{array}{ccccc}
-\Re X[0,0] & \bar X[1,0] & \bar X...
-...dots & \Re X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'U'}.
-\end{eqnarray*}">|; 
-
-$key = q/{eqnarraystar}mbox{DCT-I:}qquadX[k,:]&:=&X[0,:]+(-1)^kX[n-1,:]+2sum_{j=1}^{n-2}X+1slash2)(k+1slash2)slashn),qquadk=0,ldots,n-1.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="731" HEIGHT="230" BORDER="0"
- SRC="|."$dir".q|img76.gif"
- ALT="\begin{eqnarray*}
-\mbox{DCT-I:} \qquad
-X[k,:] & := & X[0,:] + (-1)^k X[n-1,:] +...
-...n-1} X[j,:] \cos(\pi (j+1/2)(k+1/2)/n),
-\qquad k=0,\ldots,n-1.
-\end{eqnarray*}">|; 
-
-$key = q/L^TX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="74" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img98.gif"
- ALT="$L^TX=B$">|; 
-
-$key = q/{displaymath}mathrm{gap}=left[array{{c}s_mathrm{nl}s_mathrm{l}array{right]^Tleft+z_mathrm{nl}^Ttildef(x)+z_mathrm{l}^T(Gx-h)+y^T(Ax-b).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="594" HEIGHT="48" BORDER="0"
- SRC="|."$dir".q|img193.gif"
- ALT="\begin{displaymath}
-\mathrm{gap} =
-\left[\begin{array}{c} s_\mathrm{nl} \ s_\...
-...athrm{nl}^T \tilde f(x) +
-z_\mathrm{l}^T (Gx-h) + y^T(Ax-b).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-sum_{i=1}^mlogx_imbox{subjectto}&Ax=b.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="177" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img172.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -\sum_{i=1}^m \log x_i \\\\
-\mbox{subject to} & Ax = b.
-\end{array}\end{displaymath}">|; 
-
-$key = q/zinC;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="45" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img114.gif"
- ALT="$z\in C$">|; 
-
-$key = q/{displaymath}s^Tzleqepsilon_mathrm{abs}qquadmbox{or}qquadleft(minleft{c^Tx,h^Tz+^Tz}{-min{c^Tx,h^Tz+b^Ty}}leqepsilon_mathrm{rel}right).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="596" HEIGHT="46" BORDER="0"
- SRC="|."$dir".q|img160.gif"
- ALT="\begin{displaymath}
-s^T z \leq \epsilon_\mathrm{abs} \qquad \mbox{or} \qquad
-\l...
-...in\{c^Tx, h^Tz + b^T y\}} \leq \epsilon_\mathrm{rel}
-\right).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|u|_1mbox{subjectto}&|Au-b|_2leq1.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="188" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img158.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert u\Vert _1 \\\\
-\mbox{subject to} & \Vert Au - b\Vert _2 \leq 1.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}A=left[array{{cccc}1&2&0&03&4&5&06&7&8&90&10&11&12array{right],qquadx=left[array{{c}1111array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="296" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img45.gif"
- ALT="\begin{displaymath}
-A = \left[ \begin{array}{cccc}
-1 & 2 & 0 & 0 \\\\
-3 & 4 & ...
-...= \left[\begin{array}{c} 1 \ 1 \ 1 \ 1
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}frac{|nablaf_0(x)+Dtildef(x)^Tz_mathrm{nl}+G^Tz_mathrm{l}+A^Ty|_2}{f{1},Gx_0+{{bf{1}-h,Ax_0-b)|_2}}leqepsilon_mathrm{feas}{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="742" HEIGHT="49" BORDER="0"
- SRC="|."$dir".q|img191.gif"
- ALT="\begin{displaymath}
-\frac{\Vert \nabla f_0(x) + D\tilde f(x)^Tz_\mathrm{nl} +
-...
-...+ {\bf 1}-h, Ax_0-b) \Vert _2 \}} \leq \epsilon_\mathrm{feas}
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&f_0(x)mbox{subjectto}&f_k(x)leq0,quadk=1,ldots,m&Gxpreceqh&Ax=b,array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="262" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img163.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & f_0(x) \\\\
-\mbox{subj...
-... k=1,\ldots,m \\\\
-& G x \preceq h \\\\
-& A x = b,
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}A^Tmbox{{bf{diag},(d)^{-2}Ax_2=b_2+A^Tmbox{{bf{diag},(d)^{-2}b_1,qquadmbox{{bf{diag},(d)^2x_1=Ax_2-b_1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="493" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img49.gif"
- ALT="\begin{displaymath}
-A^T \mbox{\bf diag} (d)^{-2}A x_2 = b_2 + A^T \mbox{\bf di...
-...(d)^{-2} b_1, \qquad
-\mbox{\bf diag} (d)^2 x_1 = Ax_2 - b_1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&sum_kphi((Ax-b)_k),array{qquadphi(u)=left{leq|u|leq3slash22|u|-9slash4&|u|geq3slash2.array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="507" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img204.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \sum_k \phi((Ax-b)_k)...
-...
-2\vert u\vert-9/4 & \vert u\vert \geq 3/2.\end{array}\right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}nablaf_0(x)+Dtildef(x)^Tz_mathrm{nl}+G^Tz_mathrm{l}+A^Ty=0,qquadtil{nl}=0,quadk=1,ldots,m,qquadGx+s_mathrm{l}=h,qquadAx=b,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="717" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img166.gif"
- ALT="\begin{displaymath}
-\nabla f_0(x) + D\tilde f(x)^T z_\mathrm{nl} +
-G^T z_\mat...
-... k=1,\ldots,m, \qquad
-Gx + s_\mathrm{l} = h, \qquad
-Ax = b,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}v:=sum_{k=0}^mu_knablaf_k(x)+v.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="158" HEIGHT="53" BORDER="0"
- SRC="|."$dir".q|img188.gif"
- ALT="\begin{displaymath}
-v := \sum_{k=0}^m u_k \nabla f_k(x) + v.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}left[array{{ccc}0&A^T&G^TA&0&0G&0&-W^TWarray{right]left[array{{c}u_u_yu_zarray{right]=left[array{{c}b_xb_yb_zarray{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="291" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img140.gif"
- ALT="\begin{displaymath}
-\left[\begin{array}{ccc}
-0 & A^T & G^T \\\\
-A & 0 & 0 \\\\
-...
-...= \left[\begin{array}{c} b_x \ b_y \ b_z \end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-2x_1+x_2+5x_3*[2ex]mbox{subjectto}&left|lx_3-42array{right]right|_2leq-3x_1+6x_2-10x_3+27.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="498" HEIGHT="140" BORDER="0"
- SRC="|."$dir".q|img134.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -2x_1 + x_2 + 5x_3 \ *[...
-...t] \right\Vert _2 \leq
--3x_1 + 6x_2 - 10x_3 + 27.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&f_0(x)=mathop{{bf{lse}(F_0x+g_0)mbox{subjelse}(F_ix+g_i)leq0,quadi=1,ldots,m&Gxpreceqh&Ax=barray{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="368" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img183.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & f_0(x) = \mathop{\bf lse...
-...,\quad i=1,\ldots,m \\\\
-& Gx \preceq h \\\\
-& Ax=b
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}y:=x.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="46" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img13.gif"
- ALT="\begin{displaymath}
-y := x.
-\end{displaymath}">|; 
-
-$key = q/sinC;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="44" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img113.gif"
- ALT="$s \in C$">|; 
-
-$key = q/{displaymath}mathrm{gap}leqepsilon_mathrm{abs}qquadmbox{or}qquadleft(f_0(x)<0,qufrac{mathrm{gap}}{L(x,y,z)}leqepsilon_mathrm{rel}right){displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="686" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img192.gif"
- ALT="\begin{displaymath}
-\mathrm{gap} \leq \epsilon_\mathrm{abs}
-\qquad \mbox{or} \qq...
-...ac{\mathrm{gap}}
-{L(x,y,z)} \leq \epsilon_\mathrm{rel} \right)
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=left[array{{rrrrr}0&2&0&0&32&0&0&0&01&2&0&4&00&0&1&0&0array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="168" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img81.gif"
- ALT="\begin{displaymath}
-A = \left[ \begin{array}{rrrrr}
-0 & 2 & 0 & 0 & 3 \\\\
-2 &...
-...
-1 & 2 & 0 & 4 & 0 \\\\
-0 & 0 & 1 & 0 & 0 \end{array} \right]
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alphaAA^T+betaCquad(mathrm{trans}=mathrm{'N'}),qquadC:=alphaA^TA+betaCquad(mathrm{trans}=mathrm{'T'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="501" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img36.gif"
- ALT="\begin{displaymath}
-C := \alpha AA^T + \beta C \quad (\mathrm{trans} = \mathrm{...
-... \alpha A^TA + \beta C \quad (\mathrm{trans} = \mathrm{'T'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}(2,1,0),qquad(-1,2,0),qquad(2,0,1),qquad(-2,2,1),qquad(1,3,2),qquad(4,2,3),qquad(3,0,4).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="612" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img79.gif"
- ALT="\begin{displaymath}
-(2,1,0), \qquad (-1,2,0), \qquad (2,0,1), \qquad (-2,2,1), \qquad
-(1,3,2), \qquad (4,2,3), \qquad (3,0,4).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|Ax-y|_2^2+|x|_1array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="201" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img189.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert Ax - y\Vert _2^2 + \Vert x\Vert _1
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}mathop{{bf{rank}(A)=p,qquadmathop{{bf{rank}(left[array{{c}GAarray{right])=n,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="257" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img125.gif"
- ALT="\begin{displaymath}
-\mathop{\bf rank}(A) = p, \qquad
-\mathop{\bf rank}(\left[\begin{array}{c} G \ A \end{array}\right]) = n,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alphaAB^H+baralphaBA^H+betaCquad(mathrm{trans}=mathrm{'N'}),qquaA^HB+baralphaB^HA+betaCquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="641" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img39.gif"
- ALT="\begin{displaymath}
-C := \alpha AB^H + \bar \alpha BA^H + \beta C \quad
-(\mat...
-...alpha B^HA + \beta C \quad
-(\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C_0={uin{mbox{{bf{R}}^l;|;u_kgeq0,;k=1,ldots,l},qquadC_{k+1}={(u_0,(u);|;uin{mbox{{bf{S}}^{p_k}_+right},quadk=0,ldots,N-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="1115" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img117.gif"
- ALT="\begin{displaymath}
-C_0 =
-\{ u \in {\mbox{\bf R}}^l \;\vert \; u_k \geq 0, \; ...
-...
-u \in {\mbox{\bf S}}^{p_k}_+ \right\}, \quad k=0,\ldots,N-1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x=A^{-T}B^{-1}A^{-1}{{bf{1}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="132" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img88.gif"
- ALT="\begin{displaymath}
-x = A^{-T}B^{-1}A^{-1}{\bf 1}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x^Hy.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="32" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img15.gif"
- ALT="\begin{displaymath}
-x^Hy.
-\end{displaymath}">|; 
-
-$key = q/PX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="65" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img101.gif"
- ALT="$PX=B$">|; 
-
-$key = q/{displaymath}K=l+sum_{k=0}^{M-1}q_k+sum_{k=0}^{N-1}p_k^2.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="176" HEIGHT="56" BORDER="0"
- SRC="|."$dir".q|img119.gif"
- ALT="\begin{displaymath}
-K = l + \sum_{k=0}^{M-1} q_k + \sum_{k=0}^{N-1} p_k^2.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alphaxx^T,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="111" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img26.gif"
- ALT="\begin{displaymath}
-A := A + \alpha xx^T,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alphaxy^H+baralphayx^H,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="172" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img29.gif"
- ALT="\begin{displaymath}
-A := A + \alpha xy^H + \bar \alpha yx^H,
-\end{displaymath}">|; 
-
-$key = q/mathop{mathbf{vec}}(u);MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="52" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img118.gif"
- ALT="$\mathop{\mathbf{vec}}(u)$">|; 
-
-$key = q/{displaymath}Gx+s=0,qquadAx=0,qquadc^Tx=-1,qquadssucceq0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="351" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img124.gif"
- ALT="\begin{displaymath}
-Gx + s = 0, \qquad Ax=0, \qquad c^T x = -1, \qquad s \succeq 0.
-\end{displaymath}">|; 
-
-$key = q/mathop{mathbf{vec}}(z);MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="51" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img136.gif"
- ALT="$\mathop{\mathbf{vec}}(z)$">|; 
-
-$key = q/d_1;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="20" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img170.gif"
- ALT="$d_1$">|; 
-
-$key = q/{displaymath}AX=B,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="64" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img41.gif"
- ALT="\begin{displaymath}
-A X = B,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}W_{mathrm{s},k}mathop{mathbf{vec}}{(u_{mathrm{s},k})}=mathop{mathbf{(r_k^{-T}u_{mathrm{s},k}r_k^{-1})},qquadk=0,ldots,N-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="660" HEIGHT="31" BORDER="0"
- SRC="|."$dir".q|img149.gif"
- ALT="\begin{displaymath}
-W_{\mathrm{s},k} \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})} ...
-..._k^{-T} u_{\mathrm{s},k} r_k^{-1})}, \qquad
-k = 0,\ldots,N-1.
-\end{displaymath}">|; 
-
-$key = q/f;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="14" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img200.gif"
- ALT="$f$">|; 
-
-$key = q/{displaymath}K(x)=E_1mbox{{bf{diag},(x)E_2^T+E_2mbox{{bf{diag},(x)E_1^T{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="273" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img107.gif"
- ALT="\begin{displaymath}
-K(x) = E_1\mbox{\bf diag} (x)E_2^T+E_2\mbox{\bf diag} (x)E_1^T
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alphaxy^H,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="113" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img24.gif"
- ALT="\begin{displaymath}
-A := A + \alpha x y^H,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alphaAB+betaCquad(mathrm{side}=mathrm{'L'}),qquadC:=alphaBA+betaCquad(mathrm{side}=mathrm{'R'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="463" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img33.gif"
- ALT="\begin{displaymath}
-C := \alpha AB + \beta C \quad (\mathrm{side} = \mathrm{'L'...
-... := \alpha BA + \beta C \quad (\mathrm{side} = \mathrm{'R'}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}W_mathrm{q,k}^T=W_mathrm{q,k}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="89" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img148.gif"
- ALT="\begin{displaymath}
-W_\mathrm{q,k}^T = W_\mathrm{q,k}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}|x|_1quadmbox{({x{real)},qquad|Rex|_1+|Imx|_1quadmbox{({x{complex)}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="347" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img10.gif"
- ALT="\begin{displaymath}
-\Vert x\Vert _1 \quad \mbox{($x$ real)}, \qquad
-\Vert\Re x\Vert _1 + \Vert\Im x\Vert _1 \quad \mbox{($x$ complex)}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=mathop{mathrm{op}}(Q)Cquad(mathrm{side}=mathrm{'L'}),qquadC:=Cma}=mathrm{'T'}Q^H&mathrm{trans}=mathrm{'C'},array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="663" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img63.gif"
- ALT="\begin{displaymath}
-C := \mathop{\mathrm{op}}(Q)C \quad (\mathrm{side} = \mathr...
-...} \\\\
-Q^H & \mathrm{trans} = \mathrm{'C'},
-\end{array}\right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}Px=0,qquadq^Tx=-1,qquadGx+s=0,qquadAx=0,qquadssucceq0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="442" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img179.gif"
- ALT="\begin{displaymath}
-Px = 0, \qquad q^Tx = -1, \qquad Gx + s = 0, \qquad Ax=0, \qquad
-s \succeq 0.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&(1slash2)x^TPx+q^Txmbox{subjectto}&Gxpreceqh&Ax=b.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="207" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img177.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & (1/2) x^TPx + q^T x \\\\
-\mbox{subject to} & Gx \preceq h \ & Ax = b.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}(2,1,0),qquad(-1,2,0),qquad(0,3,0),qquad(2,0,1),qquad(-2,2,1),qquad(1,3,2),qquad(4,2,3),qquad(3,0,4){displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="697" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img80.gif"
- ALT="\begin{displaymath}
-(2,1,0), \qquad (-1,2,0), \qquad (0,3,0), \qquad (2,0,1), \qquad
-(-2,2,1), \qquad (1,3,2), \qquad (4,2,3), \qquad (3,0,4)
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=LL^Tqquadmbox{or}qquadA=LL^H{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="209" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img46.gif"
- ALT="\begin{displaymath}
-A = LL^T \qquad \mbox{or} \qquad A = LL^H
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=left[array{{cccc}1&0&0&52&0&4&00&0&0&63&0&0&0array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="144" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img210.gif"
- ALT="\begin{displaymath}
-A=\left [\begin{array}{cccc}
-1 & 0 & 0 & 5\\\\
-2 & 0 & 4 & 0\\\\
-0 & 0 & 0 & 6\\\\
-3 & 0 & 0 & 0
-\end{array}\right]
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=USigmaV^T,qquadA=USigmaV^H{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="201" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img69.gif"
- ALT="\begin{displaymath}
-A = U \Sigma V^T, \qquad A = U \Sigma V^H
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alphaxx^H,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="114" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img27.gif"
- ALT="\begin{displaymath}
-A := A + \alpha xx^H,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alpha(AB^T+BA^T)+betaCquad(mathrm{trans}=mathrm{'N'}),qquadC:=alpha(A^TB+B^TA)+betaCquad(mathrm{trans}=mathrm{'T'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="635" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img38.gif"
- ALT="\begin{displaymath}
-C := \alpha (AB^T + BA^T) + \beta C \quad
-(\mathrm{trans}...
-...TB + B^TA) + \beta C \quad
-(\mathrm{trans} = \mathrm{'T'}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=PLU{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="69" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img42.gif"
- ALT="\begin{displaymath}
-A = PLU
-\end{displaymath}">|; 
-
-$key = q/{displaymath}f(x_1,ldots,x_n)=b+A_1x_1+cdots+A_nx_n+sum_{k=1}^Kmax(y_1,y_2,ldots,y_{m_k}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="458" HEIGHT="56" BORDER="0"
- SRC="|."$dir".q|img196.gif"
- ALT="\begin{displaymath}
-f(x_1,\ldots,x_n) = b + A_1 x_1 + \cdots + A_n x_n +
-\sum_{k=1}^K \max (y_1, y_2, \ldots, y_{m_k}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&x_1-x_2+x_3mbox{subjectto}&x_1left[array{{eft[array{{ccc}14&9&409&91&1040&10&15array{right]array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="734" HEIGHT="121" BORDER="0"
- SRC="|."$dir".q|img139.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & x_1 - x_2 + x_3 \\\\
-\mbo...
-...
-9 & 91 & 10 \\\\
-40 & 10 & 15
-\end{array} \right]
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}W,qquadH,qquadxin{mbox{{bf{R}}^5,qquadyin{mbox{{bf{R}}^5,qquadwin{mbox{{bf{R}}^5,qquadhin{mbox{{bf{R}}^5,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="425" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img175.gif"
- ALT="\begin{displaymath}
-W, \qquad H, \qquad x\in{\mbox{\bf R}}^5, \qquad y\in{\mbox{...
-...}^5, \qquad
-w\in{\mbox{\bf R}}^5, \qquad h\in{\mbox{\bf R}}^5,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}y:=alphaGx+betayquad(mathrm{trans}=mathrm{'N'}),qquady:=alphaG^Tx+betayquad(mathrm{trans}=mathrm{'T'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="470" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img153.gif"
- ALT="\begin{displaymath}
-y := \alpha Gx + \beta y \quad
-(\mathrm{trans} = \mathrm{'...
-...alpha G^T x + \beta y \quad
-(\mathrm{trans} = \mathrm{'T'}).
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}f(x,y)&=&left[array{{c}22array{right]x+y+left[array{{c}33array{rig&5array{right]y+left[array{{c}1317array{right].{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="366" HEIGHT="134" BORDER="0"
- SRC="|."$dir".q|img195.gif"
- ALT="\begin{eqnarray*}
-f(x,y) & = & \left[ \begin{array}{c} 2 \ 2 \end{array}\right...
-...\right] y
-+ \left[ \begin{array}{c} 13 \ 17\end{array}\right].
-\end{eqnarray*}">|; 
-
-$key = q/M;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="22" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img133.gif"
- ALT="$M$">|; 
-
-$key = q/{displaymath}C:=mathop{mathrm{op}}(Q)Cquad(mathrm{side}=mathrm{'L'}),qquadC:=Cma}=mathrm{'N'}Q^T&mathrm{trans}=mathrm{'T'},array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="659" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img62.gif"
- ALT="\begin{displaymath}
-C := \mathop{\mathrm{op}}(Q)C \quad (\mathrm{side} = \mathr...
-...} \\\\
-Q^T & \mathrm{trans} = \mathrm{'T'},
-\end{array}\right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&c^Txmbox{subjectto}&sup_{|v|_inftyleq1}(a_i+v)^Txleqb_i,qquadi=1,ldots,marray{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="387" HEIGHT="46" BORDER="0"
- SRC="|."$dir".q|img206.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & c^T x \\\\
-\mbox{subje...
-...leq 1}
-(a_i+v)^T x \leq b_i, \qquad i=1,\ldots,m
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}Px+q+G^Tz+A^Ty=0,qquadGx+s=h,qquadAx=b,qquadssucceq0,qquadzsucceq0,qquads^Tz=0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="632" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img178.gif"
- ALT="\begin{displaymath}
-Px + q + G^T z + A^T y = 0, \qquad Gx + s = h, \qquad
-Ax = b, \qquad s \succeq 0, \qquad z \succeq 0, \qquad s^T z = 0.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{[t]{ll}mbox{minimize}&c^Txmbox{subjectto}&G_0x+s_0=h_0&G_kx+m)+A^Ty+c=0&z_0succeq0&z_ksucceq0,quadk=1,ldots,N.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="828" HEIGHT="125" BORDER="0"
- SRC="|."$dir".q|img135.gif"
- ALT="\begin{displaymath}
-\begin{array}[t]{ll}
-\mbox{minimize} & c^T x \\\\
-\mbox{su...
-...succeq 0 \\\\
-& z_k \succeq 0, \quad k=1,\ldots,N.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}&left[array{{ccccc}X[0,0]&X[1,0]&X[2,0]&cdots&X[n-1,0]X[1,0]&X[1,1]&cdots&X[n-1,n-1]array{right]&mbox{ifuplo=U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="550" HEIGHT="225" BORDER="0"
- SRC="|."$dir".q|img1.gif"
- ALT="\begin{eqnarray*}
-& \left[\begin{array}{ccccc}
-X[0,0] & X[1,0] & X[2,0] & \cdots...
-...& \cdots & X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = U'}.
-\end{eqnarray*}">|; 
-
-$key = q/f=(f_0,ldots,f_m);MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="118" HEIGHT="32" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img164.gif"
- ALT="$f=(f_0,\ldots,f_m)$">|; 
-
-$key = q/{displaymath}s_mathrm{nl}succeq0,qquads_mathrm{l}succeq0,qquadz_mathrm{nl}succeqds_mathrm{nl}^Tz_mathrm{nl}+s_mathrm{l}^Tz_mathrm{l}=0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="452" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img168.gif"
- ALT="\begin{displaymath}
-s_\mathrm{nl}\succeq 0, \qquad s_\mathrm{l}\succeq 0, \qquad...
-...\mathrm{nl}^T z_\mathrm{nl} + s_\mathrm{l}^T z_\mathrm{l} = 0.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}y:=alphaAx+betayquad(mathrm{trans}=mathrm{'N'}),qquady:=alphaA^Tx+bqquady:=alphaA^Hx+betayquad(mathrm{trans}=mathrm{'C'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="716" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img17.gif"
- ALT="\begin{displaymath}
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'...
-...\alpha A^H x + \beta y \quad (\mathrm{trans} = \mathrm{'C'}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}X[k,:]:=sum_{j=0}^{n-1}e^{-2pijksqrt{-1}slashn}X[j,:],qquadk=0,ldots,n-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="376" HEIGHT="58" BORDER="0"
- SRC="|."$dir".q|img74.gif"
- ALT="\begin{displaymath}
-X[k,:] := \sum_{j=0}^{n-1} e^{-2\pi j k \sqrt{-1}/n} X[j,:],
-\qquad k=0,\ldots,n-1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&W+Hmbox{subjectto}&A_{mathrm{min},k}slashhH&h_kslashgammaleqw_kleqgammah_k,quadk=1,ldots,5.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="747" HEIGHT="140" BORDER="0"
- SRC="|."$dir".q|img174.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & W + H \\\\
-\mbox{subjec...
-...gamma \leq w_k \leq \gamma h_k, \quad k=1,\ldots,5.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}B=left[array{{rrrrr}4&3&0&0&03&0&4&0&60&-1&-3&2&00&0&1&0&00&4&2&0&2array{right],{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="206" HEIGHT="102" BORDER="0"
- SRC="|."$dir".q|img87.gif"
- ALT="\begin{displaymath}
-B = \left[\begin{array}{rrrrr}
-4 & 3 & 0 & 0 & 0 \\\\
-3 & 0...
-...0 & 0 & 1 & 0 & 0 \\\\
-0 & 4 & 2 & 0 & 2
-\end{array}\right],
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-6x_1-4x_2-5x_3*[1ex]mbox{subjectto}&16x_1ay{{ccc}68&-30&-19-30&99&23-19&23&10array{right].array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="882" HEIGHT="199" BORDER="0"
- SRC="|."$dir".q|img126.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -6x_1 - 4x_2 - 5x_3 \ *...
-...0 & 99 & 23 \\\\
--19 & 23 & 10 \end{array}\right].
-\end{array}
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&c^Txmbox{subjectto}&a_i^Tx+|x|_1leqb_i,qquadi=1,ldots,m.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="324" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img207.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & c^Tx \\\\
-\mbox{subjec...
-...x + \Vert x\Vert _1 \leq b_i, \qquad i=1,\ldots,m.
-\end{array}\end{displaymath}">|; 
-
-$key = q/LDL^TX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="98" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img94.gif"
- ALT="$LDL^TX=B$">|; 
-
-$key = q/{displaymath}C=A^TD,qquadD=left[array{{ccc}0&1&03&0&-20&1&04&0&0array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="253" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img84.gif"
- ALT="\begin{displaymath}
-C = A^TD, \qquad
-D = \left[ \begin{array}{ccc}
-0 & 1 & 0 \ 3 & 0 & -2 \ 0 & 1 & 0 \ 4 & 0 & 0
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&c^Txmbox{subjectto}&a_i^Tx+{{bf{1}^Tyleqb_i,qquadi=1,ldots,m&-ypreceqxpreceqyarray{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="316" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img208.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & c^Tx \\\\
-\mbox{subjec...
-...i, \qquad i=1,\ldots,m \\\\
-& -y \preceq x \preceq y
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|A^TX-B|_F.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="177" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img58.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert A^TX-B\Vert _F.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}A=Vmbox{{bf{diag},(lambda)V^H,qquadV^HV=I.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="237" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img65.gif"
- ALT="\begin{displaymath}
-A = V\mbox{\bf diag} (\lambda)V^H,\qquad V^HV = I.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}left[array{{cc}-mbox{{bf{diag},(d)^2&AA^T&0array{right]left[array{{c}x_1x_2array{right]=left[array{{c}b_1b_2array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="248" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img48.gif"
- ALT="\begin{displaymath}
-\left[ \begin{array}{cc}
--\mbox{\bf diag} (d)^2 & A \\\\
-...
-...ght]
-= \left[ \begin{array}{c} b_1 \ b_2 \end{array} \right]
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}&left[array{{ccccccc}ReX[0,0]&barX[1,0]&barX[2,0]&cdots&barX[k,0]&ts&vdots&ddots&&&array{right]&mbox{ifuplo='U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="627" HEIGHT="323" BORDER="0"
- SRC="|."$dir".q|img6.gif"
- ALT="\begin{eqnarray*}
-& \left[ \begin{array}{ccccccc}
-\Re X[0,0] & \bar X[1,0] & \ba...
-... \vdots & \ddots & & &
-\end{array}\right] & \mbox{if uplo='U'}.
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}s_k=(s_{k0},s_{k1})in{mbox{{bf{R}}times{mbox{{bf{R}}^{q_{k}-1},qquak0},z_{k1})in{mbox{{bf{R}}times{mbox{{bf{R}}^{q_{k}-1}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="433" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img130.gif"
- ALT="\begin{displaymath}
-s_k = (s_{k0}, s_{k1}) \in{\mbox{\bf R}}\times{\mbox{\bf R}...
-...{k0}, z_{k1}) \in{\mbox{\bf R}}\times{\mbox{\bf R}}^{q_{k}-1}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}Wu=left(W_mathrm{l}u_mathrm{l},;W_{mathrm{q},0}u_{mathrm{q},0},;ldom{s},N-1}mathop{mathbf{vec}}{(u_{mathrm{s},N-1})}right){displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="608" HEIGHT="29" BORDER="0"
- SRC="|."$dir".q|img143.gif"
- ALT="\begin{displaymath}
-Wu = \left( W_\mathrm{l} u_\mathrm{l}, \;
-W_{\mathrm{q},0}...
-...rm{s},N-1} \mathop{\mathbf{vec}}{(u_{\mathrm{s},N-1})} \right)
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|Ax-y|_2^2+{{bf{1}^Tumbox{subjectto}&-upreceqxprecequarray{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="205" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img190.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert Ax - y\Vert _2^2...
-... u \\\\
-\mbox{subject to} & -u \preceq x \preceq u
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}AZ=BZmbox{{bf{diag},(lambda)quadmbox{(type1)},qquadABZ=Zmbox{{bf{di2)},qquadBAZ=Zmbox{{bf{diag},(lambda)quadmbox{(type3)},{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="681" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img66.gif"
- ALT="\begin{displaymath}
-AZ = BZ\mbox{\bf diag} (\lambda)\quad \mbox{(type 1)}, \qq...
-...ad
-BAZ = Z\mbox{\bf diag} (\lambda) \quad \mbox{(type 3)},
-\end{displaymath}">|; 
-
-$key = q/{displaymath}PAP^T=LDL^H{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="115" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img54.gif"
- ALT="\begin{displaymath}
-PAP^T = LDL^H
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=left[array{{rrrr}1&6&0&02&-4&3&00&-3&-1&1array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="169" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img30.gif"
- ALT="\begin{displaymath}
-A = \left[\begin{array}{rrrr}
-1 & 6 & 0 & 0 \\\\
-2 & -4 & 3 & 0 \\\\
-0 & -3 & -1 & 1
-\end{array}\right]
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&w^{-1}h^{-1}d^{-1}mbox{subjectto}&(2slashA-1}leq1&gammawd^{-1}leq1&(1slashdelta)dw^{-1}leq1array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="297" HEIGHT="140" BORDER="0"
- SRC="|."$dir".q|img186.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & w^{-1} h^{-1} d^{-1} \...
-...mma wd^{-1} \leq 1 \\\\
-& (1/\delta)dw^{-1} \leq 1
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|x|_1+{{bf{1}^Tumbox{subjectto}&Axsucceq{{bf{1}-u&usucceq0.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="166" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img209.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert x\Vert _1 + {\bf 1...
-...bject to} & Ax \succeq {\bf 1}-u \\\\
-& u \succeq 0.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}W_{mathrm{s},k}^Tmathop{mathbf{vec}}{(u_{mathrm{s},k})}=mathop{math^{-1}u_{mathrm{s},k}r_k^{-T})},qquadqquadk=0,ldots,N-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="719" HEIGHT="31" BORDER="0"
- SRC="|."$dir".q|img150.gif"
- ALT="\begin{displaymath}
-W_{\mathrm{s},k}^T \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})...
-...u_{\mathrm{s},k} r_k^{-T})}, \qquad
-\qquad
-k = 0,\ldots,N-1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C=A^TB,qquadA=left[array{{ccc}0&1&01&0&10&1&01&0&0array{right],qquadB=left[array{{ccc}0&-1&02&0&20&3&02&0&0array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="419" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img83.gif"
- ALT="\begin{displaymath}
-C = A^TB, \qquad
-A = \left[ \begin{array}{ccc}
-0 & 1 & 0 \ ...
-...0 \ 2 & 0 & 2 \ 0 & 3 & 0 \ 2 & 0 & 0
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A^Tmbox{{bf{diag},(b-Ax)^{-2}Av=-mbox{{bf{diag},(b-Ax)^{-1}{{bf{1}{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="309" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img72.gif"
- ALT="\begin{displaymath}
-A^T \mbox{\bf diag} (b-Ax)^{-2} A v = -\mbox{\bf diag} (b-Ax)^{-1}{\bf 1}
-\end{displaymath}">|; 
-
-$key = q/DX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="67" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img99.gif"
- ALT="$DX=B$">|; 
-
-$key = q/{}mathrm{^T};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="14" HEIGHT="18" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img50.gif"
- ALT="${}\mathrm{^T}$">|; 
-
-$key = q/includegraphics[width=15cm]{figuresslashfloorplan.eps};FSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="681" HEIGHT="511" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img176.gif"
- ALT="\includegraphics[width=15cm]{figures/floorplan.eps}">|; 
-
-$key = q/mathrm{{}^T};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="14" HEIGHT="18" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img40.gif"
- ALT="$\mathrm{{}^T}$">|; 
-
-$key = q/{displaymath}PAP^T=LDL^T{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="113" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img52.gif"
- ALT="\begin{displaymath}
-PAP^T = LDL^T
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x:=Axquad(mathrm{trans}=mathrm{'N'}),qquadx:=A^Txquad(mathrm{trans}thrm{'T'}),qquadx:=A^Hxquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="587" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img19.gif"
- ALT="\begin{displaymath}
-x := Ax \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A...
-...'}), \qquad
-x := A^H x \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/z;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="13" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img137.gif"
- ALT="$z$">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-sum_{i=1}^mlog(b_i-a_i^Tx).array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="229" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img71.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -\sum_{i=1}^m \log(b_i-a_i^Tx).
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|X|_Fmbox{subjectto}&AX=B.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="149" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img56.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert X\Vert _F \\\\
-\mbox{subject to} & AX = B.
-\end{array}\end{displaymath}">|; 
-
-$key = q/d_2;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="20" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img171.gif"
- ALT="$d_2$">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&c^Txmbox{subjectto}&Gxpreceqh&Ax=b.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="137" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img111.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & c^T x \\\\
-\mbox{subject to} & G x \preceq h \ & Ax = b.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}{mbox{{bf{R}}^ltimes{mbox{{bf{R}}^{q_0}timescdotstimes{mbox{{bf{R}}bf{R}}^{p_0^2}timescdotstimes{mbox{{bf{R}}^{p_{N-1}^2},{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="322" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img120.gif"
- ALT="\begin{displaymath}
-{\mbox{\bf R}}^l \times {\mbox{\bf R}}^{q_0} \times \cdots \...
-... R}}^{p_0^2} \times \cdots \times
-{\mbox{\bf R}}^{p_{N-1}^2},
-\end{displaymath}">|; 
-
-$key = q/tildef=(f_1,ldots,f_m);MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="118" HEIGHT="38" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img167.gif"
- ALT="$\tilde f = (f_1,\ldots, f_m)$">|; 
-
-$key = q/L^H;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="27" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img103.gif"
- ALT="$L^H$">|; 
-
-$key = q/{displaymath}x:=A^{-1}xquad(mathrm{trans}=mathrm{'N'}),qquadx:=A^{-T}xquad(mathrm{'T'}),qquadx:=A^{-H}xquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="624" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img20.gif"
- ALT="\begin{displaymath}
-x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x...
-..., \qquad
-x := A^{-H}x \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}mbox{DST-I:}qquadX[k,:]&:=&2sum_{j=0}^{n-1}X[j,:]sin(pi(j+1)(k+1)s+1slash2)(k+1slash2)slashn),qquadk=0,ldots,n-1.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="721" HEIGHT="230" BORDER="0"
- SRC="|."$dir".q|img77.gif"
- ALT="\begin{eqnarray*}
-\mbox{DST-I:} \qquad
-X[k,:] & := &
-2 \sum_{j=0}^{n-1} X[j,:...
-...n-1} X[j,:] \sin(\pi (j+1/2)(k+1/2)/n),
-\qquad k=0,\ldots,n-1.
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}A=left[array{{rrrrr}2&3&0&0&03&0&4&0&60&-1&-3&2&00&0&1&0&00&4&2&0&1array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="204" HEIGHT="102" BORDER="0"
- SRC="|."$dir".q|img86.gif"
- ALT="\begin{displaymath}
-A = \left[\begin{array}{rrrrr}
-2 & 3 & 0 & 0 & 0 \\\\
-3 & 0...
-...0 & 0 & 1 & 0 & 0 \\\\
-0 & 4 & 2 & 0 & 1
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}mathop{mathrm{op}}(A)=left{array{{ll}A&mathrm{transA}=mathrm{'N'}A^=mathrm{'T'}B^H&mathrm{transB}=mathrm{'C'}.array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="475" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img32.gif"
- ALT="\begin{displaymath}
-\mathop{\mathrm{op}}(A) = \left\{ \begin{array}{ll}
-A & \ma...
-...\\\\
-B^H & \mathrm{transB} = \mathrm{'C'}. \end{array} \right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}left[array{{rrrr}10&0&3&00&5&0&-23&0&5&00&-2&0&2array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="150" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img85.gif"
- ALT="\begin{displaymath}
-\left[ \begin{array}{rrrr}
-10 & 0 & 3 & 0 \\\\
-0 & 5 & 0 & -2 \\\\
-3 & 0 & 5 & 0 \\\\
-0 & -2 & 0 & 2
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{}mathrm{^H};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="15" HEIGHT="18" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img51.gif"
- ALT="${}\mathrm{^H}$">|; 
-
-$key = q/S;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="15" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img106.gif"
- ALT="$S$">|; 
-
-$key = q/G_0;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="24" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img131.gif"
- ALT="$G_0$">|; 
-
-$key = q/{displaymath}left[array{{rrrr}10&0&3&00&5&0&-23&0&5&00&-2&0&2array{right]X=left[array{{cc}0&41&52&63&7array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="257" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img90.gif"
- ALT="\begin{displaymath}
-\left[ \begin{array}{rrrr}
-10 & 0 & 3 & 0 \\\\
-0 & 5 & 0 & ...
-...ray}{cc}
-0 & 4 \ 1 & 5 \ 2 & 6 \ 3 & 7\end{array} \right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}E_1=left[array{{cccc}e_{i_1}&e_{i_2}&cdots&e_{i_q}array{right],qqua[array{{cccc}e_{j_1}&e_{j_2}&cdots&e_{j_q}array{right],{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="435" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img108.gif"
- ALT="\begin{displaymath}
-E_1 = \left[ \begin{array}{cccc}
-e_{i_1} & e_{i_2} & \cdot...
-...cc}
-e_{j_1} & e_{j_2} & \cdots & e_{j_q} \end{array}\right],
-\end{displaymath}">|; 
-
-$key = q/l;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="10" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img121.gif"
- ALT="$l$">|; 
-
-$key = q/{displaymath}Gx+s=h,qquadAx=b,qquadG^Tz+A^Ty+c=0,qquadssucceq0,qquadzsucceq0,qquads^Tz=0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="589" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img122.gif"
- ALT="\begin{displaymath}
-Gx + s = h, \qquad Ax=b, \qquad G^T z + A^T y + c = 0, \qquad
-s \succeq 0, \qquad z \succeq 0, \qquad s^T z =0.
-\end{displaymath}">|; 
-
-$key = q/V^H;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="29" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img70.gif"
- ALT="$V^H$">|; 
-
-$key = q/{displaymath}y:=alphaAx+betay.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="106" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img82.gif"
- ALT="\begin{displaymath}
-y := \alpha A x + \beta y.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}PAP^T=LL^T,qquadPAP^T=LL^H,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="244" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img91.gif"
- ALT="\begin{displaymath}
-PAP^T = LL^T, \qquad PAP^T = LL^H,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}W_mathrm{l}^T=W_mathrm{l}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="70" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img145.gif"
- ALT="\begin{displaymath}
-W_\mathrm{l}^T = W_\mathrm{l}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&{{bf{1}^Txmbox{subjectto}&W+mbox{{bf{diag},(x)succeq0array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="207" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img157.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & {\bf 1}^T x \\\\
-\mbox{subject to} & W + \mbox{\bf diag} (x) \succeq 0
-\end{array}
-\end{displaymath}">|; 
-
-$key = q/LX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="64" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img97.gif"
- ALT="$LX=B$">|; 
-
-$key = q/includegraphics[width=10cm]{figuresslashportfolio1.eps};FSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="453" HEIGHT="340" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img181.gif"
- ALT="\includegraphics[width=10cm]{figures/portfolio1.eps}">|; 
-
-$key = q/{displaymath}s_0succeq0,qquadz_0succeq0{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="125" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img129.gif"
- ALT="\begin{displaymath}
-s_0 \succeq 0, \qquad z_0 \succeq 0
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alpha(xy^T+yx^T),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="170" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img28.gif"
- ALT="\begin{displaymath}
-A := A + \alpha (xy^T + yx^T),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=QR.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="61" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img61.gif"
- ALT="\begin{displaymath}
-A = Q R.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}y:=alphaAx+betayquad(mathrm{trans}=mathrm{'N'}),qquady:=alphaA^Tx+bqquady:=alphaA^Hx+betayquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="717" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img21.gif"
- ALT="\begin{displaymath}
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'...
-... \alpha A^H x + \beta y \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}b_x:=u_x,qquadb_y:=u_y,qquadb_z:=Wu_z.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="268" HEIGHT="29" BORDER="0"
- SRC="|."$dir".q|img152.gif"
- ALT="\begin{displaymath}
-b_x := u_x, \qquad b_y := u_y, \qquad b_z := W u_z.
-\end{displaymath}">|; 
-
-$key = q/B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="17" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img67.gif"
- ALT="$B$">|; 
-
-$key = q/{displaymath}x:=Axquad(mathrm{trans}=mathrm{'N'}),qquadx:=A^Txquad(mathrm{trans}thrm{'T'}),qquadx:=A^Hxquad(mathrm{trans}=mathrm{'C'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="586" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img22.gif"
- ALT="\begin{displaymath}
-x := Ax \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A...
-...}), \qquad
-x := A^H x \quad (\mathrm{trans} = \mathrm{'C'}).
-\end{displaymath}">|; 
-
-$key = q/includegraphics[width=linewidth]{figuresslashnormappr.eps};FSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="719" HEIGHT="539" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img205.gif"
- ALT="\includegraphics[width=\linewidth]{figures/normappr.eps}">|; 
-
-$key = q/{displaymath}y:=alphaAx+betay,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="107" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img18.gif"
- ALT="\begin{displaymath}
-y := \alpha A x + \beta y,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alphamathop{mathrm{op}}(A)mathop{mathrm{op}}(B)+betaC{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="177" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img31.gif"
- ALT="\begin{displaymath}
-C := \alpha \mathop{\mathrm{op}}(A) \mathop{\mathrm{op}}(B) + \beta C
-\end{displaymath}">|; 
-
-$key = q/{displaymath}f(x_1,ldots,x_n)=b+A_1x_1+cdots+A_nx_n+sum_{k=1}^Kmin(y_1,y_2,ldots,y_{m_k}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="455" HEIGHT="56" BORDER="0"
- SRC="|."$dir".q|img197.gif"
- ALT="\begin{displaymath}
-f(x_1,\ldots,x_n) = b + A_1 x_1 + \cdots + A_n x_n +
-\sum_{k=1}^K \min (y_1, y_2, \ldots, y_{m_k}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{[t]{ll}mbox{minimize}&c^Txmbox{subjectto}&G_kx+s_k=h_k,quadk=0&z_0succeq0&z_{k0}geq|z_{k1}|_2,quadk=1,ldots,M.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="669" HEIGHT="106" BORDER="0"
- SRC="|."$dir".q|img128.gif"
- ALT="\begin{displaymath}
-\begin{array}[t]{ll}
-\mbox{minimize} & c^T x \\\\
-\mbox{su...
-...k0} \geq \Vert z_{k1}\Vert _2, \quad k=1,\ldots,M.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}x:=A^{-1}xquad(mathrm{trans}=mathrm{'N'}),qquadx:=A^{-T}xquad(mathrm{'T'}),qquadx:=A^{-H}xquad(mathrm{trans}=mathrm{'T'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="624" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img23.gif"
- ALT="\begin{displaymath}
-x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x...
-..., \qquad
-x := A^{-H} x \quad (\mathrm{trans} = \mathrm{'T'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}z_0nabla^2f_0(x)+z_1nabla^2f_1(x)+cdots+z_mnabla^2f_m(x).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="304" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img165.gif"
- ALT="\begin{displaymath}
-z_0 \nabla^2f_0(x) + z_1 \nabla^2f_1(x) + \cdots + z_m \nabla^2f_m(x).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}mathop{{bf{lse}(u)=logsum_kexp(u_k),qquadF=left[array{{cccc}F_0^T&Fleft[array{{cccc}g_0^T&g_1^T&cdots&g_m^Tarray{right]^T.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="649" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img184.gif"
- ALT="\begin{displaymath}
-\mathop{\bf lse}(u) = \log \sum_k \exp(u_k), \qquad
-F = \l...
-...}{cccc}
-g_0^T & g_1^T & \cdots & g_m^T \end{array}\right]^T.
-\end{displaymath}">|; 
-
-$key = q/A;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="16" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img53.gif"
- ALT="$A$">|; 
-
-$key = q/{displaymath}u=left(u_mathrm{l},;u_{mathrm{q},0},;ldots,;u_{mathrm{q},M-1},;mathu_{mathrm{s},k}in{mbox{{bf{S}}^{p_k},quadk=0,ldots,N-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="980" HEIGHT="29" BORDER="0"
- SRC="|."$dir".q|img142.gif"
- ALT="\begin{displaymath}
-u = \left(u_\mathrm{l}, \; u_{\mathrm{q},0}, \; \ldots, \; ...
-...\mathrm{s},k} \in{\mbox{\bf S}}^{p_k}, \quad k = 0,\ldots,N-1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{[t]{ll}mbox{minimize}&c^Txmbox{subjectto}&Gx+s=h&Ax=b&ssucceq-h^Tz-b^Tymbox{subjectto}&G^Tz+A^Ty+c=0&zsucceq0.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="527" HEIGHT="87" BORDER="0"
- SRC="|."$dir".q|img112.gif"
- ALT="\begin{displaymath}
-\begin{array}[t]{ll}
-\mbox{minimize} & c^T x \\\\
-\mbox{su...
-...ct to} & G^T z + A^T y + c = 0 \\\\
-& z \succeq 0.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&sum_{k=1}^mphi((Ax-b)_k),array{qquadmbox{wuadAin{mbox{{bf{R}}^{mtimesn},quadphi(u)=sqrt{rho+u^2}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="525" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img173.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \sum_{k=1}^m \phi((Ax-b)...
-...{\mbox{\bf R}}^{m\times n}, \quad
-\phi(u) = \sqrt{\rho + u^2}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}Z^HBZ=Iquadmbox{(types1and2)},qquadZ^HB^{-1}Z=Iquadmbox{(type3)}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="409" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img68.gif"
- ALT="\begin{displaymath}
-Z^H BZ = I \quad \mbox{(types 1 and 2)}, \qquad
-Z^H B^{-1}Z = I \quad \mbox{(type 3)}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x^Ty.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="29" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img16.gif"
- ALT="\begin{displaymath}
-x^Ty.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}left[array{{ccccccc}X[k_u,0]&X[k_u-1,1]&X[k_u-2,2]&cdots&X[0,k_u]&0_l-1,2]&cdots&&&vdots&vdots&vdots&ddots&&&array{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="625" HEIGHT="161" BORDER="0"
- SRC="|."$dir".q|img4.gif"
- ALT="\begin{displaymath}
-\left[ \begin{array}{ccccccc}
-X[k_u,0] & X[k_u-1,1] & X[k_u-...
-...
-\vdots & \vdots & \vdots & \ddots & & &
-\end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|Ax-b|_infty,array{qquadarray{{ll}mbox{minimize}&|Ax-b|_1array{,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="368" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img203.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert Ax - b\Vert _\i...
-...ay}{ll}
-\mbox{minimize} & \Vert Ax - b\Vert _1
-\end{array},
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|AX-B|_F.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="167" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img55.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert AX-B\Vert _F.
-\end{array}
-\end{displaymath}">|; 
-
-$key = q/N;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="19" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img138.gif"
- ALT="$N$">|; 
-
-$key = q/{eqnarraystar}nablaf(x)&=&2mbox{{bf{diag},(E_1^T(Y-K(x)^{-1})E_2))&=&2mbox{{bf{d)^{-1}right)_{IJ}circleft(K(x)^{-1}right)_{JI},{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="589" HEIGHT="105" BORDER="0"
- SRC="|."$dir".q|img110.gif"
- ALT="\begin{eqnarray*}
-\nabla f(x)
-&=& 2 \mbox{\bf diag} ( E_1^T (Y - K(x)^{-1}) E_...
-...\left(K(x)^{-1}\right)_{IJ} \circ
-\left(K(x)^{-1}\right)_{JI},
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}ssucceq0,qquadzsucceq0,qquadqquadfrac{|Gx+s-h|_2}{max{1,|h|_2}}leqe{|G^Tz+A^Ty+c|_2}{max{1,|c|_2}}leqepsilon_mathrm{feas},{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="746" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img159.gif"
- ALT="\begin{displaymath}
-s \succeq 0, \qquad z \succeq 0, \qquad
-\qquad
-\frac{\Ver...
-..._2}{\max\{1,\Vert c\Vert _2\}} \leq
-\epsilon_\mathrm{feas},
-\end{displaymath}">|; 
-
-$key = q/L^T;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="25" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img102.gif"
- ALT="$L^T$">|; 
-
-$key = q/{displaymath}|x|_2.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="33" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img9.gif"
- ALT="\begin{displaymath}
-\Vert x\Vert _2.
-\end{displaymath}">|; 
-
-$key = q/W;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="22" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img141.gif"
- ALT="$W$">|; 
-
-$key = q/{eqnarraystar}&left[array{{ccccccc}X[0,0]&X[1,0]&X[2,0]&cdots&X[k,0]&0&cdotsX[1,ts&vdots&ddots&&&array{right]&mbox{ifuplo='U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="616" HEIGHT="323" BORDER="0"
- SRC="|."$dir".q|img5.gif"
- ALT="\begin{eqnarray*}
-& \left[ \begin{array}{ccccccc}
-X[0,0] & X[1,0] & X[2,0] & \cd...
-... \vdots & \ddots & & &
-\end{array}\right] & \mbox{if uplo='U'}.
-\end{eqnarray*}">|; 
-
-$key = q/h_0;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="21" HEIGHT="30" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img132.gif"
- ALT="$h_0$">|; 
-
-$key = q/{displaymath}beta_k>0,qquadv_{k0}>0,qquadv_k^TJv_k=1,qquadJ=left[array{{cc}1&00&-Iarray{right].{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="401" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img147.gif"
- ALT="\begin{displaymath}
-\beta_k > 0, \qquad v_{k0} > 0, \qquad
-v_k^T Jv_k = 1, \q...
-...= \left[\begin{array}{cc}
-1 & 0 \ 0 & -I \end{array}\right].
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C:=alphaAA^H+betaCquad(mathrm{trans}=mathrm{'N'}),qquadC:=alphaA^HA+betaCquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="505" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img37.gif"
- ALT="\begin{displaymath}
-C := \alpha AA^H + \beta C \quad (\mathrm{trans} = \mathrm{...
-...= \alpha A^HA + \beta C \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=left[array{{rrrrr}0&2&0&0&32&0&0&0&0-1&-2&0&4&00&0&1&0&0array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="193" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img78.gif"
- ALT="\begin{displaymath}
-A = \left[ \begin{array}{rrrrr}
-0 & 2 & 0 & 0 & 3 \\\\
-2 &...
-...-1 & -2 & 0 & 4 & 0 \\\\
-0 & 0 & 1 & 0 & 0 \end{array} \right]
-\end{displaymath}">|; 
-
-$key = q/{displaymath}h(x)=sum_kphi(x[k]),qquadphi(u)=left{array{{ll}0&|u|leq1|u|-1&1leq|u|leq22|u|-3&|u|geq2.array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="382" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img198.gif"
- ALT="\begin{displaymath}
-h(x) = \sum_k \phi(x[k]),\qquad
-\phi(u) = \left\{\begin{ar...
-...\\\\
-2\vert u\vert-3 & \vert u\vert \geq 2. \end{array}\right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-logdetK+mathop{{bf{tr}(KY)mbox{subjectto}&K_{ij}=0,quad(i,j)notinS.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="236" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img104.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -\log\det K + \mathop{...
-...box{subject to} & K_{ij}=0,\quad (i,j) \not \in S.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}W_mathrm{l}=mbox{{bf{diag},(d),qquadW_mathrm{l}^{-1}=mbox{{bf{diag},(d)^{-1}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="267" HEIGHT="29" BORDER="0"
- SRC="|."$dir".q|img144.gif"
- ALT="\begin{displaymath}
-W_\mathrm{l} = \mbox{\bf diag} (d), \qquad W_\mathrm{l}^{-1} = \mbox{\bf diag} (d)^{-1}.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}ssucceq0,qquadqquadfrac{|Gx+s|_2}{max{1,|h|_2}}leqepsilon_mathrm{fe|_2}{max{1,|b|_2}}leqepsilon_mathrm{feas},qquadc^Tx=-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="545" HEIGHT="44" BORDER="0"
- SRC="|."$dir".q|img162.gif"
- ALT="\begin{displaymath}
-s \succeq 0, \qquad
-\qquad
-\frac{\Vert Gx+s\Vert _2}{\max\{1...
-...rt b\Vert _2\}} \leq \epsilon_\mathrm{feas}, \qquad
-c^Tx = -1.
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}sum_{k=0}^mz_knabla^2f_k(x)u_x+A^Tu_y+Dtildef(x)^Tu_{z_mathrm{nl}}(d_mathrm{l})^{-2}z_mathrm{l}&=&b_{z_mathrm{l}}{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="402" HEIGHT="125" BORDER="0"
- SRC="|."$dir".q|img187.gif"
- ALT="\begin{eqnarray*}
-\sum_{k=0}^m z_k \nabla^2 f_k(x)u_x + A^T u_y +
-D \tilde f(...
-...diag} (d_\mathrm{l})^{-2} z_\mathrm{l} & = &
-b_{z_\mathrm{l}}
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}B:=alphamathop{mathrm{op}}(A)^{-1}Bquad(mathrm{side}=mathrm{'L'}),q=mathrm{'T'}A^H&mathrm{transA}=mathrm{'C'},array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="732" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img35.gif"
- ALT="\begin{displaymath}
-B := \alpha \mathop{\mathrm{op}}(A)^{-1}B \quad (\mathrm{si...
-...\\\\
-A^H & \mathrm{transA} = \mathrm{'C'}, \end{array} \right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|Pu-q|_1array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="149" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img155.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert Pu-q\Vert _1
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}A:=A+alphaxy^T,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="111" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img25.gif"
- ALT="\begin{displaymath}
-A := A + \alpha x y^T,
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|A^HX-B|_F.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="179" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img60.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert A^HX-B\Vert _F.
-\end{array}\end{displaymath}">|; 
-
-$key = q/AX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="65" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img93.gif"
- ALT="$AX=B$">|; 
-
-$key = q/{displaymath}mathop{{rm{argmax}_{k=0,ldots,n-1}|x_k|quadmbox{({x{real)},qquadmat}_{k=0,ldots,n-1}|Rex_k|+|Imx_k|quadmbox{({x{complex)}.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="467" HEIGHT="41" BORDER="0"
- SRC="|."$dir".q|img11.gif"
- ALT="\begin{displaymath}
-\mathop{\rm argmax}_{k=0,\ldots,n-1} \vert x_k\vert \quad \...
-...e x_k\vert + \vert\Im x_k\vert \quad
-\mbox{($x$ complex)}.
-\end{displaymath}">|; 
-
-$key = q/includegraphics[width=10cm]{figuresslashportfolio2.eps};FSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="453" HEIGHT="340" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img182.gif"
- ALT="\includegraphics[width=10cm]{figures/portfolio2.eps}">|; 
-
-$key = q/{displaymath}AX=Bquad(mathrm{trans}=mathrm{'N'}),qquadA^TX=Bquad(mathrm{trans}=mathrm{'T'}),qquadA^HX=Bquad(mathrm{trans}=mathrm{'C'}),{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="602" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img43.gif"
- ALT="\begin{displaymath}
-AX=B \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-A^TX=B ...
-...'T'}), \qquad
-A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-barp^Tx+mux^TSxmbox{subjectto}&{{bf{1}^Tx=1,quadxsucceq0array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="203" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img180.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -\bar p^T x + \mu x^T S ...
-...ox{subject to} & {\bf 1}^T x = 1, \quad x \succeq 0
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}xleftrightarrowy.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="44" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img12.gif"
- ALT="\begin{displaymath}
-x \leftrightarrow y.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}C=C_0timesC_1timescdotstimesC_MtimesC_{M+1}timescdotstimesC_{M+N}{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="336" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img116.gif"
- ALT="\begin{displaymath}
-C = C_0 \times C_1 \times \cdots \times C_M \times C_{M+1} \times
-\cdots \times C_{M+N}
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x=(A^{-1}+A^{-T})b{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="129" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img44.gif"
- ALT="\begin{displaymath}
-x = (A^{-1} + A^{-T})b
-\end{displaymath}">|; 
-
-$key = q/G;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="17" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img151.gif"
- ALT="$G$">|; 
-
-$key = q/{displaymath}y:=alphaAx+betayquad(mathrm{trans}=mathrm{'N'}),qquady:=alphaA^Tx+betayquad(mathrm{trans}=mathrm{'T'}).{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="469" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img154.gif"
- ALT="\begin{displaymath}
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'...
-... \alpha A^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}).
-\end{displaymath}">|; 
-
-$key = q/{displaymath}nablaf_0(x)+sum_{k=1}^mz_{mathrm{nl},k}nablaf_k(x)+G^Tz_mathrm{l}+Al},k}=0,quadk=1,ldots,m,qquadGx+s_mathrm{l}=h,qquadAx=b{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="747" HEIGHT="53" BORDER="0"
- SRC="|."$dir".q|img185.gif"
- ALT="\begin{displaymath}
-\nabla f_0(x) + \sum_{k=1}^m z_{\mathrm{nl},k}
-\nabla f_k...
-...quad k=1,\ldots,m, \qquad
-Gx + s_\mathrm{l} = h, \qquad Ax=b
-\end{displaymath}">|; 
-
-$key = q/Y;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="17" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img105.gif"
- ALT="$Y$">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|X|_Fmbox{subjectto}&A^HX=B.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="161" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img59.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert X\Vert _F \\\\
-\mbox{subject to} & A^HX=B.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&f(x)=-logdetK(x)+mathop{{bf{tr}(K(x)Y).array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="328" HEIGHT="30" BORDER="0"
- SRC="|."$dir".q|img109.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & f(x) = -\log\det K(x) + \mathop{\bf tr}(K(x)Y).
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}B:=alphamathop{mathrm{op}}(A)Bquad(mathrm{side}=mathrm{'L'}),qquadB=mathrm{'T'}A^H&mathrm{transA}=mathrm{'C'}.array{right.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="697" HEIGHT="64" BORDER="0"
- SRC="|."$dir".q|img34.gif"
- ALT="\begin{displaymath}
-B := \alpha\mathop{\mathrm{op}}(A)B \quad (\mathrm{side} = ...
-...\\\\
-A^H & \mathrm{transA} = \mathrm{'C'}. \end{array} \right.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{[t]{ll}mbox{minimize}&-4x_1-5x_2mbox{subjectto}&2x_1+x_2leq3&x_1+2x_2leq3&x_1geq0,quadx_2geq0.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="202" HEIGHT="87" BORDER="0"
- SRC="|."$dir".q|img127.gif"
- ALT="\begin{displaymath}
-\begin{array}[t]{ll}
-\mbox{minimize} & -4x_1 - 5x_2 \\\\
-\...
-...2x_2 \leq 3 \\\\
-& x_1 \geq 0, \quad x_2 \geq 0.
-\end{array}
-\end{displaymath}">|; 
-
-$key = q/{eqnarraystar}&left[array{{ccccc}X[0,0]&0&0&cdots&0X[1,0]&X[1,1]&0&cdots&0X[2,0]dots&1array{right]&mbox{ifuplo='U'anddiag='U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="662" HEIGHT="450" BORDER="0"
- SRC="|."$dir".q|img3.gif"
- ALT="\begin{eqnarray*}
-& \left[\begin{array}{ccccc}
-X[0,0] & 0 & 0 & \cdots & 0 \\\\
-X...
-...ts & 1
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'U'}.
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&-4x-5ymbox{subjectto}&2x+yleq3&x+2yleq3&xgeq0,quadygeq0.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="187" HEIGHT="83" BORDER="0"
- SRC="|."$dir".q|img202.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -4x - 5y \\\\
-\mbox{su...
-...
-& x +2y \leq 3 \\\\
-& x \geq 0, \quad y \geq 0.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}G^Tz+A^Ty=0,qquadh^Tz+b^Ty=-1,qquadzsucceq0.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="340" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img123.gif"
- ALT="\begin{displaymath}
-G^T z + A^T y = 0, \qquad h^T z + b^T y = -1, \qquad z \succeq 0.
-\end{displaymath}">|; 
-
-$key = q/C;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="17" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img115.gif"
- ALT="$C$">|; 
-
-$key = q/P^TX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="75" HEIGHT="16" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img100.gif"
- ALT="$P^TX=B$">|; 
-
-$key = q/{eqnarraystar}&left[array{{cccc}X[0,0]&0&0&cdotsX[1,0]&X[0,1]&0&cdotsX[2,0]&X[1,&ddotsarray{right]&mbox{ifuplo='U'anddiag='U'}.{eqnarraystar};MSF=1.6;TAGS=R;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="700" HEIGHT="509" BORDER="0"
- SRC="|."$dir".q|img7.gif"
- ALT="\begin{eqnarray*}
-& \left[ \begin{array}{cccc}
-X[0,0] & 0 & 0 & \cdots \\\\
-X[1,0...
-...ddots
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'U'}.
-\end{eqnarray*}">|; 
-
-$key = q/{displaymath}X[k,:]:=frac{1}{n}sum_{j=0}^{n-1}e^{2pijksqrt{-1}slashn}X[j,:],qquadk=0,ldots,n-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="382" HEIGHT="58" BORDER="0"
- SRC="|."$dir".q|img75.gif"
- ALT="\begin{displaymath}
-X[k,:] :=
-\frac{1}{n} \sum_{j=0}^{n-1} e^{2\pi j k \sqrt{-1}/n} X[j,:],
-\qquad k=0,\ldots,n-1.
-\end{displaymath}">|; 
-
-$key = q/a_i^T;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="23" HEIGHT="35" ALIGN="MIDDLE" BORDER="0"
- SRC="|."$dir".q|img73.gif"
- ALT="$a_i^T$">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&|X|_Fmbox{subjectto}&A^TX=B.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="159" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img57.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \Vert X\Vert _F \\\\
-\mbox{subject to} & A^TX=B.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}zsucceq0,qquadqquadfrac{|G^Tz+A^Ty|_2}{max{1,|c|_2}}leqepsilon_mathrm{feas},qquadh^Tz+b^Ty=-1.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="420" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img161.gif"
- ALT="\begin{displaymath}
-z \succeq 0, \qquad
-\qquad \frac{\Vert G^Tz +A^Ty\Vert _2}{\...
-..._2\}} \leq
-\epsilon_\mathrm{feas},
-\qquad h^Tz +b^Ty = -1.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}array{{ll}mbox{minimize}&{{bf{1}^Tvmbox{subjectto}&-vpreceqPu-qpreceqv.array{{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="208" HEIGHT="45" BORDER="0"
- SRC="|."$dir".q|img156.gif"
- ALT="\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & {\bf 1}^T v \\\\
-\mbox{subject to} & -v \preceq Pu - q \preceq v.
-\end{array}\end{displaymath}">|; 
-
-$key = q/{displaymath}left[array{{cccc}sum_{k=0}^mz_knabla^2f_k(x)&Dtildef(x)^T&G^T&A^TDt(d_1)&0&0G&0&-mbox{{bf{diag},(d_2)&0A&0&0&0array{right]{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="365" HEIGHT="86" BORDER="0"
- SRC="|."$dir".q|img169.gif"
- ALT="\begin{displaymath}
-\left[\begin{array}{cccc}
-\sum_{k=0}^m z_k \nabla^2 f_k(x) &...
-...box{\bf diag} (d_2) & 0 \\\\
-A & 0 & 0 & 0 \end{array}\right]
-\end{displaymath}">|; 
-
-$key = q/{displaymath}AX=B{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="59" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img47.gif"
- ALT="\begin{displaymath}
-AX=B
-\end{displaymath}">|; 
-
-$key = q/{displaymath}f(x_1,ldots,x_n)=A_1x_1+cdots+A_nx_n+b.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="272" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img194.gif"
- ALT="\begin{displaymath}
-f(x_1,\ldots,x_n) = A_1 x_1 + \cdots + A_n x_n + b.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}y:=alphax+y.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="84" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img14.gif"
- ALT="\begin{displaymath}
-y := \alpha x + y.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}x:=alphax.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="56" HEIGHT="24" BORDER="0"
- SRC="|."$dir".q|img8.gif"
- ALT="\begin{displaymath}
-x := \alpha x.
-\end{displaymath}">|; 
-
-$key = q/{displaymath}A=Vmbox{{bf{diag},(lambda)V^T,qquadV^TV=I.{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="233" HEIGHT="28" BORDER="0"
- SRC="|."$dir".q|img64.gif"
- ALT="\begin{displaymath}
-A = V\mbox{\bf diag} (\lambda)V^T,\qquad V^TV = I.
-\end{displaymath}">|; 
-
-$key = q/LDLX=B;MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="88" HEIGHT="14" ALIGN="BOTTOM" BORDER="0"
- SRC="|."$dir".q|img95.gif"
- ALT="$LDLX=B$">|; 
-
-$key = q/{displaymath}0preceqxpreceq{{bf{1},qquad{{bf{1}^Tx=2,{displaymath};MSF=1.6;AAT/;
-$cached_env_img{$key} = q|<IMG
- WIDTH="168" HEIGHT="27" BORDER="0"
- SRC="|."$dir".q|img201.gif"
- ALT="\begin{displaymath}
-0 \preceq x \preceq {\bf 1}, \qquad {\bf 1}^T x = 2,
-\end{displaymath}">|; 
-
-1;
-
diff --git a/doc/cvxopt/images.tex b/doc/cvxopt/images.tex
deleted file mode 100644
index d92f92b..0000000
--- a/doc/cvxopt/images.tex
+++ /dev/null
@@ -1,2523 +0,0 @@
-\batchmode
-\documentclass{book}
-\RequirePackage{ifthen}
-
-
-\usepackage{html,graphicx}
-
-%
-\providecommand{\eg}{{\em e.g.}}%
-\providecommand{\ie}{{\em i.e.}}%
-\providecommand{\BEA}{\begin{eqnarray}}%
-\providecommand{\EEA}{\end{eqnarray}}%
-\providecommand{\BEAS}{\begin{eqnarray*}}%
-\providecommand{\EEAS}{\end{eqnarray*}}%
-\providecommand{\Rank}{\mathop{\bf rank}}%
-\providecommand{\Tr}{\mathop{\bf tr}}%
-\providecommand{\lse}{\mathop{\bf lse}}%
-\providecommand{\diag}{\mbox{\bf diag}\,}%
-\providecommand{\ones}{{\bf 1}}%
-\providecommand{\argmax}{\mathop{\rm argmax}}%
-\providecommand{\symm}{{\mbox{\bf S}}}%
-\providecommand{\op}{\mathop{\mathrm{op}}}%
-\providecommand{\svec}{\mathop{\mathbf{vec}}} 
-
-%
-\providecommand{\code}[1]{{\tt #1}}%
-\providecommand{\pytype}[1]{{\tt #1}}%
-\providecommand{\cdata}[1]{{\tt #1}}%
-\providecommand{\var}[1]{{\tt #1}}%
-\providecommand{\samp}[1]{"{\tt #1}"}%
-\providecommand{\module}[1]{{\tt #1}}%
-\providecommand{\class}[1]{{\tt #1}}%
-\providecommand{\function}[1]{{\tt #1}}%
-\providecommand{\member}[1]{{\tt #1}}%
-\providecommand{\program}[1]{{\rm #1}}%
-\providecommand{\optional}[1]{{\rm [}#1{\rm ]}}%
-\providecommand{\file}[1]{{\tt #1}}%
-\providecommand{\ctype}[1]{{\tt #1}}%
-\providecommand{\constant}[1]{{\tt #1}} 
-
-%
-\newenvironment{cfuncdesc}[3]{
-
-{\tt #1}%
-    {\bf #2}({\tt #3})\begin{list}{}{}\item[]}{\end{list}} 
-
-%
-\newenvironment{classdesc}[2]{
-
-{\bf #1}%
-    ({\tt #2})\begin{list}{}{}\item[]}{\end{list}} 
-
-%
-\newenvironment{funcdesc}[2]{
-
-{\bf #1}%
-    ({\tt #2})\begin{list}{}{}\item[]}{\end{list}} 
-
-%
-\newenvironment{memberdesc}[3]{
-
-{\bf #2}%
-    \begin{list}{}{}\item[]}{\end{list}} 
-
-%
-\newenvironment{methoddesc}[3]{
-
-{\bf #2}()%
-    \begin{list}{}{}\item[]}{\end{list}} 
-
-%
-\newenvironment{seealso}{
-
-{\bf See also:}\begin{list}{}{}\item[]}{\end{list}}%
-\providecommand{\seetext}[1]{#1}%
-\providecommand{\ulink}[2]{\htmladdnormallink{#1}{#2}}%
-\providecommand{\seelink}[3]{\htmladdnormallink{#2}{#1}}%
-\providecommand{\citetitle}[2]{\htmladdnormallink{#2}{#1}}  
-
-%
-\providecommand{\dtc}{{\tt 'd'}}%
-\providecommand{\itc}{{\tt 'i'}}%
-\providecommand{\ztc}{{\tt 'z'}}%
-\providecommand{\None}{{\tt None}}%
-\providecommand{\True}{{\tt True}}%
-\providecommand{\False}{{\tt False}} 
-
-%
-\providecommand{\flt}{{\tt float}}%
-\providecommand{\chr}{{\tt char}}%
-\providecommand{\intgr}{{\tt integer}}%
-\providecommand{\cmplx}{{\tt complex}}%
-\providecommand{\mtrx}{{\tt matrix}}%
-\providecommand{\spmtrx}{{\tt spmatrix}} 
-
-
-\title{CVXOPT User's Guide} 
-\author{Joachim Dahl \& Lieven Vandenberghe}
-\date{Release 0.9 -- August 10, 2007} 
-
-
-
-
-\usepackage[dvips]{color}
-
-
-\pagecolor[gray]{.7}
-
-\usepackage[latin1]{inputenc}
-
-
-
-\makeatletter
-
-\makeatletter
-\count@=\the\catcode`\_ \catcode`\_=8 
-\newenvironment{tex2html_wrap}{}{}%
-\catcode`\<=12\catcode`\_=\count@
-\newcommand{\providedcommand}[1]{\expandafter\providecommand\csname #1\endcsname}%
-\newcommand{\renewedcommand}[1]{\expandafter\providecommand\csname #1\endcsname{}%
-  \expandafter\renewcommand\csname #1\endcsname}%
-\newcommand{\newedenvironment}[1]{\newenvironment{#1}{}{}\renewenvironment{#1}}%
-\let\newedcommand\renewedcommand
-\let\renewedenvironment\newedenvironment
-\makeatother
-\let\mathon=$
-\let\mathoff=$
-\ifx\AtBeginDocument\undefined \newcommand{\AtBeginDocument}[1]{}\fi
-\newbox\sizebox
-\setlength{\hoffset}{0pt}\setlength{\voffset}{0pt}
-\addtolength{\textheight}{\footskip}\setlength{\footskip}{0pt}
-\addtolength{\textheight}{\topmargin}\setlength{\topmargin}{0pt}
-\addtolength{\textheight}{\headheight}\setlength{\headheight}{0pt}
-\addtolength{\textheight}{\headsep}\setlength{\headsep}{0pt}
-\setlength{\textwidth}{451pt}
-\setlength{\textheight}{554pt}
-\newwrite\lthtmlwrite
-\makeatletter
-\let\realnormalsize=\normalsize
-\global\topskip=2sp
-\def\preveqno{}\let\real at float=\@float \let\realend at float=\end at float
-\def\@float{\let\@savefreelist\@freelist\real at float}
-\def\liih at math{\ifmmode$\else\bad at math\fi}
-\def\end at float{\realend at float\global\let\@freelist\@savefreelist}
-\let\real at dbflt=\@dbflt \let\end at dblfloat=\end at float
-\let\@largefloatcheck=\relax
-\let\if at boxedmulticols=\iftrue
-\def\@dbflt{\let\@savefreelist\@freelist\real at dbflt}
-\def\adjustnormalsize{\def\normalsize{\mathsurround=0pt \realnormalsize
- \parindent=0pt\abovedisplayskip=0pt\belowdisplayskip=0pt}%
- \def\phantompar{\csname par\endcsname}\normalsize}%
-\def\lthtmltypeout#1{{\let\protect\string \immediate\write\lthtmlwrite{#1}}}%
-\newcommand\lthtmlhboxmathA{\adjustnormalsize\setbox\sizebox=\hbox\bgroup\kern.05em }%
-\newcommand\lthtmlhboxmathB{\adjustnormalsize\setbox\sizebox=\hbox to\hsize\bgroup\hfill }%
-\newcommand\lthtmlvboxmathA{\adjustnormalsize\setbox\sizebox=\vbox\bgroup %
- \let\ifinner=\iffalse \let\)\liih at math }%
-\newcommand\lthtmlboxmathZ{\@next\next\@currlist{}{\def\next{\voidb at x}}%
- \expandafter\box\next\egroup}%
-\newcommand\lthtmlmathtype[1]{\gdef\lthtmlmathenv{#1}}%
-\newcommand\lthtmllogmath{\dimen0\ht\sizebox \advance\dimen0\dp\sizebox
-  \ifdim\dimen0>.95\vsize
-   \lthtmltypeout{%
-*** image for \lthtmlmathenv\space is too tall at \the\dimen0, reducing to .95 vsize ***}%
-   \ht\sizebox.95\vsize \dp\sizebox\z@ \fi
-  \lthtmltypeout{l2hSize %
-:\lthtmlmathenv:\the\ht\sizebox::\the\dp\sizebox::\the\wd\sizebox.\preveqno}}%
-\newcommand\lthtmlfigureA[1]{\let\@savefreelist\@freelist
-       \lthtmlmathtype{#1}\lthtmlvboxmathA}%
-\newcommand\lthtmlpictureA{\bgroup\catcode`\_=8 \lthtmlpictureB}%
-\newcommand\lthtmlpictureB[1]{\lthtmlmathtype{#1}\egroup
-       \let\@savefreelist\@freelist \lthtmlhboxmathB}%
-\newcommand\lthtmlpictureZ[1]{\hfill\lthtmlfigureZ}%
-\newcommand\lthtmlfigureZ{\lthtmlboxmathZ\lthtmllogmath\copy\sizebox
-       \global\let\@freelist\@savefreelist}%
-\newcommand\lthtmldisplayA{\bgroup\catcode`\_=8 \lthtmldisplayAi}%
-\newcommand\lthtmldisplayAi[1]{\lthtmlmathtype{#1}\egroup\lthtmlvboxmathA}%
-\newcommand\lthtmldisplayB[1]{\edef\preveqno{(\theequation)}%
-  \lthtmldisplayA{#1}\let\@eqnnum\relax}%
-\newcommand\lthtmldisplayZ{\lthtmlboxmathZ\lthtmllogmath\lthtmlsetmath}%
-\newcommand\lthtmlinlinemathA{\bgroup\catcode`\_=8 \lthtmlinlinemathB}
-\newcommand\lthtmlinlinemathB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA
-  \vrule height1.5ex width0pt }%
-\newcommand\lthtmlinlineA{\bgroup\catcode`\_=8 \lthtmlinlineB}%
-\newcommand\lthtmlinlineB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA}%
-\newcommand\lthtmlinlineZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
-  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetinline}
-\newcommand\lthtmlinlinemathZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
-  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetmath}
-\newcommand\lthtmlindisplaymathZ{\egroup %
-  \centerinlinemath\lthtmllogmath\lthtmlsetmath}
-\def\lthtmlsetinline{\hbox{\vrule width.1em \vtop{\vbox{%
-  \kern.1em\copy\sizebox}\ifdim\dp\sizebox>0pt\kern.1em\else\kern.3pt\fi
-  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
-\def\lthtmlsetmath{\hbox{\vrule width.1em\kern-.05em\vtop{\vbox{%
-  \kern.1em\kern0.8 pt\hbox{\hglue.17em\copy\sizebox\hglue0.8 pt}}\kern.3pt%
-  \ifdim\dp\sizebox>0pt\kern.1em\fi \kern0.8 pt%
-  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
-\def\centerinlinemath{%
-  \dimen1=\ifdim\ht\sizebox<\dp\sizebox \dp\sizebox\else\ht\sizebox\fi
-  \advance\dimen1by.5pt \vrule width0pt height\dimen1 depth\dimen1 
- \dp\sizebox=\dimen1\ht\sizebox=\dimen1\relax}
-
-\def\lthtmlcheckvsize{\ifdim\ht\sizebox<\vsize 
-  \ifdim\wd\sizebox<\hsize\expandafter\hfill\fi \expandafter\vfill
-  \else\expandafter\vss\fi}%
-\providecommand{\selectlanguage}[1]{}%
-\makeatletter \tracingstats = 1 
-
-
-\begin{document}
-\pagestyle{empty}\thispagestyle{empty}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength hsize=\the\hsize}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength vsize=\the\vsize}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength hoffset=\the\hoffset}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength voffset=\the\voffset}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength topmargin=\the\topmargin}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength topskip=\the\topskip}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength headheight=\the\headheight}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength headsep=\the\headsep}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength parskip=\the\parskip}\lthtmltypeout{}%
-\lthtmltypeout{latex2htmlLength oddsidemargin=\the\oddsidemargin}\lthtmltypeout{}%
-\makeatletter
-\if at twoside\lthtmltypeout{latex2htmlLength evensidemargin=\the\evensidemargin}%
-\else\lthtmltypeout{latex2htmlLength evensidemargin=\the\oddsidemargin}\fi%
-\lthtmltypeout{}%
-\makeatother
-\setcounter{page}{1}
-\onecolumn
-
-% !!! IMAGES START HERE !!!
-
-\stepcounter{chapter}
-\stepcounter{chapter}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{chapter}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4063}%
-\begin{eqnarray*}
-&  \left[\begin{array}{ccccc}
-X[0,0]   & X[1,0]   & X[2,0]   & \cdots & X[n-1,0] \\
-X[1,0]   & X[1,1]   & X[2,1]   & \cdots & X[n-1,1] \\
-X[2,0]   & X[2,1]   & X[2,2]   & \cdots & X[n-1,2] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-X[n-1,0] & X[n-1,1] & X[n-1,2] & \cdots & X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'L'}, \\
-& \left[\begin{array}{ccccc}
-X[0,0]   & X[0,1]   & X[0,2]   & \cdots & X[0,n-1] \\
-X[0,1]   & X[1,1]   & X[1,2]   & \cdots & X[1,n-1] \\
-X[0,2]   & X[1,2]   & X[2,2]   & \cdots & X[2,n-1] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-X[0,n-1] & X[1,n-1] & X[2,n-1] & \cdots & X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = U'}. 
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4070}%
-\begin{eqnarray*}
-&
-\left[\begin{array}{ccccc}
-\Re X[0,0]   & \bar X[1,0]   & \bar X[2,0]   & \cdots & \bar X[n-1,0] \\
-X[1,0]   & \Re X[1,1]   & \bar X[2,1]   & \cdots & \bar X[n-1,1] \\
-X[2,0]   & X[2,1]   & \Re X[2,2]   & \cdots & \bar X[n-1,2] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-X[n-1,0] & X[n-1,1] & X[n-1,2] & \cdots & \Re X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'L'}, \\
-& \left[\begin{array}{ccccc}
-\Re X[0,0]   & X[0,1]   & X[0,2]   & \cdots & X[0,n-1] \\
-\bar X[0,1]   & \Re X[1,1]   & X[1,2]   & \cdots & X[1,n-1] \\
-\bar X[0,2]   & \bar X[1,2]   & \Re X[2,2]   & \cdots & X[2,n-1] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-\bar X[0,n-1] & \bar X[1,n-1] & \bar X[2,n-1] & \cdots & \Re X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'U'}.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4081}%
-\begin{eqnarray*}
-& \left[\begin{array}{ccccc}
-X[0,0]   & 0        & 0        & \cdots & 0 \\
-X[1,0]   & X[1,1]   & 0        & \cdots & 0 \\
-X[2,0]   & X[2,1]   & X[2,2]   & \cdots & 0 \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-X[n-1,0] & X[n-1,1] & X[n-1,2] & \cdots & X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'L' and diag = 'N'}, \\
-& \left[\begin{array}{ccccc}
-1   & 0   & 0   & \cdots & 0 \\
-X[1,0]   & 1   & 0   & \cdots & 0 \\
-X[2,0]   & X[2,1]   & 1   & \cdots & 0 \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-X[n-1,0] & X[n-1,1] & X[n-1,2] & \cdots & 1
-\end{array}\right] & \mbox{if uplo = 'L' and diag = 'U'}, \\
-& \left[\begin{array}{ccccc}
-X[0,0]   & X[0,1]   & X[0,2]   & \cdots & X[0,n-1] \\
-0   & X[1,1]   & X[1,2]   & \cdots & X[1,n-1] \\
-0   & 0   & X[2,2]   & \cdots & X[2,n-1] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-0 & 0 & 0 & \cdots & X[n-1,n-1]
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'N'}, \\
-& \left[\begin{array}{ccccc}
-1   & X[0,1]   & X[0,2]   & \cdots & X[0,n-1] \\
-0   & 1   & X[1,2]   & \cdots & X[1,n-1] \\
-0   & 0   & 1   & \cdots & X[2,n-1] \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots \\
-0 & 0 & 0 & \cdots & 1
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'U'}.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4586}%
-\begin{displaymath}
-\left[ \begin{array}{ccccccc}
-X[k_u,0]     & X[k_u-1,1]     & X[k_u-2,2]     & \cdots & X[0,k_u] & 0               & \cdots \\
-X[k_u+1,0]   & X[k_u,1]       & X[k_u-1,2]     & \cdots & X[1,k_u] & X[0,k_u+1]   & \cdots \\
-X[k_u+2,0]   & X[k_u+1,1]     & X[k_u,2]       & \cdots & X[2,k_u] & X[1,k_u+1] & \cdots \\
- \vdots      & \vdots         &  \vdots        & \ddots & \vdots   & \vdots          & \ddots  \\
-X[k_u+k_l,0] & X[k_u+k_l-1,1] & X[k_u+k_l-2,2] & \cdots &  &  & \\
-0            & X[k_u+k_l,1]   & X[k_u+k_l-1,2] & \cdots &  &  & \\
-\vdots       & \vdots         & \vdots         & \ddots &  &  & 
-\end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4098}%
-\begin{eqnarray*}
-& \left[ \begin{array}{ccccccc}
-X[0,0] & X[1,0]   & X[2,0]   & \cdots & X[k,0]   & 0        & \cdots \\
-X[1,0] & X[0,1]   & X[1,1]   & \cdots & X[k-1,1] & X[k,1]   & \cdots \\
-X[2,0] & X[1,1]   & X[0,2]   & \cdots & X[k-2,2] & X[k-1,2] & \cdots \\
-\vdots & \vdots   &  \vdots  & \ddots & \vdots   & \vdots   & \ddots \\
-X[k,0] & X[k-1,1] & X[k-2,2] & \cdots &  &  & \\
-0      & X[k,1]   & X[k-1,2] & \cdots &  &  & \\
-\vdots & \vdots   & \vdots   & \ddots &  &  & 
-\end{array}\right] & \mbox{if uplo = 'L'}, \\
-& 
-\left[ \begin{array}{ccccccc}
-X[k,0]   & X[k-1,1] & X[k-2,2] & \cdots & X[0,k] & 0        & \cdots \\
-X[k-1,1] & X[k,1]   & X[k-1,2] & \cdots & X[1,k] & X[0,k+1] & \cdots \\
-X[k-2,2] & X[k-1,2] & X[k,2]   & \cdots & X[2,k] & X[1,k+1] & \cdots \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots & \vdots   & \ddots \\
-X[0,k]   & X[1,k]   & X[2,k]   & \cdots &  &  & \\
-0        & X[0,k+1] & X[1,k+1] & \cdots &  &  & \\
-\vdots   & \vdots   & \vdots   & \ddots &  &  & 
-\end{array}\right] & \mbox{if uplo='U'}.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4102}%
-\begin{eqnarray*}
-& \left[ \begin{array}{ccccccc}
-\Re X[0,0] & \bar X[1,0]   & \bar X[2,0]   & \cdots & \bar X[k,0]   & 0        & \cdots \\
-X[1,0] & \Re X[0,1]   & \bar X[1,1]   & \cdots & \bar X[k-1,1] & \bar X[k,1]   & \cdots \\
-X[2,0] & X[1,1]   & \Re X[0,2]   & \cdots & \bar X[k-2,2] & \bar X[k-1,2] & \cdots \\
-\vdots & \vdots   &  \vdots  & \ddots & \vdots   & \vdots   & \ddots \\
-X[k,0] & X[k-1,1] & X[k-2,2] & \cdots &  &  & \\
-0      & X[k,1]   & X[k-1,2] & \cdots &  &  & \\
-\vdots & \vdots   & \vdots   & \ddots &  &  & 
-\end{array}\right] & \mbox{if uplo = 'L'}, \\
-& 
-\left[ \begin{array}{ccccccc}
-\Re X[k,0]   & X[k-1,1] & X[k-2,2] & \cdots & X[0,k] & 0        & \cdots \\
-\bar X[k-1,1] & \Re X[k,1]   & X[k-1,2] & \cdots & X[1,k] & X[0,k+1] & \cdots \\
-\bar X[k-2,2] & \bar X[k-1,2] & \Re X[k,2]   & \cdots & X[2,k] & X[1,k+1] & \cdots \\
-\vdots   & \vdots   & \vdots   & \ddots & \vdots & \vdots   & \ddots \\
-\bar X[0,k]   & \bar X[1,k]   & \bar X[2,k]   & \cdots &  &  & \\
-0        & \bar X[0,k+1] & \bar X[1,k+1] & \cdots &  &  & \\
-\vdots   & \vdots   & \vdots   & \ddots &  &  & 
-\end{array}\right] & \mbox{if uplo='U'}.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar4107}%
-\begin{eqnarray*}
-& \left[ \begin{array}{cccc}
-X[0,0] & 0        & 0        & \cdots \\
-X[1,0] & X[0,1]   & 0        & \cdots  \\
-X[2,0] & X[1,1]   & X[0,2]   & \cdots \\
-\vdots & \vdots   & \vdots   & \ddots \\
-X[k,0] & X[k-1,1] & X[k-2,2] & \cdots \\
-0      & X[k,1]   & X[k-1,1] & \cdots \\
-\vdots & \vdots   & \vdots   & \ddots 
-\end{array}\right] & \mbox{if uplo = 'L' and diag = 'N'},  \\
-& \left[ \begin{array}{cccc}
-1      & 0        & 0        & \cdots \\
-X[1,0] & 1        & 0        & \cdots  \\
-X[2,0] & X[1,1]   & 1        & \cdots \\
-\vdots & \vdots   & \vdots   & \ddots \\
-X[k,0] & X[k-1,1] & X[k-2,2] & \cdots \\
-0      & X[k,1]   & X[k-1,2] & \cdots \\
-\vdots & \vdots   & \vdots   & \ddots 
-\end{array}\right] & \mbox{if uplo = 'L'  and diag = 'U'}, \\
-& \left[ \begin{array}{ccccccc}
-X[k,0] & X[k-1,1] & X[k-2,3] & \cdots & X[0,k]  & 0        & \cdots\\
-0      & X[k,1]   & X[k-1,2] & \cdots & X[1,k]  & X[0,k+1] & \cdots \\
-0      & 0        & X[k,2]   & \cdots & X[2,k]  & X[1,k+1] & \cdots \\
-\vdots & \vdots   &  \vdots  & \ddots & \vdots  & \vdots   & \ddots  
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'N'}, \\
-& \left[ \begin{array}{ccccccc}
-1      & X[k-1,1] & X[k-2,3] & \cdots & X[0,k]  & 0        & \cdots\\
-0      & 1        & X[k-1,2] & \cdots & X[1,k]  & X[0,k+1] & \cdots \\
-0      & 0        & 1        & \cdots & X[2,k]  & X[1,k+1] & \cdots \\
-\vdots & \vdots   &  \vdots  & \ddots & \vdots  & \vdots   & \ddots  
-\end{array}\right] & \mbox{if uplo = 'U' and diag = 'U'}.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4587}%
-\begin{displaymath} 
-x := \alpha x.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4588}%
-\begin{displaymath}
- \|x\|_2.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4589}%
-\begin{displaymath}
-\|x\|_1 \quad \mbox{($x$\  real)}, \qquad  
-\|\Re x\|_1 + \|\Im x\|_1 \quad \mbox{($x$\  complex)}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4590}%
-\begin{displaymath}
- \mathop{\rm argmax}_{k=0,\ldots,n-1} |x_k| \quad \mbox{($x$\  real)}, \qquad
- \mathop{\rm argmax}_{k=0,\ldots,n-1} |\Re x_k| + |\Im x_k| \quad 
- \mbox{($x$\  complex)}. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4591}%
-\begin{displaymath}
-  x \leftrightarrow y.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4592}%
-\begin{displaymath}
- y := x.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4593}%
-\begin{displaymath} 
-y := \alpha x + y.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4594}%
-\begin{displaymath} 
-x^Hy. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4595}%
-\begin{displaymath} 
-x^Ty. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4596}%
-\begin{displaymath} 
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'}),
-  \qquad 
-y := \alpha A^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}), 
-  \qquad
-y := \alpha A^H x + \beta y \quad (\mathrm{trans} = \mathrm{'C'}). 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4597}%
-\begin{displaymath}
-   y := \alpha A x + \beta y,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4599}%
-\begin{displaymath} 
-x := Ax \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A^T x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad
-x := A^H x \quad (\mathrm{trans} = \mathrm{'C'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4600}%
-\begin{displaymath} 
-x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A^{-T}x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
-x := A^{-H}x \quad (\mathrm{trans} = \mathrm{'C'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4601}%
-\begin{displaymath} 
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-y := \alpha A^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}), 
-\qquad 
-y := \alpha A^H x + \beta y \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4604}%
-\begin{displaymath}
-x := Ax \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A^T x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
-x := A^H x \quad (\mathrm{trans} = \mathrm{'C'}). 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4605}%
-\begin{displaymath}
-x := A^{-1}x \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-x := A^{-T} x \quad (\mathrm{trans} = \mathrm{'T'}), \qquad
-x := A^{-H} x \quad (\mathrm{trans} = \mathrm{'T'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4606}%
-\begin{displaymath} 
-A := A + \alpha x y^H,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4607}%
-\begin{displaymath} 
-A := A + \alpha x y^T, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4608}%
-\begin{displaymath}
- A := A + \alpha xx^T,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4609}%
-\begin{displaymath}
- A := A + \alpha xx^H, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4610}%
-\begin{displaymath}
- A := A + \alpha (xy^T + yx^T),
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4611}%
-\begin{displaymath}
- A := A + \alpha xy^H + \bar \alpha yx^H,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4612}%
-\begin{displaymath}
-A = \left[\begin{array}{rrrr}
-  1 &  6 &  0 & 0 \\
-  2 & -4 &  3 & 0 \\
-  0 & -3 & -1 & 1 
-  \end{array}\right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4613}%
-\begin{displaymath}
-  C := \alpha \mathop{\mathrm{op}}(A) \mathop{\mathrm{op}}(B) + \beta C 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4614}%
-\begin{displaymath}
-\mathop{\mathrm{op}}(A) =  \left\{ \begin{array}{ll}
- A & \mathrm{transA} = \mathrm{'N'} \\
- A^T & \mathrm{transA} = \mathrm{'T'} \\
- A^H & \mathrm{transA} = \mathrm{'C'} \end{array} \right.
-\qquad
-\mathop{\mathrm{op}}(B) =  \left\{ \begin{array}{ll}
- B & \mathrm{transB} = \mathrm{'N'} \\
- B^T & \mathrm{transB} = \mathrm{'T'} \\
- B^H & \mathrm{transB} = \mathrm{'C'}. \end{array} \right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4615}%
-\begin{displaymath}
- C := \alpha AB + \beta C \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
- C := \alpha BA + \beta C \quad (\mathrm{side} = \mathrm{'R'}). 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4617}%
-\begin{displaymath}
- B := \alpha\mathop{\mathrm{op}}(A)B \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
- B := \alpha B\mathop{\mathrm{op}}(A) \quad (\mathrm{side} = \mathrm{'R'}), \qquad 
- \mathop{\mathrm{op}}(A) =  \left\{ \begin{array}{ll}
- A & \mathrm{transA} = \mathrm{'N'} \\
- A^T & \mathrm{transA} = \mathrm{'T'} \\
- A^H & \mathrm{transA} = \mathrm{'C'}. \end{array} \right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4618}%
-\begin{displaymath}
- B := \alpha \mathop{\mathrm{op}}(A)^{-1}B \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
- B := \alpha B\mathop{\mathrm{op}}(A)^{-1} \quad (\mathrm{side} = \mathrm{'R'}), \qquad 
- \mathop{\mathrm{op}}(A) =  \left\{ \begin{array}{ll}
- A & \mathrm{transA} = \mathrm{'N'} \\
- A^T & \mathrm{transA} = \mathrm{'T'} \\
- A^H & \mathrm{transA} = \mathrm{'C'}, \end{array} \right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4619}%
-\begin{displaymath}
- C := \alpha AA^T + \beta C \quad (\mathrm{trans} = \mathrm{'N'}), 
- \qquad 
- C := \alpha A^TA + \beta C \quad (\mathrm{trans} = \mathrm{'T'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4620}%
-\begin{displaymath}
- C := \alpha AA^H + \beta C \quad (\mathrm{trans} = \mathrm{'N'}), 
- \qquad 
- C := \alpha A^HA + \beta C \quad (\mathrm{trans} = \mathrm{'C'}),
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4621}%
-\begin{displaymath}
- C := \alpha (AB^T + BA^T) + \beta C \quad 
-  (\mathrm{trans} = \mathrm{'N'}), \qquad 
- C := \alpha (A^TB + B^TA) + \beta C \quad 
-  (\mathrm{trans} = \mathrm{'T'}). 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath4622}%
-\begin{displaymath}
- C := \alpha AB^H + \bar \alpha BA^H + \beta C \quad 
-  (\mathrm{trans} = \mathrm{'N'}), \qquad 
- C := \alpha A^HB + \bar\alpha B^HA + \beta C \quad 
-  (\mathrm{trans} = \mathrm{'C'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8374}%
-$\mathrm{{}^T}$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8292}%
-\begin{displaymath} 
-   A X = B,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8293}%
-\begin{displaymath}
-  A = PLU 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8294}%
-\begin{displaymath}
- AX=B \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
- A^TX=B \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
- A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}), 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8295}%
-\begin{displaymath}
- x = (A^{-1} + A^{-T})b
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8298}%
-\begin{displaymath}
- A = \left[ \begin{array}{cccc}
- 1 & 2 & 0 & 0 \\
- 3 & 4 & 5 & 0 \\
- 6 & 7 & 8 & 9 \\
- 0 & 10 & 11 & 12 
- \end{array}\right], \qquad  x = \left[\begin{array}{c} 1 \\1 \\1 \\1
- \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8302}%
-\begin{displaymath}
- A = LL^T \qquad \mbox{or} \qquad A = LL^H
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8303}%
-\begin{displaymath}
- AX=B
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath7646}%
-\begin{displaymath}
- \left[ \begin{array}{cc}
- -\mbox{\bf diag}\,(d)^2  & A \\
- A^T  & 0 \end{array} \right]
- \left[ \begin{array}{c} x_1 \\x_2 \end{array} \right]
- = \left[ \begin{array}{c} b_1 \\b_2 \end{array} \right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8304}%
-\begin{displaymath}
- A^T \mbox{\bf diag}\,(d)^{-2}A x_2 = b_2 + A^T \mbox{\bf diag}\,(d)^{-2} b_1, \qquad
- \mbox{\bf diag}\,(d)^2 x_1 = Ax_2 - b_1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8376}%
-${}\mathrm{^T}$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8378}%
-${}\mathrm{^H}$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8311}%
-\begin{displaymath}
- PAP^T = LDL^T
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8390}%
-$A$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8314}%
-\begin{displaymath}
- PAP^T = LDL^H
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8318}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|AX-B\|_F.
- \end{array} 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8319}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|X\|_F \\
- \mbox{subject to} & AX = B.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8320}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|X\|_F \\
- \mbox{subject to} & A^TX=B.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8321}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|A^TX-B\|_F.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8322}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|X\|_F \\
- \mbox{subject to} & A^HX=B.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8323}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|A^HX-B\|_F.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8324}%
-\begin{displaymath}
-  A = Q R.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8325}%
-\begin{displaymath}
- C := \mathop{\mathrm{op}}(Q)C \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
- C := C\mathop{\mathrm{op}}(Q) \quad (\mathrm{side} = \mathrm{'R'}), \qquad 
- \mathop{\mathrm{op}}(Q) =  \left\{ \begin{array}{ll}
- Q & \mathrm{trans} = \mathrm{'N'} \\
- Q^T & \mathrm{trans} = \mathrm{'T'},
-\end{array}\right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8326}%
-\begin{displaymath}
- C := \mathop{\mathrm{op}}(Q)C \quad (\mathrm{side} = \mathrm{'L'}), \qquad 
- C := C\mathop{\mathrm{op}}(Q) \quad (\mathrm{side} = \mathrm{'R'}), \qquad 
- \mathop{\mathrm{op}}(Q) =  \left\{ \begin{array}{ll}
- Q & \mathrm{trans} = \mathrm{'N'} \\
- Q^T & \mathrm{trans} = \mathrm{'T'} \\
- Q^H & \mathrm{trans} = \mathrm{'C'},
-\end{array}\right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8327}%
-\begin{displaymath}
- A = V\mbox{\bf diag}\,(\lambda)V^T,\qquad  V^TV = I.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8328}%
-\begin{displaymath}
- A = V\mbox{\bf diag}\,(\lambda)V^H,\qquad  V^HV = I.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8126}%
-\begin{displaymath}
- AZ = BZ\mbox{\bf diag}\,(\lambda)\quad \mbox{(type 1)}, \qquad 
- ABZ = Z\mbox{\bf diag}\,(\lambda) \quad \mbox{(type 2)}, \qquad 
- BAZ = Z\mbox{\bf diag}\,(\lambda) \quad \mbox{(type 3)}, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8408}%
-$B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8329}%
-\begin{displaymath}
- Z^H BZ = I \quad \mbox{(types 1 and 2)}, \qquad 
- Z^H B^{-1}Z = I \quad \mbox{(type 3)}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8330}%
-\begin{displaymath}
- A = U \Sigma V^T, \qquad A = U \Sigma V^H
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8412}%
-$V^H$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8331}%
-\begin{displaymath}
- \begin{array}{ll}
-  \mbox{minimize} & -\sum_{i=1}^m \log(b_i-a_i^Tx).
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath8332}%
-\begin{displaymath}
- A^T \mbox{\bf diag}\,(b-Ax)^{-2} A v = -\mbox{\bf diag}\,(b-Ax)^{-1}{\bf 1}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline8414}%
-$a_i^T$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath10727}%
-\begin{displaymath}
-  X[k,:] := \sum_{j=0}^{n-1} e^{-2\pi j k \sqrt{-1}/n} X[j,:],
- \qquad k=0,\ldots,n-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath10728}%
-\begin{displaymath}
-  X[k,:] := 
- \frac{1}{n} \sum_{j=0}^{n-1} e^{2\pi j k \sqrt{-1}/n} X[j,:],
-  \qquad k=0,\ldots,n-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar10717}%
-\begin{eqnarray*}
-\mbox{DCT-I:} \qquad
- X[k,:]  & := & X[0,:] + (-1)^k X[n-1,:] + 
- 2 \sum_{j=1}^{n-2} X[j,:] \cos(\pi j k /(n-1)), 
- \qquad k=0,\ldots,n-1.\\
-\mbox{DCT-II:} \qquad
- X[k,:]  & := & 2 \sum_{j=0}^{n-1} X[j,:] \cos(\pi(j+1/2)k/n), 
- \qquad k=0,\ldots,n-1.\\
-\mbox{DCT-III:} \qquad
- X[k,:]  & := & X[0,:] + 2 \sum_{j=1}^{n-1} X[j,:] \cos(\pi j(k+1/2)/n),
- \qquad k=0,\ldots,n-1.\\
-\mbox{DCT-IV:} \qquad
- X[k,:]  & := & 2 \sum_{j=0}^{n-1} X[j,:] \cos(\pi (j+1/2)(k+1/2)/n), 
- \qquad k=0,\ldots,n-1.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar10723}%
-\begin{eqnarray*}
-\mbox{DST-I:} \qquad
- X[k,:] & := & 
- 2 \sum_{j=0}^{n-1} X[j,:] \sin(\pi(j+1)(k+1)/(n+1)), 
- \qquad k=0,\ldots,n-1.\\
-\mbox{DST-II:} \qquad
- X[k,:]  & := & 2 \sum_{j=0}^{n-1} X[j,:] \sin(\pi(j+1/2)(k+1)/n), 
- \qquad k=0,\ldots,n-1.\\
-\mbox{DST-III:} \qquad
- X[k,:]  & := & (-1)^k X[n-1,:] + 2 \sum_{j=0}^{n-2} 
- X[j,:] \sin(\pi(j+1)(k+1/2)/n), 
- \qquad k=0,\ldots,n-1. \\
-\mbox{DST-IV:} \qquad
- X[k,:]  & := & 2 \sum_{j=0}^{n-1} X[j,:] \sin(\pi (j+1/2)(k+1/2)/n), 
- \qquad k=0,\ldots,n-1.
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath11487}%
-\begin{displaymath}
- A = \left[ \begin{array}{rrrrr}
-  0 & 2 & 0 & 0 & 3 \\
-  2 & 0 & 0 & 0 & 0 \\
- -1 & -2 & 0 & 4 & 0 \\
-  0 & 0 & 1 & 0 & 0 \end{array} \right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath12088}%
-\begin{displaymath}
-(2,1,0), \qquad (-1,2,0), \qquad (2,0,1), \qquad (-2,2,1), \qquad
-(1,3,2), \qquad (4,2,3), \qquad (3,0,4).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath12089}%
-\begin{displaymath}
-(2,1,0), \qquad (-1,2,0), \qquad (0,3,0), \qquad (2,0,1), \qquad 
- (-2,2,1), \qquad (1,3,2), \qquad (4,2,3), \qquad (3,0,4)
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath11622}%
-\begin{displaymath}
- A = \left[ \begin{array}{rrrrr}
-  0 & 2 & 0 & 0 & 3 \\
-  2 & 0 & 0 & 0 & 0 \\
-  1 & 2 & 0 & 4 & 0 \\
-  0 & 0 & 1 & 0 & 0 \end{array} \right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath12091}%
-\begin{displaymath}
-   y := \alpha A x + \beta y.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath12095}%
-\begin{displaymath}
-C =  A^TB, \qquad
-A = \left[ \begin{array}{ccc}
-0 & 1 & 0 \\1 & 0 & 1 \\0 & 1 & 0 \\1 & 0 & 0 \end{array}\right],
-\qquad
-B = \left[ \begin{array}{ccc}
-   0 & -1 & 0 \\2 & 0 & 2 \\0 & 3 & 0 \\2 & 0 & 0 
-   \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath12096}%
-\begin{displaymath}
-C = A^TD, \qquad 
-D = \left[ \begin{array}{ccc}
-   0 & 1 & 0 \\3 & 0 & -2 \\0 & 1 & 0 \\4 & 0 & 0 
-   \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13881}%
-\begin{displaymath}
-\left[ \begin{array}{rrrr}
- 10 &  0 & 3 &  0 \\
-  0 &  5 & 0 & -2 \\
-  3 &  0 & 5 &  0 \\
-  0 & -2 & 0 &  2 
-\end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13754}%
-\begin{displaymath}
-A = \left[\begin{array}{rrrrr}
- 2 & 3 & 0 & 0 & 0 \\
- 3 & 0 & 4 & 0 & 6 \\
- 0 &-1 &-3 & 2 & 0 \\
- 0 & 0 & 1 & 0 & 0 \\
- 0 & 4 & 2 & 0 & 1 
- \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13884}%
-\begin{displaymath}
-B = \left[\begin{array}{rrrrr}
- 4 & 3 & 0 & 0 & 0 \\
- 3 & 0 & 4 & 0 & 6 \\
- 0 &-1 &-3 & 2 & 0 \\
- 0 & 0 & 1 & 0 & 0 \\
- 0 & 4 & 2 & 0 & 2 
- \end{array}\right],
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13885}%
-\begin{displaymath}
- x = A^{-T}B^{-1}A^{-1}{\bf 1}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13901}%
-$\mathrm{{}^H}$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13792}%
-\begin{displaymath}
-\left[ \begin{array}{rrrr}
- 10 &  0 & 3 &  0 \\
-  0 &  5 & 0 & -2 \\
-  3 &  0 & 5 &  0 \\
-  0 & -2 & 0 &  2 
-  \end{array}\right] X = \left[ \begin{array}{cc}
-   0 & 4 \\1 & 5 \\2 & 6 \\3 & 7\end{array} \right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13816}%
-\begin{displaymath}
-   PAP^T = LL^T, \qquad PAP^T = LL^H, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13818}%
-\begin{displaymath}
-   PAP^T = LDL^T, \qquad PAP^T = LDL^H,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13903}%
-$AX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13905}%
-$LDL^TX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13907}%
-$LDLX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13909}%
-$DL^TX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13911}%
-$LX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13913}%
-$L^TX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13915}%
-$DX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13917}%
-$P^TX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13919}%
-$PX=B$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13921}%
-$L^T$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13923}%
-$L^H$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13872}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & -\log\det K + \mathop{\bf tr}(KY)\\
- \mbox{subject to} & K_{ij}=0,\quad (i,j) \not \in S.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13927}%
-$Y$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline13929}%
-$S$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13887}%
-\begin{displaymath}
-   K(x) = E_1\mbox{\bf diag}\,(x)E_2^T+E_2\mbox{\bf diag}\,(x)E_1^T
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13888}%
-\begin{displaymath}
- E_1 = \left[ \begin{array}{cccc}
-  e_{i_1} & e_{i_2} & \cdots & e_{i_q} \end{array}\right], \qquad
- E_2 = \left[ \begin{array}{cccc}
-  e_{j_1} & e_{j_2} & \cdots & e_{j_q} \end{array}\right], 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath13889}%
-\begin{displaymath}
- \begin{array}{ll}
-   \mbox{minimize} & f(x) = -\log\det K(x) + \mathop{\bf tr}(K(x)Y).
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar13565}%
-\begin{eqnarray*}
-\nabla f(x) 
-&=& 2 \mbox{\bf diag}\,( E_1^T (Y - K(x)^{-1}) E_2)) \\
-&=& 2\mbox{\bf diag}\,(Y_{IJ} - \left(K(x)^{-1}\right)_{IJ})\\
-\nabla^2 f(x) & = & 
- 2 (E_1^T K(x)^{-1} E_1) \circ (E_2^T K(x)^{-1} E_2) 
-   + 2 (E_1^T K(x)^{-1} E_2) \circ (E_2^T K(x)^{-1} E_1) \\
-&=& 2 \left(K(x)^{-1}\right)_{II} \circ 
-      \left(K(x)^{-1}\right)_{JJ}
-   +2 \left(K(x)^{-1}\right)_{IJ} \circ 
-      \left(K(x)^{-1}\right)_{JI},
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15763}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize}   & c^T x \\
- \mbox{subject to} & G x \preceq h \\& Ax = b.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15279}%
-\begin{displaymath}
- \begin{array}[t]{ll}
- \mbox{minimize} & c^T x \\
- \mbox{subject to} & G x + s = h \\& Ax = b \\& s \succeq 0
- \end{array}
- \qquad\qquad\qquad\qquad
- \begin{array}[t]{ll}
- \mbox{maximize} & -h^T z - b^T y \\
- \mbox{subject to} & G^T z + A^T y + c = 0 \\
-   & z \succeq 0.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15841}%
-$s \in C$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15843}%
-$z\in C$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15845}%
-$C$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15764}%
-\begin{displaymath}
-C = C_0 \times C_1 \times \cdots \times C_M \times C_{M+1} \times
- \cdots \times C_{M+N}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15765}%
-\begin{displaymath}
-C_0 = 
- \{ u \in {\mbox{\bf R}}^l \;| \; u_k \geq 0, \; k=1, \ldots,l\}, \qquad 
-C_{k+1} = \{ (u_0, u_1) \in {\mbox{\bf R}}\times {\mbox{\bf R}}^{q_{k}-1} \; | \;
-   u_0 \geq \|u_1\|_2 \},  \quad k=0,\ldots, M-1, \qquad 
-C_{k+M+1} = \left\{ \mathop{\mathbf{vec}}(u) \; | \;
-  u \in {\mbox{\bf S}}^{p_k}_+ \right\}, \quad k=0,\ldots,N-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15847}%
-$\mathop{\mathbf{vec}}(u)$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15766}%
-\begin{displaymath}
- K = l + \sum_{k=0}^{M-1} q_k + \sum_{k=0}^{N-1} p_k^2.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15767}%
-\begin{displaymath}
-{\mbox{\bf R}}^l \times {\mbox{\bf R}}^{q_0} \times \cdots \times 
-{\mbox{\bf R}}^{q_{M-1}} \times {\mbox{\bf R}}^{p_0^2}  \times \cdots \times 
-{\mbox{\bf R}}^{p_{N-1}^2},
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15849}%
-$l$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15768}%
-\begin{displaymath}
- Gx + s = h, \qquad Ax=b, \qquad G^T z  + A^T y + c = 0, \qquad 
- s \succeq 0, \qquad z \succeq 0,  \qquad s^T z =0.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15769}%
-\begin{displaymath}
- G^T z + A^T y = 0, \qquad h^T z + b^T y = -1, \qquad z \succeq 0.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15770}%
-\begin{displaymath}
- Gx + s = 0, \qquad Ax=0, \qquad  c^T x = -1, \qquad s \succeq 0.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15771}%
-\begin{displaymath}
-\mathop{\bf rank}(A) = p, \qquad 
-\mathop{\bf rank}(\left[\begin{array}{c} G \\A \end{array}\right]) = n,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15772}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize}   &  -6x_1 - 4x_2 - 5x_3 \\*[1ex]
-\mbox{subject to} & 16x_1 - 14x_2 + 5x_3 \leq -3 \\*[1ex]
-  & 7x_1 + 2x_2 \leq 5 \\*[1ex]
-  & \left( (8x_1 + 13x_2 - 12x_3 - 2)^2 + (-8x_1 + 18x_2 + 6x_3 - 14)^2
- + (x_1 - 3x_2 - 17x_3 - 13)^2\right)^{1/2} \leq -24x_1 - 7x_2 + 15x_3 + 12 \\*[1ex]
- &  (x_1^2 + x_2^2 + x_3^2)^{1/2} \leq 10  \\*[1ex]
- & \left[\begin{array}{ccc}
- 7x_1 + 3x_2 + 9x_3  & -5x_1 + 13x_2 + 6x_3 &   x_1 - 6x_2 -6x_3 \\
--5x_1 + 13x_2 + 6x_3 &  x_1 + 12x_2 -7x_3 & -7x_1 -10x_2 - 7x_3 \\
- x_1 - 6x_2 -6x_3 & -7x_1 -10x_2 -7 x_3 & 
--4x_1 -28 x_2 -11x_3 \end{array}\right]  
-\preceq 
-\left[\begin{array}{ccc}
-68  & -30 & -19 \\
--30 & 99  &  23 \\
--19 & 23  & 10 \end{array}\right].
-\end{array} 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15774}%
-\begin{displaymath}
- \begin{array}[t]{ll}
-  \mbox{minimize} & -4x_1 - 5x_2 \\
-  \mbox{subject to} &  2x_1 + x_2 \leq 3 \\
- & x_1 + 2x_2 \leq 3 \\
- & x_1 \geq 0, \quad x_2 \geq 0.
- \end{array} 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15775}%
-\begin{displaymath}
- \begin{array}[t]{ll}
- \mbox{minimize} & c^T x \\
- \mbox{subject to} 
-   & G_k x + s_k = h_k, \quad k = 0, \ldots, M  \\
-   & Ax = b \\
-   & s_0 \succeq 0 \\
-   & s_{k0} \geq \|s_{k1}\|_2, \quad k = 1, \ldots, M
- \end{array}
- \qquad\qquad
- \begin{array}[t]{ll}
- \mbox{maximize} & - \sum_{k=0}^M h_k^Tz_k - b^T y \\
- \mbox{subject to} & \sum_{k=0}^M G_k^T z_k + A^T y + c = 0 \\
-   & z_0 \succeq 0 \\
-   & z_{k0} \geq \|z_{k1}\|_2, \quad k=1,\ldots,M.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15776}%
-\begin{displaymath}
-  s_0 \succeq 0, \qquad z_0 \succeq 0
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15777}%
-\begin{displaymath}
- s_k = (s_{k0}, s_{k1}) \in{\mbox{\bf R}}\times{\mbox{\bf R}}^{q_{k}-1}, \qquad 
- z_k = (z_{k0}, z_{k1}) \in{\mbox{\bf R}}\times{\mbox{\bf R}}^{q_{k}-1}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15855}%
-$G_0$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15857}%
-$h_0$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15859}%
-$M$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15778}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -2x_1 + x_2 + 5x_3 \\*[2ex]
-\mbox{subject to} 
- & \left\| \left[\begin{array}{c}
-   -13 x_1 + 3x_2 + 5x_3 - 3 \\-12 x_1 + 12x_2 - 6x_3 - 2
-   \end{array}\right] \right\|_2 \leq -12 x_1 - 6 x_2 + 5x_3 - 12  \\*[2ex]
- & \left\| \left[\begin{array}{c}
- -3x_1 + 6x_2 + 2x_3 \\x_1 + 9x_2 + 2x_3 + 3 \\-x_1 - 19 x_2 + 3 x_3 - 42
-   \end{array}\right] \right\|_2 \leq 
-   -3x_1 + 6x_2 - 10x_3 + 27.
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15779}%
-\begin{displaymath}
- \begin{array}[t]{ll}
- \mbox{minimize} & c^T x \\
- \mbox{subject to} 
-   & G_0 x + s_0 = h_0 \\
-   & G_k x + \mathop{\mathbf{vec}}{(s_k)} = \mathop{\mathbf{vec}}{(h_k)}, \quad k = 1, \ldots, N  \\
-   & Ax = b \\
-   & s_0 \succeq 0 \\
-   & s_k \succeq 0, \quad k=1,\ldots,N
- \end{array}
- \qquad\qquad
- \begin{array}[t]{ll}
- \mbox{maximize} & - h_0^Tz_0 - \sum_{k=1}^N \mathop{\bf tr}(h_kz_k) - b^T y \\
- \mbox{subject to} & 
-  G_0^Tz_0 + \sum_{k=1}^N G_k^T \mathop{\mathbf{vec}}(z_k) + A^T y + c = 0 \\
-   & z_0 \succeq 0 \\
-   & z_k \succeq 0, \quad k=1,\ldots,N.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15863}%
-$\mathop{\mathbf{vec}}(z)$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15865}%
-$z$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15871}%
-$N$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15781}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & x_1 - x_2 + x_3 \\
-\mbox{subject to} & 
-  x_1 \left[ \begin{array}{cc} -7 &  -11 \\-11 &  3
- \end{array}\right] + 
-  x_2 \left[ \begin{array}{cc}
-  7 & -18 \\-18 & 8 \end{array}\right] + 
-  x_3 \left[ \begin{array}{cc}
-  -2 & -8 \\-8 & 1 
- \end{array}\right] \preceq  
- \left[ \begin{array}{cc} 
- 33 & -9 \\-9 & 26 \end{array}\right] \\*[1ex]
-& x_1 \left[ \begin{array}{ccc} 
- -21 & -11 & 0  \\-11 & 10 & 8 \\0 & 8 & 5
- \end{array}\right] + 
- x_2 \left[ \begin{array}{ccc} 
- 0 & 10  & 16 \\
-10 & -10 & -10 \\
-16 & -10 & 3 
- \end{array}\right] + 
- x_3 \left[ \begin{array}{ccc} 
- -5  & 2 & -17 \\
- 2  & -6 & -7 \\
- -17 & 8 & 6 
- \end{array}\right]  
-\preceq  \left[ \begin{array}{ccc}
- 14 &  9 & 40 \\
-  9  & 91 & 10 \\
- 40 & 10 & 15
-\end{array} \right]
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15597}%
-\begin{displaymath}
- \left[\begin{array}{ccc}
-  0 & A^T & G^T \\
-  A & 0   & 0  \\
-  G & 0   & -W^T W \end{array}\right]
- \left[\begin{array}{c} u_x \\u_y \\u_z \end{array}\right]
- = \left[\begin{array}{c} b_x \\b_y \\b_z \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15877}%
-$W$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15782}%
-\begin{displaymath}
- u = \left(u_\mathrm{l}, \; u_{\mathrm{q},0}, \; \ldots, \; 
- u_{\mathrm{q},M-1}, \; \mathop{\mathbf{vec}}{(u_{\mathrm{s},0})}, \; \ldots, \; 
-  \mathop{\mathbf{vec}}{(u_{\mathrm{s},N-1})}\right), \qquad
- u_\mathrm{l} \in{\mbox{\bf R}}^l, \qquad 
- u_{\mathrm{q},k} \in{\mbox{\bf R}}^{q_k}, \quad k = 0,\ldots,M-1, \qquad 
- u_{\mathrm{s},k} \in{\mbox{\bf S}}^{p_k},  \quad k = 0,\ldots,N-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15783}%
-\begin{displaymath}
- Wu = \left( W_\mathrm{l} u_\mathrm{l}, \;
- W_{\mathrm{q},0} u_{\mathrm{q},0}, \; \ldots, \;
- W_{\mathrm{q},M-1} u_{\mathrm{q},M-1},\; 
- W_{\mathrm{s},0} \mathop{\mathbf{vec}}{(u_{\mathrm{s},0})}, \; \ldots, \;
- W_{\mathrm{s},N-1} \mathop{\mathbf{vec}}{(u_{\mathrm{s},N-1})} \right)
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15784}%
-\begin{displaymath}
-  W_\mathrm{l} = \mbox{\bf diag}\,(d), \qquad W_\mathrm{l}^{-1} = \mbox{\bf diag}\,(d)^{-1}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15785}%
-\begin{displaymath}
-  W_\mathrm{l}^T = W_\mathrm{l}. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15786}%
-\begin{displaymath}
-  W_{\mathrm{q},k} = \beta_k ( 2 v_k v_k^T - J),
- \qquad
-  W_{\mathrm{q},k}^{-1} = \frac{1}{\beta_k} ( 2 Jv_k v_k^T J - J),
- \qquad k = 0,\ldots,M-1,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15787}%
-\begin{displaymath}
- \beta_k > 0, \qquad v_{k0} > 0, \qquad 
- v_k^T Jv_k = 1, \qquad J = \left[\begin{array}{cc}
-   1 & 0 \\0 & -I \end{array}\right].
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15788}%
-\begin{displaymath}
-  W_\mathrm{q,k}^T = W_\mathrm{q,k}. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15789}%
-\begin{displaymath}
-  W_{\mathrm{s},k} \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})} = 
-  \mathop{\mathbf{vec}}{(r_k^T u_{\mathrm{s},k} r_k)}, \qquad
-  W_{\mathrm{s},k}^{-1} \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})} = 
- \mathop{\mathbf{vec}}{(r_k^{-T} u_{\mathrm{s},k} r_k^{-1})}, \qquad
- k = 0,\ldots,N-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15790}%
-\begin{displaymath}
-  W_{\mathrm{s},k}^T \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})} = 
-  \mathop{\mathbf{vec}}{(r_k u_{\mathrm{s},k} r_k^T)}, \qquad
- \qquad
-  W_{\mathrm{s},k}^{-T} \mathop{\mathbf{vec}}{(u_{\mathrm{s},k})} = 
- \mathop{\mathbf{vec}}{(r_k^{-1} u_{\mathrm{s},k} r_k^{-T})}, \qquad
- \qquad
- k = 0,\ldots,N-1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline15883}%
-$G$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15791}%
-\begin{displaymath}
-  b_x := u_x, \qquad b_y := u_y, \qquad b_z := W u_z.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15792}%
-\begin{displaymath}
-y := \alpha Gx + \beta y \quad 
-  (\mathrm{trans} = \mathrm{'N'}), \qquad
-y := \alpha G^T x + \beta y \quad 
- (\mathrm{trans} = \mathrm{'T'}).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15793}%
-\begin{displaymath}
-y := \alpha Ax + \beta y \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-y := \alpha A^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15794}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & \|Pu-q\|_1
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15795}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & {\bf 1}^T v \\
- \mbox{subject to} & -v \preceq Pu - q  \preceq v.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15796}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & {\bf 1}^T x \\
- \mbox{subject to} & W + \mbox{\bf diag}\,(x) \succeq 0 
- \end{array} 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15797}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & \|u\|_1 \\
- \mbox{subject to} & \|Au - b\|_2 \leq 1.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15798}%
-\begin{displaymath}
-s \succeq 0, \qquad z \succeq 0, \qquad 
-\qquad 
- \frac{\|Gx + s - h\|_2} {\max\{1,\|h\|_2\}} \leq \epsilon_\mathrm{feas}, 
-\qquad 
-\frac{\|Ax-b\|_2}{\max\{1,\|b\|_2\}} \leq \epsilon_\mathrm{feas}, 
-\qquad
-\frac{\|G^Tz +  A^Ty + c\|_2}{\max\{1,\|c\|_2\}} \leq 
- \epsilon_\mathrm{feas}, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15799}%
-\begin{displaymath}
- s^T z \leq \epsilon_\mathrm{abs} \qquad \mbox{or} \qquad
-\left( \min\left\{c^Tx,  h^T z + b^Ty \right\} < 0, \quad 
- \frac{s^Tz} {-\min\{c^Tx, h^Tz + b^T y\}} \leq \epsilon_\mathrm{rel} 
-\right).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15800}%
-\begin{displaymath}
-z \succeq 0, \qquad
-\qquad \frac{\|G^Tz +A^Ty\|_2}{\max\{1, \|c\|_2\}} \leq 
- \epsilon_\mathrm{feas}, 
- \qquad h^Tz +b^Ty = -1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath15801}%
-\begin{displaymath}
-s \succeq 0, \qquad
-\qquad
-\frac{\|Gx+s\|_2}{\max\{1, \|h\|_2\}} \leq \epsilon_\mathrm{feas}, \qquad
-\frac{\|Ax\|_2}{\max\{1, \|b\|_2\}} \leq \epsilon_\mathrm{feas},  \qquad
-c^Tx = -1.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17449}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & f_0(x) \\
- \mbox{subject to} & f_k(x) \leq 0, \quad k=1,\ldots,m \\
-  & G x \preceq h  \\
-  & A x = b,
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline17867}%
-$f=(f_0,\ldots,f_m)$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17815}%
-\begin{displaymath}
-  z_0 \nabla^2f_0(x) + z_1 \nabla^2f_1(x) + \cdots + z_m \nabla^2f_m(x).
- \end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17816}%
-\begin{displaymath}
- \nabla f_0(x) +  D\tilde f(x)^T z_\mathrm{nl} + 
- G^T z_\mathrm{l} + A^T y = 0, \qquad
-\tilde f(x) + s_\mathrm{nl} = 0, \quad k=1,\ldots,m, \qquad
- Gx + s_\mathrm{l} = h, \qquad
- Ax = b, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline17871}%
-$\tilde f = (f_1,\ldots, f_m)$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17817}%
-\begin{displaymath}
-s_\mathrm{nl}\succeq 0, \qquad s_\mathrm{l}\succeq 0, \qquad 
-z_\mathrm{nl} \succeq 0, \qquad z_\mathrm{l} \succeq 0, \qquad
-s_\mathrm{nl}^T z_\mathrm{nl} +  s_\mathrm{l}^T z_\mathrm{l} = 0.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17818}%
-\begin{displaymath}
-\left[\begin{array}{cccc}
-\sum_{k=0}^m z_k \nabla^2 f_k(x) & D\tilde f(x)^T & G^T & A^T\\
-D\tilde f(x) & -\mbox{\bf diag}\,(d_1) & 0 & 0 \\
- G & 0 & -\mbox{\bf diag}\,(d_2) & 0 \\
- A & 0 & 0 & 0 \end{array}\right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline17873}%
-$d_1$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline17875}%
-$d_2$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17819}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & -\sum_{i=1}^m \log x_i \\
- \mbox{subject to} & Ax = b. 
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17820}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} &  \sum_{k=1}^m \phi((Ax-b)_k), 
-\end{array} \qquad \mbox{where} \quad A \in{\mbox{\bf R}}^{m\times n}, \quad
-\phi(u) = \sqrt{\rho + u^2}.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17821}%
-\begin{displaymath}
-\begin{array}{ll}
- \mbox{minimize} & W + H \\
- \mbox{subject to} & A_{\mathrm{min}, k}/h_k - w_k \leq 0, 
-        \quad k=1,\ldots, 5  \\
-   &  x_1 \geq 0, \quad x_2 \geq 0,  \quad x_4 \geq 0 \\
-   & x_1 + w_1 + \rho \leq x_3, \quad x_2 + w_2 + \rho \leq x_3, \quad 
-     x_3 + w_3 + \rho \leq x_5, \quad x_4 + w_4 + \rho \leq x_5, \quad
-     x_5 + w_5 \leq W \\
-   & y_2 \geq 0,  \quad y_3 \geq 0, \quad y_5 \geq 0  \\
-   & y_2 + h_2 + \rho \leq y_1, \quad y_1 + h_1 + \rho \leq y_4, \quad 
-     y_3 + h_3 + \rho \leq y_4, \quad y_4 + h_4 \leq H, \quad
-     y_5 + h_5 \leq H \\
-   & h_k/\gamma \leq w_k \leq \gamma h_k, \quad k=1,\ldots,5.
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17822}%
-\begin{displaymath}
-W, \qquad H, \qquad x\in{\mbox{\bf R}}^5, \qquad y\in{\mbox{\bf R}}^5, \qquad
-w\in{\mbox{\bf R}}^5, \qquad h\in{\mbox{\bf R}}^5,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlpictureA{tex2html_wrap22797}%
-\includegraphics[width=15cm]{figures/floorplan.eps}%
-\lthtmlpictureZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17823}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & (1/2) x^TPx + q^T x \\
-\mbox{subject to} & Gx \preceq h \\& Ax = b.
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17824}%
-\begin{displaymath}
- Px + q + G^T z + A^T y = 0, \qquad Gx + s = h, \qquad
- Ax = b, \qquad s \succeq 0, \qquad z \succeq 0, \qquad s^T z = 0. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17826}%
-\begin{displaymath}
- Px = 0, \qquad q^Tx = -1, \qquad Gx + s = 0, \qquad Ax=0, \qquad
- s \succeq  0.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17827}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & -\bar p^T x + \mu x^T S x \\
-\mbox{subject to} & {\bf 1}^T x = 1, \quad x \succeq 0
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlpictureA{tex2html_wrap22809}%
-\includegraphics[width=10cm]{figures/portfolio1.eps}%
-\lthtmlpictureZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlpictureA{tex2html_wrap22810}%
-\includegraphics[width=10cm]{figures/portfolio2.eps}%
-\lthtmlpictureZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17828}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & f_0(x) = \mathop{\bf lse}(F_0x+g_0) \\
-\mbox{subject to} & f_i(x) = \mathop{\bf lse}(F_ix+g_i) \leq 0,\quad i=1,\ldots,m \\
- & Gx \preceq h \\
- & Ax=b
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17829}%
-\begin{displaymath}
- \mathop{\bf lse}(u) = \log \sum_k \exp(u_k), \qquad
- F = \left[ \begin{array}{cccc}
- F_0^T & F_1^T & \cdots & F_m^T \end{array}\right]^T, \qquad
- g = \left[ \begin{array}{cccc}
- g_0^T & g_1^T & \cdots & g_m^T \end{array}\right]^T. 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17830}%
-\begin{displaymath}
- \nabla f_0(x) + \sum_{k=1}^m z_{\mathrm{nl},k} 
- \nabla f_k(x) + G^T z_\mathrm{l} + A^T y = 0, \qquad
- f_k(x) + s_{\mathrm{nl},k} = 0, \quad k=1,\ldots,m,   \qquad 
- Gx + s_\mathrm{l} = h, \qquad Ax=b
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17832}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & w^{-1} h^{-1} d^{-1} \\
- \mbox{subject to} 
-  & (2/A_\mathrm{wall}) hw + (2/A_\mathrm{wall})hd \leq 1  \\
-  &  (1/A_\mathrm{flr}) wd \leq 1 \\
-  &  \alpha wh^{-1} \leq 1 \\
-  &  (1/\beta) hw^{-1} \leq 1 \\
-  &  \gamma wd^{-1} \leq 1 \\
-  &   (1/\delta)dw^{-1} \leq 1
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar17683}%
-\begin{eqnarray*}
- \sum_{k=0}^m z_k \nabla^2 f_k(x)u_x + A^T u_y + 
- D \tilde f(x)^T u_{z_\mathrm{nl}} + 
- G_\mathrm{l}^T u_{z_\mathrm{l}} & = & b_x \\
- A x  & = & b_y \\
- D\tilde f(x) x  - \mbox{\bf diag}\,(d_\mathrm{nl})^{-2} z_\mathrm{nl} & = & 
-    b_{z_\mathrm{nl}} \\
- G_\mathrm{l}x  - \mbox{\bf diag}\,(d_\mathrm{l})^{-2} z_\mathrm{l} & = & 
-    b_{z_\mathrm{l}}
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17833}%
-\begin{displaymath}
-  v :=  \sum_{k=0}^m u_k \nabla f_k(x) + v.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17836}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \|Ax - y\|_2^2 + \|x\|_1
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17837}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & \|Ax - y\|_2^2 + {\bf 1}^T u \\
- \mbox{subject to} & -u \preceq x \preceq u
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17838}%
-\begin{displaymath}
-\frac{\| \nabla f_0(x) +  D\tilde f(x)^Tz_\mathrm{nl} + 
- G^Tz_\mathrm{l} + A^T y \|_2 }
-{\max\{ 1, 
-\| \nabla f_0(x_0) + D\tilde f(x_0)^T{\bf 1}+ G^T{\bf 1}\|_2 \}} 
-\leq \epsilon_\mathrm{feas}, \qquad
-\frac{\| ( \tilde f(x) + s_{\mathrm{nl}},  Gx + s_\mathrm{l} - h, 
- Ax-b ) \|_2} 
-{\max\{1, \| ( \tilde f(x_0) + {\bf 1},  
-Gx_0 + {\bf 1}-h, Ax_0-b) \|_2 \}} \leq \epsilon_\mathrm{feas}  
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17839}%
-\begin{displaymath}
-\mathrm{gap} \leq \epsilon_\mathrm{abs}
-\qquad \mbox{or} \qquad \left( f_0(x) < 0, \quad
-\frac{\mathrm{gap}} {-f_0(x)} \leq \epsilon_\mathrm{rel} \right)
-\qquad \mbox{or} \qquad
-\left( L(x,y,z) > 0, \quad \frac{\mathrm{gap}}
-{L(x,y,z)} \leq \epsilon_\mathrm{rel} \right)
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath17840}%
-\begin{displaymath}
- \mathrm{gap} = 
-\left[\begin{array}{c} s_\mathrm{nl} \\s_\mathrm{l} 
-\end{array}\right]^T
-\left[\begin{array}{c} z_\mathrm{nl} \\z_\mathrm{l} 
-\end{array}\right],
-\qquad
-L(x,y,z) = f_0(x) + z_\mathrm{nl}^T \tilde f(x) + 
- z_\mathrm{l}^T (Gx-h) + y^T(Ax-b).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-\stepcounter{section}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19892}%
-\begin{displaymath}
- f(x_1,\ldots,x_n) = A_1 x_1 + \cdots + A_n x_n + b.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{eqnarraystar19548}%
-\begin{eqnarray*}
- f(x,y) & = & \left[ \begin{array}{c} 2 \\2 \end{array}\right] x 
-  + y + \left[ \begin{array}{c} 3 \\3 \end{array}\right], \\
- g(x,y) & = &
-  \left[ \begin{array}{cc} 1 & 3 \\2 & 4 \end{array}\right] f(x,y)
-  + \left[ \begin{array}{cc} 1 & 1 \\1 & 1 \end{array} \right] y + 
-  \left[ \begin{array}{c} 1 \\-1 \end{array} \right] \\
- & = & \left[ \begin{array}{c} 8 \\12 \end{array}\right] x 
-  + \left[ \begin{array}{cc} 2 & 4 \\3 & 5 \end{array}\right] y
-  + \left[ \begin{array}{c} 13 \\17\end{array}\right].
-\end{eqnarray*}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19893}%
-\begin{displaymath}
- f(x_1,\ldots,x_n) = b + A_1 x_1 + \cdots + A_n x_n + 
-  \sum_{k=1}^K \max (y_1, y_2, \ldots, y_{m_k}).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19894}%
-\begin{displaymath}
- f(x_1,\ldots,x_n) = b + A_1 x_1 + \cdots + A_n x_n + 
-  \sum_{k=1}^K \min (y_1, y_2, \ldots, y_{m_k}).
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19895}%
-\begin{displaymath}
-  h(x) = \sum_k  \phi(x[k]),\qquad
-  \phi(u) = \left\{\begin{array}{ll}
-     0 & |u| \leq 1 \\
-    |u|-1  & 1 \leq |u| \leq 2 \\
-    2|u|-3  & |u| \geq 2. \end{array}\right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19896}%
-\begin{displaymath}
-  f(x_1,\ldots,x_n) = 0, \qquad f(x_1,\ldots,x_n) \preceq  0, 
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlinlinemathA{tex2html_wrap_inline19918}%
-$f$%
-\lthtmlinlinemathZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19897}%
-\begin{displaymath}
-  0 \preceq x \preceq {\bf 1}, \qquad {\bf 1}^T x = 2,
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19898}%
-\begin{displaymath}
- \begin{array}{ll}
-  \mbox{minimize} & -4x - 5y \\
-  \mbox{subject to} &  2x +y \leq 3 \\
- &  x +2y \leq 3 \\
- & x \geq 0, \quad y \geq 0.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19899}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \|Ax - b\|_\infty,
- \end{array} \qquad
- \begin{array}{ll} 
- \mbox{minimize} & \|Ax - b\|_1
- \end{array},
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19900}%
-\begin{displaymath}
- \begin{array}{ll} 
- \mbox{minimize} & \sum_k \phi((Ax-b)_k), 
- \end{array} \qquad
- \phi(u) = \left\{\begin{array}{ll}
-    0 & |u| \leq 3/4 \\
-   |u|-3/4  & 3/4 \leq |u| \leq 3/2 \\
-   2|u|-9/4  & |u| \geq 3/2.\end{array}\right.
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmlpictureA{tex2html_wrap22898}%
-\includegraphics[width=\linewidth]{figures/normappr.eps}%
-\lthtmlpictureZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19901}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & c^T x \\
- \mbox{subject to} & \sup_{\|v\|_\infty \leq 1} 
-    (a_i+v)^T x \leq b_i, \qquad i=1,\ldots,m
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19902}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & c^Tx \\
- \mbox{subject to} & a_i^Tx + \|x\|_1 \leq b_i, \qquad i=1,\ldots,m.
- \end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19903}%
-\begin{displaymath}
- \begin{array}{ll}
- \mbox{minimize} & c^Tx \\
- \mbox{subject to} & a_i^Tx + {\bf 1}^Ty \leq b_i, \qquad i=1,\ldots,m \\
-& -y \preceq x \preceq y
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-{\newpage\clearpage
-\lthtmldisplayA{displaymath19904}%
-\begin{displaymath}
-\begin{array}{ll}
-\mbox{minimize} & \|x\|_1 + {\bf 1}^Tu \\
-\mbox{subject to} & Ax \succeq {\bf 1}-u \\
-& u \succeq 0.
-\end{array}
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-\stepcounter{chapter}
-\stepcounter{section}
-\stepcounter{section}
-{\newpage\clearpage
-\lthtmldisplayA{displaymath21247}%
-\begin{displaymath} 
-A=\left [\begin{array}{cccc}
-    1 & 0 & 0 & 5\\
-    2 & 0 & 4 & 0\\
-    0 & 0 & 0 & 6\\
-    3 & 0 & 0 & 0
-\end{array}\right]
-\end{displaymath}%
-\lthtmldisplayZ
-\lthtmlcheckvsize\clearpage}
-
-
-\end{document}
diff --git a/doc/cvxopt/internals.pl b/doc/cvxopt/internals.pl
deleted file mode 100644
index 56d2fee..0000000
--- a/doc/cvxopt/internals.pl
+++ /dev/null
@@ -1,218 +0,0 @@
-# LaTeX2HTML 2002-2-1 (1.71)
-# Associate internals original text with physical files.
-
-
-$key = q/chap:lapack/;
-$ref_files{$key} = "$dir".q|node18.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-umfpack/;
-$ref_files{$key} = "$dir".q|node41.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ll/;
-$ref_files{$key} = "$dir".q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-qp/;
-$ref_files{$key} = "$dir".q|node54.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-parameters/;
-$ref_files{$key} = "$dir".q|node57.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-socpsolver/;
-$ref_files{$key} = "$dir".q|node47.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:matrix/;
-$ref_files{$key} = "$dir".q|node3.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-matrices/;
-$ref_files{$key} = "$dir".q|node4.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sparse-A/;
-$ref_files{$key} = "$dir".q|node33.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-builtinfuncs/;
-$ref_files{$key} = "$dir".q|node8.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-nlcp/;
-$ref_files{$key} = "$dir".q|node52.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-random/;
-$ref_files{$key} = "$dir".q|node10.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-arithmetic/;
-$ref_files{$key} = "$dir".q|node6.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lp/;
-$ref_files{$key} = "$dir".q|node62.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-spmatrix/;
-$ref_files{$key} = "$dir".q|node33.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas3/;
-$ref_files{$key} = "$dir".q|node17.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conventions/;
-$ref_files{$key} = "$dir".q|node14.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:coneprog/;
-$ref_files{$key} = "$dir".q|node44.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-gp/;
-$ref_files{$key} = "$dir".q|node55.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:modeling/;
-$ref_files{$key} = "$dir".q|node58.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-spmatrix-arith/;
-$ref_files{$key} = "$dir".q|node35.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cholmod/;
-$ref_files{$key} = "$dir".q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas1/;
-$ref_files{$key} = "$dir".q|node15.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cp/;
-$ref_files{$key} = "$dir".q|node53.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-variables/;
-$ref_files{$key} = "$dir".q|node59.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:spmatrix/;
-$ref_files{$key} = "$dir".q|node32.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lpsolver/;
-$ref_files{$key} = "$dir".q|node46.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:c-api/;
-$ref_files{$key} = "$dir".q|node64.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp/;
-$ref_files{$key} = "$dir".q|node45.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-spsolvers/;
-$ref_files{$key} = "$dir".q|node39.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sp-Adef/;
-$ref_files{$key} = "$dir".q|node41.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-A-pd/;
-$ref_files{$key} = "$dir".q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-fftw/;
-$ref_files{$key} = "$dir".q|node28.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ldl/;
-$ref_files{$key} = "$dir".q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:intro/;
-$ref_files{$key} = "$dir".q|node2.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp-kkt/;
-$ref_files{$key} = "$dir".q|node49.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-spA-example/;
-$ref_files{$key} = "$dir".q|node34.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-orderings/;
-$ref_files{$key} = "$dir".q|node40.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas2/;
-$ref_files{$key} = "$dir".q|node16.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:solvers/;
-$ref_files{$key} = "$dir".q|node52.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-array-interface/;
-$ref_files{$key} = "$dir".q|node11.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-functions/;
-$ref_files{$key} = "$dir".q|node60.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-otherfuncs/;
-$ref_files{$key} = "$dir".q|node9.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-sdpsolver/;
-$ref_files{$key} = "$dir".q|node48.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-gevd/;
-$ref_files{$key} = "$dir".q|node25.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-indexing/;
-$ref_files{$key} = "$dir".q|node7.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:blas/;
-$ref_files{$key} = "$dir".q|node13.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-kkt-example/;
-$ref_files{$key} = "$dir".q|node20.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-external/;
-$ref_files{$key} = "$dir".q|node50.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp-struct/;
-$ref_files{$key} = "$dir".q|node49.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-nlcp/;
-$ref_files{$key} = "$dir".q|node56.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp/;
-$ref_files{$key} = "$dir".q|node45.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-covsel/;
-$ref_files{$key} = "$dir".q|node43.html|; 
-$noresave{$key} = "$nosave";
-
-1;
-
diff --git a/doc/cvxopt/labels.pl b/doc/cvxopt/labels.pl
deleted file mode 100644
index 77fe91c..0000000
--- a/doc/cvxopt/labels.pl
+++ /dev/null
@@ -1,437 +0,0 @@
-# LaTeX2HTML 2002-2-1 (1.71)
-# Associate labels original text with physical files.
-
-
-$key = q/chap:lapack/;
-$external_labels{$key} = "$URL/" . q|node18.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-umfpack/;
-$external_labels{$key} = "$URL/" . q|node41.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ll/;
-$external_labels{$key} = "$URL/" . q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-qp/;
-$external_labels{$key} = "$URL/" . q|node54.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-parameters/;
-$external_labels{$key} = "$URL/" . q|node57.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-socpsolver/;
-$external_labels{$key} = "$URL/" . q|node47.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:matrix/;
-$external_labels{$key} = "$URL/" . q|node3.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-matrices/;
-$external_labels{$key} = "$URL/" . q|node4.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sparse-A/;
-$external_labels{$key} = "$URL/" . q|node33.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-builtinfuncs/;
-$external_labels{$key} = "$URL/" . q|node8.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-nlcp/;
-$external_labels{$key} = "$URL/" . q|node52.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-random/;
-$external_labels{$key} = "$URL/" . q|node10.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-arithmetic/;
-$external_labels{$key} = "$URL/" . q|node6.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lp/;
-$external_labels{$key} = "$URL/" . q|node62.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-spmatrix/;
-$external_labels{$key} = "$URL/" . q|node33.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas3/;
-$external_labels{$key} = "$URL/" . q|node17.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conventions/;
-$external_labels{$key} = "$URL/" . q|node14.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:coneprog/;
-$external_labels{$key} = "$URL/" . q|node44.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-gp/;
-$external_labels{$key} = "$URL/" . q|node55.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:modeling/;
-$external_labels{$key} = "$URL/" . q|node58.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-spmatrix-arith/;
-$external_labels{$key} = "$URL/" . q|node35.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cholmod/;
-$external_labels{$key} = "$URL/" . q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas1/;
-$external_labels{$key} = "$URL/" . q|node15.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cp/;
-$external_labels{$key} = "$URL/" . q|node53.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-variables/;
-$external_labels{$key} = "$URL/" . q|node59.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:spmatrix/;
-$external_labels{$key} = "$URL/" . q|node32.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lpsolver/;
-$external_labels{$key} = "$URL/" . q|node46.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:c-api/;
-$external_labels{$key} = "$URL/" . q|node64.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp/;
-$external_labels{$key} = "$URL/" . q|node45.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-spsolvers/;
-$external_labels{$key} = "$URL/" . q|node39.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sp-Adef/;
-$external_labels{$key} = "$URL/" . q|node41.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-A-pd/;
-$external_labels{$key} = "$URL/" . q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-fftw/;
-$external_labels{$key} = "$URL/" . q|node28.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ldl/;
-$external_labels{$key} = "$URL/" . q|node42.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:intro/;
-$external_labels{$key} = "$URL/" . q|node2.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp-kkt/;
-$external_labels{$key} = "$URL/" . q|node49.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-spA-example/;
-$external_labels{$key} = "$URL/" . q|node34.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-orderings/;
-$external_labels{$key} = "$URL/" . q|node40.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas2/;
-$external_labels{$key} = "$URL/" . q|node16.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:solvers/;
-$external_labels{$key} = "$URL/" . q|node52.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-array-interface/;
-$external_labels{$key} = "$URL/" . q|node11.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-functions/;
-$external_labels{$key} = "$URL/" . q|node60.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-otherfuncs/;
-$external_labels{$key} = "$URL/" . q|node9.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-sdpsolver/;
-$external_labels{$key} = "$URL/" . q|node48.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-gevd/;
-$external_labels{$key} = "$URL/" . q|node25.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-indexing/;
-$external_labels{$key} = "$URL/" . q|node7.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:blas/;
-$external_labels{$key} = "$URL/" . q|node13.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-kkt-example/;
-$external_labels{$key} = "$URL/" . q|node20.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-external/;
-$external_labels{$key} = "$URL/" . q|node50.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp-struct/;
-$external_labels{$key} = "$URL/" . q|node49.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-nlcp/;
-$external_labels{$key} = "$URL/" . q|node56.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp/;
-$external_labels{$key} = "$URL/" . q|node45.html|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-covsel/;
-$external_labels{$key} = "$URL/" . q|node43.html|; 
-$noresave{$key} = "$nosave";
-
-1;
-
-
-# LaTeX2HTML 2002-2-1 (1.71)
-# labels from external_latex_labels array.
-
-
-$key = q/chap:lapack/;
-$external_latex_labels{$key} = q|4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-umfpack/;
-$external_latex_labels{$key} = q|7.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ll/;
-$external_latex_labels{$key} = q|7.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-qp/;
-$external_latex_labels{$key} = q|9.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-parameters/;
-$external_latex_labels{$key} = q|9.5|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-socpsolver/;
-$external_latex_labels{$key} = q|8.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:matrix/;
-$external_latex_labels{$key} = q|2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-matrices/;
-$external_latex_labels{$key} = q|2.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sparse-A/;
-$external_latex_labels{$key} = q|6.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-builtinfuncs/;
-$external_latex_labels{$key} = q|2.5|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-nlcp/;
-$external_latex_labels{$key} = q|9.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-random/;
-$external_latex_labels{$key} = q|2.7|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-arithmetic/;
-$external_latex_labels{$key} = q|2.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lp/;
-$external_latex_labels{$key} = q|10.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-creating-spmatrix/;
-$external_latex_labels{$key} = q|6.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas3/;
-$external_latex_labels{$key} = q|3.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conventions/;
-$external_latex_labels{$key} = q|3.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:coneprog/;
-$external_latex_labels{$key} = q|8|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-gp/;
-$external_latex_labels{$key} = q|9.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:modeling/;
-$external_latex_labels{$key} = q|10|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-spmatrix-arith/;
-$external_latex_labels{$key} = q|6.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cholmod/;
-$external_latex_labels{$key} = q|7.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas1/;
-$external_latex_labels{$key} = q|3.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-cp/;
-$external_latex_labels{$key} = q|9.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-variables/;
-$external_latex_labels{$key} = q|10.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:spmatrix/;
-$external_latex_labels{$key} = q|6|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-lpsolver/;
-$external_latex_labels{$key} = q|8.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:c-api/;
-$external_latex_labels{$key} = q|11|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp/;
-$external_latex_labels{$key} = q|8.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-spsolvers/;
-$external_latex_labels{$key} = q|7|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-sp-Adef/;
-$external_latex_labels{$key} = q|7.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-A-pd/;
-$external_latex_labels{$key} = q|7.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/c-fftw/;
-$external_latex_labels{$key} = q|5|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-chol-ldl/;
-$external_latex_labels{$key} = q|7.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:intro/;
-$external_latex_labels{$key} = q|1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp-kkt/;
-$external_latex_labels{$key} = q|8.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-spA-example/;
-$external_latex_labels{$key} = q|6.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-orderings/;
-$external_latex_labels{$key} = q|7.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-blas2/;
-$external_latex_labels{$key} = q|3.3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:solvers/;
-$external_latex_labels{$key} = q|9|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-array-interface/;
-$external_latex_labels{$key} = q|2.8|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-functions/;
-$external_latex_labels{$key} = q|10.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-otherfuncs/;
-$external_latex_labels{$key} = q|2.6|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-sdpsolver/;
-$external_latex_labels{$key} = q|8.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-gevd/;
-$external_latex_labels{$key} = q|4.2|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-indexing/;
-$external_latex_labels{$key} = q|2.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/chap:blas/;
-$external_latex_labels{$key} = q|3|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-kkt-example/;
-$external_latex_labels{$key} = q|4.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-external/;
-$external_latex_labels{$key} = q|8.6|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-conelp-struct/;
-$external_latex_labels{$key} = q|8.5|; 
-$noresave{$key} = "$nosave";
-
-$key = q/s-nlcp/;
-$external_latex_labels{$key} = q|9.4|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-conelp/;
-$external_latex_labels{$key} = q|8.1|; 
-$noresave{$key} = "$nosave";
-
-$key = q/e-covsel/;
-$external_latex_labels{$key} = q|7.5|; 
-$noresave{$key} = "$nosave";
-
-1;
-
diff --git a/doc/fftw.tex b/doc/fftw.tex
index c8e98ca..2f3ff6c 100644
--- a/doc/fftw.tex
+++ b/doc/fftw.tex
@@ -5,10 +5,9 @@ and contains routines for discrete Fourier, cosine, and sine
 transforms.  This module is optional, and only installed when 
 the FFTW library is made available during the CVXOPT installation.
 
-\begin{seealso}
+\textbf{See also:}
 \seelink{http://www.fftw.org}{FFTW3 code, documentation, copyright and
 license.}{}
-\end{seealso}
 
 \section{Discrete Fourier Transform} 
 \begin{funcdesc}{dft}{X}
diff --git a/doc/intro.tex b/doc/intro.tex
index 985b446..df579af 100644
--- a/doc/intro.tex
+++ b/doc/intro.tex
@@ -10,11 +10,9 @@ optimization applications straightforward by building on Python's
 extensive standard library and on the strengths of Python as a 
 high-level programming language.  
 
-Release 0.9 of CVXOPT includes routines for basic linear algebra 
-calculations, 
-interfaces to efficient libraries for solving dense and sparse linear 
-equations, 
-convex optimization solvers written in Python,
+Release 0.9.1 of CVXOPT includes routines for basic linear algebra 
+calculations, interfaces to efficient libraries for solving dense and 
+sparse linear equations, convex optimization solvers written in Python,
 interfaces to a few other optimization libraries, 
 and a modeling tool for piecewise-linear convex optimization problems.
 These components are organized in different modules.  
diff --git a/doc/lapack.tex b/doc/lapack.tex
index 4d7df49..33ae3be 100644
--- a/doc/lapack.tex
+++ b/doc/lapack.tex
@@ -18,10 +18,9 @@ less important arguments that are useful for selecting submatrices.
 The complete definitions are documented in the docstrings in the 
 source code.
 
-\begin{seealso}
+\textbf{See also:}
 \seelink{http://www.netlib.org/lapack/lug/lapack_lug.html}{LAPACK 
-Users' Guide, Third Edition, SIAM, 1999.}{} 
-\end{seealso}
+Users' Guide, Third Edition, SIAM, 1999}{}.
 
 
 \section{General Linear Equations}
@@ -30,12 +29,12 @@ Solves
 \[ 
    A X = B,
 \]
-where {\it A} and {\it B} are real or complex matrices, with {\it A}
+where $A$ and $B$ are real or complex matrices, with $A$
 square and nonsingular.  On exit, \var{B} is replaced by the solution.  
 The arguments \var{A} and \var{B} must have the same type (\dtc\ or
 \ztc).  
 The optional argument \var{ipiv} is an integer matrix of length at 
-least \var{n}.  
+least $n$.  
 If \var{ipiv} is provided, then \function{gesv()} solves the system, 
 replaces \var{A} with its triangular factors, and returns the 
 permutation matrix in \var{ipiv}.
@@ -63,11 +62,11 @@ complex matrix,
 \[
   A = PLU 
 \]
-where {\it A} is \var{m} by \var{n}.
+where $A$ is $m$ by $n$.
 The argument \var{ipiv} is an integer matrix of length at least
-min\{\var{m}, \var{n}\}.
-On exit, the lower triangular part of \var{A} is replaced by {\it L},
-the upper triangular part by {\it U}, and the permutation matrix is 
+$\min\{m, n\}$.
+On exit, the lower triangular part of \var{A} is replaced by $L$,
+the upper triangular part by $U$, and the permutation matrix is 
 returned in \var{ipiv}.
 Raises an \code{ArithmeticError} if the matrix is not full rank.
 \end{funcdesc}
@@ -121,38 +120,39 @@ Solves
 \[ 
    A X = B,
 \]
-where {\it A} and {\it B} are real or complex matrices, with {\it A}
-{\it n} by {\it n} and banded with \var{kl} subdiagonals.  
+where $A$ and $B$ are real or complex matrices, with $A$
+$n$ by $n$ and banded with $k_l$ subdiagonals.  
 The arguments \var{A} and \var{B} must have the same type (\dtc\ or
 \ztc).  
 
-The optional argument \var{ipiv} is an integer matrix of length at least
-{\it n}.
+The optional argument \var{ipiv} is an integer matrix of length at 
+least $n$.
 If \var{ipiv} is provided, then \var{A} must have 
-2\var{kl} + \var{ku} + 1 rows.  On entry the diagonals of {\it A} are
-stored in rows \var{kl} + 1 to 2\var{kl} + \var{ku} +1 of the \var{A}, using
-the BLAS format for general band matrices (see section~\ref{s-conventions}).
+$2k_l + k_u + 1$ rows.  On entry the diagonals of $A$ are
+stored in rows $k_l + 1$ to $2k_l + k_u +1$ of the \var{A}, using
+the BLAS format for general band matrices 
+(see section~\ref{s-conventions}).
 On exit, the factorization is returned in {\var A} and \var{ipiv}.
 
-If \var{ipiv} is not provided, then \var{A} must have \var{kl} + \var{ku} + 
-1 rows.  On entry the diagonals of {\it A} are stored in the rows of 
-\var{A}, following the standard format for general band matrices. 
+If \var{ipiv} is not provided, then \var{A} must have 
+$k_l + k_u + 1$ rows.  On entry the diagonals of $A$ are stored in the 
+rows of \var{A}, following the standard format for general band matrices. 
 In this case, \function{gbsv()} does not modify \var{A} on exit and does
 not return the factorization.
 
-On exit, \var{B} is replaced by the solution {\it X}.  
+On exit, \var{B} is replaced by the solution $X$.  
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
 
 \begin{funcdesc}{gbtrf}{A, m, kl, ipiv}
-LU factorization of a general {\it m} by {\it n} real or complex band 
-matrix with \var{kl} subdiagonals.
+LU factorization of a general $m$ by $n$ real or complex band 
+matrix with $k_l$ subdiagonals.
 The matrix is stored using the BLAS format for general band matrices
 (see section~\ref{s-conventions}), by providing the 
-diagonals (stored as rows of a \var{ku} + \var{kl} + 1 by {\it n} matrix),
-the number of rows \var{m}, and the number of subdiagonals \var{kl}.
+diagonals (stored as rows of a $k_u + k_l + 1$ by $n$ matrix),
+the number of rows $m$, and the number of subdiagonals $k_l$.
 The argument \var{ipiv} is an integer matrix of length at least
-min\{{\it m}, {\it n}\}.
+$\min\{m, n\}$.
 On exit, \var{A} and \var{ipiv} contain the details of the factorization.
 Raises an \code{ArithmeticError} if the matrix is not full rank.
 \end{funcdesc}
@@ -164,7 +164,7 @@ Solves a set of linear equations
  A^TX=B \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
  A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-with {\it A} a general band matrix with \var{kl} subdiagonals, given the 
+with $A$ a general band matrix with $k_l$ subdiagonals, given the 
 LU factorization computed by \function{gbsv()} or \function{gbtrf()}.
 On entry, \var{A} and \var{ipiv} must contain the factorization
 as computed by \function{gbsv()} or \function{gbtrf()}.  
@@ -245,24 +245,24 @@ Solves
 \[ 
    A X = B,
 \]
-where {\it A} is an {\it n} by {\it n} tridiagonal matrix, 
-with subdiagonal \var{dl} (a matrix of length {\it n}-1), 
-diagonal \var{d} (a matrix of length {\it n}), and superdiagonal 
-\var{du} (a matrix of length {\it n}-1).  
+where $A$ is an $n$ by $n$ tridiagonal matrix, 
+with subdiagonal stored as a matrix \var{dl} of length $n-1$, 
+diagonal stored as a matrix \var{d} of length $n$, and superdiagonal 
+stored as a matrix \var{du} of length $n-1$.  
 The four arguments must have the same type (\dtc\ or \ztc).
 On exit \var{dl}, \var{d}, \var{du} are overwritten with the details of 
-the LU factorization of {\it A}, and \var{B} is overwritten with the 
-solution {\it X}.  
+the LU factorization of $A$, and \var{B} is overwritten with the solution 
+$X$.  
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
 
 \begin{funcdesc}{gttrf}{dl, d, du, du2, ipiv}
-LU factorization of an {\it n} by {\it n} tridiagonal matrix with
-subdiagonal \var{dl}, diagonal \var{d} and superdiagonal \var{du}.
+LU factorization of an $n$ by $n$ tridiagonal matrix with
+subdiagonal $d_l$, diagonal $d$ and superdiagonal $d_u$.
 \var{dl}, \var{d} and \var{du} must have the same type.
-\var{du2} is a matrix of length {\it n}-2, and of the same type as 
+\var{du2} is a matrix of length $n-2$, and of the same type as 
 \var{dl}.
-\var{ipiv} is an \itc\ matrix of length {\it n}.
+\var{ipiv} is an \itc\ matrix of length $n$.
 On exit, the five arguments contain the details of the factorization.
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
@@ -274,11 +274,11 @@ Solves a set of linear equations
  A^TX=B \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
  A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} is an {\it n} by {\it n} tridiagonal matrix.
+where $A$ is an $n$ by $n$ tridiagonal matrix.
 The arguments \var{dl}, \var{d}, \var{du}, \var{du2} and \var{ipiv}
 contain the details of the LU factorization as returned by 
 \function{gttrf()}.
-On exit, \var{B} is overwritten with the solution {\it X}. 
+On exit, \var{B} is overwritten with the solution $X$. 
 \var{B} must have the same type as \var{dl}.
 \end{funcdesc}
 
@@ -289,7 +289,7 @@ Solves
 \[ 
    A X = B,
 \]
-where {\it A} is a real symmetric or complex Hermitian positive 
+where $A$ is a real symmetric or complex Hermitian positive 
 definite matrix.
 On exit, \var{B} is replaced by the solution, and \var{A} is 
 overwritten with the Cholesky factor.
@@ -303,8 +303,8 @@ Cholesky factorization
 \[
  A = LL^T \qquad \mbox{or} \qquad A = LL^H
 \]
-of a positive definite real symmetric or complex Hermitian matrix
-{\it A}.  On exit, the lower triangular part of \var{A} 
+of a positive definite real symmetric or complex Hermitian matrix $A$.  
+On exit, the lower triangular part of \var{A} 
 (if \var{uplo} is \code{'L'}) or the upper triangular part 
 (if \var{uplo} is \code{'U'}) is overwritten with the Cholesky factor 
 or its (conjugate) transpose.
@@ -316,8 +316,7 @@ Solves a set of linear equations
 \[
  AX=B
 \]
-with a positive 
-definite real symmetric or complex Hermitian matrix,
+with a positive definite real symmetric or complex Hermitian matrix,
 given the Cholesky factorization computed by 
 \function{posv()} or \function{potrf()}.
 On entry, \var{A} contains the triangular factor, as computed by
@@ -370,7 +369,6 @@ We then solve the equations
 >>> x1 = div(x1, d)                          # x1 := diag(d)^{-1}*x1 = diag(d)^{-2} * (A*x2 - b1)
 \end{verbatim}
 
-
 There are separate routines for equations with positive definite band 
 matrices.
 \begin{funcdesc}{pbsv}{A, B\optional{, uplo='L'}}
@@ -378,8 +376,8 @@ Solves
 \[
  AX=B
 \]
-where {\it A} is a real symmetric or complex Hermitian positive definite
-band matrix.  On entry, the diagonals of {\it A} are stored in \var{A}, 
+where $A$ is a real symmetric or complex Hermitian positive definite
+band matrix.  On entry, the diagonals of $A$ are stored in \var{A}, 
 using the BLAS format for symmetric or Hermitian band matrices
 (see section~\ref{s-conventions}).  On exit, \var{B} is replaced by the
 solution, and \var{A} is overwritten with the Cholesky factor (in the
@@ -394,7 +392,7 @@ Cholesky factorization
  A = LL^T \qquad \mbox{or} \qquad A = LL^H
 \]
 of a positive definite real symmetric or complex Hermitian band matrix
-{\it A}.  On entry, the diagonals of {\it A} are stored in \var{A}, 
+$A$.  On entry, the diagonals of $A$ are stored in \var{A}, 
 using the BLAS format for symmetric or Hermitian band matrices.
 On exit, \var{A} contains the Cholesky factor, in the BLAS format
 for triangular band matrices.
@@ -421,29 +419,29 @@ Solves
 \[ 
    A X = B,
 \]
-where {\it A} is an {\it n} by {\it n} positive definite real symmetric 
-or complex Hermitian tridiagonal matrix, with diagonal 
-\var{d} (a \dtc\ matrix of length {\it n}) and subdiagonal \var{e} 
-(a \dtc\ or \ztc\ matrix of length {\it n}-1).
+where $A$ is an $n$ by $n$ positive definite real symmetric 
+or complex Hermitian tridiagonal matrix.  Its diagonal 
+is stored as a \dtc\ matrix \var{d} of length $n$ and 
+its subdiagonal as a \dtc\ or \ztc\ matrix \var{e} of length $n-1$.
 The arguments \var{e} and \var{B} must have the same type.  
-On exit \var{d} contains the diagonal elements of {\it D} in 
+On exit \var{d} contains the diagonal elements of $D$ in 
 the LDL${}\mathrm{^T}$ or LDL${}\mathrm{^H}$ factorization 
-of {\it A}, and \var{e} contains the subdiagonal elements of the unit 
-lower bidiagonal matrix {\it L}.  
-\var{B} is overwritten with the solution {\it X}.  
+of $A$, and \var{e} contains the subdiagonal elements of the unit 
+lower bidiagonal matrix $L$.  
+\var{B} is overwritten with the solution $X$.  
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
 
 \begin{funcdesc}{pttrf}{d, e}
-LDL${}\mathrm{^T}$ or LDL${}\mathrm{^H}$ factorization of an {\it n} by 
-{\it n} positive definite real symmetric or complex Hermitian tridiagonal 
-matrix {\it A}.
+LDL${}\mathrm{^T}$ or LDL${}\mathrm{^H}$ factorization of an $n$ by 
+$n$ positive definite real symmetric or complex Hermitian tridiagonal 
+matrix $A$.
 On entry, the argument \var{d} is a \dtc\ matrix with the diagonal elements
-of {\it A}.  The argument \var{e} is \dtc\ or \ztc\ matrix with
-the subdiagonal elements of {\it A}.
-On exit \var{d} contains the diagonal elements of {\it D}, and \var{e} 
+of $A$.  The argument \var{e} is \dtc\ or \ztc\ matrix with
+the subdiagonal elements of $A$.
+On exit \var{d} contains the diagonal elements of $D$, and \var{e} 
 contains the subdiagonal elements of the unit lower bidiagonal matrix 
-{\it L}.  Raises an \code{ArithmeticError} if the matrix is singular.
+$L$.  Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
 
 \begin{funcdesc}{gttrs}{d, e, B\optional{, uplo='L'}}
@@ -451,16 +449,16 @@ Solves a set of linear equations
 \[
  AX=B 
 \]
-where {\it A} is an {\it n} by {\it n} positive definite real symmetric 
+where $A$ is an $n$ by $n$ positive definite real symmetric 
 or complex Hermitian tridiagonal matrix, given its LDL${}\mathrm{^T}$ or 
 LDL${}\mathrm{^H}$ factorization.
-The argument \var{d} is the diagonal of the diagonal matrix {\it D}.
+The argument \var{d} is the diagonal of the diagonal matrix $D$.
 The argument \var{uplo} only matters for complex matrices.
 If \var{uplo} is \code{'L'}, then on exit \var{e} contains the subdiagonal 
-elements of the unit bidiagonal matrix {\it L}.
+elements of the unit bidiagonal matrix $L$.
 If \var{uplo} is \code{'U'}, then \var{e} contains the complex
-conjugates of the elements of the unit bidiagonal matrix {\it L}.
-On exit, \var{B} is overwritten with the solution {\it X}. 
+conjugates of the elements of the unit bidiagonal matrix $L$.
+On exit, \var{B} is overwritten with the solution $X$. 
 \var{B} must have the same type as \var{e}.
 \end{funcdesc}
 
@@ -471,12 +469,12 @@ Solves
 \[
  AX=B
 \] 
-where {\it A} is a real or complex symmetric matrix  of order {\it n}.
+where $A$ is a real or complex symmetric matrix  of order $n$.
 On exit, \var{B} is replaced by the solution.  
 The matrices \var{A} and \var{B} must have the same type (\dtc\ or 
 \ztc).
 The optional argument \var{ipiv} is an integer matrix of length at 
-least equal to {\it n}.
+least equal to $n$.
 If \var{ipiv} is provided, \function{sysv()} solves the system and 
 returns the factorization in \var{A} and \var{ipiv}.
 If \var{ipiv} is not specified, \function{sysv()} solves the
@@ -490,8 +488,8 @@ LDL${}\mathrm{^T}$ factorization
 \[
  PAP^T = LDL^T
 \]
-of a real or complex symmetric matrix $A$ of order {\it n}.
-\var{ipiv} is an \itc\ matrix of length at least {\it n}.
+of a real or complex symmetric matrix $A$ of order $n$.
+\var{ipiv} is an \itc\ matrix of length at least $n$.
 On exit, \var{A} and \var{ipiv} contain the factorization.
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
@@ -518,12 +516,12 @@ Solves
 \[
  A X = B
 \]
-where {\it A} is a real symmetric or complex Hermitian of order {\it n}.
+where $A$ is a real symmetric or complex Hermitian of order $n$.
 On exit, \var{B} is replaced by the solution.
 The matrices \var{A} and \var{B} must have the same type (\dtc\ or 
 \ztc).
 The optional argument \var{ipiv} is an integer matrix of length at 
-least \var{n}.  
+least $n$.  
 If \var{ipiv} is provided, then \function{hesv()} solves the system and 
 returns the factorization in \var{A} and \var{ipiv}.
 If \var{ipiv} is not specified, then \function{hesv()} solves the
@@ -537,8 +535,8 @@ LDL${}\mathrm{^H}$ factorization
 \[
  PAP^T = LDL^H
 \]
-of a real symmetric or complex Hermitian matrix of order {\it  n}.
-\var{ipiv} is an \itc\ matrix of length at least \var{n}.
+of a real symmetric or complex Hermitian matrix of order $n$.
+\var{ipiv} is an \itc\ matrix of length at least $n$.
 On exit, \var{A} and \var{ipiv} contain the factorization.
 Raises an \code{ArithmeticError} if the matrix is singular.
 \end{funcdesc}
@@ -580,8 +578,8 @@ Solves a triangular set of equations
  A^TX=B \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
  A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} is real or complex and triangular of order {\it n}, 
-and \var{B} is a matrix with {\it n} rows.
+where $A$ is real or complex and triangular of order $n$, 
+and \var{B} is a matrix with $n$ rows.
 \var{A} and \var{B} are matrices with the same type (\dtc\ or \ztc).
 \function{trtrs()} is similar to \function{blas.trsm()}, except
 that it raises an \code{ArithmeticError} if a diagonal element of 
@@ -590,7 +588,7 @@ values).
 \end{funcdesc}
 
 \begin{funcdesc}{trtri}{A\optional{, uplo='L'\optional{, diag='N'}}}
-Computes the inverse of a real or complex triangular matrix {\it A}.  
+Computes the inverse of a real or complex triangular matrix $A$.  
 On exit, \var{A} contains the inverse.
 \end{funcdesc}
 
@@ -602,28 +600,28 @@ Solves a triangular set of equations
  A^TX=B \quad (\mathrm{trans} = \mathrm{'T'}), \qquad 
  A^HX=B \quad (\mathrm{trans} = \mathrm{'C'}), 
 \]
-where {\it A} is real or complex triangular band matrix of order {\it n}, 
-and \var{B} is a matrix with {\it n} rows.
-The diagonals of {\it A} are stored in \var{A} using the BLAS conventions 
+where $A$ is real or complex triangular band matrix of order $n$, 
+and \var{B} is a matrix with $n$ rows.
+The diagonals of $A$ are stored in \var{A} using the BLAS conventions 
 for triangular band matrices. 
 \var{A} and \var{B} are matrices with the same type (\dtc\ or \ztc).
-On exit, \var{B} is replaced by the solution {\it X}.
+On exit, \var{B} is replaced by the solution $X$.
 \end{funcdesc}
 
 \section{Least-Squares and Least-Norm Problems}
 \begin{funcdesc}{gels}{A, B\optional{, trans='N'}}
 Solves least-squares and least-norm problems with a full rank 
-{\it m} by {\it n} matrix {\it A}.
+$m$ by $n$ matrix $A$.
 
 \begin{enumerate}
-\item \var{trans} is \code{'N'}.  If {\it m} is greater than or equal
-to {\it n}, \function{gels()} solves the least-squares problem
+\item \var{trans} is \code{'N'}.  If $m$ is greater than or equal
+to $n$, \function{gels()} solves the least-squares problem
 \[
  \begin{array}{ll} 
  \mbox{minimize} & \|AX-B\|_F.
  \end{array} 
 \]
-If {\it m} is less than or equal to {\it n}, \function{gels()} solves 
+If $m$ is less than or equal to $n$, \function{gels()} solves 
 the least-norm problem
 \[
  \begin{array}{ll} 
@@ -633,7 +631,7 @@ the least-norm problem
 \]
 
 \item \var{trans} is \code{'T'} or \code{'C'} and \var{A} and \var{B}
-are real.  If {\it m} is greater than or equal to {\it n},
+are real.  If $m$ is greater than or equal to $n$,
 \function{gels()} solves the least-norm problem
 \[
  \begin{array}{ll} 
@@ -641,7 +639,7 @@ are real.  If {\it m} is greater than or equal to {\it n},
  \mbox{subject to} & A^TX=B.
  \end{array}
 \]
-If {\it m} is less than or equal to {\it n}, \function{gels()} solves 
+If $m$ is less than or equal to $n$, \function{gels()} solves 
 the least-squares problem
 \[
  \begin{array}{ll} 
@@ -650,7 +648,7 @@ the least-squares problem
 \]
 
 \item \var{trans} is \code{'C'} and \var{A} and \var{B}
-are complex. If {\it m} is greater than or equal to {\it n}, 
+are complex. If $m$ is greater than or equal to $n$, 
 \function{gels()} solves the least-norm problem
 \[
  \begin{array}{ll} 
@@ -658,7 +656,7 @@ are complex. If {\it m} is greater than or equal to {\it n},
  \mbox{subject to} & A^HX=B.
  \end{array}
 \]
-If {\it m} is less than or equal to {\it n}, \function{gels()} solves 
+If $m$ is less than or equal to $n$, \function{gels()} solves 
 the least-squares problem
 \[
  \begin{array}{ll} 
@@ -668,10 +666,10 @@ the least-squares problem
 \end{enumerate}
 \var{A} and \var{B} must have the same typecode (\dtc\ or \ztc).
 \var{trans} = \code{'T'} is not allowed if \var{A} is complex.
-On exit, the solution {\it X} is stored as the leading submatrix 
+On exit, the solution $X$ is stored as the leading submatrix 
 of \var{B}.
 The array \var{A} is overwritten with details of the QR or the LQ 
-factorization of {\it A}.
+factorization of $A$.
 Note that \function{gels()} does not check whether $A$ is full rank.
 \end{funcdesc}
 
@@ -680,15 +678,15 @@ QR factorization of a real or complex matrix \var{A}:
 \[
   A = Q R.
 \]
-If \var{A} is {\it m} by {\it n}, then {\it Q} is {\it m} by {\it m} 
-and orthogonal/unitary, and \var{R} is {\it m} by {\it n}
-and upper triangular (if \var{m} is greater than or equal to \var{n}), 
-or upper trapezoidal (if \var{m} is less than or equal to \var{n}).  
+If \var{A} is $m$ by $n$, then $Q$ is $m$ by $m$ 
+and orthogonal/unitary, and \var{R} is $m$ by $n$
+and upper triangular (if $m$ is greater than or equal to $n$), 
+or upper trapezoidal (if $m$ is less than or equal to $n$).  
 \var{tau}  is a matrix of the same type as {\var A} and of length at 
-least min\{\var{m}, \var{n}\}.
-On exit, {\it R} is stored in the upper triangular part of \var{A}.
-The matrix {\it Q} is stored as a product of min\{\var{m}, \var{n}\}
-elementary reflectors in the first min\{\var{m}, \var{n}\} columns 
+least $\min\{m, n\}$.
+On exit, $R$ is stored in the upper triangular part of \var{A}.
+The matrix $Q$ is stored as a product of $\min\{m, n\}$
+elementary reflectors in the first $\min\{m,n\}$ columns 
 of \var{A} and in \var{tau}.
 \end{funcdesc}
 
@@ -703,8 +701,8 @@ Product with a real orthogonal matrix:
  Q^T & \mathrm{trans} = \mathrm{'T'},
 \end{array}\right.
 \]
-where {\it Q} is square and orthogonal.  
-{\it Q} is stored in \var{A} and \var{tau} as a product 
+where $Q$ is square and orthogonal.  
+$Q$ is stored in \var{A} and \var{tau} as a product 
 of min\{\var{A}.\member{size}[0], \var{A}.\member{size}[1]\} 
 elementary reflectors, as computed by \function{geqrf()}.
 \end{funcdesc}
@@ -721,8 +719,8 @@ Product with a real orthogonal or complex unitary matrix:
  Q^H & \mathrm{trans} = \mathrm{'C'},
 \end{array}\right.
 \]
-{\it Q} is square and orthogonal or unitary.  
-{\it Q} is stored in \var{A} and \var{tau} as a product of 
+$Q$ is square and orthogonal or unitary.  
+$Q$ is stored in \var{A} and \var{tau} as a product of 
 min\{\var{A}.\member{size}[0], \var{A}.\member{size}[1]\} 
 elementary reflectors, as computed by \function{geqrf()}.
 The arrays \var{A}, \var{tau} and \var{C} must have the same type.
@@ -758,8 +756,8 @@ eigenvectors of a real symmetric matrix $A$:
 \]
 
 \begin{funcdesc}{syev}{A, W\optional{, jobz='N'\optional{, uplo='L'}}}
-Eigenvalue decomposition of a real symmetric matrix of order {\it n}.
-\var{W} is a real matrix of length at least {\it n}.
+Eigenvalue decomposition of a real symmetric matrix of order $n$.
+\var{W} is a real matrix of length at least $n$.
 On exit, \var{W} contains the eigenvalues in ascending order.
 If \var{jobz} is \code{'V'}, the eigenvectors are also computed
 and returned in \var{A}.
@@ -777,16 +775,15 @@ algorithm.  It is faster on large problems, but also uses more memory.
 range='A'\optional{, uplo='L'\optional{, vl=0.0, vu=0.0\optional{, 
 il=1, iu=1\optional{, Z=\None}}}}}}}
 Computes selected eigenvalues and eigenvectors of a real symmetric 
-matrix \var{A} of order {\it n}.
+matrix \var{A} of order $n$.
 
-\var{W} is a real matrix of length at least \var{n}.
+\var{W} is a real matrix of length at least $n$.
 On exit, \var{W} contains the eigenvalues in ascending order.
 If \var{range} is \code{'A'}, all the eigenvalues are computed.
-If \var{range} is \code{'I'}, eigenvalues \var{il} through \var{iu}
-are computed, where \var{1} \code{<=} \var{il} \code{<=} \var{iu} 
-\code{<=} \var{n}. 
+If \var{range} is \code{'I'}, eigenvalues $i_l$ through $i_u$
+are computed, where $1 \leq i_l \leq i_u \leq n$. 
 If \var{range} is \code{'V'}, the eigenvalues in the interval 
-\code{(\var{vl},\var{vu}]} are computed. 
+$(v_l,v_u]$ are computed. 
 
 If \var{jobz} is \code{'V'}, the (normalized) eigenvectors are 
 computed, and returned in \var{Z}.  If \var{jobz} is \code{'N'}, the 
@@ -794,8 +791,8 @@ eigenvectors are not computed.  In both cases, the contents of \var{A}
 are destroyed on exit.
 \var{Z} is optional (and not referenced) if \var{jobz} is \code{'N'}.
 It is required if \var{jobz} is \code{'V'} and must have at least
-\var{n} columns if \var{range} is \code{'A'} or \code{'V'} and  at
-least \code{\var{iu}-\var{il}+1} columns if \var{range} is \code{'I'}.
+$n$ columns if \var{range} is \code{'A'} or \code{'V'} and  at
+least $i_u-i_l+1$ columns if \var{range} is \code{'I'}.
 
 \function{syevx()} returns the number of computed eigenvalues.
 \end{funcdesc}
@@ -819,7 +816,7 @@ For real symmetric matrices they are identical to the corresponding
 
 \begin{funcdesc}{heev}{A, W\optional{, jobz='N'\optional{, uplo='L'}}}
 Eigenvalue decomposition of a real symmetric or complex Hermitian
-matrix of order {\it n}.
+matrix of order $n$.
 The calling sequence is identical to \function{syev()}, except that 
 \var{A} can be real or complex.
 \end{funcdesc}
@@ -832,7 +829,7 @@ This is an alternative to \function{heev()}.
 range='A'\optional{, uplo='L'\optional{, vl=0.0, vu=0.0 \optional{, 
 il=1, iu=n\optional{, Z=\None}}}}}}}
 Computes selected eigenvalues and eigenvectors of a real symmetric 
-or complex Hermitian matrix of order {\it n}.
+or complex Hermitian matrix of order $n$.
 The calling sequence is identical to \function{syevx()},
 except that \var{A} can be real or complex.
 \var{Z} must have the same type as \var{A}.
@@ -862,12 +859,12 @@ The matrix of eigenvectors is normalized as follows:
 \begin{funcdesc}{sygv}{A, B, W\optional{, itype=1\optional{, 
 jobz='N'\optional{, uplo='L'}}}}
 Solves the generalized eigenproblem~(\ref{e-gevd}) for real symmetric 
-matrices of order {\it n}, stored in real matrices \var{A} and \var{B}.
+matrices of order $n$, stored in real matrices \var{A} and \var{B}.
 \var{itype} is an integer with possible values 1, 2, 3, and specifies
 the type of eigenproblem.
-\var{W} is a real matrix of length at least {\it n}.
+\var{W} is a real matrix of length at least $n$.
 On exit, it contains the eigenvalues in ascending order.
-On exit, \var{B} contains the Cholesky factor of {\it B}.
+On exit, \var{B} contains the Cholesky factor of $B$.
 If \var{jobz} is \code{'V'}, the eigenvectors are computed
 and returned in \var{A}.
 If \var{jobz} is \code{'N'}, the eigenvectors are not returned and the 
@@ -877,7 +874,7 @@ contents of \var{A} are destroyed.
 \begin{funcdesc}{hegv}{A, B, W\optional{, itype=1\optional{, 
 jobz='N'\optional{, uplo='L'}}}}
 Generalized eigenvalue problem~(\ref{e-gevd}) of real symmetric or 
-complex Hermitian matrix of order \var{n}.
+complex Hermitian matrix of order $n$.
 The calling sequence is identical to \function{sygv()},
 except that \var{A} and \var{B} can be real or complex.
 \end{funcdesc}
@@ -891,10 +888,10 @@ Singular value decomposition
 \[
  A = U \Sigma V^T, \qquad A = U \Sigma V^H
 \]
-of a real or complex {\it m} by {\it n} matrix \var{A}.
+of a real or complex $m$ by $n$ matrix \var{A}.
 
-\var{S} is a real matrix of length at least min\{{\it m}, {\it n}\}.
-On exit, its first  min\{{\it m}, {\it n}\} elements are the 
+\var{S} is a real matrix of length at least $\min\{m, n\}$.
+On exit, its first  $\min\{m, n\}$ elements are the 
 singular values in descending order.
 
 The argument \var{jobu} controls how many left singular vectors are
@@ -904,9 +901,9 @@ If \var{jobu} is \code{'N'}, no left singular vectors are
 computed.
 If \var{jobu} is \code{'A'}, all left singular vectors are computed 
 and returned as columns of \var{U}.
-If \var{jobu} is \code{'S'}, the first min\{{\it m},{\it n}\} left 
+If \var{jobu} is \code{'S'}, the first $\min\{m, n\}$ left 
 singular vectors are computed and returned as columns of \var{U}.
-If \var{jobu} is \code{'O'}, the first min\{{\it m},{\it n}\} left 
+If \var{jobu} is \code{'O'}, the first $\min\{m, n\}$ left 
 singular vectors are computed and returned as columns of \var{A}.
 The argument \var{U} is \None\ (if \var{jobu} is \code{'N'}
 or \code{'A'}) or a matrix of the same type as \var{A}.
@@ -917,10 +914,10 @@ and \code{'O'}.
 If \var{jobvt} is \code{'N'}, no right singular vectors are 
 computed.  If \var{jobvt} is \code{'A'}, all right singular vectors 
 are computed and returned as rows of \var{Vt}.
-If \var{jobvt} is \code{'S'}, the first min\{{\it m},{\it n}\} right 
+If \var{jobvt} is \code{'S'}, the first $\min\{m, n\}$ right 
 singular vectors are computed and their (conjugate) transposes are
 returned as rows of \var{Vt}.
-If \var{jobvt} is \code{'O'}, the first min\{{\it m}, {\it n}\} right 
+If \var{jobvt} is \code{'O'}, the first $\min\{m, n\}$ right 
 singular vectors are computed and their (conjugate) transposes 
 are returned as rows of \var{A}.
 Note that the (conjugate) transposes of the right singular vectors 
@@ -933,40 +930,40 @@ On exit, the contents of \var{A} are destroyed.
 
 \begin{funcdesc}{gesdd}{A, S\optional{, jobz='N'\optional{, 
 U=\None\optional{, Vt=\None}}}} 
-Singular value decomposition of a real or complex {\it m} by {\it n} 
+Singular value decomposition of a real or complex $m$ by $n$ 
 matrix \var{A}.  This function is based on a divide-and-conquer 
 algorithm and is faster than \function{gesvd()}.
 
-\var{S} is a real matrix of length at least min\{{\it m}, {\it n}\}.
-On exit, its first min\{{\it m}, {\it n}\} elements are the 
+\var{S} is a real matrix of length at least $\min\{m, n\}$.
+On exit, its first $\min\{m, n\}$ elements are the 
 singular values in descending order.
 
 The argument \var{jobz} controls how many singular vectors are
 computed.  The possible values are \code{'N'}, \code{'A'}, \code{'S'} 
 and \code{'O'}. 
 If \var{jobz} is \code{'N'}, no singular vectors are computed.
-If \var{jobz} is \code{'A'}, all {\it m} left singular vectors are 
-computed and returned as columns of \var{U} and all {\it n} right 
+If \var{jobz} is \code{'A'}, all $m$ left singular vectors are 
+computed and returned as columns of \var{U} and all $n$ right 
 singular vectors are computed and returned as rows of \var{Vt}.
-If \var{jobz} is \code{'S'}, the first min\{{\it m}, {\it n}\} left 
+If \var{jobz} is \code{'S'}, the first $\min\{m, n\}$ left 
 and right singular vectors are computed and returned as columns of 
 \var{U} and rows of \var{Vt}.
-If \var{jobz} is \code{'O'} and {\it m} is greater than or equal
-to {\it n}, the first {\it n} left singular vectors are returned as
-columns of \var{A} and the {\it n} right singular vectors are returned
-as rows of \var{Vt}.  If \var{jobz} is \code{'O'} and {\it m} is less 
-than {\it n}, the {\it m} left singular vectors are returned as columns
-of \var{U} and the first {\it m} right singular vectors are returned 
+If \var{jobz} is \code{'O'} and $m$ is greater than or equal
+to $n$, the first $n$ left singular vectors are returned as
+columns of \var{A} and the $n$ right singular vectors are returned
+as rows of \var{Vt}.  If \var{jobz} is \code{'O'} and $m$ is less 
+than $n$, the $m$ left singular vectors are returned as columns
+of \var{U} and the first $m$ right singular vectors are returned 
 as rows of \var{A}.  
 Note that the (conjugate) transposes of the right singular vectors 
 are returned in \var{Vt} or \var{A}.
 
 The argument \var{U} can be \None\ (if \var{jobz} is \code{'N'}
-or \code{'A'} of \var{jobz} is \code{'O'} and {\it m} is greater than
-or equal to  {\it n})  or a matrix of the same type as \var{A}.
+or \code{'A'} of \var{jobz} is \code{'O'} and $m$ is greater than
+or equal to  $n$)  or a matrix of the same type as \var{A}.
 The argument \var{Vt} can be \None\ (if \var{jobz} is \code{'N'}
-or \code{'A'} or \var{jobz} is \code{'O'} and {\it m} is less than
-{\it n}) or a matrix of the same type as \var{A}.
+or \code{'A'} or \var{jobz} is \code{'O'} and $m$ is less than
+$n$) or a matrix of the same type as \var{A}.
 
 On exit, the contents of \var{A} are destroyed.
 \end{funcdesc}
@@ -984,7 +981,7 @@ a positive definite set of linear equations
 \[
  A^T \diag(b-Ax)^{-2} A v = -\diag(b-Ax)^{-1}\ones
 \]
-(where {\it A} has rows $a_i^T$), and a suitable step size is determined 
+(where $A$ has rows $a_i^T$), and a suitable step size is determined 
 by a backtracking line search.
 
 We use the level-3 BLAS function \function{syrk()} to form the Hessian 
@@ -1028,15 +1025,15 @@ def acent(A,b):
         lapack.posv(H, v)
 
         # Terminate if Newton decrement is less than TOL.
-	lam = blas.dot(g, v)
+        lam = blas.dot(g, v)
         if sqrt(-lam) < TOL: return x
 
         # 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
 \end{verbatim}
diff --git a/doc/modeling.tex b/doc/modeling.tex
index e31e924..3c10586 100644
--- a/doc/modeling.tex
+++ b/doc/modeling.tex
@@ -28,11 +28,11 @@ to MPS files.
 \end{classdesc}
 The function \function{len()} returns the length of a 
 \pytype{variable}.  A \pytype{variable} \var{x} has two attributes.
-\begin{memberdesc}{variable}{name}
+\begin{memberdesc}{name}
 The name of the variable.  
 \end{memberdesc}
 
-\begin{memberdesc}{variable}{value}
+\begin{memberdesc}{value}
 Either \None\  or a dense \dtc\ matrix of size \code{len(\var{x})} by 1.
 
 The attribute \var{x}.\member{value} is set to \None\ when the 
@@ -75,11 +75,11 @@ operations on variables and other functions.  A function \var{f} is
 interpreted as a column vector, with length \code{len(\var{f})} 
 and with a value that depends on the values of its variables.  
 Functions have two public attributes.  
-\begin{methoddesc}{funciton}{variables}
+\begin{methoddesc}{variables}
 Returns a copy of the list of variables of the function.
 \end{methoddesc}
 
-\begin{methoddesc}{function}{value}
+\begin{methoddesc}{value}
 The function value.  If any of the variables of \var{f} has value 
 \None, then \var{f}.\function{value()} returns \None.
 Otherwise, it returns a dense \dtc\ matrix of size 
@@ -264,7 +264,7 @@ affine functions or concave piecewise-linear functions.
 Piecewise-linear functions can be created using the following 
 operations.
 \begin{description}
-\item[\function{max}]  If the arguments in 
+\item[Maximum]  If the arguments in 
 \code{\var{f} = max(\var{y1},\var{y2}, \ldots)} 
 do not include any variables or functions, then the Python built-in 
 \function{max()} is evaluated.  
@@ -289,12 +289,12 @@ With one argument, \code{\var{f} = max(\var{u})} is interpreted as
 \code{\var{f} = max(\var{u}[0],\var{u}[1],\ldots,
 \var{u}[\function{len}(\var{u})-1])}.  
 
-\item[\function{min}] Similar to \function{max()} but returns a concave 
+\item[Minimum] Similar to \function{max()} but returns a concave 
 piecewise-linear function.  The arguments can be scalars of type 
 \intgr\ or \flt, dense \dtc\ matrices with one column, 
 variables, affine functions or concave piecewise-linear functions.
 
-\item[\function{abs}] 
+\item[Absolute value] 
 If \var{u} is a variable or affine function then 
 \code{\var{f} = abs(\var{u})} returns the convex piecewise-linear 
 function \code{max(\var{u},-\var{u})}.
@@ -392,16 +392,16 @@ The built-in fucntion \function{len()} returns the dimension of the
 constraint function.
 
 Constraints have four public attributes.
-\begin{methoddesc}{constraint}{type}{}
+\begin{methoddesc}{type}
 Returns \code{'='} if the constraint is an equality constraint,
 and \code{'<'} if the constraint is an inequality constraint.
 \end{methoddesc}
 
-\begin{methoddesc}{constraint}{value}{}
+\begin{methoddesc}{value}
 Returns the value of the constraint function.  
 \end{methoddesc}
 
-\begin{memberdesc}{constraint}{multiplier}
+\begin{memberdesc}{multiplier}
 For a constraint \var{c}, \var{c}.\member{multiplier} is a 
 \pytype{variable} object of dimension \code{len(\var{c})}.   
 It is used to represent the Lagrange multiplier or dual variable 
@@ -440,24 +440,24 @@ The default value is the empty string.
 The following attributes and methods are useful for examining
 and modifying optimization problems.
 
-\begin{memberdesc}{op}{objective}
+\begin{memberdesc}{objective}
 The objective or cost function.  One can write to this 
 attribute to change the objective of an existing problem.  
 \end{memberdesc}
 
-\begin{methoddesc}{op}{variables}
+\begin{methoddesc}{variables}
 Returns a list of the variables of the problem.
 \end{methoddesc}
 
-\begin{methoddesc}{op}{constraints}
+\begin{methoddesc}{constraints}
 Returns a list of the constraints.
 \end{methoddesc}
 
-\begin{methoddesc}{op}{inequalities}
+\begin{methoddesc}{inequalities}
 Returns a list of the inequality constraints.
 \end{methoddesc}
 
-\begin{methoddesc}{op}{equalities}
+\begin{methoddesc}{equalities}
 Returns a list of the equality constraints.
 \end{methoddesc}
 
@@ -660,7 +660,7 @@ pylab.show()
 \end{verbatim}
 
 \begin{center}
-\includegraphics[width=\linewidth]{figures/normappr.eps}
+\includegraphics[width=15cm]{figures/normappr.eps}
 \end{center}
 
 Equivalently, we can formulate and solve the problems as LPs.
@@ -709,7 +709,6 @@ for randomly generated data.
 \begin{verbatim}
 from cvxopt.random import normal, uniform
 from cvxopt.modeling import variable, dot, op, sum 
-from cvxopt.blas import nrm2
 
 m, n = 500, 100
 A = normal(m,n)
diff --git a/doc/solvers.tex b/doc/solvers.tex
index 00579e8..61c9023 100644
--- a/doc/solvers.tex
+++ b/doc/solvers.tex
@@ -2,71 +2,135 @@
 \label{chap:solvers}
 
 The functions in this chapter are intended for nonlinear convex 
-optimization problems in the format
-\BEQ \label{e-nlcp}
+optimization problems of the form 
+\[ 
  \begin{array}{ll}
  \mbox{minimize} & f_0(x) \\
  \mbox{subject to} & f_k(x) \leq 0, \quad k=1,\ldots,m \\
   & G x \preceq h  \\ 
   & A x = b,
  \end{array}
-\EEQ
-with $f=(f_0,\ldots,f_m)$ convex and twice differentiable.
-The inequalities are componentwise vector inequalities.
-
-The most important function in this chapter is \function{solvers.cp()}, 
-described in section~\ref{s-cp}.   There are also functions for two 
+\]
+with the functions $f_k$ convex and twice differentiable.
+The linear inequalities are generalized inequality with respect to a 
+proper convex cone, defined as a product of a nonnegative orthant,
+second-order cones, and positive semidefinite cones.   
+
+The most important functions in this chapter are 
+\function{solvers.cp()} and \function{solvers.cpl()},
+described in sections~\ref{s-cp} and~\ref{s-cpl}.   
+There are also functions for two 
 special problem classes: quadratic programming (section~\ref{s-qp}) and 
 geometric programming~(section~\ref{s-gp}).
-These solvers are all interfaces to a more general function 
-\function{nlcp()}, which can also be called directly but requires 
-user-provided functions for evaluating the constraints and for solving 
-KKT equations.  This allows the user to exploit certain types of 
-problem structure (section~\ref{s-nlcp}).
+In section~\ref{s-nlcp} we explain how customized solvers can be 
+implemented that exploit structure in specific classes of problems.
+The last section describes the algorithm parameters that control the 
+solvers.
 
 \section{General Solver} \label{s-cp}
-\begin{funcdesc}{cp}{F\optional{, G, h\optional{, A, b}}}
-Solves an optimization problem~(\ref{e-nlcp})
-with $f=(f_0,\ldots,f_m)$ convex and twice differentiable.
-\var{F} is a function that evaluates the objective and nonlinear 
-constraint functions.  It must handle the following calling sequences.
+\begin{funcdesc}{cp}{F\optional{, G, h\optional{, dims\optional{, A, b\optional{, kktsolver}}}}}
+Solves a convex optimization problem
+\BEQ \label{e-nlcp}
+ \begin{array}{ll}
+ \mbox{minimize} & f_0(x) \\
+ \mbox{subject to} & f_k(x) \leq 0, \quad k=1,\ldots,m \\
+  & G x \preceq h  \\ 
+  & A x = b,
+ \end{array}
+\EEQ
+
+The argument \var{F} is a function that evaluates the objective and 
+nonlinear constraint functions.  It must handle the following calling 
+sequences.
 
 \begin{itemize}
 \item \code{F()} returns a tuple (\var{m}, \var{x0}), where \var{m} is 
  the number of nonlinear constraints and \var{x0} is a point in the 
- domain of {\it f}.  \var{x0} is a dense real matrix of size 
- ({\it n}, 1).
+ domain of $f$.  \var{x0} is a dense real matrix of size 
+ $(n, 1)$.
 
 \item \code{F(x)}, with \var{x} a dense real matrix of size 
- ({\it n},1), returns a tuple (\var{f}, \var{Df}).  
- \var{f} is a dense real matrix of size ({\it m}+1,1), with 
- \code{\var{f}[\var{k}]} equal to {\it f\_k(x)}. 
- (If {\it m} is zero, \var{f} can also be returned as a number.)
- \var{Df} is a dense or sparse real matrix of size ({\it m}+1, {\it n}) 
+ $(n,1)$, returns a tuple (\var{f}, \var{Df}).  
+ \var{f} is a dense real matrix of size $(m+1,1)$, with 
+ \code{\var{f}[\var{k}]} equal to $f_k(x)$. 
+ (If $m$ is zero, \var{f} can also be returned as a number.)
+ \var{Df} is a dense or sparse real matrix of size $(m+1, n)$ 
  with \code{\var{Df}[\var{k},:]} equal to the transpose of the gradient
- of {\it f\_k} at {\it x}.
- If \var{x} is not in the domain of {\it f}, \code{F(x)} returns 
+ $\nabla f_k(x)$.
+ If \var{x} is not in the domain of $f$, \code{F(x)} returns 
  \None\ or a tuple (\None,\None).
 
 \item \code{F(x,z)}, with \var{x} a dense real matrix of size 
- ({\it n},1) and \var{z} a positive dense real matrix of size 
- ({\it m}+1,1) returns a tuple (\var{f}, \var{Df}, \var{H}).  
+ $(n,1)$ and \var{z} a positive dense real matrix of size 
+ $(m+1,1)$ returns a tuple (\var{f}, \var{Df}, \var{H}).  
  \var{f} and \var{Df} are defined as above.  
  \var{H} is a square dense or sparse real matrix of size 
- ({\it n}, {\it n}), whose lower triangular part contains the lower 
+ $(n, n)$, whose lower triangular part contains the lower 
  triangular part of
  \[
   z_0 \nabla^2f_0(x) + z_1 \nabla^2f_1(x) + \cdots + z_m \nabla^2f_m(x).
  \]
  If \var{F} is called with two arguments, it can be assumed that 
- \var{x} is in the domain of {\it f}.
+ $x$ is in the domain of $f$.
 \end{itemize}
 
-\var{G} and \var{A} are dense or sparse real matrices with {\it n} 
-columns.  Their default values are matrices of size (0, {\it n}).
-\var{h} and \var{b} are dense real matrices with one column, and the 
-same number of rows as \var{G} and \var A, respectively.
-Their default values are matrices of size (0,1).
+The linear inequalities are with respect to a cone $C$ defined as a 
+Cartesian product of a nonnegative orthant, a number of second-order 
+cones, and a number of positive semidefinite cones:
+\[
+C = C_0 \times C_1 \times \cdots \times C_M \times C_{M+1} \times
+ \cdots \times C_{M+N}
+\]
+with
+\[
+C_0 = 
+ \{ u \in \reals^l \;| \; u_k \geq 0, \; k=1, \ldots,l\}, \qquad 
+C_{k+1} = \{ (u_0, u_1) \in \reals \times \reals^{q_{k}-1} \; | \;
+   u_0 \geq \|u_1\|_2 \},  \quad k=0,\ldots, M-1, \qquad 
+C_{k+M+1} = \left\{ \svec(u) \; | \;
+  u \in \symm^{p_k}_+ \right\}, \quad k=0,\ldots,N-1.
+\]
+Here $\svec(u)$ denotes a symmetric matrix $u$ stored as a vector 
+in column major order.  
+
+The arguments \var{h} and \var{b} are real single-column dense 
+matrices.  \var{G} and \var{A} are real dense or sparse matrices.
+The default values for \var{A} and \var{b} are sparse matrices with 
+zero rows, meaning that there are no equality constraints.  
+The number of rows of \var{G} and \var{h} is equal to
+\[
+ K = l + \sum_{k=0}^{M-1} q_k + \sum_{k=0}^{N-1} p_k^2.
+\]
+The columns of \var{G} and \var{h} are vectors in
+\[
+\reals^l \times \reals^{q_0} \times \cdots \times 
+\reals^{q_{M-1}} \times \reals^{p_0^2}  \times \cdots \times 
+\reals^{p_{N-1}^2},
+\]
+where the last $N$ components represent symmetric matrices stored in 
+column major order.  The strictly upper triangular entries of these 
+matrices are not accessed (i.e.,  the symmetric matrices are stored
+in the 'L'-type column major order used in the \module{blas} and
+\module{lapack} modules).
+
+The argument \var{dims} is a dictionary with the dimensions of the 
+cones.  It has three fields. 
+\begin{description}
+\item[\var{dims['l']}:] $l$, the dimension of the nonnegative orthant
+ (a nonnegative integer).
+\item[\var{dims['q']}:] $[q_0, \ldots, q_{M-1}]$, 
+a list with the dimensions of the second-order cones (positive integers).
+\item[\var{dims['s']}:] $[p_0, \ldots, p_{N-1}]$, 
+a list with the dimensions of the positive semidefinite cones
+(nonnegative integers).
+\end{description}
+
+The default value of \var{dims} is 
+\code{\{'l': h.size[0], 'q': [], 's': []\}}, \ie, the default assumption
+is that the linear inequalities are componentwise inequalities.
+
+The role of the optional argument \var{kktsolver} is explained in 
+section~\ref{s-nlcp}.  
 
 \function{cp()} returns a dictionary with keys \code{'status'}, 
 \code{'x'}, \code{'snl'}, \code{'sl'}, \code{'y'}, \code{'znl'}, 
@@ -80,8 +144,8 @@ The possible values of the \code{'status'} key are:
 \code{'znl'}, \code{'zl'} and \code{'y'} entries are the optimal 
 values of the dual variables associated with the nonlinear 
 inequalities, the linear inequalities, and the linear equality 
-constraints.  These vectors approximately satisfy the Karush-
-Kuhn-Tucker (KKT) conditions
+constraints.  These vectors approximately satisfy the 
+Karush-Kuhn-Tucker (KKT) conditions
 \[
  \nabla f_0(x) +  D\tilde f(x)^T z_\mathrm{nl} + 
  G^T z_\mathrm{l} + A^T y = 0, \qquad
@@ -102,17 +166,14 @@ The \code{'x'}, \code{'snl'}, \code{'sl'},
 \code{'y'}, \code{'znl'} and \code{'zl'} entries are \None. 
 \end{description}
 
-\function{cp()} requires that the problem is solvable and that the 
-Karush-Kuhn-Tucker matrix
+\function{cp()} requires that the problem is solvable and that 
 \[
-\left[\begin{array}{cccc}
-\sum_{k=0}^m z_k \nabla^2 f_k(x) & D\tilde f(x)^T & G^T & A^T\\
-D\tilde f(x) & -\diag(d_1) & 0 & 0 \\
- G & 0 & -\diag(d_2) & 0 \\ 
- A & 0 & 0 & 0 \end{array}\right]
+\Rank(A) = p, \qquad 
+\Rank\left(\left[\begin{array}{cccccc} 
+\sum_{k=0}^m z_k \nabla^2 f_k(x) & A^T &
+ \nabla f_1(x) & \cdots \nabla f_m(x) & G^T \end{array}\right]\right) = n,
 \]
-is nonsingular for all {\it x}, all nonnegative {\it z}, and all positive 
-$d_1$, $d_2$.  
+for all $x$ and all positive $z$. 
 \end{funcdesc}
 
 
@@ -131,7 +192,7 @@ assumping it is solvable.
 
 \begin{verbatim}
 from cvxopt import solvers 
-from cvxopt.base import matrix, spmatrix, log
+from cvxopt.base import matrix, spdiag, log
 
 def acent(A, b):
     m, n = A.size
@@ -141,7 +202,7 @@ def acent(A, b):
         f = -sum(log(x))
         Df = -(x**-1).T 
         if z is None: return f, Df
-        H = z[0] * spmatrix(x**-2, range(n), range(n))
+        H = spdiag(z[0] * x**-2)
         return f, Df, H
     return solvers.cp(F, A=A, b=b)['x']
 \end{verbatim}
@@ -159,7 +220,7 @@ problem
 
 \begin{verbatim}
 from cvxopt import solvers 
-from cvxopt.base import matrix, spmatrix, sqrt, div
+from cvxopt.base import matrix, spdiag, sqrt, div
 
 def robls(A, b, rho): 
     m, n = A.size
@@ -170,11 +231,125 @@ def robls(A, b, rho):
         f = sum(w)
         Df = div(y, w).T * A 
         if z is None: return f, Df 
-        H = A.T * spmatrix(z[0]*rho*(w**-3), range(m), range(m)) * A
+        H = A.T * spdiag(z[0]*rho*(w**-3)) * A
         return f, Df, H
     return solvers.cp(F)['x']
 \end{verbatim}
 
+\item[Example: analytic centering with cone constraints]
+\[
+ \begin{array}{ll}
+ \mbox{minimize} & - \log(1-x_1^2) - \log(1-x_2^2) - \log(1-x_3^2) \\*[1ex]
+ \mbox{subject to} & \|x\|_2 \leq 1 \\*[1ex]
+ &   x_1 \left[\begin{array}{rrr} 
+   -21 & -11 & 0 \\ -11 & 10 & 8 \\ 0 & 8 & 5 
+  \end{array}\right] +
+   x_2 \left[\begin{array}{rrr} 
+   0 & 10 & 16 \\ 10 & -10 & -10 \\ 16 & -10 & 3 
+  \end{array}\right] +
+   x_3 \left[\begin{array}{rrr} 
+   -5 & 2 & -17 \\ 2 & -6 & 8 \\ -17 & -7 & 6 
+  \end{array}\right] \preceq \left[\begin{array}{rrr}
+   20 & 10 & 40 \\ 10 & 80 & 10 \\ 40 & 10 & 15 \end{array}\right].
+ \end{array}
+\]
+
+\begin{verbatim}
+from cvxopt.base import matrix, log, div, spdiag
+from cvxopt import solvers
+
+def F(x = None, z = None):
+     if x is None:  return 0, matrix(0.0, (3,1)) 
+     if max(abs(x)) >= 1.0:  return None
+     u = 1 - x**2
+     val = -sum(log(u))
+     Df = div(2*x, u).T
+     if z is None:  return val, Df
+     H = spdiag(2 * z[0] * div(1 + u**2, u**2))
+     return val, Df, H
+
+G = matrix([ [0., -1.,  0.,  0., -21., -11.,   0., -11.,  10.,   8.,   0.,   8., 5.], 
+             [0.,  0., -1.,  0.,   0.,  10.,  16.,  10., -10., -10.,  16., -10., 3.], 
+             [0.,  0.,  0., -1.,  -5.,   2., -17.,   2.,  -6.,   8., -17.,  -7., 6.] ])  
+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']
+   4.1132e-01
+   5.5885e-01
+  -7.2007e-01
+\end{verbatim}
+\end{description}
+
+
+\section{Problems with Linear Objectives} \label{s-cpl}
+
+The following function for problems with a linear objective 
+is simpler to use than \function{cp()}.  (In fact, \function{cp()} 
+converts the problem to one with a linear objective, and then 
+calls~\function{cpl()}.) 
+
+\begin{funcdesc}{cpl}{c, F\optional{, G, h\optional{, dims\optional{, A, b\optional{, kktsolver}}}}}
+Solves a convex optimization problem with a linear objective
+\[
+ \begin{array}{ll}
+ \mbox{minimize} & c^T x \\
+ \mbox{subject to} & f_k(x) \leq 0, \quad k=0,\ldots,m-1 \\
+  & G x \preceq h  \\ 
+  & A x = b.
+ \end{array}
+\]
+
+\var{c} is a real single-column dense matrix.  
+
+\var{F} is a function that evaluates the nonlinear constraint functions.  
+It must handle the following calling sequences.
+
+\begin{itemize}
+\item \code{F()} returns a tuple (\var{m}, \var{x0}), where \var{m} is 
+ the number of nonlinear constraints and \var{x0} is a point in the 
+ domain of $f$.  \var{x0} is a dense real matrix of size $(n, 1)$.
+
+\item \code{F(x)}, with \var{x} a dense real matrix of size 
+ $(n, 1)$, returns a tuple (\var{f}, \var{Df}).  
+ \var{f} is a dense real matrix of size $(m, 1)$, with 
+ \code{\var{f}[\var{k}]} equal to $f_k(x)$. 
+ \var{Df} is a dense or sparse real matrix of size $(m,n$ 
+ with \code{\var{Df}[\var{k},:]} equal to the transpose of the gradient
+ $\nabla f_k(x)$.
+ If \var{x} is not in the domain of $f$, \code{F(x)} returns 
+ \None\ or a tuple (\None,\None).
+
+\item \code{F(x,z)}, with \var{x} a dense real matrix of size 
+ $(n,1)$ and \var{z} a positive dense real matrix of size 
+ $(m,1)$ returns a tuple (\var{f}, \var{Df}, \var{H}).  
+ \var{f} and \var{Df} are defined as above.  
+ \var{H} is a square dense or sparse real matrix of size 
+ $(n,n)$, whose lower triangular part contains the lower 
+ triangular part of
+ \[
+  z_0 \nabla^2f_0(x) + z_1 \nabla^2f_1(x) + \cdots + 
+ z_{m-1} \nabla^2f_{m-1}(x).
+ \]
+ If \var{F} is called with two arguments, it can be assumed that 
+ $x$ is in the domain of $f$.
+\end{itemize}
+
+The other arguments have the same meaning as in~\function{cp()}.
+
+\function{cpl()} requires that the problem is solvable and that 
+\[
+\Rank(A) = p, \qquad 
+\Rank\left(\left[\begin{array}{cccccc} 
+\sum_{k=0}^{m-1} z_k \nabla^2 f_k(x) & A^T &
+ \nabla f_0(x) & \cdots \nabla f_{m-1}(x) & G^T \end{array}\right]\right) 
+ = n,
+\]
+for all $x$ and all positive $z$. 
+\end{funcdesc}
+
+
+\begin{description}
 \item[Example: floor planning]
 
 This example is the floor planning problem of section 8.8.2 in the book 
@@ -242,18 +417,17 @@ def floorplan(Amin):
     #
     #     -wk + Amink / hk <= 0,  k = 1, ..., 5
 
+    c = matrix(2*[1.0] + 20*[0.0])
+
     def F(x=None, z=None):
         if x is None:  return 5, matrix(17*[0.0] + 5*[1.0])
         if min(x[17:]) <= 0.0:  return None 
-        f = matrix(0.0, (6,1))
-        f[0] = x[0] + x[1]  
-        f[1:] = -x[12:17] + div(Amin, x[17:]) 
-        Df = matrix(0.0, (6,22))
-        Df[0, [0,1]] = 1.0
-        Df[1:,12:17] = spmatrix(-1.0, range(5), range(5))
-        Df[1:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
+        f = -x[12:17] + div(Amin, x[17:]) 
+        Df = matrix(0.0, (5,22))
+        Df[:,12:17] = spmatrix(-1.0, range(5), range(5))
+        Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
         if z is None: return f, Df
-        H = spmatrix( 2.0* mul(z[1:], div(Amin, x[17::]**3)), range(17,22), range(17,22) )
+        H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), range(17,22) )
         return f, Df, H
 
     G = matrix(0.0, (26,22)) 
@@ -286,7 +460,7 @@ def floorplan(Amin):
     G[25, [16, 21]] = 1.0, -gamma                       #  w5 - gamma * h5 <= 0.0
 
     # solve and return W, H, x, y, w, h 
-    sol = solvers.cp(F, G, h)  
+    sol = solvers.cpl(c, F, G, h)  
     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')
@@ -295,7 +469,7 @@ 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]], '#D0D0D0')
+               [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([])
@@ -306,7 +480,7 @@ 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]], '#D0D0D0')
+               [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([])
@@ -317,7 +491,7 @@ 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]],'#D0D0D0')
+               [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([])
@@ -328,7 +502,7 @@ 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]],'#D0D0D0')
+               [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([])
@@ -466,9 +640,9 @@ c2 = [ x[0] + x[1] for x in portfolios ]
 c3 = [ x[0] + x[1] + x[2] for x in portfolios ] 
 c4 = [ x[0] + x[1] + x[2] + x[3] for x in portfolios ]
 pylab.fill(risks + [.20], c1 + [0.0], '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1, '#D0D0D0') 
-pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3, '#D0D0D0') 
+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')
@@ -499,11 +673,11 @@ where
  g = \left[ \begin{array}{cccc}
  g_0^T & g_1^T & \cdots & g_m^T \end{array}\right]^T. 
 \]
-\var{K} is a list of {\it m}+1 positive integers with 
+\var{K} is a list of $m+1$ positive integers with 
 \code{\var{K}[\var i]}
-equal to the number of rows in {\it F\_i}.
-\var{F} is a dense or sparse real matrix of size 
-\code{(sum(\var K),\var n)}.
+equal to the number of rows in $F_i$.
+\var{F} is a dense or sparse real matrix of 
+size \code{(sum(\var K),\var n)}.
 \var{g} is a dense real matrix with one column and the same number of
 rows as \var{F}.
 \var{G} and \var{A} are dense or sparse real matrices.
@@ -545,7 +719,7 @@ and \code{'zl'} entries are \None.
 \end{funcdesc}
 
 As an example, we solve the small GP of section 2.4 of the paper 
-\citetitle{http://www.stanford.edu/\~{}boyd/gp\_tutorial}{A Tutorial on Geometric Programming}.  
+\citetitle{http://www.stanford.edu/\~{}boyd/gp\_tutorial.html}{A Tutorial on Geometric Programming}.  
 The  posynomial form of the problem is
 \[
  \begin{array}{ll}
@@ -559,7 +733,7 @@ The  posynomial form of the problem is
   &   (1/\delta)dw^{-1} \leq 1
  \end{array}
 \]
-with variables {\it h}, {\it w}, {\it d}.
+with variables $h$, $w$, $d$.
 
 \begin{verbatim}
 from cvxopt.base import matrix, log, exp
@@ -582,89 +756,223 @@ h, w, d = exp( solvers.gp(K, F, g)['x'] )
 
 
 \section{Exploiting Structure} \label{s-nlcp}
-The solvers \function{cp()}, \function{qp()} and \function{gp()} are 
-interfaces to \function{nlcp()}, which can also be called directly
-but requires user-provided functions for evaluating the constraint 
-and for solving the KKT equations.
-
-\begin{funcdesc}{nlcp}{kktsolver, F\optional{, G, h\optional{, A, b}}}
-Solves the nonlinear convex optimization problem~(\ref{e-nlcp}).
-
-The meaning of the arguments \var{h} and \var{b} is the same 
-as for \function{cp()}.
-The arguments \var{kktsolver}, \var{F}, \var{G} and \var{A} are  
-functions that must handle the following calling sequences.
-\begin{itemize}
-\item \function{kktsolver}(\var{x}, \var{z}, \var{dnl}, \var{dl}),
-returns a function for solving KKT systems
-\BEAS
- \sum_{k=0}^m z_k \nabla^2 f_k(x)u_x + A^T u_y + 
- D \tilde f(x)^T u_{z_\mathrm{nl}} + 
- G_\mathrm{l}^T u_{z_\mathrm{l}} & = & b_x \\
- A x  & = & b_y \\
- D\tilde f(x) x  - \diag(d_\mathrm{nl})^{-2} z_\mathrm{nl} & = & 
-    b_{z_\mathrm{nl}} \\
- G_\mathrm{l}x  - \diag(d_\mathrm{l})^{-2} z_\mathrm{l} & = & 
-    b_{z_\mathrm{l}}
-\EEAS
-where $\tilde f = (f_1, \ldots, f_m)$.
-The arguments are single-column real dense matrices. \var{x} is in the 
-domain of the objective and constraint functions.  \var{z}, \var{dnl}
-and \var{dl} are positive vectors.
-
-The function \var{f} created by 
-\samp{f = kktsolver(bx, by, bznl, bzl)} will be 
-called as \samp{f(bx, by, bznl, bzl)}.
-On entry, the arguments contain the righthand sides.  On exit, they
-should be replaced by the solution. 
-
-\item Called with no arguments, \code{\function{F}()} returns a tuple
-(\var{m}, \var{x0}), where \var{m} is the number of nonlinear 
-inequality constraints) and \var{x0} is a point in the domain
-of {\it f}).
-
-Called with one argument, \function{F(\var{x})} returns a tuple 
-(\var{f}, \var{Df}).  \var{f} is a dense matrix of size ({\it m}+1,1)
-with the function values of the objective function and the 
-nonlinear constraint functions at \var{x}.
-\var{Df} is a dense or sparse real matrix of size (\var{m}+1,\var{n}) 
-with \code{\var{Df}[\var{k},:]} equal to the transpose of the gradient
-of {\it f\_k} at {\it x}.
-Alternatively, \var{Df} can be given as a function.  In that case
-the function call \function{Df}(\var{u},\var{v}), 
-where \var{u} and \var{v} are dense column vectors, should evaluate
-\[
-  v :=  \sum_{k=0}^m u_k \nabla f_k(x) + v.
-\]
-
-If \var{x} is not in the domain of {\it f}, \function{F}(\var{x})
-returns \None\ or (\None,\None).
-
-\item 
-\function{G}(\var{x}, \var{y}\optional{, 
-\var{alpha}=1.0\optional{, \var{beta}=0.0\optional{, 
-\var{trans}=\code{'N'}}}}) evaluates the matrix-vector products
-\[
-y := \alpha G x + \beta y \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
-y := \alpha G^T x + \beta y \quad (\mathrm{trans} = \mathrm{'T'}).
-\]
-Alternatively, \var{G} can be specified as a real sparse or dense 
-matrix. 
-
-\item \function{A}(\var{x}, \var{y}\optional{, 
-\var{alpha}=1.0\optional{, \var{beta}=0.0\optional{, 
-\var{trans}=\code{'N'}}}})  evaluates the matrix vector products 
-\[
-y := \alpha Ax + \beta y \quad 
-  (\mathrm{trans} = \mathrm{'N'}), \qquad
-y := \alpha A^Tx + \beta y \quad 
- (\mathrm{trans} = \mathrm{'T'}).
-\]
-Alternatively, \var{A} can be specified as a real sparse or dense 
-matrix. 
-\end{itemize}
+By default, the functions \function{cp()} and \function{cpl()} do not
+exploit problem structure.
+Two mechanisms are provided for implementing customized solvers that 
+take advantage of problem structure.
+
+\begin{description}
+\item[\emph{Providing a function for solving KKT equations.}]
+The most expensive step of each iteration of \function{cp()} is the
+solution of a set of linear equations (`KKT equations') of the form
+\BEQ \label{e-cp-kkt}
+ \left[\begin{array}{ccc}
+  H & A^T & \tilde G^T \\
+  A & 0   & 0  \\
+  \tilde G & 0   & -W^T W \end{array}\right]
+ \left[\begin{array}{c} u_x \\ u_y \\ u_z \end{array}\right]
+ = \left[\begin{array}{c} b_x \\ b_y \\ b_z \end{array}\right],
+\EEQ
+where 
+\[
+ H = \sum_{k=0}^m z_k \nabla^2f_k(x), \qquad
+ \tilde G = \left[\begin{array}{cccc}
+ \nabla f_1(x) & \cdots & \nabla f_m(x) & G^T \end{array}\right]^T.
+\]
+
+The matrix $W$ depends on the current iterates and is defined as follows.
+Suppose 
+\[
+ u = \left(u_\mathrm{nl}, \; u_\mathrm{l}, \; u_{\mathrm{q},0}, \; 
+  \ldots, \; 
+ u_{\mathrm{q},M-1}, \; \svec{(u_{\mathrm{s},0})}, \; \ldots, \; 
+  \svec{(u_{\mathrm{s},N-1})}\right), \qquad
+ u_\mathrm{l} \in\reals^l, \qquad 
+ u_{\mathrm{q},k} \in\reals^{q_k}, \quad k = 0,\ldots,M-1, \qquad 
+ u_{\mathrm{s},k} \in\symm^{p_k},  \quad k = 0,\ldots,N-1.
+\]
+Then $W$ is a block-diagonal matrix, 
+\[
+ Wu = \left( W_\mathrm{nl} u_\mathrm{nl}, \; 
+ W_\mathrm{l} u_\mathrm{l}, \;
+ W_{\mathrm{q},0} u_{\mathrm{q},0}, \; \ldots, \;
+ W_{\mathrm{q},M-1} u_{\mathrm{q},M-1},\; 
+ W_{\mathrm{s},0} \svec{(u_{\mathrm{s},0})}, \; \ldots, \;
+ W_{\mathrm{s},N-1} \svec{(u_{\mathrm{s},N-1})} \right)
+\]
+with the following diagonal blocks.
+\BIT
+\item The first block is a \emph{positive diagonal scaling} with a 
+ vector $d_{\mathrm{nl}}$:
+\[
+  W_\mathrm{nl} = \diag(d_\mathrm{nl}), 
+ \qquad W_\mathrm{nl}^{-1} = \diag(d_\mathrm{nl})^{-1}.
+\]
+This transformation is symmetric:
+\[
+  W_\mathrm{nl}^T = W_\mathrm{nl}. 
+\]
+
+\item The second block is a \emph{positive diagonal scaling} with a 
+ vector $d_{\mathrm{l}}$:
+\[
+  W_\mathrm{l} = \diag(d_\mathrm{l}), 
+ \qquad W_\mathrm{l}^{-1} = \diag(d_\mathrm{l})^{-1}.
+\]
+This transformation is symmetric:
+\[
+  W_\mathrm{l}^T = W_\mathrm{l}. 
+\]
+
+\item The next $M$ blocks are positive multiples of \emph{hyperbolic 
+ Householder transformations}:
+\[
+  W_{\mathrm{q},k} = \beta_k ( 2 v_k v_k^T - J),
+ \qquad
+  W_{\mathrm{q},k}^{-1} = \frac{1}{\beta_k} ( 2 Jv_k v_k^T J - J),
+ \qquad k = 0,\ldots,M-1,
+\]
+where
+\[
+ \beta_k > 0, \qquad v_{k0} > 0, \qquad 
+ v_k^T Jv_k = 1, \qquad J = \left[\begin{array}{cc}
+   1 & 0 \\ 0 & -I \end{array}\right].
+\]
+These transformations are also symmetric:
+\[
+  W_{\mathrm{q},k}^T = W_{\mathrm{q},k}. 
+\]
+
+\item The last $N$ blocks are \emph{congruence transformations} with 
+ nonsingular matrices:
+\[
+  W_{\mathrm{s},k} \svec{(u_{\mathrm{s},k})} = 
+  \svec{(r_k^T u_{\mathrm{s},k} r_k)}, \qquad
+  W_{\mathrm{s},k}^{-1} \svec{(u_{\mathrm{s},k})} = 
+ \svec{(r_k^{-T} u_{\mathrm{s},k} r_k^{-1})}, \qquad
+ k = 0,\ldots,N-1.
+\]
+In  general, this operation is not symmetric, and
+\[
+  W_{\mathrm{s},k}^T \svec{(u_{\mathrm{s},k})} = 
+  \svec{(r_k u_{\mathrm{s},k} r_k^T)}, \qquad
+ \qquad
+  W_{\mathrm{s},k}^{-T} \svec{(u_{\mathrm{s},k})} = 
+ \svec{(r_k^{-1} u_{\mathrm{s},k} r_k^{-T})}, \qquad
+ \qquad
+ k = 0,\ldots,N-1.
+\]
+\EIT
+It is often possible to exploit problem structure
+to solve~(\ref{e-cp-kkt}) faster than by 
+standard methods.  The last argument \var{kktsolver} of 
+\function{cp()} allows the user to supply a Python  function for 
+solving the KKT equations.
+This function will be called as \samp{f = kktsolver(x, z, W)}. 
+The argument \var{x} is the point at which the derivatives in the
+KKT matrix are evaluated.  \var{z} is a positive vector of 
+length it $m + 1$, containing the coefficients in the 1,1 block $H$.
+\var{W} is a dictionary that contains the parameters of the scaling:
+
+\BIT
+\item \code{W['dnl']} is the positive vector that defines the diagonal
+ scaling for the nonlinear inequalities.   
+ \code{W['dnli']} is its componentwise inverse.
+\item \code{W['dl']} is the positive vector that defines the diagonal
+ scaling for the componentwise linear inequalities.   
+ \code{W['dli']} is its componentwise inverse.
+\item \code{W['beta']} and \code{W['v']} are lists of length $M$ with 
+ the coefficients and vectors that define the hyperbolic Householder 
+ transformations.
+\item \code{W['r']} is a list of length $N$ with the matrices that
+ define the the congruence transformations.  
+ \code{W['rti']} is  a list of length $N$ with the transposes of the 
+ inverses of the matrices in \code{W['r']}.
+\EIT
+
+The function call \samp{f = kktsolver(x, z, W)} should return a routine
+for solving the KKT system~(\ref{e-cp-kkt}) defined by \var{x}, \var{z}, 
+\var{W}.
+It will be called as \samp{f(bx, by, bz)}.
+On entry, \var{bx}, \var{by}, \var{bz} contain the righthand side.  
+On exit, they should contain the solution of the KKT system, with 
+the last component scaled, \ie, on exit,
+\[
+  b_x := u_x, \qquad b_y := u_y, \qquad b_z := W u_z.
+\]
+
+The role of the argument \var{kktsolver} in the function \function{cpl()}
+is similar, except that in~(\ref{e-cp-kkt}),
+\[
+ H = \sum_{k=0}^{m-1} z_k \nabla^2f_k(x), \qquad
+ \tilde G = \left[\begin{array}{cccc}
+ \nabla f_0(x) & \cdots & \nabla f_{m-1}(x) & G^T \end{array}\right]^T.
+\]
+
+\item[\emph{Specifying constraints via Python functions}.]
+In the default use of \function{cp()}, the arguments \var{G} and 
+\var{A} are the coefficient matrices in the constraints 
+of~(\ref{e-cp-kkt}).
+It is also possible to specify these matrices by providing Python 
+functions that evaluate the corresponding matrix-vector products and 
+their adjoints.
+
+If the argument \var{G} of \function{conelp()} is a Python
+function, it should be defined as follows:
+\begin{funcdesc}{\var{G}}{\var{u}, \var{v} \optional{, 
+\var{alpha}\optional{, \var{beta}\optional{, \var{trans}}}}} 
+This evaluates the matrix-vector products
+\[
+v := \alpha Gu + \beta v \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
+v := \alpha G^T u + \beta v \quad (\mathrm{trans} = \mathrm{'T'}).
+\]
+The default values of the optional arguments must be
+\code{alpha = 1.0}, \code{beta = 0.0}, \code{trans = 'N'}.
 \end{funcdesc}
 
+Similarly, if the argument \var{A} is a Python function, then it must
+be defined as follows.
+\begin{funcdesc}{\var{A}}{\var{u}, \var{v} \optional{, 
+\var{alpha}\optional{, \var{beta}\optional{, \var{trans}}}}} 
+This evaluates the matrix-vector products
+\[
+v := \alpha Au + \beta v \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
+v := \alpha A^T u + \beta v \quad (\mathrm{trans} = \mathrm{'T'}).
+\]
+The default values of the optional arguments must be
+\code{alpha = 1.0}, \code{beta = 0.0}, \code{trans = 'N'}.
+\end{funcdesc}
+
+In a similar way, when the first argument \var{F()} of \function{cp()}
+returns matrices of first derivatives or second derivatives 
+\var{Df}, \var{H}, these matrices can be specified as Python functions.
+If \var{Df} is a Python function, it should be defined as follows:
+\begin{funcdesc}{\var{Df}}{\var{u}, \var{v} \optional{, 
+\var{alpha}\optional{, \var{beta}\optional{, \var{trans}}}}} 
+This evaluates the matrix-vector products
+\[
+v := \alpha Df(x) u + \beta v \quad (\mathrm{trans} = \mathrm{'N'}), \qquad
+v := \alpha Df(x)^T u + \beta v \quad (\mathrm{trans} = \mathrm{'T'}).
+\]
+The default values of the optional arguments must be
+\code{alpha = 1.0}, \code{beta = 0.0}, \code{trans = 'N'}.
+\end{funcdesc}
+
+If \var{H} is a Python function, it should be defined as follows:
+\begin{funcdesc}{\var{H}}{\var{u}, \var{v} \optional{, 
+\var{alpha}\optional{, \var{beta}}}} 
+This evaluates the matrix-vector product
+\[
+v := \alpha H u + \beta v.
+\]
+The default values of the optional arguments must be
+\code{alpha = 1.0}, \code{beta = 0.0}, \code{trans = 'N'}.
+\end{funcdesc}
+
+If \var{G}, \var{A}, \var{Df}, or \var{H} are Python functions, then 
+the argument \var{kktsolver} must also be provided.
+\end{description}
+
 As an example, we consider the 1-norm regularized least-squares problem
 \[
 \begin{array}{ll}
@@ -679,11 +987,11 @@ program
  \mbox{subject to} & -u \preceq x \preceq u
  \end{array}
 \]
-with variables {\it x} and {\it u}.  The implementation below is 
-efficient when {\it A} has many more columns than rows. 
+with variables $x$ and $u$.  The implementation below is 
+efficient when $A$ has many more columns than rows. 
 
 \begin{verbatim}
-from cvxopt.base import matrix, spmatrix, mul, div
+from cvxopt.base import matrix, spdiag, mul, div
 from cvxopt import blas, lapack, solvers
 
 m, n = A.size
@@ -691,7 +999,7 @@ def F(x=None):
     """
     Function and gradient evaluation of
 
-	f = || A*x[:n] - y ||_2^2 +  sum(x[n:])
+        f = || A*x[:n] - y ||_2^2 +  sum(x[n:])
     """
 
     nvars = 2*n
@@ -700,12 +1008,25 @@ def F(x=None):
     f = blas.nrm2(r)**2 + sum(x[n:])
     gradf = matrix(1.0, (1,2*n))
     blas.gemv(A, r, gradf, alpha=2.0, trans='T')  
-    return f, +gradf
+    if z is None:
+        return f, gradf
+    else:
+        def Hf(u, v, alpha = 1.0, beta = 0.0):
+            # A function that evaluates 
+            #
+            #     v := alpha * [2.0 * z[0] * A'*A, 0; 0, 0] * u + beta * v
+            #
+            blas.scal(beta, v)
+            w = matrix(0.0, (m, 1))
+            blas.gemv(A, u, w)
+            blas.gemv(A, w, v, alpha = 2.0 * z[0] * alpha, beta = 1.0, trans = 'T')
+        return f, gradf, Hf
+
 
 
 def G(u, v, alpha=1.0, beta=0.0, trans='N'):
     """
-	v := alpha*[I, -I; -I, -I] * u + beta * v  (trans = 'N' or 'T')
+        v := alpha*[I, -I; -I, -I] * u + beta * v  (trans = 'N' or 'T')
     """
 
     v *= beta
@@ -722,6 +1043,7 @@ h = matrix(0.0, (2*n,1))
 #     [  I             -I   -D1^-1   0     ] [zl[:n]]     [bzl[:n]]
 #     [ -I             -I    0      -D2^-1 ] [zl[n:]]     [bzl[n:]]
 #
+# where D1 = W['dli'][:n]**2, D2 = W['dli'][n:]**2, 
 #    
 # We first eliminate zl and x[n:]:
 #
@@ -749,7 +1071,7 @@ h = matrix(0.0, (2*n,1))
 S = matrix(0.0, (m,m))
 Asc = matrix(0.0, (m,n))
 v = matrix(0.0, (m,1))
-def kktsolver(x, z, dnl, dl):
+def Fkkt(x, z, W):
 
     # Factor 
     #
@@ -757,29 +1079,29 @@ def kktsolver(x, z, dnl, dl):
     #
     # where D = 2*D1*D2*(D1+D2)^-1, D1 = dl[:n]**2, D2 = dl[n:]**2.
 
-    d1, d2 = dl[:n]**2, dl[n:]**2    # d1 = diag(D1), d2 = diag(D2)
+    d1, d2 = W['dli'][:n]**2, W['dli'][n:]**2   # d1 = diag(D1), d2 = diag(D2)
     # ds is square root of diagonal of D
     ds = sqrt(2.0) * div( mul(dl[:n], dl[n:]), sqrt(d1+d2) )
     d3 =  div(d2 - d1, d1 + d2)
  
     # Asc = A*diag(d)^-1/2
-    Asc = A * spmatrix( ds**-1, range(n), range(n))
+    Asc = A * spdiag(ds**-1)
 
     # S = 1/z[0]*I + A * D^-1 * A'
     blas.syrk(Asc, S)
     S[::m+1] += 1.0 / z[0] 
     lapack.potrf(S)
 
-    def g(x, y, znl, zl):
+    def g(x, y, z):
 
-        x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + mul(d1, zl[:n] + mul(d3, zl[:n])) - mul(d2, zl[n:] - mul(d3, zl[n:])) )
+        x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + mul(d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - mul(d3, z[n:])) )
         x[:n] = div( x[:n], ds) 
 
         # Solve
         #
         #     S * v = 0.5 * A * D^-1 * ( bx[:n] - (D2-D1)*(D1+D2)^-1 * bx[n:] 
-        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] )
-	    
+        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n] - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] )
+	  
         blas.gemv(Asc, x, v)
         lapack.potrs(S, v)
 	
@@ -787,21 +1109,21 @@ def kktsolver(x, z, dnl, dl):
         blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
         x[:n] = div(x[:n], ds)
 
-        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] ) - (D2-D1)*(D1+D2)^-1 * x[:n]         
-        x[n:] = div( x[n:] - mul(d1, zl[:n]) - mul(d2, zl[n:]), d1+d2 ) - mul( d3, x[:n] )
+        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n]  - D2*bz[n:] ) - (D2-D1)*(D1+D2)^-1 * x[:n]         
+        x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 ) - mul( d3, x[:n] )
 	    
-        # zl[:n] = D1 * (  x[:n] - x[n:] - bzl[:n] )
-        # zl[n:] = D2 * ( -x[:n] - x[n:] - bzl[n:] ).
-        zl[:n] = mul( d1,  x[:n] - x[n:] - zl[:n] ) 
-        zl[n:] = mul( d2, -x[:n] - x[n:] - zl[n:] ) 
+        # z[:n] = D1^1/2 * (  x[:n] - x[n:] - bz[:n] )
+        # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ).
+        z[:n] = mul( W['dli'][:n],  x[:n] - x[n:] - z[:n] )
+        z[n:] = mul( W['dli'][n:], -x[:n] - x[n:] - z[n:] )
 
     return g
 
-x = solvers.nlcp(kktsolver, F, G, h)['x'][:n]
+x = solvers.cp(F, G, h, kktsolver = Fkkt)['x'][:n]
 \end{verbatim}
 
 
-\section{Algorithm Parameters} \label{s-parameters}
+\section{Algorithm Parameters} \label{s-parameters2}
 The following algorithm control parameters are accessible via the 
 dictionary \member{solvers.options}.  By default the dictionary 
 is empty and the default values of the parameters are used.
@@ -814,7 +1136,7 @@ adding entries with the following key values.
 (default: \True).
 \item[\code{'maxiters'}] maximum number of iterations (default: 100).
 \item[\code{'abstol'}] absolute accuracy (default: \code{1e-7}).
-\item[\code{'reltol'}] relative accuracy (default: \code{1e-7}).
+\item[\code{'reltol'}] relative accuracy (default: \code{1e-6}).
 \item[\code{'feastol'}] tolerance for feasibility conditions (default:
 \code{1e-7}).
 \end{description}
@@ -827,23 +1149,23 @@ turns off the screen output during calls to the solvers.
 The tolerances \var{abstol}, \var{reltol} and \var{feastol} have the
 following meaning in \function{nlcp()}. 
 
-\function{nlcp()} returns with status \code{'optimal'} if
+\function{cpl()} returns with status \code{'optimal'} if
 \[
-\frac{\| \nabla f_0(x) +  D\tilde f(x)^Tz_\mathrm{nl} + 
+\frac{\| c +  Df(x)^Tz_\mathrm{nl} + 
  G^Tz_\mathrm{l} + A^T y \|_2 }
 {\max\{ 1, 
-\| \nabla f_0(x_0) + D\tilde f(x_0)^T\ones + G^T\ones \|_2 \}} 
+\| c + Df(x_0)^T\ones + G^T\ones \|_2 \}} 
 \leq \epsilon_\mathrm{feas}, \qquad
-\frac{\| ( \tilde f(x) + s_{\mathrm{nl}},  Gx + s_\mathrm{l} - h, 
+\frac{\| ( f(x) + s_{\mathrm{nl}},  Gx + s_\mathrm{l} - h, 
  Ax-b ) \|_2} 
-{\max\{1, \| ( \tilde f(x_0) + \ones,  
+{\max\{1, \| ( f(x_0) + \ones,  
 Gx_0 + \ones-h, Ax_0-b) \|_2 \}} \leq \epsilon_\mathrm{feas}  
 \]
-where {\it x0} is the point returned by \code{F()}, and
+where $x_0$ is the point returned by \code{F()}, and
 \[
 \mathrm{gap} \leq \epsilon_\mathrm{abs}
-\qquad \mbox{or} \qquad \left( f_0(x) < 0, \quad
-\frac{\mathrm{gap}} {-f_0(x)} \leq \epsilon_\mathrm{rel} \right)
+\qquad \mbox{or} \qquad \left( c^Tx < 0, \quad
+\frac{\mathrm{gap}} {-c^Tx} \leq \epsilon_\mathrm{rel} \right)
 \qquad \mbox{or} \qquad
 \left( L(x,y,z) > 0, \quad \frac{\mathrm{gap}}
 {L(x,y,z)} \leq \epsilon_\mathrm{rel} \right)
@@ -856,20 +1178,25 @@ where
 \left[\begin{array}{c} z_\mathrm{nl} \\ z_\mathrm{l} 
 \end{array}\right],
 \qquad
-L(x,y,z) = f_0(x) + z_\mathrm{nl}^T \tilde f(x) + 
- z_\mathrm{l}^T (Gx-h) + y^T(Ax-b).
+L(x,y,z) = c^Tx + z_\mathrm{nl}^T f(x) + z_\mathrm{l}^T (Gx-h) + y^T(Ax-b).
 \]
-The functions \function{qp()}, \function{gp()} and \function{cp()}
-call \function{nlcp()} and hence use the same stopping criteria
-(with {\it x0}=0 for \function{qp()} and \function{gp()}).
+The functions \function{cp()}, \function{qp()}, and \function{gp()} 
+call \function{cpl()} and hence use the same stopping criteria
+(with $x_0=0$ for \function{qp()} and \function{gp()}).
+
+The MOSEK interior-point algorithm parameters are set to their default 
+values.  They can be modified by adding an entry 
+\code{solvers.options['MOSEK']}.  This entry is a dictionary with 
+MOSEK parameter/value pairs, with the parameter names imported from
+\module{pymosek}.  For details see Section 14.1.3 of the 
+\ulink{MOSEK Python API Manual}{http://www.mosek.com/fileadmin/products/5_0/tools/doc/html/pyapi/index.html}.
+
 
-The MOSEK \ulink{control parameters}{http://www.mosek.com/fileadmin/products/3/tools/doc/html/tools/node22.html}
-are set to their default values.
-The corresponding keys in \code{solvers.options} are strings with the 
-name of the MOSEK parameter.  For example the command
+For example the commands
 \begin{verbatim}
 >>> from cvxopt import solvers 
->>> solvers.options['MSK_IPAR_LOG'] = 0
+>>> import pymosek
+>>> solvers.options['MOSEK'] = {pymosek.iparam.log: 0}
 \end{verbatim}
-turns off the screen output during calls of \function{qp()} with the 
-\code{'mosek'} option.
+turn off the screen output during calls of  \function{qp()} 
+with the \code{'mosek'} option.
diff --git a/doc/spsolvers.tex b/doc/spsolvers.tex
index 827998a..682c4dd 100644
--- a/doc/spsolvers.tex
+++ b/doc/spsolvers.tex
@@ -3,7 +3,7 @@ In this section we describe routines for solving sparse sets of linear
 equations.
 
 A real symmetric or complex Hermitian sparse matrix is stored as
-an \spmtrx\ object \var{X}  of size ({\it n}, {\it n}) and an 
+an \spmtrx\ object \var{X}  of size ($n$, $n$) and an 
 additional character argument \code{uplo} with possible values 
 \code{'L'} and \code{'U'}.  
 If \code{uplo} is \code{'L'}, the lower triangular part
@@ -14,8 +14,8 @@ If \code{uplo} is \code{'U'}, the upper triangular part
 of \var{X} contains the upper triangular part of the
 matrix, and the lower triangular matrix of \var{X} is ignored.
 
-A general sparse square matrix of order {\it n} is represented by an
-\spmtrx\ object of size ({\it n}, {\it n}).
+A general sparse square matrix of order $n$ is represented by an
+\spmtrx\ object of size ($n$, $n$).
 
 Dense matrices, which appear as righthand sides of equations, are 
 stored using the same conventions as in the BLAS and LAPACK modules.
@@ -25,17 +25,18 @@ stored using the same conventions as in the BLAS and LAPACK modules.
 CVXOPT includes an interface to the AMD library for computing 
 approximate minimum degree orderings of sparse matrices.
 
-\begin{seealso}
-\seelink{http://www.cise.ufl.edu/research/sparse/amd}{AMD code, 
+\textbf{See also:}
+\BIT
+\item \seelink{http://www.cise.ufl.edu/research/sparse/amd}{AMD code, 
 documentation, copyright and license.}{}
-\seetext{P.\ R.\ Amestoy, T.\ A.\ Davis, I.\ S.\ Duff,
+\item \seetext{P.\ R.\ Amestoy, T.\ A.\ Davis, I.\ S.\ Duff,
 Algorithm 837: AMD, An Approximate Minimum Degree Ordering Algorithm,
 ACM Transactions on Mathematical Software, 30(3), 381-388, 2004.}
-\end{seealso}
+\EIT
 
 \begin{funcdesc}{order}{A\optional{, uplo='L'}}
 Computes the approximate mimimum degree ordering of a symmetric  sparse
-matrix {\it A}.  
+matrix $A$.  
 The ordering is returned as an integer dense matrix with length equal 
 to the order of \var{A}.  Its entries specify a permutation that 
 reduces fill-in during the Cholesky factorization.
@@ -72,13 +73,14 @@ sparse non-symmetric sets of linear equations.
 They call routines from the UMFPACK library, with all control options 
 set to the default values described in the UMFPACK user guide.  
 
-\begin{seealso}
-\seelink{http://www.cise.ufl.edu/research/sparse/umfpack}{UMFPACK code, documentation, copyright and license.}{}
-\seetext{T.\ A.\ Davis,
+\textbf{See also:}
+\BIT
+\item \seelink{http://www.cise.ufl.edu/research/sparse/umfpack}{UMFPACK code, documentation, copyright and license.}{}
+\item \seetext{T.\ A.\ Davis,
 Algorithm 832: UMFPACK -- an unsymmetric-pattern multifrontal method 
 with a column pre-ordering strategy,
 ACM Transactions on Mathematical Software, 30(2), 196-199, 2004.}
-\end{seealso}
+\EIT
 
 \begin{funcdesc}{linsolve}{A, B\optional{, trans='N'}}
 Solves a sparse set of linear equations 
@@ -163,7 +165,7 @@ coefficients.
 The numerical factorization on the other hand depends on the sparsity 
 pattern of the matrix and on its the numerical values.
 
-As an example, suppose {\it A} is the matrix~(\ref{e-sp-Adef}) and 
+As an example, suppose $A$ is the matrix~(\ref{e-sp-Adef}) and 
 \[
 B = \left[\begin{array}{rrrrr}
  4 & 3 & 0 & 0 & 0 \\
@@ -173,7 +175,7 @@ B = \left[\begin{array}{rrrrr}
  0 & 4 & 2 & 0 & 2 
  \end{array}\right],
 \]
-which differs from {\it A} in its first and last entries.
+which differs from $A$ in its first and last entries.
 The following code computes
 \[
  x = A^{-T}B^{-1}A^{-1}\ones.
@@ -215,10 +217,8 @@ The routines can also be used for computing {LDL$\mathrm{{}^T}$}
 (with L unit lower-triangular and D diagonal and nonsingular) if 
 such a factorization exists.  
 
-\begin{seealso}
+\textbf{See also:}
 \seelink{http://www.cise.ufl.edu/research/sparse/cholmod}{CHOLMOD code, documentation, copyright and license.}{}
-\end{seealso}
-
 
 \begin{funcdesc}{linsolve}{A, B\optional{, p=\None\optional{, 
 uplo='L'}}}
@@ -226,7 +226,7 @@ Solves
 \[
  AX = B 
 \]
-with {\it A} sparse and real symmetric or complex Hermitian.
+with $A$ sparse and real symmetric or complex Hermitian.
 \var{B} is a dense matrix of the same type as \var{A}.  On exit it 
 is overwritten with the solution.
 The argument \var{p} is an integer matrix with length equal to the 
@@ -297,9 +297,9 @@ and
 \BEQ \label{e-chol-ldl}
    PAP^T = LDL^T, \qquad PAP^T = LDL^H,
 \EEQ
-where {\it P} is a permutation matrix, {\it L} is lower triangular 
+where $P$ is a permutation matrix, $L$ is lower triangular 
 (unit lower triangular in the second factorization), and 
-{\it D} is nonsingular diagonal.  The type of factorization depends 
+$D$ is nonsingular diagonal.  The type of factorization depends 
 on the value of \code{options['supernodal']} (see below).
 
 If \var{uplo} is \code{'L'}, only the lower triangular part of \var{A} 
@@ -341,16 +341,22 @@ factorization~(\ref{e-chol-ll}) or~(\ref{e-chol-ldl}) computed by
 \var{sys} is an integer with values between 0 and 8. 
 
 \begin{center}
-\begin{tabular}{c|c|} 
+\begin{tabular}{c|c|} \hline
  \var{sys} & equation \\ \hline
- 0 & $AX=B$     \\ 1 & $LDL^TX=B$ \\ 2 & $LDLX=B$   \\ 
- 3 & $DL^TX=B$  \\ 4 & $LX=B$     \\ 5 & $L^TX=B$  \\
- 6 & $DX=B$     \\ 7 & $P^TX=B$   \\ 8 & $PX=B$    
+ 0 & $AX=B$     \\ \hline 
+ 1 & $LDL^TX=B$ \\ \hline 
+ 2 & $LDLX=B$   \\ \hline
+ 3 & $DL^TX=B$  \\ \hline
+ 4 & $LX=B$     \\ \hline 
+ 5 & $L^TX=B$   \\ \hline
+ 6 & $DX=B$     \\ \hline 
+ 7 & $P^TX=B$   \\ \hline 
+ 8 & $PX=B$  \\ \hline  
 \end{tabular}
 \end{center}
 
 (If \var{F} is a Cholesky factorization of the form~(\ref{e-chol-ll}), 
-{\it D} is an identity matrix in this table. 
+$D$ is an identity matrix in this table. 
 If \var{A} is complex, $L^T$ should be replaced by $L^H$.)
 
 The matrix \var{B} is a dense \dtc\ or \ztc\ matrix, with the same type
@@ -377,10 +383,10 @@ For the same example as above:
 \end{verbatim}
 
 \begin{funcdesc}{diag}{F}
-Returns the diagonal elements of the Cholesky factor {\it L} 
+Returns the diagonal elements of the Cholesky factor $L$ 
 in~(\ref{e-chol-ll}), as a dense matrix of the same type as \var{A}.
 Note that this only applies to Cholesky factorizations.
-The matrix {\it D} in an LDL$\mathrm{{}^T}$ factorization can be 
+The matrix $D$ in an LDL$\mathrm{{}^T}$ factorization can be 
 retrieved via \function{cholmod.solve()} with \var{sys} equal to 6.
 \end{funcdesc}
 
@@ -437,7 +443,7 @@ factorization.  We consider the problem
  \mbox{subject to} & K_{ij}=0,\quad (i,j) \not \in S.
  \end{array}
 \EEQ
-The optimization variable is a symmetric matrix {\it K} of order {\it n}
+The optimization variable is a symmetric matrix $K$ of order $n$
 and the domain of the problem is the set of positive definite matrices.
 The matrix $Y$ and the index set  $S$ are given.  We assume that all 
 the diagonal positions are included in $S$.
@@ -445,12 +451,12 @@ This problem arises in maximum likelihood estimation of the covariance
 matrix of a zero-mean normal distribution, with constraints 
 that specify that pairs of variables are conditionally independent.
 
-We can express {\it K} as
+We can express $K$ as
 \[
    K(x) = E_1\diag(x)E_2^T+E_2\diag(x)E_1^T
 \]
-where {\it x} are the nonzero elements in the lower triangular part
-of {\it K}, with the diagonal elements scaled by 1/2,
+where $x$ are the nonzero elements in the lower triangular part
+of $K$, with the diagonal elements scaled by 1/2,
 and
 \[
  E_1 = \left[ \begin{array}{cccc}
@@ -458,8 +464,8 @@ and
  E_2 = \left[ \begin{array}{cccc}
   e_{j_1} & e_{j_2} & \cdots & e_{j_q} \end{array}\right], 
 \]
-where ({\it i\_k}, {\it j\_k}) are the positions of the nonzero 
-entries in the lower-triangular part of {\it K}.
+where ($i_k$, $j_k$) are the positions of the nonzero 
+entries in the lower-triangular part of $K$.
 With this notation, we can solve problem~(\ref{e-covsel}) by solving
 the unconstrained problem
 \[
diff --git a/examples/book/README b/examples/book/README
index 9068854..a862c04 100644
--- a/examples/book/README
+++ b/examples/book/README
@@ -4,4 +4,4 @@ www.stanford.edu/~boyd/cvxbook).
 
 The scripts require the plotting library Matplotlib, available at
 matplotlib.sourceforge.net.  They were tested with Matplotlib 
-version 0.87.7-0.3.
+version 0.90.1.
diff --git a/examples/book/chap4/portfolio b/examples/book/chap4/portfolio
index 7d0046d..3cc4859 100755
--- a/examples/book/chap4/portfolio
+++ b/examples/book/chap4/portfolio
@@ -42,10 +42,10 @@ 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], '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1 , '#D0D0D0') 
-pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3,  '#D0D0D0') 
+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')
diff --git a/examples/book/chap4/rls b/examples/book/chap4/rls
index b9a1e35..6ef3173 100755
--- a/examples/book/chap4/rls
+++ b/examples/book/chap4/rls
@@ -70,7 +70,7 @@ pylab.plot( [ blas.nrm2(b)**2 ] + lbnds[:kmax] +
 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]], '#D0D0D0')
+    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')
diff --git a/examples/book/chap6/basispursuit b/examples/book/chap6/basispursuit
index ee686ae..b6b2a48 100755
--- a/examples/book/chap6/basispursuit
+++ b/examples/book/chap6/basispursuit
@@ -60,7 +60,6 @@ pylab.xlabel('t')
 # Signal.
 y = mul( 1.0 + 0.5 * sin(11*ts), sin(30 * sin(5*ts)))
 
-
 # Basis pursuit problem
 #
 #     minimize    ||A*x - y||_2^2 + ||x||_1
@@ -73,8 +72,9 @@ y = mul( 1.0 + 0.5 * sin(11*ts), sin(30 * sin(5*ts)))
 m, n = A.size
 r = matrix(0.0, (m,1))
 gradf = matrix(1.0, (1,2*n))
+w = matrix(0.0, (m, 1))
 
-def F(x=None):
+def F(x = None, z = None):
     """
     Function and gradient evaluation of
 
@@ -82,24 +82,34 @@ def F(x=None):
     """
 
     nvars = 2*n
-    if x is None: return 0, matrix(0.0, (nvars,1))
+    if x is None: 
+        return 0, matrix(0.0, (nvars,1))
     blas.copy(y, r)
     blas.gemv(A, x, r, beta=-1.0)      # r = A*x[:n] - y
     f = blas.nrm2(r)**2 + blas.asum(x, offset=n)
-    blas.gemv(A, r, gradf, alpha=2.0, trans='T')  #gradf = [2*A'*r; 1.0]
-    return f, +gradf
-
-
-def G(u, v, alpha=1.0, beta=0.0, trans='N'):
+    blas.gemv(A, r, gradf, alpha = 2.0, trans = 'T') # gradf = [2*A'*r; 1.0]
+    if z is None:
+        return f, +gradf
+    else:
+        def H(u, v, alpha = 1.0, beta = 0.0):
+            # u := alpha * [2.0 * z[0] * A'*A, 0; 0, 0] * u + beta * v 
+            blas.scal(beta, v)
+            blas.gemv(A, u, w)
+            blas.gemv(A, w, v, alpha = 2.0 * z[0] * alpha, beta = 1.0, 
+                trans = 'T')
+        return f, +gradf, H
+        
+
+def G(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
     """
 	v := alpha*[I, -I; -I, -I] * u + beta * v  (trans = 'N' or 'T')
     """
 
     blas.scal(beta, v) 
-    blas.axpy(u, v, n=n) 
-    blas.axpy(u, v, n=n, alpha=-1.0, offsetx=n) 
-    blas.axpy(u, v, n=n, alpha=-1.0, offsety=n) 
-    blas.axpy(u, v, n=n, alpha=-1.0, offsetx=n, offsety=n) 
+    blas.axpy(u, v, n = n, alpha = alpha) 
+    blas.axpy(u, v, n = n, alpha = -alpha, offsetx = n) 
+    blas.axpy(u, v, n = n, alpha = -alpha, offsety = n) 
+    blas.axpy(u, v, n = n, alpha = -alpha, offsetx = n, offsety = n) 
 
 h = matrix(0.0, (2*n,1))
 
@@ -108,22 +118,23 @@ h = matrix(0.0, (2*n,1))
 #
 #     [  2.0*z[0]*A'*A  0    I      -I     ] [x[:n] ]     [bx[:n] ]
 #     [  0              0   -I      -I     ] [x[n:] ]  =  [bx[n:] ].
-#     [  I             -I   -D1^-1   0     ] [zl[:n]]     [bzl[:n]]
-#     [ -I             -I    0      -D2^-1 ] [zl[n:]]     [bzl[n:]]
+#     [  I             -I   -D1^-1   0     ] [z[:n] ]     [bz[:n] ]
+#     [ -I             -I    0      -D2^-1 ] [z[n:] ]     [bz[n:] ]
 #
+# where D1 = W['dli'][:n]**2,  D2 = W['dli'][:n]**2.
 #    
-# We first eliminate zl and x[n:]:
+# We first eliminate z and x[n:]:
 #
 #     ( 2*z[0]*A'*A + 4*D1*D2*(D1+D2)^-1 ) * x[:n] = 
 #         bx[:n] - (D2-D1)*(D1+D2)^-1 * bx[n:] 
-#         + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n]
-#         - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:]           
+#         + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n]
+#         - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:]           
 #
-#     x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] ) 
+#     x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n]  - D2*bz[n:] ) 
 #              - (D2-D1)*(D1+D2)^-1 * x[:n]         
 #
-#     zl[:n] = D1 * ( x[:n] - x[n:] - bzl[:n] )
-#     zl[n:] = D2 * (-x[:n] - x[n:] - bzl[n:] ).
+#     z[:n] = D1 * ( x[:n] - x[n:] - bz[:n] )
+#     z[n:] = D2 * (-x[:n] - x[n:] - bz[n:] ).
 #
 #
 # The first equation has the form
@@ -144,7 +155,7 @@ S = matrix(0.0, (m,m))
 Asc = matrix(0.0, (m,n))
 v = matrix(0.0, (m,1))
 
-def kktsolver(x, z, dnl, dl):
+def Fkkt(x, z, W):
 
     # Factor 
     #
@@ -152,10 +163,10 @@ def kktsolver(x, z, dnl, dl):
     #
     # where D = 2*D1*D2*(D1+D2)^-1, D1 = dl[:n]**2, D2 = dl[n:]**2.
 
-    d1 = dl[:n]**2    # d1 = diag(D1)
-    d2 = dl[n:]**2    # d2 = diag(D2)
+    d1, d2 = W['dli'][:n]**2, W['dli'][n:]**2    
+
     # ds is square root of diagonal of D
-    ds = sqrt(2.0) * div( mul(dl[:n], dl[n:]), sqrt(d1+d2) )
+    ds = sqrt(2.0) * div( mul( W['dli'][:n], W['dli'][n:]), sqrt(d1+d2) )
     d3 =  div(d2 - d1, d1 + d2)
  
     # Asc = A*diag(d)^-1/2
@@ -168,19 +179,19 @@ def kktsolver(x, z, dnl, dl):
     S[::m+1] += 1.0 / z[0] 
     lapack.potrf(S)
 
-    def g(x, y, znl, zl):
+    def g(x, y, z):
 
         x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + \
-                mul(d1, zl[:n] + mul(d3, zl[:n])) - \
-                mul(d2, zl[n:] - mul(d3, zl[n:])) )
+                mul(d1, z[:n] + mul(d3, z[:n])) - \
+                mul(d2, z[n:] - mul(d3, z[n:])) )
         x[:n] = div( x[:n], ds) 
 
         # Solve
         #
         #     S * v = 0.5 * A * D^-1 * ( bx[:n] 
         #             - (D2-D1)*(D1+D2)^-1 * bx[n:] 
-        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n]
-        #             - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] )
+        #             + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n]
+        #             - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] )
 	    
         blas.gemv(Asc, x, v)
         lapack.potrs(S, v)
@@ -189,19 +200,19 @@ def kktsolver(x, z, dnl, dl):
         blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
         x[:n] = div(x[:n], ds)
 
-        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] )
+        # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n]  - D2*bz[n:] )
         #         - (D2-D1)*(D1+D2)^-1 * x[:n]         
-        x[n:] = div( x[n:] - mul(d1, zl[:n]) - mul(d2, zl[n:]), d1+d2 )\
+        x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\
                 - mul( d3, x[:n] )
 	    
-        # zl[:n] = D1 * (  x[:n] - x[n:] - bzl[:n] )
-        # zl[n:] = D2 * ( -x[:n] - x[n:] - bzl[n:] ).
-        zl[:n] = mul( d1,  x[:n] - x[n:] - zl[:n] ) 
-        zl[n:] = mul( d2, -x[:n] - x[n:] - zl[n:] ) 
+        # z[:n] = D1^1/2 * (  x[:n] - x[n:] - bz[:n] )
+        # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ).
+        z[:n] = mul( W['dli'][:n],  x[:n] - x[n:] - z[:n] ) 
+        z[n:] = mul( W['dli'][n:], -x[:n] - x[n:] - z[n:] ) 
 
     return g
 
-x = solvers.nlcp(kktsolver, F, G, h)['x'][:n]
+x = solvers.cp(F, G, h, kktsolver = Fkkt)['x'][:n]
 
 I = [ k for k in xrange(n) if abs(x[k]) > 1e-2 ]
 xls = +y
diff --git a/examples/book/chap6/consumerpref b/examples/book/chap6/consumerpref
index 988f63d..69870c4 100755
--- a/examples/book/chap6/consumerpref
+++ b/examples/book/chap6/consumerpref
@@ -59,13 +59,13 @@ 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)')
+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()
 
diff --git a/examples/book/chap6/old/README b/examples/book/chap6/old/README
deleted file mode 100644
index 7df549e..0000000
--- a/examples/book/chap6/old/README
+++ /dev/null
@@ -1,2 +0,0 @@
-tv and smoothrec use cholmod
-tv_new and smoothrec_new use lapack band solvers
diff --git a/examples/book/chap6/old/smoothrec b/examples/book/chap6/old/smoothrec
deleted file mode 100755
index 18b4b9a..0000000
--- a/examples/book/chap6/old/smoothrec
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python
-
-# Figures 6.8-10, pages 313-314
-# Quadratic smoothing.
-
-from math import pi
-from cvxopt import random, blas, lapack, cholmod
-from cvxopt.base import matrix, spmatrix, sin, mul
-import pylab
-
-n = 4000
-t = matrix(range(n), tc='d')
-ex = 0.5 * mul( sin(2*pi/n * t), sin(0.01 * t))
-corr = ex + 0.05 * random.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')
-
-
-# A = D'*D is an n by n tridiagonal matrix with -1.0 on the 
-# upper/lower diagonal and 1, 2, 2, ..., 2, 2, 1 on the diagonal.
-A = spmatrix( (n-1)*[-1.0] + [1.0] + (n-2)*[2.0] + [1.0],
-    range(1,n) + [0] + range(1,n-1) + [n-1], 
-    range(n-1) + [0] + range(1,n-1) + [n-1]) 
-I = spmatrix(1.0, range(n), range(n))
-F = cholmod.symbolic(A)
-
-nopts = 50
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
-cost1, cost2 = [], []
-for delta in deltas:
-    cholmod.numeric(I + 10**delta * A, F )
-    xr = +corr 
-    cholmod.solve(F, xr)
-    cost1 += [blas.nrm2(xr - corr)] 
-    cost2 += [blas.nrm2(xr[1:] - xr[:-1])] 
-
-# Find solutions with ||xhat - xcorr || roughly equal to 8.0, 3.1, 1.0.
-mv1, k1 = min(zip([abs(c - 8.0) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k1] * A, F )
-xr1 = +corr 
-cholmod.solve(F, xr1)
-mv2, k2 = min(zip([abs(c - 3.1) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k2] * A, F )
-xr2 = +corr 
-cholmod.solve(F, xr2)
-mv3, k3 = min(zip([abs(c - 1.0) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k3] * A, F )
-xr3 = +corr 
-cholmod.solve(F, xr3)
-
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', [cost1[k2]], [cost2[k2]], 'o',
-    [cost1[k3]], [cost2[k3]], 'o')
-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/old/smoothrec_new b/examples/book/chap6/old/smoothrec_new
deleted file mode 100755
index 87a9213..0000000
--- a/examples/book/chap6/old/smoothrec_new
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/python
-
-# Figures 6.8-10, pages 313-314
-# Quadratic smoothing.
-
-### Same as smoothrec, but uses LAPACK solvers for band matrices.
-
-from math import pi
-from cvxopt import random, blas, lapack 
-from cvxopt.base import matrix, spmatrix, sin, mul
-import pylab
-
-n = 4000
-t = matrix(range(n), tc='d')
-ex = 0.5 * mul( sin(2*pi/n * t), sin(0.01 * t))
-corr = ex + 0.05 * random.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')
-
-
-# A = D'*D is an n by n tridiagonal matrix with -1.0 on the 
-# upper/lower diagonal and 1, 2, 2, ..., 2, 2, 1 on the diagonal.
-## A = spmatrix( (n-1)*[-1.0] + [1.0] + (n-2)*[2.0] + [1.0],
-##     range(1,n) + [0] + range(1,n-1) + [n-1], 
-##     range(n-1) + [0] + range(1,n-1) + [n-1]) 
-## I = spmatrix(1.0, range(n), range(n))
-## F = cholmod.symbolic(A)
-
-A = matrix(0.0, (2,n))
-A[0,:] = [1.0] + (n-2)*[2.0] + [1.0]
-A[1,:n-1] = -1.0
-I = matrix(n*[[1.0, 0.0]])
-
-nopts = 50
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
-cost1, cost2 = [], []
-for delta in deltas:
-##     cholmod.numeric(I + 10**delta * A, F )
-    xr = +corr 
-##     cholmod.solve(F, xr)
-    lapack.pbsv(I + 10**delta * A, xr)
-    cost1 += [blas.nrm2(xr - corr)] 
-    cost2 += [blas.nrm2(xr[1:] - xr[:-1])] 
-
-# Find solutions with ||xhat - xcorr || roughly equal to 8.0, 3.1, 1.0.
-mv1, k1 = min(zip([abs(c - 8.0) for c in cost1], range(nopts)))
-## cholmod.numeric(I + 10**deltas[k1] * A, F )
-xr1 = +corr 
-## cholmod.solve(F, xr1)
-lapack.pbsv(I + 10**deltas[k1] * A, xr1)
-mv2, k2 = min(zip([abs(c - 3.1) for c in cost1], range(nopts)))
-## cholmod.numeric(I + 10**deltas[k2] * A, F )
-xr2 = +corr 
-## cholmod.solve(F, xr2)
-lapack.pbsv(I + 10**deltas[k2] * A, xr2)
-mv3, k3 = min(zip([abs(c - 1.0) for c in cost1], range(nopts)))
-## cholmod.numeric(I + 10**deltas[k3] * A, F )
-xr3 = +corr 
-## cholmod.solve(F, xr3)
-lapack.pbsv(I + 10**deltas[k3] * A, xr3)
-
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', [cost1[k2]], [cost2[k2]], 'o',
-    [cost1[k3]], [cost2[k3]], 'o')
-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/old/tv b/examples/book/chap6/old/tv
deleted file mode 100755
index 335a177..0000000
--- a/examples/book/chap6/old/tv
+++ /dev/null
@@ -1,293 +0,0 @@
-#!/usr/bin/python
-
-# Figures 6.11-14, pages 315-317.
-# Total variation reconstruction.
-
-from math import pi
-from cvxopt import random, blas, lapack, cholmod, solvers
-from cvxopt.base import matrix, spmatrix, sin, mul, div
-solvers.options['show_progress'] = 0
-import pylab
-
-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] ) + \
-    0.5 * sin( 2.0*pi/n * t )
-corr = ex + 0.1 * random.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])
-
-
-# Quadratic smoothing.
-# A = D'*D is an n by n tridiagonal matrix with -1.0 on the 
-# upper/lower diagonal and 1, 2, 2, ..., 2, 2, 1 on the diagonal.
-
-A = spmatrix( (n-1)*[-1.0] + [1.0] + (n-2)*[2.0] + [1.0],
-    range(1,n) + [0] + range(1,n-1) + [n-1], 
-    range(n-1) + [0] + range(1,n-1) + [n-1]) 
-I = spmatrix(1.0, range(n), range(n))
-F = cholmod.symbolic(A)
-nopts = 100
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
-
-cost1, cost2 = [], []
-for delta in deltas:
-    cholmod.numeric(I + 10**delta * A, F )
-    xr = +corr 
-    cholmod.solve(F, xr)
-    cost1 += [blas.nrm2(xr - corr)] 
-    cost2 += [blas.nrm2(xr[1:] - xr[:-1])] 
-
-# Find solutions with ||xhat - xcorr || roughly equal to 4, 7, 10.
-mv1, k1 = min(zip([abs(c - 10.0) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k1] * A, F )
-xr1 = +corr 
-cholmod.solve(F, xr1)
-mv2, k2 = min(zip([abs(c - 7.0) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k2] * A, F )
-xr2 = +corr 
-cholmod.solve(F, xr2)
-mv3, k3 = min(zip([abs(c - 4.0) for c in cost1], range(nopts)))
-cholmod.numeric(I + 10**deltas[k3] * A, F )
-xr3 = +corr 
-cholmod.solve(F, xr3)
-
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', 
-    [cost1[k2]], [cost2[k2]], 'o', [cost1[k3]], [cost2[k3]], 'o')
-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.
-#
-# minimize (1/2) * ||x-corr||_2^2 + delta * || D*x ||_1
-#
-# minimize    (1/2) * ||x-corr||_2^2 + delta * 1'*y
-# subject to  -y <= D*x <= y
-#
-# Variables x (n), y (n-1).
-
-def tv(delta):
-    """
-        minimize    (1/2) * ||x-corr||_2^2 + delta * sum(y)
-        subject to  -y <= D*x <= y
-    
-    Variables x (n), y (n-1).
-    """
-
-    def F(x=None):
-        """
-        Function and gradient evaluation of 
-
-            f = 1/2 * || x[:n]-corr ||_2^2 + delta * sum(x[n:]).
-        """
-    
-        nvars = 2*n - 1
-        if x is None: return 0, matrix(0.0, (nvars,1))
-        f = 0.5 * blas.nrm2( x[:n]-corr )**2 + delta * sum(x[n:])
-        gradf = matrix(0.0, (1,nvars))
-        gradf[:n] = x[:n]-corr
-        gradf[n:] = delta
-        return f, gradf 
-
-
-    def G(u, v, alpha=1.0, beta=0.0, trans='N'):
-        """
-           v := alpha*[D, -I;  -D, -I] * u + beta * v  (trans = 'N')
-           v := alpha*[D, -I;  -D, -I]' * u + beta * v  (trans = 'T')
-
-        For an n-vector z, D*z = z[1:] - z[:-1].
-        For an (n-1)-vector z, D'*z = [-z;0] + [0; z].
-        """
-
-        v *= beta
-        if trans == 'N':
-            y = u[1:n] - u[:n-1]
-            v[:n-1] += alpha*(y - u[n:])
-            v[n-1:] += alpha*(-y - u[n:])
-        else:
-            y = u[:n-1] - u[n-1:]
-            v[:n-1] -= alpha * y
-            v[1:n] += alpha * y
-            v[n:] -= alpha * (u[:n-1] + u[n-1:])
-
-    h = matrix(0.0, (2*(n-1),1))
-
-
-    # Customized solver for KKT system with coefficient
-    #
-    #     [  z[0]*I  0    D'   -D' ] 
-    #     [  0       0   -I    -I  ] 
-    #     [  D      -I   -D1    0  ] 
-    #     [ -D      -I    0    -D2 ].
-     
-    # First do a symbolic factorization of tridiagonal matrix.
-    S = spmatrix((2*n-1)*[1.0], range(1,n)+range(n), 
-        range(n-1)+range(n))
-    fact = cholmod.symbolic(S)
-
-    def kktsolver(x, z, dnl, dl):
-        """
-        Factor the tridiagonal matrix
-
-             S = z[0]*I + 4.0 * D' * diag( d1.*d2./(d1+d2) ) * D 
-
-        with d1 = dl[:n-1]**2 = diag(D1^-1),  
-        d2 = dl[n-1:]**2 = diag(D2^-1).
-        """
-
-        d1 = dl[:n-1]**2
-        d2 = dl[n-1:]**2
-        d = 4.0*div( mul(d1,d2), d1+d2) 
-        S[::n+1] = z[0]
-        S[n+1::n+1] = S[n+1::n+1] + d
-        S[:(n**2-1):n+1] = S[:(n**2-1):n+1] + d
-        S[1::n+1] = -d
-        cholmod.numeric(S, fact)
-        def g(x, y, znl, zl):
-
-            """
-            Solve 
-
-                [  z[0]*I  0   D'  -D' ] [x[:n]   ]    [bx[:n]   ]
-                [  0       0  -I   -I  ] [x[n:]   ] =  [bx[n:]   ]
-                [  D      -I  -D1   0  ] [zl[:n-1]]    [bzl[:n-1]]
-                [ -D      -I   0   -D2 ] [zl[n-1:]]    [bzl[n-1:]].
-
-            First solve
-                 
-                S*x[:n] = bx[:n] + D' * ( (d1-d2) ./ (d1+d2) .* bx[n:] 
-                    + 2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:]) ).
-
-            Then take
-
-                x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-                         - d2.*bzl[n-1:]  + (d1-d2) .* D*x[:n] ) 
-                zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-                zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:]).
-            """
-
-            # y = (d1-d2) ./ (d1+d2) .* bx[n:] + 
-            #     2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:])
-            y = mul( div(d1-d2, d1+d2), x[n:]) + \
-                mul( 0.5*d, zl[:n-1]-zl[n-1:] ) 
-
-            # x[:n] += D*y
-            x[:n-1] -= y
-            x[1:n] += y
-
-            # x[:n] := S^-1 * x[:n]
-            cholmod.solve(fact, x)
-
-            # u = D*x[:n]
-            u = x[1:n] - x[0:n-1]
-
-            # x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-            #     - d2.*bzl[n-1:]  + (d1-d2) .* u) 
-            x[n:] = div( x[n:] - mul(d1, zl[:n-1]) - 
-                mul(d2, zl[n-1:]) + mul(d1-d2, u), d1+d2 )
-
-            # zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-            # zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:])
-            zl[:n-1] = mul(d1, u - x[n:] - zl[:n-1])
-            zl[n-1:] = mul(d2, -u - x[n:] - zl[n-1:])
-
-        return g
-
-    return solvers.nlcp(kktsolver, F, G, h)['x'][:n]
-
-nopts = 15
-deltas = -3.0 + (3.0-(-3.0))/(nopts-1) * matrix(range(nopts))
-cost1, cost2 = [], []
-for delta, k in zip(deltas, xrange(nopts)):
-    xtv = tv(10**delta)
-    cost1 += [blas.nrm2(xtv - corr)] 
-    cost2 += [blas.asum(xtv[1:] - xtv[:-1])] 
-mv1, k1 = min(zip([abs(c - 20.0) for c in cost2], range(nopts)))
-xtv1 = tv(10**deltas[k1])
-mv2, k2 = min(zip([abs(c - 8.0) for c in cost2], range(nopts)))
-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(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])
-
-pylab.figure(2, facecolor='w') #figsize=(8,7.5))
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-        [0], [blas.asum(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', [cost1[k2]], [cost2[k2]], 'o',
-    [cost1[k3]], [cost2[k3]], 'o')
-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(3, 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/chap6/old/tv_new b/examples/book/chap6/old/tv_new
deleted file mode 100755
index 201d46d..0000000
--- a/examples/book/chap6/old/tv_new
+++ /dev/null
@@ -1,291 +0,0 @@
-#!/usr/bin/python
-
-# Figures 6.11-14, pages 315-317.
-# Total variation reconstruction.
-
-### same as tv, but uses LAPACK solvers for band systems
-
-from math import pi
-from cvxopt import random, blas, lapack, solvers
-from cvxopt.base import matrix, spmatrix, sin, mul, div
-solvers.options['show_progress'] = 0
-import pylab
-
-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] ) + \
-    0.5 * sin( 2.0*pi/n * t )
-corr = ex + 0.1 * random.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])
-
-
-# Quadratic smoothing.
-# A = D'*D is an n by n tridiagonal matrix with -1.0 on the 
-# upper/lower diagonal and 1, 2, 2, ..., 2, 2, 1 on the diagonal.
-
-A = matrix(0.0, (2,n))
-A[0,:] = [1.0] + (n-2)*[2.0] + [1.0]
-A[1,:n-1] = -1.0
-I = matrix(n*[[1.0, 0.0]])
-
-nopts = 100
-deltas = -10.0 + 20.0/(nopts-1) * matrix(range(nopts))
-
-cost1, cost2 = [], []
-for delta in deltas:
-    xr = +corr 
-    lapack.pbsv(I + 10**delta * A, xr)
-    cost1 += [blas.nrm2(xr - corr)] 
-    cost2 += [blas.nrm2(xr[1:] - xr[:-1])] 
-
-# Find solutions with ||xhat - xcorr || roughly equal to 4, 7, 10.
-mv1, k1 = min(zip([abs(c - 10.0) for c in cost1], range(nopts)))
-xr1 = +corr 
-lapack.pbsv(I + 10**deltas[k1] * A, xr1)
-mv2, k2 = min(zip([abs(c - 7.0) for c in cost1], range(nopts)))
-xr2 = +corr 
-lapack.pbsv(I + 10**deltas[k2] * A, xr2)
-mv3, k3 = min(zip([abs(c - 4.0) for c in cost1], range(nopts)))
-xr3 = +corr 
-lapack.pbsv(I + 10**deltas[k3] * A, xr3)
-
-pylab.figure(2, facecolor='w')
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-    [0], [blas.nrm2(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', 
-    [cost1[k2]], [cost2[k2]], 'o', [cost1[k3]], [cost2[k3]], 'o')
-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.
-#
-# minimize (1/2) * ||x-corr||_2^2 + delta * || D*x ||_1
-#
-# minimize    (1/2) * ||x-corr||_2^2 + delta * 1'*y
-# subject to  -y <= D*x <= y
-#
-# Variables x (n), y (n-1).
-
-def tv(delta):
-    """
-        minimize    (1/2) * ||x-corr||_2^2 + delta * sum(y)
-        subject to  -y <= D*x <= y
-    
-    Variables x (n), y (n-1).
-    """
-
-    def F(x=None):
-        """
-        Function and gradient evaluation of 
-
-            f = 1/2 * || x[:n]-corr ||_2^2 + delta * sum(x[n:]).
-        """
-    
-        nvars = 2*n - 1
-        if x is None: return 0, matrix(0.0, (nvars,1))
-        f = 0.5 * blas.nrm2( x[:n]-corr )**2 + delta * sum(x[n:])
-        gradf = matrix(0.0, (1,nvars))
-        gradf[:n] = x[:n]-corr
-        gradf[n:] = delta
-        return f, gradf 
-
-
-    def G(u, v, alpha=1.0, beta=0.0, trans='N'):
-        """
-           v := alpha*[D, -I;  -D, -I] * u + beta * v  (trans = 'N')
-           v := alpha*[D, -I;  -D, -I]' * u + beta * v  (trans = 'T')
-
-        For an n-vector z, D*z = z[1:] - z[:-1].
-        For an (n-1)-vector z, D'*z = [-z;0] + [0; z].
-        """
-
-        v *= beta
-        if trans == 'N':
-            y = u[1:n] - u[:n-1]
-            v[:n-1] += alpha*(y - u[n:])
-            v[n-1:] += alpha*(-y - u[n:])
-        else:
-            y = u[:n-1] - u[n-1:]
-            v[:n-1] -= alpha * y
-            v[1:n] += alpha * y
-            v[n:] -= alpha * (u[:n-1] + u[n-1:])
-
-    h = matrix(0.0, (2*(n-1),1))
-
-
-    # Customized solver for KKT system with coefficient
-    #
-    #     [  z[0]*I  0    D'   -D' ] 
-    #     [  0       0   -I    -I  ] 
-    #     [  D      -I   -D1    0  ] 
-    #     [ -D      -I    0    -D2 ].
-     
-    # First do a symbolic factorization of tridiagonal matrix.
-    S = matrix(0.0, (2,n))
-
-    def kktsolver(x, z, dnl, dl):
-        """
-        Factor the tridiagonal matrix
-
-             S = z[0]*I + 4.0 * D' * diag( d1.*d2./(d1+d2) ) * D 
-
-        with d1 = dl[:n-1]**2 = diag(D1^-1),  
-        d2 = dl[n-1:]**2 = diag(D2^-1).
-        """
-
-        d1 = dl[:n-1]**2
-        d2 = dl[n-1:]**2
-        d = 4.0*div( mul(d1,d2), d1+d2) 
-        S[0,:] = z[0]
-        S[0,:n-1] += d.T
-        S[0,1:] += d.T
-        S[1,:n-1] = -d.T
-        lapack.pbtrf(S)
-        def g(x, y, znl, zl):
-
-            """
-            Solve 
-
-                [  z[0]*I  0   D'  -D' ] [x[:n]   ]    [bx[:n]   ]
-                [  0       0  -I   -I  ] [x[n:]   ] =  [bx[n:]   ]
-                [  D      -I  -D1   0  ] [zl[:n-1]]    [bzl[:n-1]]
-                [ -D      -I   0   -D2 ] [zl[n-1:]]    [bzl[n-1:]].
-
-            First solve
-                 
-                S*x[:n] = bx[:n] + D' * ( (d1-d2) ./ (d1+d2) .* bx[n:] 
-                    + 2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:]) ).
-
-            Then take
-
-                x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-                         - d2.*bzl[n-1:]  + (d1-d2) .* D*x[:n] ) 
-                zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-                zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:]).
-            """
-
-            # y = (d1-d2) ./ (d1+d2) .* bx[n:] + 
-            #     2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:])
-            y = mul( div(d1-d2, d1+d2), x[n:]) + \
-                mul( 0.5*d, zl[:n-1]-zl[n-1:] ) 
-
-            # x[:n] += D*y
-            x[:n-1] -= y
-            x[1:n] += y
-
-            # x[:n] := S^-1 * x[:n]
-            lapack.pbtrs(S, x) 
-
-            # u = D*x[:n]
-            u = x[1:n] - x[0:n-1]
-
-            # x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-            #     - d2.*bzl[n-1:]  + (d1-d2) .* u) 
-            x[n:] = div( x[n:] - mul(d1, zl[:n-1]) - 
-                mul(d2, zl[n-1:]) + mul(d1-d2, u), d1+d2 )
-
-            # zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-            # zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:])
-            zl[:n-1] = mul(d1, u - x[n:] - zl[:n-1])
-            zl[n-1:] = mul(d2, -u - x[n:] - zl[n-1:])
-
-        return g
-
-    return solvers.nlcp(kktsolver, F, G, h)['x'][:n]
-
-
-nopts = 15
-deltas = -3.0 + (3.0-(-3.0))/(nopts-1) * matrix(range(nopts))
-cost1, cost2 = [], []
-for delta, k in zip(deltas, xrange(nopts)):
-    xtv = tv(10**delta)
-    cost1 += [blas.nrm2(xtv - corr)] 
-    cost2 += [blas.asum(xtv[1:] - xtv[:-1])] 
-mv1, k1 = min(zip([abs(c - 20.0) for c in cost2], range(nopts)))
-xtv1 = tv(10**deltas[k1])
-mv2, k2 = min(zip([abs(c - 8.0) for c in cost2], range(nopts)))
-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(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])
-
-pylab.figure(2, facecolor='w') #figsize=(8,7.5))
-pylab.plot(cost1, cost2, [blas.nrm2(corr)], [0], 'o',
-        [0], [blas.asum(corr[1:] - corr[:-1])], 'o') 
-pylab.plot([cost1[k1]], [cost2[k1]], 'o', [cost1[k2]], [cost2[k2]], 'o',
-    [cost1[k3]], [cost2[k3]], 'o')
-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(3, 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/chap6/penalties b/examples/book/chap6/penalties
index 98c45a4..6871db0 100755
--- a/examples/book/chap6/penalties
+++ b/examples/book/chap6/penalties
@@ -7,7 +7,7 @@
 
 import pylab
 from cvxopt import random, lapack, solvers
-from cvxopt.base import matrix, spmatrix, log, div
+from cvxopt.base import matrix, spdiag, log, div
 from cvxopt.modeling import variable, op, max, sum 
 solvers.options['show_progress'] = 0
 
@@ -81,9 +81,8 @@ def F(x=None, z=None):
     f = -sum(log(1.0 - y**2))
     gradf = 2.0 * A.T * div(y, 1-y**2)
     if z is None: return f, gradf.T
-    H = A.T * spmatrix(2.0 * div( 1.0+y**2, (1.0 - y**2)**2 ), range(m),
-        range(m)) * A
-    return f, gradf.T, z[0]*H
+    H = A.T * spdiag(2.0 * z[0] * div( 1.0+y**2, (1.0 - y**2)**2 )) * A
+    return f, gradf.T, H
 xlb = solvers.cp(F)['x']
 
 pylab.subplot(414)
diff --git a/examples/book/chap6/regsel b/examples/book/chap6/regsel
index 2de8c57..a572a1b 100755
--- a/examples/book/chap6/regsel
+++ b/examples/book/chap6/regsel
@@ -7,7 +7,7 @@
 
 import pylab
 from cvxopt import blas, lapack, solvers 
-from cvxopt.base import matrix, spmatrix, mul
+from cvxopt.base import matrix, mul
 from pickle import load
 solvers.options['show_progress'] = 0
 
@@ -118,7 +118,7 @@ res2, card2 = [ bestres[0] ], [ 0 ]
 for k in xrange(1,m+1):
     res2 += [bestres[k-1], bestres[k]]
     card2 += [ k, k]
-pylab.plot( bestres, range(m+1), 'go')
+pylab.plot( bestres.T, range(m+1), 'go')
 pylab.plot( res2, card2, 'g-')
 
 pylab.xlabel('||A*x-b||_2')
diff --git a/examples/book/chap6/smoothrec b/examples/book/chap6/smoothrec
index 219661a..4e14b66 100755
--- a/examples/book/chap6/smoothrec
+++ b/examples/book/chap6/smoothrec
@@ -5,7 +5,7 @@
 
 from math import pi
 from cvxopt import random, blas, lapack 
-from cvxopt.base import matrix, spmatrix, sin, mul
+from cvxopt.base import matrix, sin, mul
 import pylab
 
 n = 4000
diff --git a/examples/book/chap6/tv b/examples/book/chap6/tv
index fc5d35d..8f2a33f 100755
--- a/examples/book/chap6/tv
+++ b/examples/book/chap6/tv
@@ -106,7 +106,7 @@ def tv(delta):
     Variables x (n), y (n-1).
     """
 
-    def F(x=None):
+    def F(x = None, z = None):
         """
         Function and gradient evaluation of 
 
@@ -114,12 +114,17 @@ def tv(delta):
         """
     
         nvars = 2*n - 1
-        if x is None: return 0, matrix(0.0, (nvars,1))
+        if x is None: 
+            return 0, matrix(0.0, (nvars,1))
         f = 0.5 * blas.nrm2( x[:n]-corr )**2 + delta * sum(x[n:])
         gradf = matrix(0.0, (1,nvars))
         gradf[:n] = x[:n]-corr
         gradf[n:] = delta
-        return f, gradf 
+        if z is None:
+            return f, gradf 
+        else:
+            H = spmatrix(1.0, range(n), range(n), (nvars, nvars))
+            return f, gradf, H
 
 
     def G(u, v, alpha=1.0, beta=0.0, trans='N'):
@@ -156,51 +161,51 @@ def tv(delta):
     Sd = matrix(0.0, (n,1))
     Se = matrix(0.0, (n-1,1))
 
-    def kktsolver(x, z, dnl, dl):
+    def Fkkt(x, z, W):
         """
         Factor the tridiagonal matrix
 
              S = z[0]*I + 4.0 * D' * diag( d1.*d2./(d1+d2) ) * D 
 
-        with d1 = dl[:n-1]**2 = diag(D1^-1),  
-        d2 = dl[n-1:]**2 = diag(D2^-1).
+        with d1 = W['dli'][:n-1]**2 = diag(D1^-1) 
+        d2 = W['dli'][n-1:]**2 = diag(D2^-1).
         """
 
-        d1 = dl[:n-1]**2
-        d2 = dl[n-1:]**2
+        d1 = W['dli'][:n-1]**2
+        d2 = W['dli'][n-1:]**2
         d = 4.0*div( mul(d1,d2), d1+d2) 
         Sd[:] = z[0]
         Sd[:n-1] += d
         Sd[1:] += d
         Se[:] = -d
         lapack.pttrf(Sd, Se)
-        def g(x, y, znl, zl):
+        def g(x, y, z):
 
             """
             Solve 
 
                 [  z[0]*I  0   D'  -D' ] [x[:n]   ]    [bx[:n]   ]
                 [  0       0  -I   -I  ] [x[n:]   ] =  [bx[n:]   ]
-                [  D      -I  -D1   0  ] [zl[:n-1]]    [bzl[:n-1]]
-                [ -D      -I   0   -D2 ] [zl[n-1:]]    [bzl[n-1:]].
+                [  D      -I  -D1   0  ] [z[:n-1] ]    [bz[:n-1] ]
+                [ -D      -I   0   -D2 ] [z[n-1:] ]    [bz[n-1:] ].
 
             First solve
                  
                 S*x[:n] = bx[:n] + D' * ( (d1-d2) ./ (d1+d2) .* bx[n:] 
-                    + 2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:]) ).
+                    + 2*d1.*d2./(d1+d2) .* (bz[:n-1] - bz[n-1:]) ).
 
             Then take
 
-                x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-                         - d2.*bzl[n-1:]  + (d1-d2) .* D*x[:n] ) 
-                zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-                zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:]).
+                x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bz[:n-1] 
+                         - d2.*bz[n-1:]  + (d1-d2) .* D*x[:n] ) 
+                z[:n-1] = d1 .* (D*x[:n] - x[n:] - bz[:n-1])
+                z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:]).
             """
 
             # y = (d1-d2) ./ (d1+d2) .* bx[n:] + 
-            #     2*d1.*d2./(d1+d2) .* (bzl[:n-1] - bzl[n-1:])
+            #     2*d1.*d2./(d1+d2) .* (bz[:n-1] - bz[n-1:])
             y = mul( div(d1-d2, d1+d2), x[n:]) + \
-                mul( 0.5*d, zl[:n-1]-zl[n-1:] ) 
+                mul( 0.5*d, z[:n-1]-z[n-1:] ) 
 
             # x[:n] += D*y
             x[:n-1] -= y
@@ -212,19 +217,20 @@ def tv(delta):
             # u = D*x[:n]
             u = x[1:n] - x[0:n-1]
 
-            # x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bzl[:n-1] 
-            #     - d2.*bzl[n-1:]  + (d1-d2) .* u) 
-            x[n:] = div( x[n:] - mul(d1, zl[:n-1]) - 
-                mul(d2, zl[n-1:]) + mul(d1-d2, u), d1+d2 )
+            # x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bz[:n-1] 
+            #     - d2.*bz[n-1:]  + (d1-d2) .* u) 
+            x[n:] = div( x[n:] - mul(d1, z[:n-1]) - 
+                mul(d2, z[n-1:]) + mul(d1-d2, u), d1+d2 )
 
-            # zl[:n-1] = d1 .* (D*x[:n] - x[n:] - bzl[:n-1])
-            # zl[n-1:] = d2 .* (-D*x[:n] - x[n:] - bzl[n-1:])
-            zl[:n-1] = mul(d1, u - x[n:] - zl[:n-1])
-            zl[n-1:] = mul(d2, -u - x[n:] - zl[n-1:])
+            # z[:n-1] = d1 .* (D*x[:n] - x[n:] - bz[:n-1])
+            # z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:])
+            z[:n-1] = mul(W['dli'][:n-1], u - x[n:] - z[:n-1])
+            z[n-1:] = mul(W['dli'][n-1:], -u - x[n:] - z[n-1:])
 
         return g
 
-    return solvers.nlcp(kktsolver, F, G, h)['x'][:n]
+    solvers.options['feastol'] = 1e-6
+    return solvers.cp(F, G, h, kktsolver = Fkkt)['x'][:n]
 
 
 nopts = 15
diff --git a/examples/book/chap7/expdesign b/examples/book/chap7/expdesign
index 5887458..26bf1f8 100755
--- a/examples/book/chap7/expdesign
+++ b/examples/book/chap7/expdesign
@@ -6,7 +6,7 @@
 from math import pi, log, sqrt
 import pylab
 from cvxopt import base, blas, lapack, solvers
-from cvxopt.base import matrix, spmatrix, mul, cos, sin
+from cvxopt.base import matrix, spmatrix, spdiag, mul, cos, sin
 solvers.options['show_progress'] = False
 
 V = matrix([-2.1213,    2.1213,
@@ -52,7 +52,7 @@ b = matrix(1.0)
 
 def F(x=None, z=None):
     if x is None: return 0, matrix(1.0, (n,1))
-    X = V * spmatrix(x, range(n), range(n)) * V.T
+    X = V * spdiag(x) * V.T
     L = +X
     try: lapack.potrf(L)
     except ArithmeticError: return None
@@ -64,9 +64,9 @@ def F(x=None, z=None):
     H = matrix(0.0, (n,n))
     blas.syrk(W, H, trans='T')
     return f, gradf, z[0] * H**2
-xd = solvers.cp(F, G, h, A, b)['x']
+xd = solvers.cp(F, G, h, A = A, b = b)['x']
 
-pylab.figure(1, facecolor='w', figsize=(5,5))
+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')
@@ -77,11 +77,11 @@ 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)
 
-W = V * spmatrix(xd, range(n), range(n)) * V.T
+W = V * spdiag(xd) * V.T
 lapack.potrf(W)
 ellipse = sqrt(2.0) * circle
 blas.trmm(W, ellipse)
-pylab.plot(ellipse[0,:], ellipse[1,:], 'k--')
+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')
@@ -109,7 +109,7 @@ xe = sol['x'][:n]
 Z = sol['zs'][0]
 mu = sol['y'][0]
 
-pylab.figure(2, facecolor='w', figsize=(5,5))
+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')
@@ -123,7 +123,7 @@ 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,:], ellipse[1,:], 'k--')
+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')
@@ -163,7 +163,7 @@ xa = sol['x'][:n]
 Z = sol['zs'][0][:2,:2]
 mu = sol['y'][0]
 
-pylab.figure(3, facecolor='w', figsize=(5,5))
+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')
@@ -178,7 +178,7 @@ 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,:], ellipse[1,:], 'k--')
+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')
diff --git a/examples/book/chap7/logreg b/examples/book/chap7/logreg
index 61fb736..c0cbd80 100755
--- a/examples/book/chap7/logreg
+++ b/examples/book/chap7/logreg
@@ -5,7 +5,7 @@
 
 import pylab, pickle
 from cvxopt import solvers
-from cvxopt.base import matrix, spmatrix, log, exp, div
+from cvxopt.base import matrix, spdiag, log, exp, div
 solvers.options['show_progress'] = False
 
 data = pickle.load(open("logreg.bin"))
@@ -30,7 +30,7 @@ def F(x=None, z=None):
    f = c.T*x + sum(log(1+w))
    grad = c + A.T * div(w, 1+w)  
    if z is None: return f, grad.T
-   H = A.T * spmatrix(div(w,(1+w)**2), range(m), range(m)) * A
+   H = A.T * spdiag(div(w,(1+w)**2)) * A
    return f, grad.T, z[0]*H 
 sol = solvers.cp(F)
 a, b = sol['x'][0], sol['x'][1]
diff --git a/examples/book/chap7/maxent b/examples/book/chap7/maxent
index 9b77c93..18a8a01 100755
--- a/examples/book/chap7/maxent
+++ b/examples/book/chap7/maxent
@@ -5,7 +5,7 @@
 
 import pylab
 from cvxopt import solvers, blas
-from cvxopt.base import matrix, spmatrix, log, div
+from cvxopt.base import matrix, spmatrix, spdiag, log, div
 solvers.options['show_progress'] = False
 
 # minimize     p'*log p  
@@ -41,9 +41,9 @@ def F(x=None, z=None):
    f = x.T*log(x)
    grad = 1.0 + log(x)
    if z is None: return f, grad.T
-   H = spmatrix(x**-1, range(n), range(n))
-   return f, grad.T, z[0]*H 
-sol = solvers.cp(F, G, h, A, b)
+   H = spdiag(z[0] * x**-1)
+   return f, grad.T, H 
+sol = solvers.cp(F, G, h, A=A, b=b)
 p = sol['x']
 
 
diff --git a/examples/book/chap7/probbounds b/examples/book/chap7/probbounds
index 844385c..0370ee8 100755
--- a/examples/book/chap7/probbounds
+++ b/examples/book/chap7/probbounds
@@ -118,7 +118,7 @@ L /= sqrt(1 - r - blas.dot(q, xc))
 
 def makefig1():
     pylab.figure(1, facecolor='w', figsize=(6,6))
-    pylab.plot(V[0,:], V[1,:], '-')
+    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) )
@@ -128,7 +128,7 @@ def makefig1():
         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,:], c[1]+circle[1,:], ':')
+        pylab.plot(c[0] + circle[0,:].T, c[1]+circle[1,:].T, 'g:')
         if k >= 1:
             v = V[:,k-1]
             if k==1: 
@@ -139,7 +139,7 @@ def makefig1():
                 [v[1], v[1] + 5*dir[1]], 'b-')
     ellipse = +circle
     blas.trsm(L, ellipse, transA='T')
-    pylab.plot(xc[0] + ellipse[0,:], xc[1]+ellipse[1,:], 'r-')
+    pylab.plot(xc[0] + ellipse[0,:].T, xc[1]+ellipse[1,:].T, 'r-')
     for Xk in X: 
         pylab.plot([Xk[0]], [Xk[1]], 'ro')
 
diff --git a/examples/book/chap8/centers b/examples/book/chap8/centers
index 39bde8c..57caa08 100755
--- a/examples/book/chap8/centers
+++ b/examples/book/chap8/centers
@@ -6,7 +6,7 @@
 import pylab
 from math import log, pi
 from cvxopt import blas, lapack, solvers
-from cvxopt.base import matrix, spmatrix, sqrt, mul, cos, sin, log
+from cvxopt.base import matrix, spdiag, sqrt, mul, cos, sin, log
 from cvxopt.modeling import variable, op 
 solvers.options['show_progress'] = False
 
@@ -53,7 +53,7 @@ circle[0,:], circle[1,:] = R*cos(angles), R*sin(angles)
 circle += xc[:,nopts*[0]]
 
 # plot maximum inscribed disk
-pylab.fill(circle[0,:], circle[1,:], '#F0F0F0')
+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')
@@ -151,7 +151,7 @@ circle[0,:], circle[1,:] = cos(angles), sin(angles)
 # ellipse = L * circle + c
 ellipse = L * circle + c[:, nopts*[0]]
 
-pylab.fill(ellipse[0,:], ellipse[1,:], '#F0F0F0')
+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')
@@ -170,12 +170,12 @@ def F(x=None, z=None):
     f = -sum(log(y))
     Df = (y**-1).T * G
     if z is None: return matrix(f), Df
-    H =  G.T * spmatrix(y**-1, range(m), range(m)) * G
+    H =  G.T * spdiag(y**-1) * G
     return matrix(f), Df, z[0]*H
 
 sol = solvers.cp(F)
 xac = sol['x']
-Hac = G.T * spmatrix( (h-G*xac)**-1, range(m), range(m)) * G
+Hac = G.T * spdiag((h-G*xac)**-1) * G
 
 pylab.figure(3, facecolor='w')
 
@@ -197,7 +197,7 @@ lapack.potrf(Hac)
 ellipse = +circle
 blas.trsm(Hac, ellipse, transA='T')
 ellipse += xac[:, nopts*[0]]
-pylab.fill(ellipse[0,:], ellipse[1,:], '#F0F0F0')
+pylab.fill(ellipse[0,:].T, ellipse[1,:].T, facecolor = '#F0F0F0')
 pylab.plot([xac[0]], [xac[1]], 'ko')
 
 pylab.title('Analytic center (fig 8.7)')
diff --git a/examples/book/chap8/ellipsoids b/examples/book/chap8/ellipsoids
index 062a781..5f6a518 100755
--- a/examples/book/chap8/ellipsoids
+++ b/examples/book/chap8/ellipsoids
@@ -121,8 +121,8 @@ blas.trsm(L, circle, transA='T')
 ellipse = circle + c[:, nopts*[0]]
 ellipse2 = 0.5 * circle + c[:, nopts*[0]]
 
-pylab.plot(ellipse[0,:], ellipse[1,:], 'k-')
-pylab.fill(ellipse2[0,:], ellipse2[1,:], '#F0F0F0')
+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')
@@ -219,8 +219,8 @@ circle[0,:], circle[1,:] = cos(angles), sin(angles)
 ellipse = L * circle + c[:, nopts*[0]]
 ellipse2 = 2.0 * L * circle + c[:, nopts*[0]]
 
-pylab.plot(ellipse2[0,:], ellipse2[1,:], 'k-')
-pylab.fill(ellipse[0,:], ellipse[1,:], '#F0F0F0')
+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')
diff --git a/examples/book/chap8/floorplan b/examples/book/chap8/floorplan
index 2cd5903..f7b6028 100755
--- a/examples/book/chap8/floorplan
+++ b/examples/book/chap8/floorplan
@@ -54,22 +54,21 @@ def floorplan(Amin):
     #     -w4 + Amin4 / h4 <= 0 
     #     -w5 + Amin5 / h5 <= 0.
 
+    c = matrix(2*[1.0] + 20*[0.0])
+
     def F(x=None, z=None):
         if x is None:  
             return 5, matrix(17*[0.0] + 5*[1.0])
         if min(x[17:]) <= 0.0:  
             return None 
-        f = matrix(0.0, (6,1))
-        f[0] = x[0] + x[1]  
-        f[1:] = -x[12:17] + div(Amin, x[17:]) 
-        Df = matrix(0.0, (6,22))
-        Df[0, [0,1]] = 1.0
-        Df[1:,12:17] = spmatrix(-1.0, range(5), range(5))
-        Df[1:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
+        f = -x[12:17] + div(Amin, x[17:]) 
+        Df = matrix(0.0, (5,22))
+        Df[:,12:17] = spmatrix(-1.0, range(5), range(5))
+        Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))
         if z is None: 
             return f, Df
-        H = spmatrix( 2.0* mul(z[1:], div(Amin, x[17::]**3)), 
-            range(17,22), range(17,22) )
+        H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), 
+            range(17,22) )
         return f, Df, H
 
     # linear inequalities
@@ -155,7 +154,7 @@ def floorplan(Amin):
     G[25, [16, 21]] = 1.0, -gamma
 
     # solve and return W, H, x, y, w, h 
-    sol = solvers.cp(F, G, h)
+    sol = solvers.cpl(c, F, G, h)
     return  sol['x'][0], sol['x'][1], sol['x'][2:7], sol['x'][7:12], \
         sol['x'][12:17], sol['x'][17:] 
 
@@ -168,7 +167,7 @@ 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]], '#D0D0D0')
+               [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([])
@@ -179,7 +178,7 @@ 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]], '#D0D0D0')
+               [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([])
@@ -190,7 +189,7 @@ 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]],'#D0D0D0')
+               [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([])
@@ -201,7 +200,7 @@ 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]],'#D0D0D0')
+               [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([])
diff --git a/examples/book/chap8/linsep b/examples/book/chap8/linsep
index 4b94ca2..9ecf7e4 100755
--- a/examples/book/chap8/linsep
+++ b/examples/book/chap8/linsep
@@ -6,7 +6,7 @@
 import pylab, pickle
 from cvxopt import solvers 
 from cvxopt.blas import dot
-from cvxopt.base import matrix, spmatrix, log, exp, div
+from cvxopt.base import matrix, spmatrix, spdiag, log, exp, div
 from cvxopt.modeling import variable, op
 solvers.options['show_progress'] = False
 
@@ -29,7 +29,7 @@ a = a.value
 b = b.value
 
 pylab.figure(1, facecolor='w', figsize=(5,5))
-pts = matrix([-10.0, 10.0], (1,2))
+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',
@@ -85,7 +85,7 @@ a = sol['x'][:2]
 b = sol['x'][2]
 
 pylab.figure(2, facecolor='w', figsize=(5,5))
-pts = matrix([-10.0, 10.0], (1,2))
+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',
@@ -113,14 +113,14 @@ def F(x=None, z=None):
    f = dot(c,x) + sum(log(1+w)) 
    grad = c + A.T * div(w, 1+w)  
    if z is None: return matrix(f), grad.T
-   H = A.T * spmatrix(div(w,(1+w)**2), range(len(w)), range(len(w))) * A
+   H = A.T * spdiag(div(w,(1+w)**2)) * A
    return matrix(f), grad.T, z[0]*H 
 
 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], (1,2))
+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',
diff --git a/examples/book/chap8/placement b/examples/book/chap8/placement
index e9f7657..a47d627 100755
--- a/examples/book/chap8/placement
+++ b/examples/book/chap8/placement
@@ -120,7 +120,7 @@ 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]], ':')
+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')
@@ -140,7 +140,7 @@ 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]], ':')
+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')
@@ -160,7 +160,7 @@ 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]], ':')
+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')
diff --git a/examples/doc/chap10/l1svc b/examples/doc/chap10/l1svc
new file mode 100755
index 0000000..e82ef73
--- /dev/null
+++ b/examples/doc/chap10/l1svc
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+# The 1-norm support vector classifier of section 9.5.
+
+from cvxopt.random import normal, setseed
+from cvxopt.modeling import variable, op, max, sum
+from cvxopt.blas import nrm2
+
+m, n = 500, 100
+A = normal(m,n) 
+
+x = variable(A.size[1],'x')  
+u = variable(A.size[0],'u')  
+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)
diff --git a/examples/doc/chap10/lp b/examples/doc/chap10/lp
new file mode 100755
index 0000000..259d6db
--- /dev/null
+++ b/examples/doc/chap10/lp
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+# The small LP of section 10.4.  
+
+from cvxopt.base import matrix
+from cvxopt.modeling import variable, op, dot
+
+x = variable()  
+y = variable()  
+c1 = ( 2*x+y <= 3 )  
+c2 = ( x+2*y <= 3 )  
+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]
+
+x = variable(2)  
+A = matrix([[2.,1.,-1.,0.], [1.,2.,0.,-1.]])  
+b = matrix([3.,3.,0.,0.])  
+c = matrix([-4.,-5.])  
+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  
diff --git a/examples/doc/normappr b/examples/doc/chap10/normappr
similarity index 98%
rename from examples/doc/normappr
rename to examples/doc/chap10/normappr
index 254a8f4..ba6c315 100755
--- a/examples/doc/normappr
+++ b/examples/doc/chap10/normappr
@@ -5,7 +5,7 @@
 from cvxopt.random import normal, setseed
 from cvxopt.modeling import variable, op, max, sum
 
-setseed(1)
+setseed(0)
 m, n = 500, 100
 A = normal(m,n)
 b = normal(m)
diff --git a/examples/doc/chap10/roblp b/examples/doc/chap10/roblp
new file mode 100755
index 0000000..74d8607
--- /dev/null
+++ b/examples/doc/chap10/roblp
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+
+# The robust LP example of section 9.5.
+
+from cvxopt.random import normal, uniform  
+from cvxopt.modeling import variable, dot, op, sum  
+from cvxopt.blas import nrm2  
+     
+m, n = 500, 100  
+A = normal(m,n)  
+b = uniform(m)  
+c = normal(n)  
+     
+x = variable(n)  
+op(dot(c,x), A*x+sum(abs(x)) <= b).solve()  
+     
+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)
diff --git a/examples/doc/acent b/examples/doc/chap4/acent
similarity index 100%
rename from examples/doc/acent
rename to examples/doc/chap4/acent
diff --git a/examples/doc/covsel b/examples/doc/chap7/covsel
similarity index 100%
rename from examples/doc/covsel
rename to examples/doc/chap7/covsel
diff --git a/examples/doc/covsel.bin b/examples/doc/chap7/covsel.bin
similarity index 100%
rename from examples/doc/covsel.bin
rename to examples/doc/chap7/covsel.bin
diff --git a/examples/doc/l1 b/examples/doc/chap8/l1
similarity index 97%
rename from examples/doc/l1
rename to examples/doc/chap8/l1
index 9091890..54c4b89 100755
--- a/examples/doc/l1
+++ b/examples/doc/chap8/l1
@@ -3,7 +3,7 @@
 # The 1-norm approximation example of section 8.5.  
 
 from cvxopt import base, random, blas, lapack, solvers
-from cvxopt.base import matrix, spmatrix, mul, div
+from cvxopt.base import matrix, spdiag, mul, div
 from math import sqrt
 solvers.options['refinement'] = False
 
@@ -68,7 +68,7 @@ def l1(P, q):
         di = W['di']
         d1, d2 = di[:m]**2, di[m:]**2
         D = div( mul(d1,d2), d1+d2 )  
-        A = P.T * spmatrix(4*D, range(m), range(m)) * P
+        A = P.T * spdiag(4*D) * P
         lapack.potrf(A)
 
         def f(x, y, z):
diff --git a/examples/doc/chap8/lp b/examples/doc/chap8/lp
new file mode 100755
index 0000000..2ffef69
--- /dev/null
+++ b/examples/doc/chap8/lp
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+
+# The small LP of section 8.3.  
+
+from cvxopt.base import matrix  
+from cvxopt import solvers  
+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']  
diff --git a/examples/doc/mcsdp b/examples/doc/chap8/mcsdp
similarity index 100%
rename from examples/doc/mcsdp
rename to examples/doc/chap8/mcsdp
diff --git a/examples/doc/qcl1 b/examples/doc/chap8/qcl1
similarity index 100%
rename from examples/doc/qcl1
rename to examples/doc/chap8/qcl1
diff --git a/examples/doc/chap8/sdp b/examples/doc/chap8/sdp
new file mode 100755
index 0000000..a1c3751
--- /dev/null
+++ b/examples/doc/chap8/sdp
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+# The small SDP of section 8.4.  
+
+from cvxopt.base import matrix  
+from cvxopt import solvers  
+c = matrix([1.,-1.,1.])  
+G = [ matrix([[-7., -11., -11., 3.],  
+              [ 7., -18., -18., 8.],  
+              [-2.,  -8.,  -8., 1.]]) ]  
+G += [ matrix([[-21., -11.,   0., -11.,  10.,   8.,   0.,   8., 5.],  
+               [  0.,  10.,  16.,  10., -10., -10.,  16., -10., 3.],  
+               [ -5.,   2., -17.,   2.,  -6.,   8., -17.,  -7., 6.]]) ]  
+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]  
diff --git a/examples/doc/chap8/socp b/examples/doc/chap8/socp
new file mode 100755
index 0000000..41a1357
--- /dev/null
+++ b/examples/doc/chap8/socp
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+# The small SOCP of section 8.3.  
+
+from cvxopt.base import matrix  
+from cvxopt import solvers  
+c = matrix([-2., 1., 5.])  
+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]  
diff --git a/examples/doc/chap9/acent b/examples/doc/chap9/acent
new file mode 100755
index 0000000..c295a25
--- /dev/null
+++ b/examples/doc/chap9/acent
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+# The equality constrained analytical centering example of section 9.1.  
+
+from cvxopt import random, blas
+from cvxopt.base import matrix, spmatrix, spdiag, log
+from cvxopt import solvers
+
+def acent(A, b):
+     
+    # Returns the solution of
+    #
+    #     minimize    -sum log(x)
+    #     subject to  A*x = b
+    
+    m, n = A.size
+    def F(x=None, z=None):
+        if x is None:  return 0, matrix(1.0, (n,1))
+        if min(x) <= 0.0:  return None
+        f = -sum(log(x))
+        Df = -(x**-1).T 
+        if z is None: return matrix(f), Df
+        H = spdiag(z[0] * x**-2)
+        return f, Df, H
+ 
+    return solvers.cp(F, A=A, b=b)['x']
+
+
+# Randomly generate a feasible problem
+
+m, n = 50, 500
+y = random.normal(m,1)
+
+# Random A with A'*y > 0.
+s = random.uniform(n,1)
+A = random.normal(m,n)
+r = s - A.T * y
+# A = A - (1/y'*y) * y*r'
+blas.ger(y, r, A, alpha = 1.0/blas.dot(y,y)) 
+
+# Random feasible x > 0.
+x = random.uniform(n,1)
+b = A*x
+
+x = acent(A,b)
diff --git a/examples/doc/chap9/acent2 b/examples/doc/chap9/acent2
new file mode 100755
index 0000000..54f314a
--- /dev/null
+++ b/examples/doc/chap9/acent2
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+# The analytic centering with cone constraints example of section 9.1.  
+
+from cvxopt.base import matrix, log, div, spdiag  
+from cvxopt import solvers  
+ 
+def F(x = None, z = None):  
+     if x is None:  return 0, matrix(0.0, (3,1))  
+     if max(abs(x)) >= 1.0:  return None  
+     u = 1 - x**2  
+     val = -sum(log(u))  
+     Df = div(2*x, u).T  
+     if z is None:  return val, Df  
+     H = spdiag(2 * z[0] * div(1 + u**2, u**2))  
+     return val, Df, H  
+ 
+G = matrix([ 
+    [0., -1.,  0.,  0., -21., -11.,   0., -11.,  10.,   8.,   0.,   8., 5.],
+    [0.,  0., -1.,  0.,   0.,  10.,  16.,  10., -10., -10.,  16., -10., 3.],
+    [0.,  0.,  0., -1.,  -5.,   2., -17.,   2.,  -6.,   8., -17.,  -7., 6.]
+    ])  
+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']  
diff --git a/examples/doc/chap9/floorplan b/examples/doc/chap9/floorplan
new file mode 100755
index 0000000..7d83259
--- /dev/null
+++ b/examples/doc/chap9/floorplan
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+
+# The floor planning example section 9.2.  
+
+import pylab  
+from cvxopt import solvers  
+from cvxopt.base import matrix, spmatrix, mul, div  
+solvers.options['show_progress'] = False
+ 
+def floorplan(Amin):  
+ 
+    #     minimize    W+H  
+    #     subject to  Amink / hk <= wk, k = 1,..., 5  
+    #                 x1 >= 0,  x2 >= 0, x4 >= 0  
+    #                 x1 + w1 + rho <= x3  
+    #                 x2 + w2 + rho <= x3  
+    #                 x3 + w3 + rho <= x5  
+    #                 x4 + w4 + rho <= x5  
+    #                 x5 + w5 <= W  
+    #                 y2 >= 0,  y3 >= 0,  y5 >= 0  
+    #                 y2 + h2 + rho <= y1  
+    #                 y1 + h1 + rho <= y4  
+    #                 y3 + h3 + rho <= y4  
+    #                 y4 + h4 <= H  
+    #                 y5 + h5 <= H  
+    #                 hk/gamma <= wk <= gamma*hk,  k = 1, ..., 5  
+    #  
+    # 22 Variables W, H, x (5), y (5), w (5), h (5).  
+    #  
+    # W, H:  scalars; bounding box width and height  
+    # x, y:  5-vectors; coordinates of bottom left corners of blocks  
+    # w, h:  5-vectors; widths and heigths of the 5 blocks  
+ 
+    rho, gamma = 1.0, 5.0   # min spacing, min aspect ratio  
+ 
+    # The objective is to minimize W + H.  There are five nonlinear  
+    # constraints  
+    #  
+    #     -wk + Amink / hk <= 0,  k = 1, ..., 5  
+ 
+    c = matrix(2*[1.0] + 20*[0.0])  
+ 
+    def F(x=None, z=None):  
+        if x is None:  return 5, matrix(17*[0.0] + 5*[1.0])  
+        if min(x[17:]) <= 0.0:  return None  
+        f = -x[12:17] + div(Amin, x[17:])  
+        Df = matrix(0.0, (5,22))  
+        Df[:,12:17] = spmatrix(-1.0, range(5), range(5))  
+        Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5))  
+        if z is None: return f, Df  
+        H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), 
+            range(17,22) )  
+        return f, Df, H  
+ 
+    G = matrix(0.0, (26,22))  
+    h = matrix(0.0, (26,1))  
+
+    # -x1 <= 0  
+    G[0,2] = -1.0                                    
+
+    # -x2 <= 0   
+    G[1,3] = -1.0                                   
+
+    # -x4 <= 0  
+    G[2,5] = -1.0
+
+    # x1 - x3 + w1 <= -rho
+    G[3, [2, 4, 12]], h[3] = [1.0, -1.0, 1.0], -rho  
+
+    # x2 - x3 + w2 <= -rho
+    G[4, [3, 4, 13]], h[4] = [1.0, -1.0, 1.0], -rho  
+
+    # x3 - x5 + w3 <= -rho
+    G[5, [4, 6, 14]], h[5] = [1.0, -1.0, 1.0], -rho  
+
+    # x4 - x5 + w4 <= -rho
+    G[6, [5, 6, 15]], h[6] = [1.0, -1.0, 1.0], -rho  
+
+    # -W + x5 + w5 <= 0  
+    G[7, [0, 6, 16]] = -1.0, 1.0, 1.0                
+
+    # -y2 <= 0  
+    G[8,8] = -1.0                                    
+
+    # -y3 <= 0  
+    G[9,9] = -1.0                                    
+
+    # -y5 <= 0  
+    G[10,11] = -1.0                                  
+
+    # -y1 + y2 + h2 <= -rho  
+    G[11, [7, 8, 18]], h[11] = [-1.0, 1.0, 1.0], -rho  
+
+    # y1 - y4 + h1 <= -rho  
+    G[12, [7, 10, 17]], h[12] = [1.0, -1.0, 1.0], -rho  
+
+    # y3 - y4 + h3 <= -rho  
+    G[13, [9, 10, 19]], h[13] = [1.0, -1.0, 1.0], -rho  
+
+    # -H + y4 + h4 <= 0  
+    G[14, [1, 10, 20]] = -1.0, 1.0, 1.0                 
+
+    # -H + y5 + h5 <= 0  
+    G[15, [1, 11, 21]] = -1.0, 1.0, 1.0                 
+
+    # -w1 + h1/gamma <= 0  
+    G[16, [12, 17]] = -1.0, 1.0/gamma                   
+
+    # w1 - gamma * h1 <= 0  
+    G[17, [12, 17]] = 1.0, -gamma                       
+
+    # -w2 + h2/gamma <= 0  
+    G[18, [13, 18]] = -1.0, 1.0/gamma                   
+
+    #  w2 - gamma * h2 <= 0  
+    G[19, [13, 18]] = 1.0, -gamma                       
+
+    # -w3 + h3/gamma <= 0  
+    G[20, [14, 18]] = -1.0, 1.0/gamma                   
+
+    #  w3 - gamma * h3 <= 0  
+    G[21, [14, 19]] = 1.0, -gamma                       
+
+    # -w4  + h4/gamma <= 0  
+    G[22, [15, 19]] = -1.0, 1.0/gamma                   
+
+    #  w4 - gamma * h4 <= 0  
+    G[23, [15, 20]] = 1.0, -gamma                       
+
+    # -w5 + h5/gamma <= 0  
+    G[24, [16, 21]] = -1.0, 1.0/gamma                   
+
+    #  w5 - gamma * h5 <= 0.0  
+    G[25, [16, 21]] = 1.0, -gamma                       
+
+    # solve and return W, H, x, y, w, h  
+    sol = solvers.cpl(c, F, G, h)  
+    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()
diff --git a/examples/doc/chap9/gp b/examples/doc/chap9/gp
new file mode 100755
index 0000000..a0b4fee
--- /dev/null
+++ b/examples/doc/chap9/gp
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+# The small GP of section 9.4
+
+from cvxopt.base import matrix, log, exp  
+from cvxopt import solvers  
+ 
+Aflr  = 1000.0  
+Awall = 100.0  
+alpha = 0.5  
+beta  = 2.0  
+gamma = 0.5  
+delta = 2.0  
+ 
+F = matrix( [[-1., 1., 1., 0., -1.,  1.,  0.,  0.],  
+             [-1., 1., 0., 1.,  1., -1.,  1., -1.],  
+             [-1., 0., 1., 1.,  0.,  0., -1.,  1.]])  
+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)   
diff --git a/examples/doc/chap9/l1regls b/examples/doc/chap9/l1regls
new file mode 100755
index 0000000..308d3b9
--- /dev/null
+++ b/examples/doc/chap9/l1regls
@@ -0,0 +1,155 @@
+#!/usr/bin/python
+
+# The 1-norm regularized least-squares example of section 9.5.
+
+from cvxopt.base import matrix, spdiag, mul, div
+from cvxopt import base, blas, lapack, solvers, random
+import math
+
+def l1regls(A, y):
+
+    m, n = A.size
+    def F(x = None, z = None):
+        """
+        Function and gradient evaluation of
+
+            f = || A*x[:n] - y ||_2^2 +  sum(x[n:])
+        """
+
+        nvars = 2*n
+        if x is None: return 0, matrix(0.0, (nvars,1))
+        r = A*x[:n] - y
+        f = blas.nrm2(r)**2 + sum(x[n:])
+        gradf = matrix(1.0, (1,2*n))
+        blas.gemv(A, r, gradf, alpha=2.0, trans='T')  
+        if z is None:
+            return f, gradf
+        else:
+            def Hf(u, v, alpha = 1.0, beta = 0.0):
+               # Hf evaluates
+               #
+               #     v := alpha * [2.0*z[0] * A'*A, 0; 0, 0] * u + beta * v 
+               #
+               blas.scal(beta, v)
+               w = matrix(0.0, (m, 1))    
+               blas.gemv(A, u, w)
+               blas.gemv(A, w, v, alpha = 2.0 * z[0] * alpha, beta = 1.0, 
+                   trans = 'T')
+            return f, gradf, Hf
+
+
+    def G(u, v, alpha=1.0, beta=0.0, trans='N'):
+        """
+            v := alpha*[I, -I; -I, -I] * u + beta * v  (trans = 'N' or 'T')
+        """
+
+        v *= beta
+        v[:n] += alpha*(u[:n] - u[n:])
+        v[n:] += alpha*(-u[:n] - u[n:])
+
+    h = matrix(0.0, (2*n,1))
+
+
+    # Customized solver for the KKT system 
+    #
+    #     [  2.0*z[0]*A'*A  0    I      -I     ] [x[:n] ]     [bx[:n] ]
+    #     [  0              0   -I      -I     ] [x[n:] ]  =  [bx[n:] ].
+    #     [  I             -I   -D1^-1   0     ] [zl[:n]]     [bzl[:n]]
+    #     [ -I             -I    0      -D2^-1 ] [zl[n:]]     [bzl[n:]]
+    #
+    # where D1 = W['dli'][:n]**2, D2 = W['dli'][:n]**2.
+    #    
+    # We first eliminate zl and x[n:]:
+    #
+    #     ( 2*z[0]*A'*A + 4*D1*D2*(D1+D2)^-1 ) * x[:n] = 
+    #         bx[:n] - (D2-D1)*(D1+D2)^-1 * bx[n:] + 
+    #         D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - 
+    #         D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:]           
+    #
+    #     x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] ) 
+    #         - (D2-D1)*(D1+D2)^-1 * x[:n]         
+    #
+    #     zl[:n] = D1 * ( x[:n] - x[n:] - bzl[:n] )
+    #     zl[n:] = D2 * (-x[:n] - x[n:] - bzl[n:] ).
+    #
+    # The first equation has the form
+    #
+    #     (z[0]*A'*A + D)*x[:n]  =  rhs
+    #
+    # and is equivalent to
+    #
+    #     [ D    A'       ] [ x:n] ]  = [ rhs ]
+    #     [ A   -1/z[0]*I ] [ v    ]    [ 0   ].
+    #
+    # It can be solved as 
+    #
+    #     ( A*D^-1*A' + 1/z[0]*I ) * v = A * D^-1 * rhs
+    #     x[:n] = D^-1 * ( rhs - A'*v ).
+
+    S = matrix(0.0, (m,m))
+    Asc = matrix(0.0, (m,n))
+    v = matrix(0.0, (m,1))
+
+    def Fkkt(x, z, W):
+
+        # Factor 
+        #
+        #     S = A*D^-1*A' + 1/z[0]*I 
+        #
+        # where D = 2*D1*D2*(D1+D2)^-1, D1 = dl[:n]**-2, D2 = dl[n:]**-2.
+
+        d1, d2 = W['dli'][:n]**2, W['dli'][n:]**2
+
+        # ds is square root of diagonal of D
+        ds = math.sqrt(2.0) * div( mul( W['dli'][:n], W['dli'][n:]), 
+            base.sqrt(d1+d2) )
+        d3 =  div(d2 - d1, d1 + d2)
+     
+        # Asc = A*diag(d)^-1/2
+        Asc = A * spdiag(ds**-1)
+
+        # S = 1/z[0]*I + A * D^-1 * A'
+        blas.syrk(Asc, S)
+        S[::m+1] += 1.0 / z[0] 
+        lapack.potrf(S)
+
+        def g(x, y, z):
+
+            x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + 
+                mul(d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - 
+                mul(d3, z[n:])) )
+            x[:n] = div( x[:n], ds) 
+
+            # Solve
+            #
+            #     S * v = 0.5 * A * D^-1 * ( bx[:n] - 
+            #         (D2-D1)*(D1+D2)^-1 * bx[n:] + 
+            #         D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - 
+            #         D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] )
+                
+            blas.gemv(Asc, x, v)
+            lapack.potrs(S, v)
+            
+            # x[:n] = D^-1 * ( rhs - A'*v ).
+            blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T')
+            x[:n] = div(x[:n], ds)
+
+            # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n]  - D2*bzl[n:] ) 
+            #         - (D2-D1)*(D1+D2)^-1 * x[:n]         
+            x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\
+                - mul( d3, x[:n] )
+                
+            # zl[:n] = D1^1/2 * (  x[:n] - x[n:] - bzl[:n] )
+            # zl[n:] = D2^1/2 * ( -x[:n] - x[n:] - bzl[n:] ).
+            z[:n] = mul( W['dli'][:n],  x[:n] - x[n:] - z[:n] ) 
+            z[n:] = mul( W['dli'][n:], -x[:n] - x[n:] - z[n:] ) 
+
+        return g
+
+    return solvers.cp(F, G, h, kktsolver = Fkkt)['x'][:n]
+
+m, n = 100, 1000
+random.setseed()
+A = random.normal(m,n)
+b = random.normal(m)
+x = l1regls(A, b)
diff --git a/examples/book/chap4/portfolio b/examples/doc/chap9/portfolio
similarity index 80%
copy from examples/book/chap4/portfolio
copy to examples/doc/chap9/portfolio
index 7d0046d..1b936f4 100755
--- a/examples/book/chap4/portfolio
+++ b/examples/doc/chap9/portfolio
@@ -1,7 +1,6 @@
 #!/usr/bin/python
  
-# Figure 4.12, page 187.
-# Risk-return trade-off.
+# The risk-return trade-off of section 9.3.
 
 from math import sqrt
 from cvxopt.base import matrix
@@ -42,10 +41,10 @@ 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], '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c2[-1::-1] + c1 , '#D0D0D0') 
-pylab.fill(risks[-1::-1] + risks, c3[-1::-1] + c2, '#F0F0F0') 
-pylab.fill(risks[-1::-1] + risks, c4[-1::-1] + c3,  '#D0D0D0') 
+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')
diff --git a/examples/doc/chap9/robls b/examples/doc/chap9/robls
new file mode 100755
index 0000000..54a80e6
--- /dev/null
+++ b/examples/doc/chap9/robls
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+# The robust least-squares example of section 9.1.  
+
+from math import sqrt, ceil, floor
+from cvxopt import random, solvers, blas, lapack
+from cvxopt.base import matrix, spmatrix, spdiag, sqrt, mul, div
+import pylab
+
+def robls(A, b, rho): 
+
+    # Minimize  sum_k sqrt(rho + (A*x-b)_k^2).
+
+    m, n = A.size
+    def F(x=None, z=None):
+        if x is None: return 0, matrix(0.0, (n,1))
+        y = A*x-b
+        w = sqrt(rho + y**2)
+        f = sum(w)
+        Df = div(y, w).T * A 
+        if z is None: return f, Df 
+        H = A.T * spdiag(z[0]*rho*(w**-3)) * A
+        return f, Df, H
+
+    return solvers.cp(F)['x']
+
+
+random.setseed()
+m, n  = 500, 100
+A = random.normal(m,n)
+b = random.normal(m,1)
+xh = robls(A,b,0.1)
+
+try: import pylab
+except ImportError: pass
+else:
+
+    # Least-squares solution.
+    pylab.subplot(211)
+    xls = +b
+    lapack.gels(+A,xls)
+    rls =  A*xls[:n] - b
+    pylab.hist(rls, m/5)
+    pylab.title('Least-squares solution')
+    pylab.xlabel('Residual')
+    mr = ceil(max(rls))
+    pylab.axis([-mr, mr, 0, 25])
+ 
+    # Robust least-squares solution with rho = 0.01.
+    pylab.subplot(212)
+    rh =  A*xh - b
+    pylab.hist(rh, m/5)
+    mr = ceil(max(rh))
+    pylab.title('Robust least-squares solution')
+    pylab.xlabel('Residual')
+    pylab.axis([-mr, mr, 0, 50])
+
+    pylab.show()
diff --git a/src/C/SuiteSparse/CHOLMOD/Check/cholmod_write.c b/src/C/SuiteSparse/CHOLMOD/Check/cholmod_write.c
index dc461ba..0c2d83f 100644
--- a/src/C/SuiteSparse/CHOLMOD/Check/cholmod_write.c
+++ b/src/C/SuiteSparse/CHOLMOD/Check/cholmod_write.c
@@ -24,6 +24,7 @@
 
 #include "cholmod_internal.h"
 #include "cholmod_check.h"
+#include "cholmod_matrixops.h"
 #include <string.h>
 #include <ctype.h>
 
@@ -120,10 +121,10 @@ static int print_value
     Int is_integer  /* TRUE if printing as an integer */
 )
 {
-    double y, z ;
+    double y ;
     char s [MAXLINE], *p ;
-    Int width, i, c, dest, src ;
-    int ok ;
+    Int i, dest = 0, src = 0 ;
+    int width, ok ;
 
     if (is_integer)
     {
@@ -358,11 +359,11 @@ int CHOLMOD(write_sparse)
     cholmod_common *Common
 )
 {
-    double x, z ;
+    double x = 0, z = 0 ;
     double *Ax, *Az ;
     Int *Ap, *Ai, *Anz, *Zp, *Zi, *Znz ;
     Int nrow, ncol, is_complex, symmetry, i, j, q, iz, p, nz, is_binary, stype,
-	is_integer, asym, is_sym, xtype, apacked, zpacked, pend, qend, k, zsym ;
+	is_integer, asym, is_sym, xtype, apacked, zpacked, pend, qend, zsym ;
     int ok ;
 
     /* ---------------------------------------------------------------------- */
@@ -524,6 +525,8 @@ int CHOLMOD(write_sparse)
 	ok = ok && (fprintf (f, " real") > 0) ;
     }
 
+    is_sym = FALSE ;
+
     switch (asym)
     {
 	case CHOLMOD_MM_RECTANGULAR:
@@ -659,10 +662,9 @@ int CHOLMOD(write_dense)
     cholmod_common *Common
 )
 {
-    double x, z ;
-    FILE *cf ;
+    double x = 0, z = 0 ;
     double *Xx, *Xz ;
-    Int nrow, ncol, is_complex, i, j, nz, xtype, p ;
+    Int nrow, ncol, is_complex, i, j, xtype, p ;
     int ok ;
 
     /* ---------------------------------------------------------------------- */
diff --git a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_resymbol.c b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_resymbol.c
index a25f771..c1c0018 100644
--- a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_resymbol.c
+++ b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_resymbol.c
@@ -442,7 +442,10 @@ int CHOLMOD(resymbol_noperm)
 	/* ------------------------------------------------------------------ */
 
 	/* flag the diagonal entry */
-	mark = CHOLMOD(clear_flag) (Common) ;
+	/* mark = CHOLMOD(clear_flag) (Common) ; */
+	CHOLMOD_CLEAR_FLAG (Common) ;
+	mark = Common->mark ;
+
 	Flag [k] = mark ;
 	PRINT1 (("	row: "ID" (diagonal)\n", k)) ;
 
@@ -596,7 +599,9 @@ int CHOLMOD(resymbol_noperm)
     /* clear workspace */
     /* ---------------------------------------------------------------------- */
 
-    CHOLMOD(clear_flag) (Common) ;
+    /* CHOLMOD(clear_flag) (Common) ; */
+    CHOLMOD_CLEAR_FLAG (Common) ;
+
     DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol final L (i, x):", Common)) ;
     ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
     return (TRUE) ;
diff --git a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowcolcounts.c b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowcolcounts.c
index 7965868..62d5770 100644
--- a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowcolcounts.c
+++ b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowcolcounts.c
@@ -509,7 +509,9 @@ int CHOLMOD(rowcolcounts)
     /* ---------------------------------------------------------------------- */
 
     Common->mark = EMPTY ;
-    CHOLMOD(clear_flag) (Common) ;
+    /* CHOLMOD(clear_flag) (Common) ; */
+    CHOLMOD_CLEAR_FLAG (Common) ;
+
     ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
 
     /* ---------------------------------------------------------------------- */
diff --git a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowfac.c b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowfac.c
index f0be0e9..255bb9b 100644
--- a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowfac.c
+++ b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_rowfac.c
@@ -299,7 +299,9 @@ int CHOLMOD(row_subtree)
     /* ---------------------------------------------------------------------- */
 
     Flag = Common->Flag ;	/* size nrow, Flag [i] < mark must hold */
-    mark = CHOLMOD(clear_flag) (Common) ;
+    /* mark = CHOLMOD(clear_flag) (Common) ; */
+    CHOLMOD_CLEAR_FLAG (Common) ;
+    mark = Common->mark ;
 
     /* ---------------------------------------------------------------------- */
     /* compute the pattern of L(k,:) */
diff --git a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_spsolve.c b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_spsolve.c
index 9ae0a93..a9c34f9 100644
--- a/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_spsolve.c
+++ b/src/C/SuiteSparse/CHOLMOD/Cholesky/cholmod_spsolve.c
@@ -75,7 +75,7 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
     cholmod_sparse *X ;
     double *Bx, *Bz, *Xx, *Xz, *B4x, *B4z, *X4x, *X4z ;
     Int *Bi, *Bp, *Xp, *Xi, *Bnz ;
-    Int n, nrhs, q, p, i, j, j1, j2, packed, block, pend, jn, xtype ;
+    Int n, nrhs, q, p, i, j, jfirst, jlast, packed, block, pend, j_n, xtype ;
     size_t xnz, nzmax ;
 
     /* ---------------------------------------------------------------------- */
@@ -147,25 +147,25 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
     /* solve in chunks of 4 columns at a time */
     /* ---------------------------------------------------------------------- */
 
-    for (j1 = 0 ; j1 < nrhs ; j1 += block)
+    for (jfirst = 0 ; jfirst < nrhs ; jfirst += block)
     {
 
 	/* ------------------------------------------------------------------ */
 	/* adjust the number of columns of B4 */
 	/* ------------------------------------------------------------------ */
 
-	j2 = MIN (nrhs, j1 + block) ;
-	B4->ncol = j2 - j1 ;
+	jlast = MIN (nrhs, jfirst + block) ;
+	B4->ncol = jlast - jfirst ;
 
 	/* ------------------------------------------------------------------ */
-	/* scatter B(j1:j2-1) into B4 */
+	/* scatter B(jfirst:jlast-1) into B4 */
 	/* ------------------------------------------------------------------ */
 
-	for (j = j1 ; j < j2 ; j++)
+	for (j = jfirst ; j < jlast ; j++)
 	{
 	    p = Bp [j] ;
 	    pend = (packed) ? (Bp [j+1]) : (p + Bnz [j]) ;
-	    jn = (j-j1)*n ;
+	    j_n = (j-jfirst)*n ;
 
 	    switch (B->xtype)
 	    {
@@ -173,14 +173,14 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		case CHOLMOD_REAL:
 		    for ( ; p < pend ; p++)
 		    {
-			B4x [Bi [p] + jn] = Bx [p] ;
+			B4x [Bi [p] + j_n] = Bx [p] ;
 		    }
 		    break ;
 
 		case CHOLMOD_COMPLEX:
 		    for ( ; p < pend ; p++)
 		    {
-			q = Bi [p] + jn ;
+			q = Bi [p] + j_n ;
 			B4x [2*q  ] = Bx [2*p  ] ;
 			B4x [2*q+1] = Bx [2*p+1] ;
 		    }
@@ -189,7 +189,7 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		case CHOLMOD_ZOMPLEX:
 		    for ( ; p < pend ; p++)
 		    {
-			q = Bi [p] + jn ;
+			q = Bi [p] + j_n ;
 			B4x [q] = Bx [p] ;
 			B4z [q] = Bz [p] ;
 		    }
@@ -217,10 +217,10 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 	/* append the solution onto X */
 	/* ------------------------------------------------------------------ */
 
-	for (j = j1 ; j < j2 ; j++)
+	for (j = jfirst ; j < jlast ; j++)
 	{
 	    Xp [j] = xnz ;
-	    jn = (j-j1)*n ;
+	    j_n = (j-jfirst)*n ;
 	    if ( xnz + n <= nzmax)
 	    {
 
@@ -234,7 +234,7 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_REAL:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [i + jn] ;
+			    x = X4x [i + j_n] ;
 			    if (IS_NONZERO (x))
 			    {
 				Xi [xnz] = i ;
@@ -247,8 +247,8 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_COMPLEX:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [2*(i + jn)  ] ;
-			    z = X4x [2*(i + jn)+1] ;
+			    x = X4x [2*(i + j_n)  ] ;
+			    z = X4x [2*(i + j_n)+1] ;
 			    if (IS_NONZERO (x) || IS_NONZERO (z))
 			    {
 				Xi [xnz] = i ;
@@ -262,8 +262,8 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_ZOMPLEX:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [i + jn] ;
-			    z = X4z [i + jn] ;
+			    x = X4x [i + j_n] ;
+			    z = X4z [i + j_n] ;
 			    if (IS_NONZERO (x) || IS_NONZERO (z))
 			    {
 				Xi [xnz] = i ;
@@ -289,7 +289,7 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_REAL:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [i + jn] ;
+			    x = X4x [i + j_n] ;
 			    if (IS_NONZERO (x))
 			    {
 				EXPAND_AS_NEEDED ;
@@ -303,8 +303,8 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_COMPLEX:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [2*(i + jn)  ] ;
-			    z = X4x [2*(i + jn)+1] ;
+			    x = X4x [2*(i + j_n)  ] ;
+			    z = X4x [2*(i + j_n)+1] ;
 			    if (IS_NONZERO (x) || IS_NONZERO (z))
 			    {
 				EXPAND_AS_NEEDED ;
@@ -319,8 +319,8 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_ZOMPLEX:
 			for (i = 0 ; i < n ; i++)
 			{
-			    x = X4x [i + jn] ;
-			    z = X4z [i + jn] ;
+			    x = X4x [i + j_n] ;
+			    z = X4z [i + j_n] ;
 			    if (IS_NONZERO (x) || IS_NONZERO (z))
 			    {
 				EXPAND_AS_NEEDED ;
@@ -341,14 +341,14 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 	/* clear B4 for next iteration */
 	/* ------------------------------------------------------------------ */
 
-	if (j2 < nrhs)
+	if (jlast < nrhs)
 	{
 
-	    for (j = j1 ; j < j2 ; j++)
+	    for (j = jfirst ; j < jlast ; j++)
 	    {
 		p = Bp [j] ;
 		pend = (packed) ? (Bp [j+1]) : (p + Bnz [j]) ;
-		jn = (j-j1)*n ;
+		j_n = (j-jfirst)*n ;
 
 		switch (B->xtype)
 		{
@@ -356,14 +356,14 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_REAL:
 			for ( ; p < pend ; p++)
 			{
-			    B4x [Bi [p] + jn] = 0 ;
+			    B4x [Bi [p] + j_n] = 0 ;
 			}
 			break ;
 
 		    case CHOLMOD_COMPLEX:
 			for ( ; p < pend ; p++)
 			{
-			    q = Bi [p] + jn ;
+			    q = Bi [p] + j_n ;
 			    B4x [2*q  ] = 0 ;
 			    B4x [2*q+1] = 0 ;
 			}
@@ -372,7 +372,7 @@ cholmod_sparse *CHOLMOD(spsolve)	    /* returns the sparse solution X */
 		    case CHOLMOD_ZOMPLEX:
 			for ( ; p < pend ; p++)
 			{
-			    q = Bi [p] + jn ;
+			    q = Bi [p] + j_n ;
 			    B4x [q] = 0 ;
 			    B4z [q] = 0 ;
 			}
diff --git a/src/C/SuiteSparse/CHOLMOD/Cholesky/t_cholmod_rowfac.c b/src/C/SuiteSparse/CHOLMOD/Cholesky/t_cholmod_rowfac.c
index 57f0f33..38120ce 100644
--- a/src/C/SuiteSparse/CHOLMOD/Cholesky/t_cholmod_rowfac.c
+++ b/src/C/SuiteSparse/CHOLMOD/Cholesky/t_cholmod_rowfac.c
@@ -261,7 +261,9 @@ static int TEMPLATE (cholmod_rowfac)
 	/* nonzero pattern of kth row of L is now in Stack [top..n-1].
 	 * Flag [Stack [top..n-1]] is equal to mark, but no longer needed */
 
-	mark = CHOLMOD(clear_flag) (Common) ;
+	/* mark = CHOLMOD(clear_flag) (Common) ; */
+	CHOLMOD_CLEAR_FLAG (Common) ;
+	mark = Common->mark ;
 
 	/* ------------------------------------------------------------------ */
 	/* compute kth row of L and store in column form */
diff --git a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_aat.c b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_aat.c
index 0b2b75b..7514edf 100644
--- a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_aat.c
+++ b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_aat.c
@@ -125,7 +125,9 @@ cholmod_sparse *CHOLMOD(aat)
     for (j = 0 ; j < n ; j++)
     {
 	/* clear the Flag array */
-	mark = CHOLMOD(clear_flag) (Common) ;
+	/* mark = CHOLMOD(clear_flag) (Common) ; */
+	CHOLMOD_CLEAR_FLAG (Common) ;
+	mark = Common->mark ;
 
 	/* exclude the diagonal, if requested */
 	if (!diag)
diff --git a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_add.c b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_add.c
index c7fbba5..04eca8b 100644
--- a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_add.c
+++ b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_add.c
@@ -152,7 +152,9 @@ cholmod_sparse *CHOLMOD(add)
 
     /* If integer overflow occurs, nzmax < 0 and the allocate fails properly
      * (likewise in most other matrix manipulation routines). */
-    nzmax = A->nzmax + B->nzmax ;
+
+    nzmax = CHOLMOD(nnz) (A, Common) + CHOLMOD(nnz) (B, Common) ;
+
     C = CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, FALSE, TRUE,
 	    SIGN (A->stype), values ? A->xtype : CHOLMOD_PATTERN, Common) ;
     if (Common->status < CHOLMOD_OK)
@@ -176,7 +178,9 @@ cholmod_sparse *CHOLMOD(add)
 	Cp [j] = nz ;
 
 	/* clear the Flag array */
-	mark = CHOLMOD(clear_flag) (Common) ;
+	/* mark = CHOLMOD(clear_flag) (Common) ; */
+	CHOLMOD_CLEAR_FLAG (Common) ;
+	mark = Common->mark ;
 
 	/* scatter B into W */
 	pb = Bp [j] ;
diff --git a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_common.c b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_common.c
index d954024..9b00b8d 100644
--- a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_common.c
+++ b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_common.c
@@ -167,7 +167,7 @@ int CHOLMOD(start)
     /* Common->called_nd is TRUE if cholmod_analyze called or NESDIS */
     Common->called_nd = FALSE ;
 
-    DEBUG_INIT ("cholmod start") ;
+    DEBUG_INIT ("cholmod start", Common) ;
     return (TRUE) ;
 }
 
diff --git a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_factor.c b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_factor.c
index 8af9b38..0185ce4 100644
--- a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_factor.c
+++ b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_factor.c
@@ -765,7 +765,7 @@ cholmod_factor *CHOLMOD(copy_factor)
 	    CHOLMOD(free_factor) (&L2, Common) ;
 	    return (NULL) ;	/* out of memory */
 	}
-	ASSERT (L->nzmax == L2->nzmax) ;
+	ASSERT (MAX (1, L->nzmax) == L2->nzmax) ;
 
 	/* ------------------------------------------------------------------ */
 	/* copy the contents of a simplicial numeric factor */
diff --git a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_memory.c b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_memory.c
index 141f006..f6a1f00 100644
--- a/src/C/SuiteSparse/CHOLMOD/Core/cholmod_memory.c
+++ b/src/C/SuiteSparse/CHOLMOD/Core/cholmod_memory.c
@@ -204,8 +204,6 @@ void *CHOLMOD(free)	/* always returns NULL */
 	/* This assertion will fail if the user calls cholmod_malloc and
 	 * cholmod_free with mismatched memory sizes.  It shouldn't fail
 	 * otherwise. */
-	DEBUG (if (Common->malloc_count == 0 && Common->memory_inuse != 0)
-	    PRINT0 (("inuse: %d\n", Common->memory_inuse))) ;
 	ASSERT (IMPLIES (Common->malloc_count == 0, Common->memory_inuse == 0));
     }
     /* return NULL, and the caller should assign this to p.  This avoids
diff --git a/src/C/SuiteSparse/CHOLMOD/Doc/ChangeLog b/src/C/SuiteSparse/CHOLMOD/Doc/ChangeLog
index 6cc80d3..487ba9a 100644
--- a/src/C/SuiteSparse/CHOLMOD/Doc/ChangeLog
+++ b/src/C/SuiteSparse/CHOLMOD/Doc/ChangeLog
@@ -1,3 +1,28 @@
+Nov 1, 2007, version 1.6.0
+
+    * minor lint cleanup (no bugs)
+
+    * new CHOLMOD_CLEAR_FLAG macro, which speeds up the calls to
+	cholmod_clear_flag, avoiding the function call if not needed.  Note
+	that this leads to untested lines in the Tcov test, but the lines of
+	the macro are tested in several places, just not everywhere it appers.
+
+    * port to MATLAB 7.5 (mex -lmwblas option now required for Linux)
+
+    * minor bug fix to cholmod_add.c to avoid potential Int overflow
+
+    * extra option added to cholmod2 mexFunction
+
+    * sparse2 mexFunction modified to ensure nnz(A) == nzmax(A) always holds
+	(It didn't in v1.5.0 if numerically zero entries were dropped in A).
+
+    * correction to Help comments for spsym function
+
+    * bug fix to cholmod_symmetry.c: determination of Hermitian vs non-Hermitian
+	matrices was incorrect if the diagonal was imaginary.
+
+    * performance fix for cholmod_nesdis.c and nesdis mexFunction
+
 May 31, 2007, version 1.5.0
 
     * 64-bit MATLAB interface
diff --git a/src/C/SuiteSparse/CHOLMOD/Doc/UserGuide.tex b/src/C/SuiteSparse/CHOLMOD/Doc/UserGuide.tex
index 1f656fd..8a0d72e 100644
--- a/src/C/SuiteSparse/CHOLMOD/Doc/UserGuide.tex
+++ b/src/C/SuiteSparse/CHOLMOD/Doc/UserGuide.tex
@@ -21,7 +21,7 @@ Dept. of Computer and Information Science and Engineering \\
 Univ. of Florida, Gainesville, FL}
 \title{User Guide for CHOLMOD: a sparse Cholesky factorization and
 modification package}
-\date{Version 1.5, May 31, 2007}
+\date{Version 1.6, Nov 1, 2007}
 \maketitle
 
 %-------------------------------------------------------------------------------
diff --git a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_blas.h b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_blas.h
index 7d2b051..7957968 100644
--- a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_blas.h
+++ b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_blas.h
@@ -430,7 +430,7 @@ void BLAS_DGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
     } \
 }
 
-void BLAS_ZGERU (BLAS_INT *m, BLAS_INT *n, double *alpha,
+void BLAS_ZGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
 	double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy,
 	double *A, BLAS_INT *lda) ;
 
diff --git a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_core.h b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_core.h
index e282f9d..523f505 100644
--- a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_core.h
+++ b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_core.h
@@ -244,10 +244,10 @@
  *	#endif
  */
 
-#define CHOLMOD_DATE "May 31, 2007"
+#define CHOLMOD_DATE "Nov 1, 2007"
 #define CHOLMOD_VER_CODE(main,sub) ((main) * 1000 + (sub))
 #define CHOLMOD_MAIN_VERSION 1
-#define CHOLMOD_SUB_VERSION 5
+#define CHOLMOD_SUB_VERSION 6
 #define CHOLMOD_SUBSUB_VERSION 0
 #define CHOLMOD_VERSION \
     CHOLMOD_VER_CODE(CHOLMOD_MAIN_VERSION,CHOLMOD_SUB_VERSION)
@@ -1008,6 +1008,17 @@ int cholmod_l_free_work (cholmod_common *) ;
 /* cholmod_clear_flag:  clear Flag workspace in Common */
 /* -------------------------------------------------------------------------- */
 
+/* use a macro for speed */
+#define CHOLMOD_CLEAR_FLAG(Common) \
+{ \
+    Common->mark++ ; \
+    if (Common->mark <= 0) \
+    { \
+	Common->mark = EMPTY ; \
+	CHOLMOD (clear_flag) (Common) ; \
+    } \
+}
+
 UF_long cholmod_clear_flag
 (
     cholmod_common *Common
diff --git a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_internal.h b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_internal.h
index 89160d6..383eecb 100644
--- a/src/C/SuiteSparse/CHOLMOD/Include/cholmod_internal.h
+++ b/src/C/SuiteSparse/CHOLMOD/Include/cholmod_internal.h
@@ -57,6 +57,10 @@
 #undef NDEBUG
  */
 
+#ifdef MATLAB_MEX_FILE
+#include "mex.h"
+#endif
+
 #if !defined(NPRINT) || !defined(NDEBUG)
 #include <stdio.h>
 #endif
@@ -349,7 +353,7 @@ int  cholmod_l_dump_partition (UF_long, UF_long *, UF_long *, UF_long *,
 	UF_long *, UF_long, cholmod_common *) ;
 int  cholmod_l_dump_work(int, int, UF_long, cholmod_common *) ;
 
-#define DEBUG_INIT(s)  { CHOLMOD(dump_init)(s, Common) ; }
+#define DEBUG_INIT(s,Common)  { CHOLMOD(dump_init)(s, Common) ; }
 #define ASSERT(expression) (assert (expression))
 
 #define PRK(k,params) \
@@ -364,7 +368,14 @@ int  cholmod_l_dump_work(int, int, UF_long, cholmod_common *) ;
 #define PRINT1(params) PRK (1, params)
 #define PRINT2(params) PRK (2, params)
 #define PRINT3(params) PRK (3, params)
-#define PRINTM(params) PRK (CHOLMOD(dump_malloc), params)
+
+#define PRINTM(params) \
+{ \
+    if (CHOLMOD(dump_malloc) > 0) \
+    { \
+	printf params ; \
+    } \
+}
 
 #define DEBUG(statement) statement
 
@@ -372,7 +383,7 @@ int  cholmod_l_dump_work(int, int, UF_long, cholmod_common *) ;
 
 /* Debugging disabled (the normal case) */
 #define PRK(k,params)
-#define DEBUG_INIT(s)
+#define DEBUG_INIT(s,Common)
 #define PRINT0(params)
 #define PRINT1(params)
 #define PRINT2(params)
diff --git a/src/C/SuiteSparse/CHOLMOD/README.txt b/src/C/SuiteSparse/CHOLMOD/README.txt
index 985a190..193d758 100644
--- a/src/C/SuiteSparse/CHOLMOD/README.txt
+++ b/src/C/SuiteSparse/CHOLMOD/README.txt
@@ -1,5 +1,5 @@
 CHOLMOD: a sparse CHOLesky MODification package 
-Version 1.5, May 31, 2007.  Copyright (c) 2005-2007.
+Version 1.6, Nov 1, 2007.  Copyright (c) 2005-2007.
 -----------------------------------------------
 
     CHOLMOD is a set of routines for factorizing sparse symmetric positive
@@ -34,9 +34,16 @@ LAPACK is available at http://www.netlib.org/lapack
 METIS is authored by George Karypis, Univ. of Minnesota.  Its use in CHOLMOD
 is optional.  See http://www-users.cs.umn.edu/~karypis/metis.
 Place a copy of the metis-4.0 directory in the same directory that
-contains the CHOLMOD, AMD, COLAMD, and CCOLAMD directories.  Then do:
-    cd metis-4.0 ; make
-You may then compile CHOLMOD.
+contains the CHOLMOD, AMD, COLAMD, and CCOLAMD directories prior to compiling
+with "make".
+
+If you do not wish to use METIS, you must edit UFconfig and change the line:
+
+    CHOLMOD_CONFIG =
+
+to
+
+    CHOLMOD_CONFIG = -DNPARTITION
 
 The CHOLMOD, AMD, COLAMD, CCOLAMD, and UFconfig directories must all reside
 in a common parent directory.  To compile all these libraries,
diff --git a/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_numeric.c b/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_numeric.c
index 28c6abc..93d33a2 100644
--- a/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_numeric.c
+++ b/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_numeric.c
@@ -287,7 +287,8 @@ int CHOLMOD(super_numeric)
 
     /* Flag array was used as workspace, clear it */
     Common->mark = EMPTY ;
-    CHOLMOD(clear_flag) (Common) ;
+    /* CHOLMOD(clear_flag) (Common) ; */
+    CHOLMOD_CLEAR_FLAG (Common) ;
     ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
     CHOLMOD(free_dense) (&C, Common) ;
     return (ok) ;
diff --git a/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_symbolic.c b/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_symbolic.c
index d41aa60..c7cd0c7 100644
--- a/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_symbolic.c
+++ b/src/C/SuiteSparse/CHOLMOD/Supernodal/cholmod_super_symbolic.c
@@ -113,7 +113,8 @@ static void subtree
 /* clear workspace used by cholmod_super_symbolic */
 #define FREE_WORKSPACE \
 { \
-    CHOLMOD(clear_flag) (Common) ; \
+    /* CHOLMOD(clear_flag) (Common) ; */ \
+    CHOLMOD_CLEAR_FLAG (Common) ; \
     for (k = 0 ; k <= nfsuper ; k++) \
     { \
 	Head [k] = EMPTY ; \
@@ -180,7 +181,6 @@ int CHOLMOD(super_symbolic)
     {
 	/* F must be present in the unsymmetric case */
 	RETURN_IF_NULL (F, FALSE) ;
-	ASSERT (CHOLMOD(dump_sparse) (F, "Fsup", Common) >= 0) ;
     }
     if (L->is_super)
     {
@@ -190,8 +190,6 @@ int CHOLMOD(super_symbolic)
     }
     Common->status = CHOLMOD_OK ;
 
-    ASSERT (CHOLMOD(dump_sparse) (A, "Asup", Common) >= 0) ;
-
     /* ---------------------------------------------------------------------- */
     /* allocate workspace */
     /* ---------------------------------------------------------------------- */
@@ -649,7 +647,9 @@ int CHOLMOD(super_symbolic)
 	     * of all columns A(0:k,j) for each nonzero F(j,k). */
 
 	    /* clear the Flag array and mark the current supernode */
-	    mark = CHOLMOD(clear_flag) (Common) ;
+	    /* mark = CHOLMOD(clear_flag) (Common) ; */
+	    CHOLMOD_CLEAR_FLAG (Common) ;
+	    mark = Common->mark ;
 	    Flag [s] = mark ;
 	    ASSERT (s == SuperMap [k]) ;
 
diff --git a/src/C/SuiteSparse/COLAMD/Demo/colamd_example.out b/src/C/SuiteSparse/COLAMD/Demo/colamd_example.out
index 0c4026c..93d121d 100644
--- a/src/C/SuiteSparse/COLAMD/Demo/colamd_example.out
+++ b/src/C/SuiteSparse/COLAMD/Demo/colamd_example.out
@@ -15,7 +15,7 @@ Column 3, with 2 entries:
     row 1
     row 3
 
-colamd version 2.7, May 31, 2007: OK.  
+colamd version 2.7, Nov 1, 2007: OK.  
 colamd: number of dense or empty rows ignored:           0
 colamd: number of dense or empty columns ignored:        0
 colamd: number of garbage collections performed:         0
@@ -38,7 +38,7 @@ Column 3, with 1 entries:
     row 4
 Column 4, with 0 entries:
 
-symamd version 2.7, May 31, 2007: OK.  
+symamd version 2.7, Nov 1, 2007: OK.  
 symamd: number of dense or empty rows ignored:           0
 symamd: number of dense or empty columns ignored:        0
 symamd: number of garbage collections performed:         0
diff --git a/src/C/SuiteSparse/COLAMD/Demo/colamd_l_example.out b/src/C/SuiteSparse/COLAMD/Demo/colamd_l_example.out
index bbf8901..3605229 100644
--- a/src/C/SuiteSparse/COLAMD/Demo/colamd_l_example.out
+++ b/src/C/SuiteSparse/COLAMD/Demo/colamd_l_example.out
@@ -15,7 +15,7 @@ Column 3, with 2 entries:
     row 1
     row 3
 
-colamd version 2.7, May 31, 2007: OK.  
+colamd version 2.7, Nov 1, 2007: OK.  
 colamd: number of dense or empty rows ignored:           0
 colamd: number of dense or empty columns ignored:        0
 colamd: number of garbage collections performed:         0
@@ -38,7 +38,7 @@ Column 3, with 1 entries:
     row 4
 Column 4, with 0 entries:
 
-symamd version 2.7, May 31, 2007: OK.  
+symamd version 2.7, Nov 1, 2007: OK.  
 symamd: number of dense or empty rows ignored:           0
 symamd: number of dense or empty columns ignored:        0
 symamd: number of garbage collections performed:         0
diff --git a/src/C/SuiteSparse/COLAMD/Include/colamd.h b/src/C/SuiteSparse/COLAMD/Include/colamd.h
index dc53ad5..26372d8 100644
--- a/src/C/SuiteSparse/COLAMD/Include/colamd.h
+++ b/src/C/SuiteSparse/COLAMD/Include/colamd.h
@@ -81,11 +81,11 @@ extern "C" {
  * Versions 2.3 and earlier of COLAMD do not include a #define'd version number.
  */
 
-#define COLAMD_DATE "May 31, 2007"
+#define COLAMD_DATE "Nov 1, 2007"
 #define COLAMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub))
 #define COLAMD_MAIN_VERSION 2
 #define COLAMD_SUB_VERSION 7
-#define COLAMD_SUBSUB_VERSION 0
+#define COLAMD_SUBSUB_VERSION 1
 #define COLAMD_VERSION \
 	COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION,COLAMD_SUB_VERSION)
 
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/Contents.m b/src/C/SuiteSparse/COLAMD/MATLAB/Contents.m
deleted file mode 100644
index 960fd14..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/Contents.m
+++ /dev/null
@@ -1,19 +0,0 @@
-% COLAMD, column approximate minimum degree ordering
-%
-% Primary:
-%   colamd2     - Column approximate minimum degree permutation.
-%   symamd2     - SYMAMD Symmetric approximate minimum degree permutation.
-%
-% helper and test functions:
-%   colamd_demo - demo for colamd, column approx minimum degree ordering algorithm
-%   colamd_make - compiles COLAMD2 and SYMAMD2 for MATLAB
-%   colamd_make - compiles and installs COLAMD2 and SYMAMD2 for MATLAB
-%   colamd_test - test colamd2 and symamd2
-%   luflops     - compute the flop count for sparse LU factorization
-%
-% Example:
-%   p = colamd2 (A)
-%
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/Makefile b/src/C/SuiteSparse/COLAMD/MATLAB/Makefile
deleted file mode 100644
index ee9415f..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# COLAMD Makefile for MATLAB mexFunctions
-
-default: colamd2 symamd2
-
-include ../../UFconfig/UFconfig.mk
-
-I = -I../../UFconfig -I../Include
-
-INC = ../Include/colamd.h ../../UFconfig/UFconfig.h
-
-SRC = ../Source/colamd.c ../Source/colamd_global.c
-
-MX = $(MEX) -DDLONG $(I)
-
-# Compiles the MATLAB-callable routines
-mex: colamd2 symamd2
-
-symamd2: symamdmex.c $(INC) $(SRC)
-	$(MX) -output symamd2mex symamdmex.c $(SRC)
-
-colamd2: colamdmex.c $(INC) $(SRC)
-	$(MX) -output colamd2mex colamdmex.c $(SRC)
-
-# Compiles the extensive test code
-test: mex colamdtestmex.c symamdtestmex.c $(INC) $(SRC)
-	$(MX) colamdtestmex.c $(SRC)
-	$(MX) symamdtestmex.c $(SRC)
-
-clean:
-	- $(RM) $(CLEAN)
-
-purge: distclean
-
-distclean: clean
-	- $(RM) *.mex* *.dll
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamd2.m b/src/C/SuiteSparse/COLAMD/MATLAB/colamd2.m
deleted file mode 100644
index 9916cc7..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamd2.m
+++ /dev/null
@@ -1,87 +0,0 @@
-function [p,stats] = colamd2 (S, knobs)
-%COLAMD2 Column approximate minimum degree permutation.
-%    P = COLAMD2(S) returns the column approximate minimum degree permutation
-%    vector for the sparse matrix S.  For a non-symmetric matrix S, S(:,P)
-%    tends to have sparser LU factors than S.  The Cholesky factorization of
-%    S(:,P)'*S(:,P) also tends to be sparser than that of S'*S.  The ordering
-%    is followed by a column elimination tree post-ordering.
-%
-%    Note that this function is the source code for the built-in MATLAB colamd
-%    function.  It has been renamed here to colamd2 to avoid a filename clash.
-%    colamd and colamd2 are identical.
-%
-%    See also COLAMD, AMD, SYMAMD, SYMAMD2.
-%
-%    Example:
-%            P = colamd2 (S)
-%            [P, stats] = colamd2 (S, knobs)
-%
-%    knobs is an optional one- to three-element input vector.  If S is m-by-n,
-%    then rows with more than max(16,knobs(1)*sqrt(n)) entries are ignored.
-%    Columns with more than max(16,knobs(2)*sqrt(min(m,n))) entries are
-%    removed prior to ordering, and ordered last in the output permutation P.
-%    Only completely dense rows or columns are removed if knobs(1) and knobs(2)
-%    are < 0, respectively.  If knobs(3) is nonzero, stats and knobs are
-%    printed.  The default is knobs = [10 10 0].  Note that knobs differs from
-%    earlier versions of colamd.
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-%
-%    Acknowledgements: This work was supported by the National Science
-%       Foundation, under grants DMS-9504974 and DMS-9803599.
-
-%-------------------------------------------------------------------------------
-% Perform the colamd ordering:
-%-------------------------------------------------------------------------------
-
-if (nargout <= 1 & nargin == 1)						    %#ok
-    p = colamd2mex (S) ;
-elseif (nargout <= 1 & nargin == 2)					    %#ok
-    p = colamd2mex (S, knobs) ;
-elseif (nargout == 2 & nargin == 1)					    %#ok
-    [p, stats] = colamd2mex (S) ;
-elseif (nargout == 2 & nargin == 2)					    %#ok
-    [p, stats] = colamd2mex (S, knobs) ;
-else
-    error ('colamd:  incorrect number of input and/or output arguments') ;
-end
-
-%-------------------------------------------------------------------------------
-% column elimination tree post-ordering:
-%-------------------------------------------------------------------------------
-
-[ignore, q] = etree (S (:,p), 'col') ;
-p = p (q) ;
-
-%    stats is an optional 20-element output vector that provides data about the
-%    ordering and the validity of the input matrix S.  Ordering statistics are
-%    in stats (1:3).  stats (1) and stats (2) are the number of dense or empty
-%    rows and columns ignored by COLAMD and stats (3) is the number of
-%    garbage collections performed on the internal data structure used by
-%    COLAMD (roughly of size 2.2*nnz(S) + 4*m + 7*n integers).
-%
-%    MATLAB built-in functions are intended to generate valid sparse matrices,
-%    with no duplicate entries, with ascending row indices of the nonzeros
-%    in each column, with a non-negative number of entries in each column (!)
-%    and so on.  If a matrix is invalid, then COLAMD may or may not be able
-%    to continue.  If there are duplicate entries (a row index appears two or
-%    more times in the same column) or if the row indices in a column are out
-%    of order, then COLAMD can correct these errors by ignoring the duplicate
-%    entries and sorting each column of its internal copy of the matrix S (the
-%    input matrix S is not repaired, however).  If a matrix is invalid in other
-%    ways then COLAMD cannot continue, an error message is printed, and no
-%    output arguments (P or stats) are returned.  COLAMD is thus a simple way
-%    to check a sparse matrix to see if it's valid.
-%
-%    stats (4:7) provide information if COLAMD was able to continue.  The
-%    matrix is OK if stats (4) is zero, or 1 if invalid.  stats (5) is the
-%    rightmost column index that is unsorted or contains duplicate entries,
-%    or zero if no such column exists.  stats (6) is the last seen duplicate
-%    or out-of-order row index in the column index given by stats (5), or zero
-%    if no such row index exists.  stats (7) is the number of duplicate or
-%    out-of-order row indices.
-%
-%    stats (8:20) is always zero in the current version of COLAMD (reserved
-%    for future use).
-
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_demo.m b/src/C/SuiteSparse/COLAMD/MATLAB/colamd_demo.m
deleted file mode 100644
index f2fd442..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_demo.m
+++ /dev/null
@@ -1,179 +0,0 @@
-%COLAMD_DEMO demo for colamd, column approx minimum degree ordering algorithm
-%
-% Example:
-%   colamd_demo
-% 
-% The following m-files and mexFunctions provide alternative sparse matrix
-% ordering methods for MATLAB.  They are typically faster (sometimes much
-% faster) and typically provide better orderings than their MATLAB counterparts:
-% 
-%       colamd          a replacement for colmmd.
-%
-%                       Typical usage:  p = colamd (A) ;
-%
-%       symamd          a replacement for symmmd.  Based on colamd.
-%
-%                       Typical usage:  p = symamd (A) ;
-%
-% For a description of the methods used, see the colamd.c file.
-%
-% http://www.cise.ufl.edu/research/sparse/colamd/
-%
-% See also colamd, symamd
-
-% Minor changes:  in MATLAB 7, symmmd and colmmd are flagged as "obsolete".
-% This demo checks if they exist, so it should still work when they are removed.
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-
-%-------------------------------------------------------------------------------
-% Print the introduction, the help info, and compile the mexFunctions
-%-------------------------------------------------------------------------------
-
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Colamd2/symamd2 demo.') ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-help colamd_demo ;
-
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Colamd help information:') ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-help colamd2 ;
-
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Symamd help information:') ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-help symamd2 ;
-
-%-------------------------------------------------------------------------------
-% Solving Ax=b
-%-------------------------------------------------------------------------------
-
-n = 100 ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Solving Ax=b for a small %d-by-%d random matrix:', n, n) ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, '\nNote: Random sparse matrices are AWFUL test cases.\n') ;
-fprintf (1, 'They''re just easy to generate in a demo.\n') ;
-
-% set up the system
-
-rand ('state', 0) ;
-randn ('state', 0) ;
-spparms ('default') ;
-A = sprandn (n, n, 5/n) + speye (n) ;
-b = (1:n)' ;
-
-fprintf (1, '\n\nSolving via lu (PAQ = LU), where Q is from colamd2:\n') ;
-q = colamd2 (A) ;
-I = speye (n) ;
-Q = I (:, q) ;
-[L,U,P] = lu (A*Q) ;
-fl = luflops (L, U) ;
-x = Q * (U \ (L \ (P * b))) ;
-fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q):          %d\n', fl) ;
-fprintf (1, 'residual:                                     %e\n', norm (A*x-b));
-
-try
-    fprintf (1, '\n\nSolving via lu (PAQ = LU), where Q is from colmmd:\n') ;
-    q = colmmd (A) ;
-    I = speye (n) ;
-    Q = I (:, q) ;
-    [L,U,P] = lu (A*Q) ;
-    fl = luflops (L, U) ;
-    x = Q * (U \ (L \ (P * b))) ;
-    fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q):          %d\n', fl) ;
-    fprintf (1, 'residual:                                     %e\n', ...
-	norm (A*x-b)) ;
-catch
-    fprintf (1, 'colmmd is obsolete; test skipped\n') ;
-end
-
-fprintf (1, '\n\nSolving via lu (PA = LU), without regard for sparsity:\n') ;
-[L,U,P] = lu (A) ;
-fl = luflops (L, U) ;
-x = U \ (L \ (P * b)) ;
-fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q):          %d\n', fl) ;
-fprintf (1, 'residual:                                     %e\n', norm (A*x-b));
-
-%-------------------------------------------------------------------------------
-% Large demo for colamd2
-%-------------------------------------------------------------------------------
-
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Large demo for colamd2 (symbolic analysis only):') ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-
-rand ('state', 0) ;
-randn ('state', 0) ;
-spparms ('default') ;
-n = 1000 ;
-fprintf (1, 'Generating a random %d-by-%d sparse matrix.\n', n, n) ;
-A = sprandn (n, n, 5/n) + speye (n) ;
-
-fprintf (1, '\n\nUnordered matrix:\n') ;
-lnz = symbfact (A, 'col') ;
-fprintf (1, 'nz in Cholesky factors of A''A:            %d\n', sum (lnz)) ;
-fprintf (1, 'flop count for Cholesky of A''A:           %d\n', sum (lnz.^2)) ;
-
-tic ;
-p = colamd2 (A) ;
-t = toc ;
-lnz = symbfact (A (:,p), 'col') ;
-fprintf (1, '\n\nColamd run time:                          %f\n', t) ;
-fprintf (1, 'colamd2 ordering quality: \n') ;
-fprintf (1, 'nz in Cholesky factors of A(:,p)''A(:,p):  %d\n', sum (lnz)) ;
-fprintf (1, 'flop count for Cholesky of A(:,p)''A(:,p): %d\n', sum (lnz.^2)) ;
-
-try
-    tic ;
-    p = colmmd (A) ;
-    t = toc ;
-    lnz = symbfact (A (:,p), 'col') ;
-    fprintf (1, '\n\nColmmd run time:                          %f\n', t) ;
-    fprintf (1, 'colmmd ordering quality: \n') ;
-    fprintf (1, 'nz in Cholesky factors of A(:,p)''A(:,p):  %d\n', sum (lnz)) ;
-    fprintf (1, 'flop count for Cholesky of A(:,p)''A(:,p): %d\n', ...
-	sum (lnz.^2)) ;
-catch
-    fprintf (1, 'colmmd is obsolete; test skipped\n') ;
-end
-
-%-------------------------------------------------------------------------------
-% Large demo for symamd2
-%-------------------------------------------------------------------------------
-
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-fprintf (1, 'Large demo for symamd2 (symbolic analysis only):') ;
-fprintf (1, '\n-----------------------------------------------------------\n') ;
-
-fprintf (1, 'Generating a random symmetric %d-by-%d sparse matrix.\n', n, n) ;
-A = A+A' ;
-
-fprintf (1, '\n\nUnordered matrix:\n') ;
-lnz = symbfact (A, 'sym') ;
-fprintf (1, 'nz in Cholesky factors of A:       %d\n', sum (lnz)) ;
-fprintf (1, 'flop count for Cholesky of A:      %d\n', sum (lnz.^2)) ;
-
-tic ;
-p = symamd2 (A) ;
-t = toc ;
-lnz = symbfact (A (p,p), 'sym') ;
-fprintf (1, '\n\nSymamd run time:                   %f\n', t) ;
-fprintf (1, 'symamd2 ordering quality: \n') ;
-fprintf (1, 'nz in Cholesky factors of A(p,p):  %d\n', sum (lnz)) ;
-fprintf (1, 'flop count for Cholesky of A(p,p): %d\n', sum (lnz.^2)) ;
-
-try
-    tic ;
-    p = symmmd (A) ;
-    t = toc ;
-    lnz = symbfact (A (p,p), 'sym') ;
-    fprintf (1, '\n\nSymmmd run time:                   %f\n', t) ;
-    fprintf (1, 'symmmd ordering quality: \n') ;
-    fprintf (1, 'nz in Cholesky factors of A(p,p):  %d\n', sum (lnz)) ;
-    fprintf (1, 'flop count for Cholesky of A(p,p): %d\n', sum (lnz.^2)) ;
-catch
-    fprintf (1, 'symmmd is obsolete\n') ;
-end
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_install.m b/src/C/SuiteSparse/COLAMD/MATLAB/colamd_install.m
deleted file mode 100644
index 7ac0110..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_install.m
+++ /dev/null
@@ -1,18 +0,0 @@
-function colamd_install
-%COLAMD_MAKE to compile and install the colamd2 and symamd2 mexFunction.
-%   Your current directory must be COLAMD/MATLAB for this function to work.
-%
-% Example:
-%   colamd_install
-%
-% See also colamd2, symamd2.
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-
-colamd_make
-addpath (pwd)
-fprintf ('\nThe following path has been added.  You may wish to add it\n') ;
-fprintf ('permanently, using the MATLAB pathtool command.\n') ;
-fprintf ('%s\n\n', pwd) ;
-colamd_demo
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_make.m b/src/C/SuiteSparse/COLAMD/MATLAB/colamd_make.m
deleted file mode 100644
index 1748f9d..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_make.m
+++ /dev/null
@@ -1,29 +0,0 @@
-function colamd_make
-%COLAMD_MAKE compiles COLAMD2 and SYMAMD2 for MATLAB
-%
-% Example:
-%   colamd_make
-%
-% See also colamd, symamd
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-
-details = 0 ;	    % 1 if details of each command are to be printed
-d = '' ;
-if (~isempty (strfind (computer, '64')))
-    d = '-largeArrayDims' ;
-end
-src = '../Source/colamd.c ../Source/colamd_global.c' ;
-cmd = sprintf ('mex -DDLONG -O %s -I../../UFconfig -I../Include -output ', d) ;
-s = [cmd 'colamd2mex colamdmex.c ' src] ;
-if (details)
-    fprintf ('%s\n', s) ;
-end
-eval (s) ;
-s = [cmd 'symamd2mex symamdmex.c ' src] ;
-if (details)
-    fprintf ('%s\n', s) ;
-end
-eval (s) ;
-fprintf ('COLAMD2 and SYMAMD2 successfully compiled.\n') ;
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_test.m b/src/C/SuiteSparse/COLAMD/MATLAB/colamd_test.m
deleted file mode 100644
index 7de7e81..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamd_test.m
+++ /dev/null
@@ -1,511 +0,0 @@
-function colamd_test
-%COLAMD_TEST test colamd2 and symamd2
-% Example:
-%   colamd_test
-%
-% COLAMD and SYMAMD testing function.  Here we try to give colamd2 and symamd2
-% every possible type of matrix and erroneous input that they may encounter. 
-% We want either a valid permutation returned or we want them to fail
-% gracefully.
-%
-% You are prompted as to whether or not the colamd2 and symand routines and
-% the test mexFunctions are to be compiled.
-%
-% See also colamd2, symamd2
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-
-
-help colamd_test
-
-s = input (...
-'Compile colamd2, symand2, and the test codes? (y/n, default is yes): ', 's') ;
-
-do_compile = 1 ;
-if (~isempty (s))
-    if (s (1) == 'n' | s (1) == 'N')					    %#ok
-	do_compile = 0 ;
-    end
-end
-
-if (do_compile)
-    fprintf ('Compiling colamd2, symamd2, and test mexFunctions.\n') ;
-    colamd_make ;
-
-    d = '' ;
-    if (~isempty (strfind (computer, '64')))
-	d = '-largeArrayDims' ;
-    end
-    cmd = sprintf ('mex -DDLONG -O %s -I../../UFconfig -I../Include ', d) ;
-    src = '../Source/colamd.c ../Source/colamd_global.c' ;
-    eval ([cmd 'colamdtestmex.c ' src]) ;
-    eval ([cmd 'symamdtestmex.c ' src]) ;
-    fprintf ('Done compiling.\n') ; 
-
-end
-
-fprintf ('\nThe following codes will be tested:\n') ;
-which colamd2 
-which symamd2
-which colamd2mex
-which symamd2mex
-which colamdtestmex
-which symamdtestmex
-
-fprintf ('\nStarting the tests.  Please be patient.\n') ;
-
-rand ('state', 0) ;
-randn ('state', 0) ;
-
-A = sprandn (500,500,0.4) ;
-
-p = colamd2 (A, [10 10 1]) ; check_perm (p, A) ;
-p = colamd2 (A, [2  7  1]) ; check_perm (p, A) ;
-p = symamd2 (A, [10 1]) ; check_perm (p, A) ;
-p = symamd2 (A, [7  1]) ; check_perm (p, A) ;
-p = symamd2 (A, [4  1]) ; check_perm (p, A) ;
-
-
-fprintf ('Null matrices') ;
-A = zeros (0,0) ;
-A = sparse (A) ;
-
-[p, stats] = colamd2 (A, [10 10 0]) ;					    %#ok
-check_perm (p, A) ;
-
-[p, stats] = symamd2 (A, [10 0]) ;					    %#ok
-check_perm (p, A) ;
-
-A = zeros (0, 100) ;
-A = sparse (A) ;
-[p, stats] = colamd2 (A, [10 10 0]) ;					    %#ok
-check_perm (p, A) ;
-
-A = zeros (100, 0) ;
-A = sparse (A) ;
-[p, stats] = colamd2 (A, [10 10 0]) ;
-check_perm (p, A) ;
-fprintf (' OK\n') ;
-
-
-fprintf ('Matrices with a few dense row/cols\n') ;
-
-for trial = 1:20
-
-    % random square unsymmetric matrix
-    A = rand_matrix (1000, 1000, 1, 10, 20) ;
-
-    for tol = [0:.1:2 3:20 1e6]
-
-	[p, stats] = colamd2 (A, [tol tol 0]) ;				    %#ok
-	check_perm (p, A) ;
-
-	B = A + A' ;
-	[p, stats] = symamd2 (B, [tol 0]) ;				    %#ok
-	check_perm (p, A) ;
-
-	[p, stats] = colamd2 (A, [tol 1 0]) ;				    %#ok
-	check_perm (p, A) ;
-
-	[p, stats] = colamd2 (A, [1 tol 0]) ;				    %#ok
-	check_perm (p, A) ;
-
-	fprintf ('.') ;
-
-    end
-end
-fprintf (' OK\n') ;
-
-fprintf ('General matrices\n') ;
-for trial = 1:400
-
-    % matrix of random mtype
-    mtype = irand (3) ;
-    A = rand_matrix (2000, 2000, mtype, 0, 0) ;
-    p = colamd2 (A) ;
-    check_perm (p, A) ;
-    if (mtype == 3)
-	p = symamd2 (A) ;
-	check_perm (p, A) ;
-    end
-
-    fprintf ('.') ;
-end
-fprintf (' OK\n') ;
-
-fprintf ('Test error handling with invalid inputs\n') ;
-
-% Check different erroneous input.
-for trial = 1:30
-
-    A = rand_matrix (1000, 1000, 2, 0, 0) ;
-    [m n] = size (A) ;
-
-    for err = 1:13
-
-        p = Tcolamd (A, [n n 0 0 err]) ;
-        if (p ~= -1)							    %#ok
-	    check_perm (p, A) ;
-	end
-
-	if (err == 1)
-	    % check different (valid) input args to colamd2
-	    p = Acolamd (A) ;
-
-	    p2 = Acolamd (A, [10 10 0 0 0]) ;
-	    if (any (p ~= p2))
-		error ('colamd2: mismatch 1!') ;
-	    end
-	    [p2 stats] = Acolamd (A) ;					    %#ok
-	    if (any (p ~= p2))
-		error ('colamd2: mismatch 2!') ;
-	    end
-	    [p2 stats] = Acolamd (A, [10 10 0 0 0]) ;
-	    if (any (p ~= p2))
-		error ('colamd2: mismatch 3!') ;
-	    end
-	end
-
-	B = A'*A ;
-        p = Tsymamd (B, [n 0 err]) ;
-        if (p ~= -1)							    %#ok
-	    check_perm (p, A) ;
-	end
-
-	if (err == 1)
-
-	    % check different (valid) input args to symamd2
-	    p = Asymamd (B) ;
-	    check_perm (p, A) ;
-	    p2 = Asymamd (B, [10 0 0]) ;
-	    if (any (p ~= p2))
-		error ('symamd2: mismatch 1!') ;
-	    end
-	    [p2 stats] = Asymamd (B) ;					    %#ok
-	    if (any (p ~= p2))
-		error ('symamd2: mismatch 2!') ;
-	    end
-	    [p2 stats] = Asymamd (B, [10 0 0]) ;			    %#ok
-	    if (any (p ~= p2))
-		error ('symamd2: mismatch 3!') ;
-	    end
-	end
-
-	fprintf ('.') ;
-    end
-
-end
-fprintf (' OK\n') ;
-
-fprintf ('Matrices with a few empty columns\n') ;
-
-for trial = 1:400
-
-    % some are square, some are rectangular
-    n = 0 ;
-    while (n < 5)
-	A = rand_matrix (1000, 1000, irand (2), 0, 0) ;
-	[m n] = size (A) ;
-    end
-
-    % Add 5 null columns at random locations.
-    null_col = randperm (n) ;
-    null_col = sort (null_col (1:5)) ;
-    A (:, null_col) = 0 ;
-
-    % Order the matrix and make sure that the null columns are ordered last.
-    [p, stats] = colamd2 (A, [1e6 1e6 0]) ;
-    check_perm (p, A) ;
-
-%    if (stats (2) ~= 5)
-%	stats (2)
-%	error ('colamd2: wrong number of null columns') ;
-%    end
-
-    % find all null columns in A
-    null_col = find (sum (spones (A), 1) == 0) ;
-    nnull = length (null_col) ;						    %#ok
-    if (any (null_col ~= p ((n-4):n)))
-	error ('colamd2: Null cols are not ordered last in natural order') ;
-    end
-
-    fprintf ('.') ;
-
-end
-fprintf (' OK\n') ;
-
-fprintf ('Matrices with a few empty rows and columns\n') ;
-
-for trial = 1:400
-
-    % symmetric matrices
-    n = 0 ;
-    while (n < 5)
-	A = rand_matrix (1000, 1000, 3, 0, 0) ;
-	[m n] = size (A) ;
-    end
-
-    % Add 5 null columns and rows at random locations.
-    null_col = randperm (n) ;
-    null_col = sort (null_col (1:5)) ;
-    A (:, null_col) = 0 ;
-    A (null_col, :) = 0 ;
-
-    % Order the matrix and make sure that the null rows/cols are ordered last.
-    [p,stats] = symamd2 (A, [10 0]) ;
-    check_perm (p, A) ;
-
-    % find actual number of null rows and columns
-    Alo = tril (A, -1) ;
-    nnull = length (find (sum (Alo') == 0 & sum (Alo) == 0)) ;		    %#ok
-
-    if (stats (2) ~= nnull | nnull < 5)					    %#ok
-	error ('symamd2: wrong number of null columns') ;
-    end
-    if (any (null_col ~= p ((n-4):n)))
-	error ('symamd2: Null cols are not ordered last in natural order') ;
-    end
-
-    fprintf ('.') ;
-
-end
-fprintf (' OK\n') ;
-
-fprintf ('Matrices with a few empty rows\n') ;
-
-% Test matrices with null rows inserted.
-
-for trial = 1:400
-
-    m = 0 ;
-    while (m < 5)
-	A = rand_matrix (1000, 1000, 2, 0, 0) ;
-	[m n] = size (A) ;						    %#ok
-    end
-
-    % Add 5 null rows at random locations.
-    null_row = randperm (m) ;
-    null_row = sort (null_row (1:5)) ;
-    A (null_row, :) = 0 ;
-
-    p = colamd2 (A, [10 10 0]) ;
-    check_perm (p, A) ;
-    if (stats (1) ~= 5)
-	error ('colamd2: wrong number of null rows') ;
-    end
-    fprintf ('.') ;
-end
-fprintf (' OK\n') ;
-
-
-fprintf ('\ncolamd2 and symamd2:  all tests passed\n\n') ;
-
-%-------------------------------------------------------------------------------
-
-function [p,stats] = Acolamd (S, knobs)
-% Acolamd:  compare colamd2 and Tcolamd results
-
-if (nargin < 3)
-    if (nargout == 1)
-	[p] = colamd2 (S) ;
-	[p1] = Tcolamd (S, [10 10 0 0 0]) ;
-    else
-	[p, stats] = colamd2 (S) ;
-	[p1, stats1] = Tcolamd (S, [10 10 0 0 0]) ;			    %#ok
-    end
-else
-    if (nargout == 1)
-	[p] = colamd2 (S, knobs (1:3)) ;
-	[p1] = Tcolamd (S, knobs) ;
-    else
-	[p, stats] = colamd2 (S, knobs (1:3)) ;
-	[p1, stats1] = Tcolamd (S, knobs) ;			    %#ok
-    end
-end
-
-check_perm (p, S) ;
-check_perm (p1, S) ;
-
-if (any (p1 ~= p))
-    error ('Acolamd mismatch!') ;
-end
-
-
-%-------------------------------------------------------------------------------
-
-function [p,stats] = Asymamd (S, knobs)
-% Asymamd:  compare symamd2 and Tsymamd results
-
-if (nargin < 3)
-    if (nargout == 1)
-	[p] = symamd2 (S) ;
-	[p1] = Tsymamd (S, [10 0 0]) ;
-    else
-	[p, stats] = symamd2 (S) ;
-	[p1, stats1] = Tsymamd (S, [10 0 0]) ;				%#ok
-    end
-else
-    if (nargout == 1)
-	[p] = symamd2 (S, knobs (1:2)) ;
-	[p1] = Tsymamd (S, knobs) ;
-    else
-	[p, stats] = symamd2 (S, knobs (1:2)) ;
-	[p1, stats1] = Tsymamd (S, knobs) ;			    %#ok
-    end
-end
-
-if (any (p1 ~= p))
-    error ('Asymamd mismatch!') ;
-end
-
-
-%-------------------------------------------------------------------------------
-
-function check_perm (p, A)
-% check_perm:  check for a valid permutation vector
-
-if (isempty (A) & isempty (p))						    %#ok
-    % empty permutation vectors of empty matrices are OK
-    return
-end
-
-if (isempty (p))
-    error ('bad permutation: cannot be empty') ;
-end
-
-[m n] = size (A) ;
-[pm pn] = size (p) ;
-if (pn == 1)
-    % force p to be a row vector
-    p = p' ;
-    [pm pn] = size (p) ;
-end
-
-if (n ~= pn)
-    error ('bad permutation: wrong size') ;
-end
-
-if (pm ~= 1) ;
-    % p must be a vector
-    error ('bad permutation: not a vector') ;
-else
-    if (any (sort (p) - (1:pn)))
-	error ('bad permutation') ;
-    end
-end
-
-%-------------------------------------------------------------------------------
-
-function i = irand (n)
-% irand: return a random integer between 1 and n
-i = min (n, 1 + floor (rand * n)) ;
-
-%-------------------------------------------------------------------------------
-
-function A = rand_matrix (nmax, mmax, mtype, drows, dcols)
-% rand_matrix:  return a random sparse matrix
-%
-% A = rand_matrix (nmax, mmax, mtype, drows, dcols)
-%
-% A binary matrix of random size, at most nmax-by-mmax, with drows dense rows
-% and dcols dense columns.
-%
-% mtype 1: square unsymmetric (mmax is ignored)
-% mtype 2: rectangular
-% mtype 3: symmetric (mmax is ignored)
-
-n = irand (nmax) ;
-if (mtype ~= 2)
-    % square
-    m = n ;
-else
-    m = irand (mmax) ;
-end
-
-A = sprand (m, n, 10 / max (m,n)) ;
-
-if (drows > 0)
-    % add dense rows
-    for k = 1:drows
-	i = irand (m) ;
-	nz = irand (n) ;
-	p = randperm (n) ;
-	p = p (1:nz) ;
-	A (i,p) = 1 ;
-    end
-end
-
-if (dcols > 0)
-    % add dense cols
-    for k = 1:dcols
-	j = irand (n) ;
-	nz = irand (m) ;
-	p = randperm (m) ;
-	p = p (1:nz) ;
-	A (p,j) = 1 ;
-    end
-end
-
-A = spones (A) ;
-
-% ensure that there are no empty columns
-d = find (full (sum (A)) == 0) ;					    %#ok
-A (m,d) = 1 ;								    %#ok
-
-% ensure that there are no empty rows
-d = find (full (sum (A,2)) == 0) ;					    %#ok
-A (d,n) = 1 ;								    %#ok
-
-if (mtype == 3)
-    % symmetric
-    A = A + A' + speye (n) ;
-end
-
-A = spones (A) ;
-
-%-------------------------------------------------------------------------------
-
-function [p,stats] = Tcolamd (S, knobs)
-% Tcolamd:  run colamd2 in a testing mode
-
-if (nargout <= 1 & nargin == 1)						    %#ok
-    p = colamdtestmex (S) ;
-elseif (nargout <= 1 & nargin == 2)					    %#ok
-    p = colamdtestmex (S, knobs) ;
-elseif (nargout == 2 & nargin == 1)					    %#ok
-    [p, stats] = colamdtestmex (S) ;
-elseif (nargout == 2 & nargin == 2)					    %#ok
-    [p, stats] = colamdtestmex (S, knobs) ;
-else
-    error ('colamd2:  incorrect number of input and/or output arguments') ;
-end
-
-if (p (1) ~= -1)
-    [ignore, q] = etree (S (:,p), 'col') ;
-    p = p (q) ;
-    check_perm (p, S) ;
-end
-
-%-------------------------------------------------------------------------------
-
-function [p, stats] = Tsymamd (S, knobs)
-% Tsymamd: run symamd2 in a testing mode
-
-if (nargout <= 1 & nargin == 1)						    %#ok
-    p = symamdtestmex (S) ;
-elseif (nargout <= 1 & nargin == 2)					    %#ok
-    p = symamdtestmex (S, knobs) ;
-elseif (nargout == 2 & nargin == 1)					    %#ok
-    [p, stats] = symamdtestmex (S) ;
-elseif (nargout == 2 & nargin == 2)					    %#ok
-    [p, stats] = symamdtestmex (S, knobs) ;
-else
-    error ('symamd2:  incorrect number of input and/or output arguments') ;
-end
-
-if (p (1) ~= -1)
-    [ignore, q] = etree (S (p,p)) ;
-    p = p (q) ;
-    check_perm (p, S) ;
-end
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamdmex.c b/src/C/SuiteSparse/COLAMD/MATLAB/colamdmex.c
deleted file mode 100644
index 93f16d5..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamdmex.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* ========================================================================== */
-/* === colamd mexFunction =================================================== */
-/* ========================================================================== */
-
-/* Usage:
-
-	P = colamd2 (A) ;
-	[ P, stats ] = colamd2 (A, knobs) ;
-
-    see colamd.m for a description.
-
-    Authors:
-
-	The authors of the code itself are Stefan I. Larimore and Timothy A.
-	Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
-	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
-	Ng, Oak Ridge National Laboratory.
-
-    Acknowledgements:
-
-	This work was supported by the National Science Foundation, under
-	grants DMS-9504974 and DMS-9803599.
-
-    Notice:
-
-	Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved.
-
-	See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
-	file) for the License.
-
-    Availability:
-
-	The colamd/symamd library is available at
-
-	    http://www.cise.ufl.edu/research/sparse/colamd/
-
-	This is the http://www.cise.ufl.edu/research/sparse/colamd/colamdmex.c
-	file.  It requires the colamd.c and colamd.h files.
-
-*/
-
-/* ========================================================================== */
-/* === Include files ======================================================== */
-/* ========================================================================== */
-
-#include "colamd.h"
-#include "mex.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include <string.h>
-#include "UFconfig.h"
-
-/* ========================================================================== */
-/* === colamd mexFunction =================================================== */
-/* ========================================================================== */
-
-void mexFunction
-(
-    /* === Parameters ======================================================= */
-
-    int nlhs,			/* number of left-hand sides */
-    mxArray *plhs [],		/* left-hand side matrices */
-    int nrhs,			/* number of right--hand sides */
-    const mxArray *prhs []	/* right-hand side matrices */
-)
-{
-    /* === Local variables ================================================== */
-
-    UF_long *A ;		/* colamd's copy of the matrix, and workspace */
-    UF_long *p ;		/* colamd's copy of the column pointers */
-    UF_long Alen ;		/* size of A */
-    UF_long n_col ;		/* number of columns of A */
-    UF_long n_row ;		/* number of rows of A */
-    UF_long nnz ;		/* number of entries in A */
-    UF_long full ;		/* TRUE if input matrix full, FALSE if sparse */
-    double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
-    double *out_perm ;		/* output permutation vector */
-    double *out_stats ;		/* output stats vector */
-    double *in_knobs ;		/* input knobs vector */
-    UF_long i ;			/* loop counter */
-    mxArray *Ainput ;		/* input matrix handle */
-    UF_long spumoni ;		/* verbosity variable */
-    UF_long stats [COLAMD_STATS] ;	/* stats for colamd */
-
-    colamd_printf = mexPrintf ;	/* COLAMD printf routine */
-
-    /* === Check inputs ===================================================== */
-
-    if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
-    {
-	mexErrMsgTxt (
-	"colamd: incorrect number of input and/or output arguments") ;
-    }
-
-    /* === Get knobs ======================================================== */
-
-    colamd_l_set_defaults (knobs) ;
-    spumoni = 0 ;
-
-    /* check for user-passed knobs */
-    if (nrhs == 2)
-    {
-	in_knobs = mxGetPr (prhs [1]) ;
-	i = mxGetNumberOfElements (prhs [1]) ;
-	if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
-	if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ;
-	if (i > 2) spumoni = (UF_long) (in_knobs [2] != 0) ;
-    }
-
-    /* print knob settings if spumoni is set */
-    if (spumoni)
-    {
-	mexPrintf ("\ncolamd version %d.%d, %s:\n",
-	    COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
-	if (knobs [COLAMD_DENSE_ROW] >= 0)
-	{
-	    mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))"
-		" entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(1): %g, only completely dense rows removed\n",
-		in_knobs [0]) ;
-	}
-	if (knobs [COLAMD_DENSE_COL] >= 0)
-	{
-	    mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))"
-		" entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(2): %g, only completely dense columns removed\n",
-		in_knobs [1]) ;
-	}
-	mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
-	    in_knobs [2]) ;
-    }
-
-    /* === If A is full, convert to a sparse matrix ========================= */
-
-    Ainput = (mxArray *) prhs [0] ;
-    if (mxGetNumberOfDimensions (Ainput) != 2)
-    {
-	mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ;
-    }
-    full = !mxIsSparse (Ainput) ;
-    if (full)
-    {
-	mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
-    }
-
-    /* === Allocate workspace for colamd ==================================== */
-
-    /* get size of matrix */
-    n_row = mxGetM (Ainput) ;
-    n_col = mxGetN (Ainput) ;
-
-    /* get column pointer vector so we can find nnz */
-    p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
-    (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ;
-    nnz = p [n_col] ;
-    Alen = (UF_long) colamd_l_recommended (nnz, n_row, n_col) ;
-    if (Alen == 0)
-    {
-    	mexErrMsgTxt ("colamd: problem too large") ;
-    }
-
-    /* === Copy input matrix into workspace ================================= */
-
-    A = (UF_long *) mxCalloc (Alen, sizeof (UF_long)) ;
-    (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ;
-
-    if (full)
-    {
-	mxDestroyArray (Ainput) ;
-    }
-
-    /* === Order the columns (destroys A) =================================== */
-
-    if (!colamd_l (n_row, n_col, Alen, A, p, knobs, stats))
-    {
-	colamd_l_report (stats) ;
-	mexErrMsgTxt ("colamd error!") ;
-    }
-    mxFree (A) ;
-
-    /* === Return the permutation vector ==================================== */
-
-    plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
-    out_perm = mxGetPr (plhs [0]) ;
-    for (i = 0 ; i < n_col ; i++)
-    {
-	/* colamd is 0-based, but MATLAB expects this to be 1-based */
-	out_perm [i] = p [i] + 1 ;
-    }
-    mxFree (p) ;
-
-    /* === Return the stats vector ========================================== */
-
-    /* print stats if spumoni is set */
-    if (spumoni)
-    {
-	colamd_l_report (stats) ;
-    }
-
-    if (nlhs == 2)
-    {
-	plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
-	out_stats = mxGetPr (plhs [1]) ;
-	for (i = 0 ; i < COLAMD_STATS ; i++)
-	{
-	    out_stats [i] = stats [i] ;
-	}
-
-	/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
-	/* note that this correction doesn't occur if symamd returns FALSE */
-	out_stats [COLAMD_INFO1] ++ ; 
-	out_stats [COLAMD_INFO2] ++ ; 
-    }
-}
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/colamdtestmex.c b/src/C/SuiteSparse/COLAMD/MATLAB/colamdtestmex.c
deleted file mode 100644
index 9b90a46..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/colamdtestmex.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* ========================================================================== */
-/* === colamdtest mexFunction =============================================== */
-/* ========================================================================== */
-
-/* COLAMD test function
- 
-    This MATLAB mexFunction is for testing only.  It is not meant for
-    production use.  See colamdmex.c instead.
-
-    Usage:
-
-	[ P, stats ] = colamdtest (A, knobs) ;
-
-    See colamd.m for a description.  knobs is required.
-
-	knobs (1)	dense row control
-	knobs (2)	dense column control
-	knobs (3)	spumoni
-	knobs (4)	for testing only.  Controls the workspace used by
-			colamd.
-
-	knobs (5)	for testing only.  Controls how the input matrix is
-			jumbled prior to calling colamd, to test its error
-			handling capability.
-
-    Authors:
-
-	The authors of the code itself are Stefan I. Larimore and Timothy A.
-	Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
-	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
-	Ng, Oak Ridge National Laboratory.
-
-    Acknowledgements:
-
-	This work was supported by the National Science Foundation, under
-	grants DMS-9504974 and DMS-9803599.
-
-    Notice:
-
-	Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved.
-
-	See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
-	file) for the License.
-
-    Availability:
-
-	The colamd/symamd library is available at
-
-	    http://www.cise.ufl.edu/research/sparse/colamd/
-
-	This is the
-	http://www.cise.ufl.edu/research/sparse/colamd/colamdtestmex.c
-       	file.  It requires the colamd.c and colamd.h files.
-
-*/
-
-/* ========================================================================== */
-/* === Include files ======================================================== */
-/* ========================================================================== */
-
-#include "colamd.h"
-#include "mex.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include <string.h>
-#include "UFconfig.h"
-
-static void dump_matrix
-(
-    UF_long A [ ],
-    UF_long p [ ],
-    UF_long n_row,
-    UF_long n_col,
-    UF_long Alen,
-    UF_long limit
-) ;
-
-/* ========================================================================== */
-/* === colamd mexFunction =================================================== */
-/* ========================================================================== */
-
-void mexFunction
-(
-    /* === Parameters ======================================================= */
-
-    int nlhs,			/* number of left-hand sides */
-    mxArray *plhs [],		/* left-hand side matrices */
-    int nrhs,			/* number of right--hand sides */
-    const mxArray *prhs []	/* right-hand side matrices */
-)
-{
-    /* === Local variables ================================================== */
-
-    UF_long *A ;		/* colamd's copy of the matrix, and workspace */
-    UF_long *p ;		/* colamd's copy of the column pointers */
-    UF_long Alen ;		/* size of A */
-    UF_long n_col ;		/* number of columns of A */
-    UF_long n_row ;		/* number of rows of A */
-    UF_long nnz ;		/* number of entries in A */
-    UF_long full ;		/* TRUE if input matrix full, FALSE if sparse */
-    double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
-    double *out_perm ;		/* output permutation vector */
-    double *out_stats ;		/* output stats vector */
-    double *in_knobs ;		/* input knobs vector */
-    UF_long i ;			/* loop counter */
-    mxArray *Ainput ;		/* input matrix handle */
-    UF_long spumoni ;		/* verbosity variable */
-    UF_long stats2 [COLAMD_STATS] ;	/* stats for colamd */
-
-    UF_long *cp, *cp_end, result, col, length ;
-    UF_long *stats ;
-    stats = stats2 ;
-
-    colamd_printf = mexPrintf ;	/* COLAMD printf routine */
-
-    /* === Check inputs ===================================================== */
-
-    if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
-    {
-	mexErrMsgTxt (
-	"colamd: incorrect number of input and/or output arguments") ;
-    }
-
-    if (nrhs != 2)
-    {
-	mexErrMsgTxt ("colamdtest: knobs are required") ;
-    }
-    /* for testing we require all 5 knobs */
-    if (mxGetNumberOfElements (prhs [1]) != 5)
-    {
-	mexErrMsgTxt ("colamd: must have all 5 knobs for testing") ;
-    }
-
-    /* === Get knobs ======================================================== */
-
-    colamd_l_set_defaults (knobs) ;
-    spumoni = 0 ;
-
-    /* check for user-passed knobs */
-    if (nrhs == 2)
-    {
-	in_knobs = mxGetPr (prhs [1]) ;
-	i = mxGetNumberOfElements (prhs [1]) ;
-	if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
-	if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ;
-	if (i > 2) spumoni = (UF_long) in_knobs [2] ;
-    }
-
-    /* print knob settings if spumoni is set */
-    if (spumoni)
-    {
-	mexPrintf ("\ncolamd version %d.%d, %s:\n",
-	    COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
-	if (knobs [COLAMD_DENSE_ROW] >= 0)
-	{
-	    mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))"
-		" entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(1): %g, only completely dense rows removed\n",
-		in_knobs [0]) ;
-	}
-	if (knobs [COLAMD_DENSE_COL] >= 0)
-	{
-	    mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))"
-		" entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(2): %g, only completely dense columns removed\n",
-		in_knobs [1]) ;
-	}
-	mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
-	    in_knobs [2]) ;
-    }
-
-    /* === If A is full, convert to a sparse matrix ========================= */
-
-    Ainput = (mxArray *) prhs [0] ;
-    if (mxGetNumberOfDimensions (Ainput) != 2)
-    {
-	mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ;
-    }
-    full = !mxIsSparse (Ainput) ;
-    if (full)
-    {
-	mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
-    }
-
-    /* === Allocate workspace for colamd ==================================== */
-
-    /* get size of matrix */
-    n_row = mxGetM (Ainput) ;
-    n_col = mxGetN (Ainput) ;
-
-    /* get column pointer vector so we can find nnz */
-    p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
-    (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ;
-    nnz = p [n_col] ;
-    Alen = (UF_long) colamd_l_recommended (nnz, n_row, n_col) ;
-    if (Alen == 0)
-    {
-    	mexErrMsgTxt ("colamd: problem too large") ;
-    }
-
-
-/* === Modify size of Alen if testing ======================================= */
-
-/*
-	knobs [3]	amount of workspace given to colamd.
-			<  0 : TIGHT memory
-			>  0 : MIN + knob [3] - 1
-			== 0 : RECOMMENDED memory
-*/
-
-/* Here only for testing */
-/* size of the Col and Row structures */
-#define COLAMD_C(n_col) (((n_col) + 1) * 24 / sizeof (UF_long))
-#define COLAMD_R(n_row) (((n_row) + 1) * 16 / sizeof (UF_long))
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define COLAMD_MIN_MEMORY(nnz,n_row,n_col) \
-    (2 * (nnz) + COLAMD_C (n_col) + COLAMD_R (n_row))
-
-    /* get knob [3], if negative */
-    if (in_knobs [3] < 0)
-    {
-	Alen = COLAMD_MIN_MEMORY (nnz, n_row, n_col) + n_col ;
-    }
-    else if (in_knobs [3] > 0)
-    {
-	Alen = COLAMD_MIN_MEMORY (nnz, n_row, n_col) + in_knobs [3] - 1 ;
-    }
-
-    /* otherwise, we use the recommended amount set above */
-
-    /* === Copy input matrix into workspace ================================= */
-
-    A = (UF_long *) mxCalloc (Alen, sizeof (UF_long)) ;
-    (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ;
-
-    if (full)
-    {
-	mxDestroyArray (Ainput) ;
-    }
-
-
-/* === Jumble matrix ======================================================== */
-
-/*
-	knobs [4]	FOR TESTING ONLY: Specifies how to jumble matrix
-			0 : No jumbling
-			1 : Make n_row less than zero
-			2 : Make first pointer non-zero
-			3 : Make column pointers not non-decreasing
-			4 : Make a column pointer greater or equal to Alen
-			5 : Make row indices not strictly increasing
-			6 : Make a row index greater or equal to n_row
-			7 : Set A = NULL
-			8 : Set p = NULL
-			9 : Repeat row index
-			10: make row indices not sorted
-			11: jumble columns massively (note this changes
-				the pattern of the matrix A.)
-			12: Set stats = NULL
-			13: Make n_col less than zero
-*/
-
-    /* jumble appropriately */
-    switch ((UF_long) in_knobs [4])
-    {
-
-	case 0 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: no errors expected\n") ;
-	    }
-	    result = 1 ;		/* no errors */
-	    break ;
-
-	case 1 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: nrow out of range\n") ;
-	    }
-	    result = 0 ;		/* nrow out of range */
-	    n_row = -1 ;
-	    break ;
-
-	case 2 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: p [0] nonzero\n") ;
-	    }
-	    result = 0 ;		/* p [0] must be zero */
-	    p [0] = 1 ;
-	    break ;
-
-	case 3 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: negative length last column\n") ;
-	    }
-	    result = (n_col == 0) ;	/* p must be monotonically inc. */
-	    p [n_col] = p [0] ;
-	    break ;
-
-	case 4 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: Alen too small\n") ;
-	    }
-	    result = 0 ;		/* out of memory */
-	    p [n_col] = Alen ;
-	    break ;
-
-	case 5 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: row index out of range (-1)\n") ;
-	    }
-	    if (nnz > 0)		/* row index out of range */
-	    {
-		result = 0 ;
-		A [nnz-1] = -1 ;
-	    }
-	    else
-	    {
-	        if (spumoni > 0)
-		{
-		    mexPrintf ("Note: no row indices to put out of range\n") ;
-		}
-		result = 1 ;
-	    }
-	    break ;
-
-	case 6 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: row index out of range (n_row)\n") ;
-	    }
-	    if (nnz > 0)		/* row index out of range */
-	    {
-		if (spumoni > 0)
-		{
-		    mexPrintf ("Changing A[nnz-1] from %d to %d\n",
-			    A [nnz-1], n_row) ; 
-		}
-		result = 0 ;
-		A [nnz-1] = n_row ;
-	    }
-	    else
-	    {
-	        if (spumoni > 0)
-		{
-		    mexPrintf ("Note: no row indices to put out of range\n") ;
-		}
-		result = 1 ;
-	    }
-	    break ;
-
-	case 7 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: A not present\n") ;
-	    }
-	    result = 0 ;		/* A not present */
-	    A = (UF_long *) NULL ;
-	    break ;
-
-	case 8 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: p not present\n") ;
-	    }
-	    result = 0 ;		/* p not present */
-	    p = (UF_long *) NULL ;
-	    break ;
-
-	case 9 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: duplicate row index\n") ;
-	    }
-	    result = 1 ;		/* duplicate row index */
-
-	    for (col = 0 ; col < n_col ; col++)
-	    {
-		length = p [col+1] - p [col] ;
-	    	if (length > 1)
-		{
-		    A [p [col]] = A [p [col] + 1] ;
-		    if (spumoni > 0)
-		    {
-			mexPrintf ("Made duplicate row %d in col %d\n",
-		    	 A [p [col] + 1], col) ;
-		    }
-		    break ;
-		}
-	    }
-
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, Alen, col+2) ;
-	    }
-	    break ;
-
-	case 10 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: unsorted column\n") ;
-	    }
-	    result = 1 ;		/* jumbled columns */
-
-	    for (col = 0 ; col < n_col ; col++)
-	    {
-		length = p [col+1] - p [col] ;
-	    	if (length > 1)
-		{
-		    i = A[p [col]] ;
-		    A [p [col]] = A[p [col] + 1] ;
-		    A [p [col] + 1] = i ;
-		    if (spumoni > 0)
-		    {
-			mexPrintf ("Unsorted column %d \n", col) ;
-		    }
-		    break ;
-		}
-	    }
-
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, Alen, col+2) ;
-	    }
-	    break ;
-
-	case 11 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: massive jumbling\n") ;
-	    }
-	    result = 1 ;		/* massive jumbling, but no errors */
-	    srand (1) ;
-	    for (i = 0 ; i < n_col ; i++)
-	    {
-		cp = &A [p [i]] ;
-		cp_end = &A [p [i+1]] ;
-		while (cp < cp_end)
-		{
-		    *cp++ = rand() % n_row ;
-		}
-	    }
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, Alen, n_col) ;
-	    }
-	    break ;
-
-	case 12 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: stats not present\n") ;
-	    }
-	    result = 0 ;		/* stats not present */
-	    stats = (UF_long *) NULL ;
-	    break ;
-
-	case 13 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("colamdtest: ncol out of range\n") ;
-	    }
-	    result = 0 ;		/* ncol out of range */
-	    n_col = -1 ;
-	    break ;
-
-    }
-
-
-    /* === Order the columns (destroys A) =================================== */
-
-    if (!colamd_l (n_row, n_col, Alen, A, p, knobs, stats))
-    {
-
-	/* return p = -1 if colamd failed */
-	plhs [0] = mxCreateDoubleMatrix (1, 1, mxREAL) ;
-	out_perm = mxGetPr (plhs [0]) ;
-	out_perm [0] = -1 ;
-	mxFree (p) ;
-	mxFree (A) ;
-
-	if (spumoni > 0 || result)
-	{
-	    colamd_l_report (stats) ;
-	}
-
-	if (result)
-	{
-	    mexErrMsgTxt ("colamd should have returned TRUE\n") ;
-	}
-
-	return ;
-	/* mexErrMsgTxt ("colamd error!") ; */
-    }
-
-    if (!result)
-    {
-	colamd_l_report (stats) ;
-	mexErrMsgTxt ("colamd should have returned FALSE\n") ;
-    }
-    mxFree (A) ;
-
-    /* === Return the permutation vector ==================================== */
-
-    plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
-    out_perm = mxGetPr (plhs [0]) ;
-    for (i = 0 ; i < n_col ; i++)
-    {
-	/* colamd is 0-based, but MATLAB expects this to be 1-based */
-	out_perm [i] = p [i] + 1 ;
-    }
-    mxFree (p) ;
-
-    /* === Return the stats vector ========================================== */
-
-    /* print stats if spumoni > 0 */
-    if (spumoni > 0)
-    {
-	colamd_l_report (stats) ;
-    }
-
-    if (nlhs == 2)
-    {
-	plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
-	out_stats = mxGetPr (plhs [1]) ;
-	for (i = 0 ; i < COLAMD_STATS ; i++)
-	{
-	    out_stats [i] = stats [i] ;
-	}
-
-	/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
-	/* note that this correction doesn't occur if symamd returns FALSE */
-	out_stats [COLAMD_INFO1] ++ ; 
-	out_stats [COLAMD_INFO2] ++ ; 
-    }
-}
-
-
-static void dump_matrix
-(
-    UF_long A [ ],
-    UF_long p [ ],
-    UF_long n_row,
-    UF_long n_col,
-    UF_long Alen,
-    UF_long limit
-)
-{
-    UF_long col, k, row ;
-
-    mexPrintf ("dump matrix: nrow %d ncol %d Alen %d\n", n_row, n_col, Alen) ;
-
-    for (col = 0 ; col < MIN (n_col, limit) ; col++)
-    {
-	mexPrintf ("column %d, p[col] %d, p [col+1] %d, length %d\n",
-		col, p [col], p [col+1], p [col+1] - p [col]) ;
-    	for (k = p [col] ; k < p [col+1] ; k++)
-	{
-	    row = A [k] ;
-	    mexPrintf (" %d", row) ;
-	}
-	mexPrintf ("\n") ;
-    }
-}
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/luflops.m b/src/C/SuiteSparse/COLAMD/MATLAB/luflops.m
deleted file mode 100644
index f3c9e45..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/luflops.m
+++ /dev/null
@@ -1,34 +0,0 @@
-function fl = luflops (L, U)
-%LUFLOPS compute the flop count for sparse LU factorization
-%
-%  Example:
-%      fl = luflops (L,U)
-%
-%  Given a sparse LU factorization (L and U), return the flop count required
-%  by a conventional LU factorization algorithm to compute it.   L and U can
-%  be either sparse or full matrices.  L must be lower triangular and U must
-%  be upper triangular.  Do not attempt to use this on the permuted L from
-%  [L,U] = lu (A).  Instead, use [L,U,P] = lu (A) or [L,U,P,Q] = lu (A).
-%
-%  Note that there is a subtle undercount in this estimate.  Suppose A is
-%  completely dense, but during LU factorization exact cancellation occurs,
-%  causing some of the entries in L and U to become identically zero.  The
-%  flop count returned by this routine is an undercount.  There is a simple
-%  way to fix this (L = spones (L) + spones (tril (A))), but the fix is partial.
-%  It can also occur that some entry in L is a "symbolic" fill-in (zero in
-%  A, but a fill-in entry and thus must be computed), but numerically
-%  zero.  The only way to get a reliable LU factorization would be to do a
-%  purely symbolic factorization of A.  This cannot be done with
-%  symbfact (A, 'col').
-%
-%  See NA Digest, Vol 00, #50, Tuesday, Dec. 5, 2000
-%
-% See also symbfact
-
-%    Copyright 1998-2007, Timothy A. Davis
-
-
-Lnz = full (sum (spones (L))) - 1 ;	% off diagonal nz in cols of L
-Unz = full (sum (spones (U')))' - 1 ;	% off diagonal nz in rows of U
-fl = 2*Lnz*Unz + sum (Lnz) ;
-
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/symamd2.m b/src/C/SuiteSparse/COLAMD/MATLAB/symamd2.m
deleted file mode 100644
index ecae450..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/symamd2.m
+++ /dev/null
@@ -1,86 +0,0 @@
-function [p, stats] = symamd2 (S, knobs)
-%SYMAMD Symmetric approximate minimum degree permutation.
-%    P = SYMAMD2(S) for a symmetric positive definite matrix S, returns the
-%    permutation vector p such that S(p,p) tends to have a sparser Cholesky
-%    factor than S.  Sometimes SYMAMD works well for symmetric indefinite
-%    matrices too.  The matrix S is assumed to be symmetric; only the
-%    strictly lower triangular part is referenced.   S must be square.
-%    Note that p = amd(S) is much faster and generates comparable orderings.
-%    The ordering is followed by an elimination tree post-ordering.
-%
-%    Note that this function is source code for the built-in MATLAB symamd
-%    function.  It has been renamed here to symamd2 to avoid a filename clash.
-%    symamd and symamd2 are identical.
-%
-%    See also SYMAMD, AMD, COLAMD, COLAMD2.
-%
-%    Example:
-%            P = symamd2 (S)
-%            [P, stats] = symamd2 (S, knobs)
-%
-%    knobs is an optional one- to two-element input vector.  If S is n-by-n,
-%    then rows and columns with more than max(16,knobs(1)*sqrt(n)) entries are
-%    removed prior to ordering, and ordered last in the output permutation P.
-%    No rows/columns are removed if knobs(1)<0.  If knobs(2) is nonzero, stats
-%    and knobs are printed.  The default is knobs = [10 0].  Note that knobs
-%    differs from earlier versions of symamd.
-
-%    Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore
-%    Developed in collaboration with J. Gilbert and E. Ng.
-%    Acknowledgements: This work was supported by the National Science
-%       Foundation, under grants DMS-9504974 and DMS-9803599.
-
-%-------------------------------------------------------------------------------
-% perform the symamd ordering:
-%-------------------------------------------------------------------------------
-
-if (nargout <= 1 & nargin == 1)						    %#ok
-    p = symamd2mex (S) ;
-elseif (nargout <= 1 & nargin == 2)					    %#ok
-    p = symamd2mex (S, knobs) ;
-elseif (nargout == 2 & nargin == 1)					    %#ok
-    [p, stats] = symamd2mex (S) ;
-elseif (nargout == 2 & nargin == 2)					    %#ok
-    [p, stats] = symamd2mex (S, knobs) ;
-else
-    error('symamd:  incorrect number of input and/or output arguments.') ;
-end
-
-%-------------------------------------------------------------------------------
-% symmetric elimination tree post-ordering:
-%-------------------------------------------------------------------------------
-
-[ignore, q] = etree (S (p,p)) ;
-p = p (q) ;
-
-
-%    stats is an optional 20-element output vector that provides data about the
-%    ordering and the validity of the input matrix S.  Ordering statistics are
-%    in stats (1:3).  stats (1) = stats (2) is the number of dense or empty
-%    rows and columns ignored by SYMAMD and stats (3) is the number of
-%    garbage collections performed on the internal data structure used by
-%    SYMAMD (roughly of size 8.4*nnz(tril(S,-1)) + 9*n integers).
-%
-%    MATLAB built-in functions are intended to generate valid sparse matrices,
-%    with no duplicate entries, with ascending row indices of the nonzeros
-%    in each column, with a non-negative number of entries in each column (!)
-%    and so on.  If a matrix is invalid, then SYMAMD may or may not be able
-%    to continue.  If there are duplicate entries (a row index appears two or
-%    more times in the same column) or if the row indices in a column are out
-%    of order, then SYMAMD can correct these errors by ignoring the duplicate
-%    entries and sorting each column of its internal copy of the matrix S (the
-%    input matrix S is not repaired, however).  If a matrix is invalid in other
-%    ways then SYMAMD cannot continue, an error message is printed, and no
-%    output arguments (P or stats) are returned.  SYMAMD is thus a simple way
-%    to check a sparse matrix to see if it's valid.
-%
-%    stats (4:7) provide information if SYMAMD was able to continue.  The
-%    matrix is OK if stats (4) is zero, or 1 if invalid.  stats (5) is the
-%    rightmost column index that is unsorted or contains duplicate entries,
-%    or zero if no such column exists.  stats (6) is the last seen duplicate
-%    or out-of-order row index in the column index given by stats (5), or zero
-%    if no such row index exists.  stats (7) is the number of duplicate or
-%    out-of-order row indices.
-%
-%    stats (8:20) is always zero in the current version of SYMAMD (reserved
-%    for future use).
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/symamdmex.c b/src/C/SuiteSparse/COLAMD/MATLAB/symamdmex.c
deleted file mode 100644
index 253366d..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/symamdmex.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* ========================================================================== */
-/* === symamd mexFunction =================================================== */
-/* ========================================================================== */
-
-/* SYMAMD mexFunction
-
-    Usage:
-
-	P = symamd2 (A) ;
-	[ P, stats ] = symamd2 (A, knobs) ;
-
-    See symamd.m for a description.
-
-    Authors:
-
-	The authors of the code itself are Stefan I. Larimore and Timothy A.
-	Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
-	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
-	Ng, Oak Ridge National Laboratory.
-
-    Acknowledgements:
-
-	This work was supported by the National Science Foundation, under
-	grants DMS-9504974 and DMS-9803599.
-
-    Notice:
-
-	Copyright (c) 1998-2007, Timothy A. Davis.  All Rights Reserved.
-
-	See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
-	file) for the License.
-
-    Availability:
-
-	The colamd/symamd library is available at
-
-	    http://www.cise.ufl.edu/research/sparse/colamd/
-
-	This is the http://www.cise.ufl.edu/research/sparse/colamd/symamdmex.c
-	file.  It requires the colamd.c and colamd.h files.
-
-*/
-
-/* ========================================================================== */
-/* === Include files ======================================================== */
-/* ========================================================================== */
-
-#include "colamd.h"
-#include "mex.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include "UFconfig.h"
-
-/* ========================================================================== */
-/* === symamd mexFunction =================================================== */
-/* ========================================================================== */
-
-void mexFunction
-(
-    /* === Parameters ======================================================= */
-
-    int nlhs,			/* number of left-hand sides */
-    mxArray *plhs [],		/* left-hand side matrices */
-    int nrhs,			/* number of right--hand sides */
-    const mxArray *prhs []	/* right-hand side matrices */
-)
-{
-    /* === Local variables ================================================== */
-
-    UF_long *perm ;		/* column ordering of M and ordering of A */
-    UF_long *A ;		/* row indices of input matrix A */
-    UF_long *p ;		/* column pointers of input matrix A */
-    UF_long n_col ;		/* number of columns of A */
-    UF_long n_row ;		/* number of rows of A */
-    UF_long full ;		/* TRUE if input matrix full, FALSE if sparse */
-    double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
-    double *out_perm ;		/* output permutation vector */
-    double *out_stats ;		/* output stats vector */
-    double *in_knobs ;		/* input knobs vector */
-    UF_long i ;			/* loop counter */
-    mxArray *Ainput ;		/* input matrix handle */
-    UF_long spumoni ;		/* verbosity variable */
-    UF_long stats [COLAMD_STATS] ;	/* stats for symamd */
-
-    colamd_printf = mexPrintf ;	/* COLAMD printf routine */
-
-    /* === Check inputs ===================================================== */
-
-    if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
-    {
-	mexErrMsgTxt (
-	"symamd: incorrect number of input and/or output arguments.") ;
-    }
-
-    /* === Get knobs ======================================================== */
-
-    colamd_l_set_defaults (knobs) ;
-    spumoni = 0 ;
-
-    /* check for user-passed knobs */
-    if (nrhs == 2)
-    {
-	in_knobs = mxGetPr (prhs [1]) ;
-	i = mxGetNumberOfElements (prhs [1]) ;
-	if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
-	if (i > 1) spumoni = (UF_long) (in_knobs [1] != 0) ;
-    }
-
-    /* print knob settings if spumoni is set */
-    if (spumoni)
-    {
-	mexPrintf ("\nsymamd version %d.%d, %s:\n",
-	    COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
-	if (knobs [COLAMD_DENSE_ROW] >= 0)
-	{
-	    mexPrintf ("knobs(1): %g, rows/cols with > "
-		"max(16,%g*sqrt(size(A,2))) entries removed\n",
-		in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(1): %g, no dense rows removed\n", in_knobs [0]) ;
-	}
-	mexPrintf ("knobs(2): %g, statistics and knobs printed\n",
-	    in_knobs [1]) ;
-    }
-
-    /* === If A is full, convert to a sparse matrix ========================= */
-
-    Ainput = (mxArray *) prhs [0] ;
-    if (mxGetNumberOfDimensions (Ainput) != 2)
-    {
-	mexErrMsgTxt ("symamd: input matrix must be 2-dimensional.") ;
-    }
-    full = !mxIsSparse (Ainput) ;
-    if (full)
-    {
-	mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
-    }
-
-    /* === Allocate workspace for symamd ==================================== */
-
-    /* get size of matrix */
-    n_row = mxGetM (Ainput) ;
-    n_col = mxGetN (Ainput) ;
-    if (n_col != n_row)
-    {
-	mexErrMsgTxt ("symamd: matrix must be square.") ;
-    }
-
-    A = (UF_long *) mxGetIr (Ainput) ;
-    p = (UF_long *) mxGetJc (Ainput) ;
-    perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
-
-    /* === Order the rows and columns of A (does not destroy A) ============= */
-
-    if (!symamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree))
-    {
-	symamd_l_report (stats) ;
-	mexErrMsgTxt ("symamd error!") ;
-    }
-
-    if (full)
-    {
-	mxDestroyArray (Ainput) ;
-    }
-
-    /* === Return the permutation vector ==================================== */
-
-    plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
-    out_perm = mxGetPr (plhs [0]) ;
-    for (i = 0 ; i < n_col ; i++)
-    {
-	/* symamd is 0-based, but MATLAB expects this to be 1-based */
-	out_perm [i] = perm [i] + 1 ;
-    }
-    mxFree (perm) ;
-
-    /* === Return the stats vector ========================================== */
-
-    /* print stats if spumoni is set */
-    if (spumoni)
-    {
-	symamd_l_report (stats) ;
-    }
-
-    if (nlhs == 2)
-    {
-	plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
-	out_stats = mxGetPr (plhs [1]) ;
-	for (i = 0 ; i < COLAMD_STATS ; i++)
-	{
-	    out_stats [i] = stats [i] ;
-	}
-
-	/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
-	/* note that this correction doesn't occur if symamd returns FALSE */
-	out_stats [COLAMD_INFO1] ++ ; 
-	out_stats [COLAMD_INFO2] ++ ; 
-    }
-}
diff --git a/src/C/SuiteSparse/COLAMD/MATLAB/symamdtestmex.c b/src/C/SuiteSparse/COLAMD/MATLAB/symamdtestmex.c
deleted file mode 100644
index c41101f..0000000
--- a/src/C/SuiteSparse/COLAMD/MATLAB/symamdtestmex.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/* ========================================================================== */
-/* === symamdtest mexFunction =============================================== */
-/* ========================================================================== */
-
-/* SYMAMD test function
-
-    This MATLAB mexFunction is for testing only.  It is not meant for
-    production use.  See symamdmex.c instead.
-
-    Usage:
-
-	[ P, stats ] = symamdtest (A, knobs) ;
-
-    See symamd.m for a description.  knobs is required.
-
-	knobs (1)	dense row control
-	knobs (2)	spumoni
-	knobs (3)	for testing only.  Controls how the input matrix is
-			jumbled prior to calling symamd, to test its error
-			handling capability.
-
-    Authors:
-
-	The authors of the code itself are Stefan I. Larimore and Timothy A.
-	Davis (davis at cise.ufl.edu), University of Florida.  The algorithm was
-	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
-	Ng, Oak Ridge National Laboratory.
-
-    Acknowledgements:
-
-	This work was supported by the National Science Foundation, under
-	grants DMS-9504974 and DMS-9803599.
-
-    Notice:
-
-	Copyright (c) 1998-2007, Timothy A. Davis.  All Rights Reserved.
-
-	See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
-	file) for the License.
-
-    Availability:
-
-	The colamd/symamd library is available at
-
-	    http://www.cise.ufl.edu/research/sparse/colamd/
-
-	This is the
-	http://www.cise.ufl.edu/research/sparse/colamd/symamdtestmex.c
-       	file.  It requires the colamd.c and colamd.h files.
-
-*/
-
-/* ========================================================================== */
-/* === Include files ======================================================== */
-/* ========================================================================== */
-
-#include "colamd.h"
-#include "mex.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include <string.h>
-#include "UFconfig.h"
-
-static void dump_matrix
-(
-    UF_long A [ ],
-    UF_long p [ ],
-    UF_long n_row,
-    UF_long n_col,
-    UF_long Alen,
-    UF_long limit
-) ;
-
-/* ========================================================================== */
-/* === symamd mexFunction =================================================== */
-/* ========================================================================== */
-
-void mexFunction
-(
-    /* === Parameters ======================================================= */
-
-    int nlhs,			/* number of left-hand sides */
-    mxArray *plhs [],		/* left-hand side matrices */
-    int nrhs,			/* number of right--hand sides */
-    const mxArray *prhs []	/* right-hand side matrices */
-)
-{
-    /* === Local variables ================================================== */
-
-    UF_long *perm ;		/* column ordering of M and ordering of A */
-    UF_long *A ;		/* row indices of input matrix A */
-    UF_long *p ;		/* column pointers of input matrix A */
-    UF_long n_col ;		/* number of columns of A */
-    UF_long n_row ;		/* number of rows of A */
-    UF_long full ;		/* TRUE if input matrix full, FALSE if sparse */
-    double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
-    double *out_perm ;		/* output permutation vector */
-    double *out_stats ;		/* output stats vector */
-    double *in_knobs ;		/* input knobs vector */
-    UF_long i ;			/* loop counter */
-    mxArray *Ainput ;		/* input matrix handle */
-    UF_long spumoni ;		/* verbosity variable */
-    UF_long stats2 [COLAMD_STATS] ;	/* stats for symamd */
-
-    UF_long *cp, *cp_end, result, nnz, col, length ;
-    UF_long *stats ;
-    stats = stats2 ;
-
-    colamd_printf = mexPrintf ;	/* COLAMD printf routine */
-
-    /* === Check inputs ===================================================== */
-
-    if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
-    {
-	mexErrMsgTxt (
-	"symamd: incorrect number of input and/or output arguments.") ;
-    }
-
-    if (nrhs != 2)
-    {
-	mexErrMsgTxt ("symamdtest: knobs are required") ;
-    }
-    /* for testing we require all 3 knobs */
-    if (mxGetNumberOfElements (prhs [1]) != 3)
-    {
-	mexErrMsgTxt ("symamdtest: must have all 3 knobs for testing") ;
-    }
-
-    /* === Get knobs ======================================================== */
-
-    colamd_l_set_defaults (knobs) ;
-    spumoni = 0 ;
-
-    /* check for user-passed knobs */
-    if (nrhs == 2)
-    {
-	in_knobs = mxGetPr (prhs [1]) ;
-	i = mxGetNumberOfElements (prhs [1]) ;
-	if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
-	if (i > 1) spumoni = (UF_long) in_knobs [1] ;
-    }
-
-    /* print knob settings if spumoni is set */
-    if (spumoni)
-    {
-	mexPrintf ("\nsymamd version %d.%d, %s:\n",
-	    COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
-	if (knobs [COLAMD_DENSE_ROW] >= 0)
-	{
-	    mexPrintf ("knobs(1): %g, rows/cols with > "
-		"max(16,%g*sqrt(size(A,2))) entries removed\n",
-		in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
-	}
-	else
-	{
-	    mexPrintf ("knobs(1): %g, no dense rows removed\n", in_knobs [0]) ;
-	}
-	mexPrintf ("knobs(2): %g, statistics and knobs printed\n",
-	    in_knobs [1]) ;
-	mexPrintf ("Testing %d\n", in_knobs [2]) ;
-    }
-
-    /* === If A is full, convert to a sparse matrix ========================= */
-
-    Ainput = (mxArray *) prhs [0] ;
-    if (mxGetNumberOfDimensions (Ainput) != 2)
-    {
-	mexErrMsgTxt ("symamd: input matrix must be 2-dimensional.") ;
-    }
-    full = !mxIsSparse (Ainput) ;
-    if (full)
-    {
-	mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
-    }
-
-    /* === Allocate workspace for symamd ==================================== */
-
-    /* get size of matrix */
-    n_row = mxGetM (Ainput) ;
-    n_col = mxGetN (Ainput) ;
-    if (n_col != n_row)
-    {
-	mexErrMsgTxt ("symamd: matrix must be square.") ;
-    }
-
-    /* p = mxGetJc (Ainput) ; */
-    p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
-    (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ;
-
-    nnz = p [n_col] ;
-    if (spumoni > 0)
-    {
-	mexPrintf ("symamdtest: nnz %d\n", nnz) ;
-    }
-
-    /* A = mxGetIr (Ainput) ; */
-    A = (UF_long *) mxCalloc (nnz+1, sizeof (UF_long)) ;
-    (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ;
-
-    perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
-
-/* === Jumble matrix ======================================================== */
-
-
-/*
-	knobs [2]	FOR TESTING ONLY: Specifies how to jumble matrix
-			0 : No jumbling
-			1 : (no errors)
-			2 : Make first pointer non-zero
-			3 : Make column pointers not non-decreasing
-			4 : (no errors)
-			5 : Make row indices not strictly increasing
-			6 : Make a row index greater or equal to n_row
-			7 : Set A = NULL
-			8 : Set p = NULL
-			9 : Repeat row index
-			10: make row indices not sorted
-			11: jumble columns massively (note this changes
-				the pattern of the matrix A.)
-			12: Set stats = NULL
-			13: Make n_col less than zero
-*/
-
-    /* jumble appropriately */
-    switch ((UF_long) in_knobs [2])
-    {
-
-	case 0 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: no errors expected\n") ;
-	    }
-	    result = 1 ;		/* no errors */
-	    break ;
-
-	case 1 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: no errors expected (1)\n") ;
-	    }
-	    result = 1 ;
-	    break ;
-
-	case 2 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: p [0] nonzero\n") ;
-	    }
-	    result = 0 ;		/* p [0] must be zero */
-	    p [0] = 1 ;
-	    break ;
-
-	case 3 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: negative length last column\n") ;
-	    }
-	    result = (n_col == 0) ;	/* p must be monotonically inc. */
-	    p [n_col] = p [0] ;
-	    break ;
-
-	case 4 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: no errors expected (4)\n") ;
-	    }
-	    result = 1 ;
-	    break ;
-
-	case 5 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: row index out of range (-1)\n") ;
-	    }
-	    if (nnz > 0)		/* row index out of range */
-	    {
-		result = 0 ;
-		A [nnz-1] = -1 ;
-	    }
-	    else
-	    {
-	        if (spumoni > 0)
-		{
-		    mexPrintf ("Note: no row indices to put out of range\n") ;
-		}
-		result = 1 ;
-	    }
-	    break ;
-
-	case 6 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: row index out of range (ncol)\n") ;
-	    }
-	    if (nnz > 0)		/* row index out of range */
-	    {
-		result = 0 ;
-		A [nnz-1] = n_col ;
-	    }
-	    else
-	    {
-	        if (spumoni > 0)
-		{
-		    mexPrintf ("Note: no row indices to put out of range\n") ;
-		}
-		result = 1 ;
-	    }
-	    break ;
-
-	case 7 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: A not present\n") ;
-	    }
-	    result = 0 ;		/* A not present */
-	    A = (UF_long *) NULL ;
-	    break ;
-
-	case 8 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: p not present\n") ;
-	    }
-	    result = 0 ;		/* p not present */
-	    p = (UF_long *) NULL ;
-	    break ;
-
-	case 9 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: duplicate row index\n") ;
-	    }
-	    result = 1 ;		/* duplicate row index */
-
-	    for (col = 0 ; col < n_col ; col++)
-	    {
-		length = p [col+1] - p [col] ;
-	    	if (length > 1)
-		{
-		    A [p [col+1]-2] = A [p [col+1] - 1] ;
-		    if (spumoni > 0)
-		    {
-			mexPrintf ("Made duplicate row %d in col %d\n",
-		    	 A [p [col+1] - 1], col) ;
-		    }
-		    break ;
-		}
-	    }
-
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, nnz, col+2) ;
-	    }
-	    break ;
-
-	case 10 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: unsorted column\n") ;
-	    }
-	    result = 1 ;		/* jumbled columns */
-
-	    for (col = 0 ; col < n_col ; col++)
-	    {
-		length = p [col+1] - p [col] ;
-	    	if (length > 1)
-		{
-		    i = A[p [col]] ;
-		    A [p [col]] = A[p [col] + 1] ;
-		    A [p [col] + 1] = i ;
-		    if (spumoni > 0)
-		    {
-			mexPrintf ("Unsorted column %d \n", col) ;
-		    }
-		    break ;
-		}
-	    }
-
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, nnz, col+2) ;
-	    }
-	    break ;
-
-	case 11 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: massive jumbling\n") ;
-	    }
-	    result = 1 ;		/* massive jumbling, but no errors */
-	    srand (1) ;
-	    for (i = 0 ; i < n_col ; i++)
-	    {
-		cp = &A [p [i]] ;
-		cp_end = &A [p [i+1]] ;
-		while (cp < cp_end)
-		{
-		    *cp++ = rand() % n_row ;
-		}
-	    }
-	    if (spumoni > 1)
-	    {
-		dump_matrix (A, p, n_row, n_col, nnz, n_col) ;
-	    }
-	    break ;
-
-	case 12 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: stats not present\n") ;
-	    }
-	    result = 0 ;		/* stats not present */
-	    stats = (UF_long *) NULL ;
-	    break ;
-
-	case 13 :
-	    if (spumoni > 0)
-	    {
-		mexPrintf ("symamdtest: ncol out of range\n") ;
-	    }
-	    result = 0 ;		/* ncol out of range */
-	    n_col = -1 ;
-	    break ;
-
-    }
-
-    /* === Order the rows and columns of A (does not destroy A) ============= */
-
-    if (!symamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree))
-    {
-
-	/* return p = -1 if colamd failed */
-	plhs [0] = mxCreateDoubleMatrix (1, 1, mxREAL) ;
-	out_perm = mxGetPr (plhs [0]) ;
-	out_perm [0] = -1 ;
-	mxFree (p) ;
-	mxFree (A) ;
-
-	if (spumoni > 0 || result)
-	{
-	    symamd_l_report (stats) ;
-	}
-
-	if (result)
-	{
-	    mexErrMsgTxt ("symamd should have returned TRUE\n") ;
-	}
-
-	return ;
-	/* mexErrMsgTxt ("symamd error!") ; */
-    }
-
-    if (!result)
-    {
-	symamd_l_report (stats) ;
-	mexErrMsgTxt ("symamd should have returned FALSE\n") ;
-    }
-
-    if (full)
-    {
-	mxDestroyArray (Ainput) ;
-    }
-
-    /* === Return the permutation vector ==================================== */
-
-    plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
-    out_perm = mxGetPr (plhs [0]) ;
-    for (i = 0 ; i < n_col ; i++)
-    {
-	/* symamd is 0-based, but MATLAB expects this to be 1-based */
-	out_perm [i] = perm [i] + 1 ;
-    }
-    mxFree (perm) ;
-
-    /* === Return the stats vector ========================================== */
-
-    /* print stats if spumoni > 0 */
-    if (spumoni > 0)
-    {
-	symamd_l_report (stats) ;
-    }
-
-    if (nlhs == 2)
-    {
-	plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
-	out_stats = mxGetPr (plhs [1]) ;
-	for (i = 0 ; i < COLAMD_STATS ; i++)
-	{
-	    out_stats [i] = stats [i] ;
-	}
-
-	/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
-	/* note that this correction doesn't occur if symamd returns FALSE */
-	out_stats [COLAMD_INFO1] ++ ; 
-	out_stats [COLAMD_INFO2] ++ ; 
-    }
-}
-
-
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-
-
-static void dump_matrix
-(
-    UF_long A [ ],
-    UF_long p [ ],
-    UF_long n_row,
-    UF_long n_col,
-    UF_long Alen,
-    UF_long limit
-)
-{
-    UF_long col, k, row ;
-
-    mexPrintf ("dump matrix: nrow %d ncol %d Alen %d\n", n_row, n_col, Alen) ;
-
-    if (!A)
-    {
-    	mexPrintf ("A not present\n") ;
-	return ;
-    }
-
-    if (!p)
-    {
-    	mexPrintf ("p not present\n") ;
-	return ;
-    }
-
-    for (col = 0 ; col < MIN (n_col, limit) ; col++)
-    {
-	mexPrintf ("column %d, p[col] %d, p [col+1] %d, length %d\n",
-		col, p [col], p [col+1], p [col+1] - p [col]) ;
-    	for (k = p [col] ; k < p [col+1] ; k++)
-	{
-	    row = A [k] ;
-	    mexPrintf (" %d", row) ;
-	}
-	mexPrintf ("\n") ;
-    }
-}
diff --git a/src/C/SuiteSparse/Contents.m b/src/C/SuiteSparse/Contents.m
index 6ea5659..5f6f306 100644
--- a/src/C/SuiteSparse/Contents.m
+++ b/src/C/SuiteSparse/Contents.m
@@ -16,6 +16,7 @@
 %   camd         - constrained amd.
 %   ccolamd      - constrained colamd.
 %   csymamd      - constrained symamd.
+%   meshnd       - nested dissection of regular 2D and 3D meshes
 %
 %-------------------------------------------------------------------------------
 % CHOLMOD: a sparse supernodal Cholesky update/downdate package:
@@ -113,7 +114,14 @@
 %   luflop            - given L and U, computes # of flops required
 %
 %-------------------------------------------------------------------------------
-% UFGET: MATLAB interface to the UF Sparse Matrix Collection
+% Other packages:
+%-------------------------------------------------------------------------------
+%
+%   UFGET           MATLAB interface to the UF Sparse Matrix Collection
+%   MATLAB_Tools    various simple m-files
+%   SSMULT          sparse matrix times sparse matrix
+%   LINFACTOR       solve Ax=b using LU or CHOL
+%
 %-------------------------------------------------------------------------------
 %
 % For help on compiling SuiteSparse or the demos, testing functions, etc.,
diff --git a/src/C/SuiteSparse/Makefile b/src/C/SuiteSparse/Makefile
index da7dc78..b56e0c8 100644
--- a/src/C/SuiteSparse/Makefile
+++ b/src/C/SuiteSparse/Makefile
@@ -7,7 +7,7 @@ include UFconfig/UFconfig.mk
 # Compile the default rules for each package
 default:
 	( cd UFconfig/xerbla ; $(MAKE) )
-	( cd metis-4.0 ; $(MAKE) )
+#	( cd metis-4.0 ; $(MAKE) )
 	( cd AMD ; $(MAKE) )
 	( cd CAMD ; $(MAKE) )
 	( cd COLAMD ; $(MAKE) )
@@ -41,7 +41,7 @@ mex:
 # Remove all files not in the original distribution
 purge:
 	( cd UFconfig/xerbla ; $(MAKE) purge )
-	( cd metis-4.0 ; $(MAKE) realclean )
+#	( cd metis-4.0 ; $(MAKE) realclean )
 	( cd AMD ; $(MAKE) purge )
 	( cd CAMD ; $(MAKE) purge )
 	( cd COLAMD ; $(MAKE) purge )
@@ -55,13 +55,14 @@ purge:
 	( cd CXSparse ; $(MAKE) purge )
 	( cd RBio ; $(RM) *.mex* )
 	( cd UFcollection ; $(RM) *.mex* )
+	( cd SSMULT ; $(RM) *.mex* )
 #	( cd LPDASA ; $(MAKE) purge )
 #	( cd PARAKLETE ; $(MAKE) purge )
 
 # Remove all files not in the original distribution, but keep the libraries
 clean:
 	( cd UFconfig/xerbla ; $(MAKE) clean )
-	( cd metis-4.0 ; $(MAKE) clean )
+#	( cd metis-4.0 ; $(MAKE) clean )
 	( cd AMD ; $(MAKE) clean )
 	( cd CAMD ; $(MAKE) clean )
 	( cd COLAMD ; $(MAKE) clean )
@@ -88,3 +89,11 @@ cx:
 	( cd CXSparse/Demo ; $(MAKE) > cs_demo.out )
 	( cd CXSparse ; $(MAKE) purge )
 
+# statement coverage (Linux only); this requires a lot of time.
+# The umfpack tcov requires a lot of disk space
+cov:
+	( cd CXSparse ; $(MAKE) cov )
+	( cd CSparse ; $(MAKE) cov )
+	( cd KLU ; $(MAKE) cov )
+	( cd CHOLMOD ; $(MAKE) cov )
+	( cd UMFPACK ; $(MAKE) cov )
diff --git a/src/C/SuiteSparse/README.txt b/src/C/SuiteSparse/README.txt
index 924c514..f0d7ec4 100644
--- a/src/C/SuiteSparse/README.txt
+++ b/src/C/SuiteSparse/README.txt
@@ -11,9 +11,7 @@ SuiteSparse_install.  All packages will be compiled, and several demos will be
 run.
 ================================================================================
 
-May 31, 2007.  SuiteSparse version 3.0.
-
-UF suite of sparse matrix algorithms:
+Nov 1, 2007.  SuiteSparse version 3.1
 
     AMD		approximate minimum degree ordering
 
@@ -51,10 +49,20 @@ UF suite of sparse matrix algorithms:
 
     LPDASA	LP dual active set algorithm (to appear)
 
+    MESHND      2D and 3D mesh generation and nested dissection ordering
+
+    SSMULT      sparse matrix multiply for MATLAB
+
+    LINFACTOR   simple m-file demonstrating how to use LU and CHOL in
+                MATLAB to solve Ax=b
 
-CHOLMOD and KLU optionally use METIS 4.0.1
-(http://www-users.cs.umn.edu/~karypis/metis).  Place a copy of the metis-4.0
-directory in the same directory (SuiteSparse) containing this README file.
+    MATLAB_Tools    various simple m-files for use in MATLAB
+
+CHOLMOD optionally uses METIS 4.0.1
+(http://www-users.cs.umn.edu/~karypis/metis).  To use METIS, place a copy of
+the metis-4.0 directory in the same directory (CHOLMOD_ACM_TOMS) containing
+this README file.  The use of METIS will improve the ordering quality in
+CHOLMOD.
 
 Refer to each package for license, copyright, and author information.  All
 codes are authored or co-authored by Timothy A. Davis, CISE Dept., Univ. of
@@ -70,34 +78,58 @@ If you use SuiteSparse_install in MATLAB, stop reading here.
 To use "make" in Unix/Linux:
 ----------------------------
 
+(1) Use the right BLAS and LAPACK libraries
+
     See http://www.netlib.org/blas for the Fortran reference BLAS (slow, but
     they work).  See http://www.tacc.utexas.edu/~kgoto/ or
     http://www.cs.utexas.edu/users/flame/goto/ for an optimized BLAS.  See
     http://www.netlib.org/lapack for LAPACK.  The UFconfig/UFconfig.mk file
     assumes the vanilla BLAS (-lblas).  You should use an optimized BLAS;
     otherwise UMFPACK and CHOLMOD will be slow.  Change -lblas to -l(your BLAS
-    library here).
+    library here) in the UFconfig/UFconfig.mk file.
+
+(2) Configure METIS (or don't use METIS)
 
     cd to metis-4.0 and edit the Makefile.in file.  I recommend making these
     changes to metis-4.0/Makefile.in:
 
-    CC = gcc
-    OPTFLAGS = -O3
-    COPTIONS = -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
-
-    then type "make".  Now compile CHOLMOD.
-
-    To compile all the C-callable libraries in SuiteSparse:  First, edit the
-    UFconfig/UFconfig.mk file (see that file for instructions), if necessary.
-    Next, type "make" in this directory to compile all packages in this
-    distribution.  CHOLMOD can be compiled without METIS (use -DNPARTITION);
-    this option is handled by SuiteSparse_install.m in MATLAB automatically, if
-    the metis-4.0 directory does not appear (in the same directory as CHOLMOD,
-    AMD, UMFPACK, etc).
-
-    To compile each package, cd to the top-level directory (AMD, COLAMD, etc)
-    and type "make".  Type "make clean" in the same directory to remove all but
-    the compiled libraries.  Type "make distclean" to remove all files not in
-    the original distribution.  Alternatively, just type "make" in this
-    directory.
+        CC = gcc
+        OPTFLAGS = -O3
+        COPTIONS = -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+
+    Next, cd to metis-4.0 and type "make".
+
+    If you do not wish to use METIS, then edit the UFconfig/UFconfig.mk file,
+    and change the line
+
+        CHOLMOD_CONFIG =
+
+    to
+
+        CHOLMOD_CONFIG = -DNPARTITION
+
+    Also change the line
+
+        METIS = ../../metis-4.0/libmetis.a
+
+    to
+
+        METIS =
+
+(3) Make other changes to UFconfig/UFconfig.mk as needed
+
+    Edit the UFconfig/UFconfig.mk file as needed.  Directions are in that file.
+    If you have compiled SuiteSparse already (partially or completely), then
+    whenever you edit the UFconfig/UFconfig.mk file, you should then type
+    "make purge" (or "make realclean") in this directory.
+
+(4) Type "make" in this directory.  All packages will be be compiled.  METIS
+    will be compiled if you have it.  Several demos will be run.
+
+    The libraries will appear in */Lib/*.a.  Include files, as needed by user
+    programs that use CHOLMOD, AMD, CAMD, COLAMD, CCOLAMD, BTF, KLU, UMFPACK,
+    LDL, etc. are in */Include/*.h.
+
+    The METIS library is in metis-4.0/libmetis.a.  METIS Include files (not
+    needed by the end user of SuiteSparse) are in located in metis-4.0/Lib/*.h.
 
diff --git a/src/C/SuiteSparse/README_cvxopt b/src/C/SuiteSparse/README_cvxopt
index 6e4c6ec..6e99bc1 100644
--- a/src/C/SuiteSparse/README_cvxopt
+++ b/src/C/SuiteSparse/README_cvxopt
@@ -1,5 +1,6 @@
-This is the May 31, 2007 (version 3.0) distribution of the SuiteSparse 
-package, with the following files and directories removed.
+This is the Nov 1, 2007 (version 3.1.0) distribution of the SuiteSparse 
+package from www.cise.ufl.edu/research/sparse/SuiteSparse/, with the 
+following files and directories removed.
 
 AMD/Demo
 AMD/MATLAB
@@ -13,6 +14,7 @@ CHOLMOD/Modify
 CHOLMOD/Partition
 CHOLMOD/Tcov
 CHOLMOD/Valgrind
+COLAMD/MATLAB
 CSparse
 Csparse_to_CXsparse
 CXSparse
@@ -20,8 +22,14 @@ CXSparse_newfiles
 CXSparse_newfiles.tar.gz
 KLU
 LDL
+LINFACTOR
+MATLAB_Tools
+MESHND
 RBio
+SSMULT
+SuiteSparse_demo.m
 SuiteSparse_install.m
+SuiteSparse_test.m
 UFcollection
 UMFPACK/Demo
 UMFPACK/MATLAB
diff --git a/src/C/SuiteSparse/SuiteSparse_demo.m b/src/C/SuiteSparse/SuiteSparse_demo.m
deleted file mode 100644
index 1247014..0000000
--- a/src/C/SuiteSparse/SuiteSparse_demo.m
+++ /dev/null
@@ -1,113 +0,0 @@
-function SuiteSparse_demo (matrixpath)
-%SUITESPARSE_DEMO a demo of all packages in SuiteSparse
-%
-% Example:
-%   SuiteSparse_demo
-%
-% See also umfpack, cholmod, amd, camd, colamd, ccolamd, btf, klu,
-%   CSparse, CXSparse, ldlsparse
-
-% Copyright (c) Timothy A. Davis, Univ. of Florida
-
-if (nargin < 1)
-    try
-	% older versions of MATLAB do not have an input argument to mfilename
-	p = mfilename ('fullpath') ;
-	t = strfind (p, filesep) ;
-	matrixpath = [ p(1:t(end)) 'CXSparse/Matrix' ] ;
-    catch
-	% mfilename failed, assume we're in the SuiteSparse directory
-	matrixpath = 'CXSparse/Matrix' ;
-    end
-end
-
-input ('Hit enter to run the CXSparse demo: ') ;
-try
-    cs_demo (0, matrixpath)
-catch
-    fprintf ('\nIf you have an older version of MATLAB, you must run the\n') ;
-    fprintf ('SuiteSparse_demo while in the SuiteSparse directory.\n\n') ;
-    fprintf ('CXSparse demo failed\n' )
-end
-
-input ('Hit enter to run the UMFPACK demo: ') ;
-try
-    umfpack_demo (1)
-catch
-    disp (lasterr) ;
-    fprintf ('UMFPACK demo failed\n' )
-end
-
-input ('Hit enter to run the CHOLMOD demo: ') ;
-try
-    cholmod_demo
-catch
-    disp (lasterr) ;
-    fprintf ('CHOLMOD demo failed\n' )
-end
-
-input ('Hit enter to run the CHOLMOD graph partitioning demo: ') ;
-try
-    graph_demo
-catch
-    disp (lasterr) ;
-    fprintf ('graph_demo failed, probably because METIS not installed\n') ;
-end
-
-input ('Hit enter to run the AMD demo: ') ;
-try
-    amd_demo
-catch
-    disp (lasterr) ;
-    fprintf ('AMD demo failed\n' )
-end
-
-input ('Hit enter to run the CAMD demo: ') ;
-try
-    camd_demo
-catch
-    disp (lasterr) ;
-    fprintf ('CAMD demo failed\n' )
-end
-
-input ('Hit enter to run the COLAMD demo: ') ;
-try
-    colamd_demo
-catch
-    disp (lasterr) ;
-    fprintf ('COLAMD demo failed\n' )
-end
-
-input ('Hit enter to run the CCOLAMD demo: ') ;
-try
-    ccolamd_demo
-catch
-    disp (lasterr) ;
-    fprintf ('CCOLAMD demo failed\n' )
-end
-
-input ('Hit enter to run the BTF demo: ') ;
-try
-    btf_demo
-catch
-    disp (lasterr) ;
-    fprintf ('BTF demo failed\n' )
-end
-
-input ('Hit enter to run the KLU demo: ') ;
-try
-    klu_demo
-catch
-    disp (lasterr) ;
-    fprintf ('KLU demo failed\n' )
-end
-
-input ('Hit enter to run the LDL demo: ') ;
-try
-    ldldemo
-catch
-    disp (lasterr) ;
-    fprintf ('LDL demo failed\n' )
-end
-
-fprintf ('\n\n---- SuiteSparse demos complete\n') ;
diff --git a/src/C/SuiteSparse/UFconfig/README.txt b/src/C/SuiteSparse/UFconfig/README.txt
index 0e165a4..eb26fe1 100644
--- a/src/C/SuiteSparse/UFconfig/README.txt
+++ b/src/C/SuiteSparse/UFconfig/README.txt
@@ -18,9 +18,13 @@ do not require UFconfig.
 
 UFconfig is not required by:
 
-  CSparse		    a Concise Sparse matrix package
-  RBio			    read/write files in Rutherford/Boeing format
-  UFcollection		    tools for managing the UF Sparse Matrix Collection
+  CSparse	a Concise Sparse matrix package
+  RBio		read/write files in Rutherford/Boeing format
+  UFcollection	tools for managing the UF Sparse Matrix Collection
+  LINFACTOR     simple m-file to show how to use LU and CHOL to solve Ax=b
+  MESHND        2D and 3D mesh generation and nested dissection ordering
+  MATLAB_Tools  misc collection of m-files
+  SSMULT        sparse matrix times sparse matrix, for use in MATLAB
 
 In addition, the xerbla/ directory contains Fortan and C versions of the
 BLAS/LAPACK xerbla routine, which is called when an invalid input is passed to
diff --git a/src/C/SuiteSparse/UFconfig/UFconfig.h b/src/C/SuiteSparse/UFconfig/UFconfig.h
index 91bbeac..36c1bd3 100644
--- a/src/C/SuiteSparse/UFconfig/UFconfig.h
+++ b/src/C/SuiteSparse/UFconfig/UFconfig.h
@@ -76,22 +76,26 @@ extern "C" {
  * version of SuiteSparse, with another package from another version of
  * SuiteSparse, may or may not work.
  *
- * SuiteSparse Version 3.0.0 contains the following packages:
+ * SuiteSparse Version 3.1.0 contains the following packages:
  *
  *  AMD		    version 2.2.0
  *  CAMD	    version 2.2.0
- *  COLAMD	    version 2.7.0
- *  CCOLAMD	    version 2.7.0
- *  CHOLMOD	    version 1.5.0
- *  CSparse	    version 2.2.0
- *  CXSparse	    version 2.2.0
- *  KLU		    version 1.0.0
- *  BTF		    version 1.0.0
- *  LDL		    version 2.0.0
+ *  COLAMD	    version 2.7.1
+ *  CCOLAMD	    version 2.7.1
+ *  CHOLMOD	    version 1.6.0
+ *  CSparse	    version 2.2.1
+ *  CXSparse	    version 2.2.1
+ *  KLU		    version 1.0.1
+ *  BTF		    version 1.0.1
+ *  LDL		    version 2.0.1
  *  UFconfig	    version number is the same as SuiteSparse
- *  UMFPACK	    version 5.1.0
- *  RBio	    version 1.1.0
- *  UFcollection    version 1.1.0
+ *  UMFPACK	    version 5.2.0
+ *  RBio	    version 1.1.1
+ *  UFcollection    version 1.1.1
+ *  LINFACTOR       version 1.1.0
+ *  MESHND          version 1.1.0
+ *  SSMULT          version 1.1.0
+ *  MATLAB_Tools    no specific version number
  *
  * Other package dependencies:
  *  BLAS	    required by CHOLMOD and UMFPACK
@@ -99,10 +103,10 @@ extern "C" {
  *  METIS 4.0.1	    required by CHOLMOD (optional) and KLU (optional)
  */
 
-#define SUITESPARSE_DATE "May 31, 2007"
+#define SUITESPARSE_DATE "Nov 1, 2007"
 #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub))
 #define SUITESPARSE_MAIN_VERSION 3
-#define SUITESPARSE_SUB_VERSION 0
+#define SUITESPARSE_SUB_VERSION 1
 #define SUITESPARSE_SUBSUB_VERSION 0
 #define SUITESPARSE_VERSION \
     SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION)
diff --git a/src/C/SuiteSparse/UFconfig/UFconfig.mk b/src/C/SuiteSparse/UFconfig/UFconfig.mk
index 8d33eab..5f4f8e2 100644
--- a/src/C/SuiteSparse/UFconfig/UFconfig.mk
+++ b/src/C/SuiteSparse/UFconfig/UFconfig.mk
@@ -51,11 +51,11 @@ F77LIB =
 # C and Fortran libraries
 LIB = -lm
 
-# For compiling MATLAB mexFunctions (MATLAB 7.4 or later)
-MEX = mex -O -largeArrayDims -lmwlapack
+# For compiling MATLAB mexFunctions (MATLAB 7.5)
+MEX = mex -O -largeArrayDims -lmwlapack -lmwblas
 
-# For compiling MATLAB mexFunctions (MATLAB 7.3, but the 7.4 might work OK)
-# MEX = mex -O -largeArrayDims
+# For compiling MATLAB mexFunctions (MATLAB 7.3 and 7.4)
+# MEX = mex -O -largeArrayDims -lmwlapack
 
 # For MATLAB 7.2 or earlier, you must use one of these options:
 # MEX = mex -O -lmwlapack
@@ -184,7 +184,7 @@ CHOLMOD_CONFIG =
 
 # Using default compilers:
 # CC = gcc
-# CFLAGS = -O3
+CFLAGS = -O3
 
 # alternatives:
 # CFLAGS = -g -fexceptions \
@@ -193,7 +193,7 @@ CHOLMOD_CONFIG =
 # CFLAGS = -O3 -fexceptions \
    	-Wall -W -Werror -Wshadow -Wmissing-prototypes -Wstrict-prototypes \
     	-Wredundant-decls -Wnested-externs -Wdisabled-optimization -ansi
-CFLAGS = -O3 -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+# CFLAGS = -O3 -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
 # CFLAGS = -O3
 
 # consider:
@@ -218,11 +218,11 @@ CFLAGS = -O3 -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
 # LAPACK = -llapack64
 
 
-# SUSE Linux 10.1, AMD Opteron
+# SUSE Linux 10.1, AMD Opteron, with GOTO Blas
 # F77 = gfortran
 # BLAS = -lgoto_opteron64 -lgfortran
 
-# SUSE Linux 10.1, Intel Pentium
+# SUSE Linux 10.1, Intel Pentium, with GOTO Blas
 # F77 = gfortran
 # BLAS = -lgoto -lgfortran
 
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/ChangeLog b/src/C/SuiteSparse/UMFPACK/Doc/ChangeLog
index c2e258b..82f50aa 100644
--- a/src/C/SuiteSparse/UMFPACK/Doc/ChangeLog
+++ b/src/C/SuiteSparse/UMFPACK/Doc/ChangeLog
@@ -1,3 +1,14 @@
+Nov 1, 2007, version 5.2.0
+
+    * change of license to GNU GPL from GNU LGPL.  This is the primary change to
+	this version.
+
+    * minor lint cleanup
+
+    * port to MATLAB 7.5 (added -lmwblas to mex command)
+
+    * added info output to the umfpack_btf command.
+
 May 31, 2007, version 5.1.0
 
     * port to 64-bit MATLAB
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/License b/src/C/SuiteSparse/UMFPACK/Doc/License
index 3ee02fd..19f2fa9 100644
--- a/src/C/SuiteSparse/UMFPACK/Doc/License
+++ b/src/C/SuiteSparse/UMFPACK/Doc/License
@@ -1,4 +1,4 @@
-UMFPACK Version 5.0, Copyright 1995-2006 by Timothy A. Davis.
+UMFPACK Version 5.1.1, Copyright 1995-2007 by Timothy A. Davis.
 All Rights Reserved.
 UMFPACK is available under alternate licenses, contact T. Davis for details.
 
@@ -8,22 +8,22 @@ UMFPACK License:
     UMFPACK implies that you agree to this License.
 
     This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
+    modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
+    version 2 of the License, or (at your option) any later version.
 
     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
+    General Public License for more details.
 
-    You should have received a copy of the GNU Lesser General Public
+    You should have received a copy of the GNU General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
     USA
 
     Permission is hereby granted to use or copy this program under the
-    terms of the GNU LGPL, provided that the Copyright, this License,
+    terms of the GNU GPL, provided that the Copyright, this License,
     and the Availability of the original version is retained on all copies.
     User documentation of any code that uses this code or any modified
     version of this code must cite the Copyright, this License, the
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/QuickStart.tex b/src/C/SuiteSparse/UMFPACK/Doc/QuickStart.tex
index 61846a2..e210577 100644
--- a/src/C/SuiteSparse/UMFPACK/Doc/QuickStart.tex
+++ b/src/C/SuiteSparse/UMFPACK/Doc/QuickStart.tex
@@ -18,8 +18,8 @@
 \author{Timothy A. Davis \\
 Dept. of Computer and Information Science and Engineering \\
 Univ. of Florida, Gainesville, FL}
-\title{UMFPACK Version 5.1 Quick Start Guide}
-\date{May 31, 2007}
+\title{UMFPACK Version 5.2 Quick Start Guide}
+\date{Nov 1, 2007}
 \maketitle
 
 %-------------------------------------------------------------------------------
@@ -35,7 +35,7 @@ Univ. of Florida, Gainesville, FL}
 \end{abstract}
 %-------------------------------------------------------------------------------
 
-UMFPACK Version 5.1, Copyright\copyright 1995-2006 by Timothy A. Davis.
+UMFPACK Version 5.2, Copyright\copyright 1995-2006 by Timothy A. Davis.
 All Rights Reserved.  Refer to the UMFPACK User Guide
 for the License. See \newline
 http://www.cise.ufl.edu/research/sparse/umfpack
@@ -234,8 +234,8 @@ for more details.
 \label{Install}
 %-------------------------------------------------------------------------------
 
-You will need to install both UMFPACK v5.1 and AMD v2.2 to use UMFPACK.
-Note that UMFPACK v5.1 cannot use AMD v1.2 or earlier.
+You will need to install both UMFPACK v5.2 and AMD v2.2 to use UMFPACK.
+Note that UMFPACK v5.2 cannot use AMD v1.2 or earlier.
 The {\tt UMFPACK} and {\tt AMD} subdirectories must be placed side-by-side
 within the same parent directory.  AMD is a stand-alone package that
 is required by UMFPACK.  UMFPACK can be compiled without the
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/UserGuide.stex b/src/C/SuiteSparse/UMFPACK/Doc/UserGuide.stex
index 8cf79f1..271419c 100644
--- a/src/C/SuiteSparse/UMFPACK/Doc/UserGuide.stex
+++ b/src/C/SuiteSparse/UMFPACK/Doc/UserGuide.stex
@@ -20,8 +20,8 @@
 \author{Timothy A. Davis \\
 Dept. of Computer and Information Science and Engineering \\
 Univ. of Florida, Gainesville, FL}
-\title{UMFPACK Version 5.1 User Guide}
-\date{May 31, 2007}
+\title{UMFPACK Version 5.2.0 User Guide}
+\date{Nov 1, 2007}
 \maketitle
 
 %-------------------------------------------------------------------------------
@@ -38,7 +38,7 @@ Univ. of Florida, Gainesville, FL}
 
 Technical Report TR-04-003 (revised)
 
-UMFPACK Version 5.1, Copyright\copyright 1995-2006 by Timothy A. Davis.
+UMFPACK Version 5.2.0, Copyright\copyright 1995-2006 by Timothy A. Davis.
 All Rights Reserved.
 UMFPACK is available under alternate licences; contact T. Davis for details.
 
@@ -47,22 +47,22 @@ UMFPACK is available under alternate licences; contact T. Davis for details.
     UMFPACK implies that you agree to this License.
 
     This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
+    modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
+    version 2 of the License, or (at your option) any later version.
 
     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
+    General Public License for more details.
 
-    You should have received a copy of the GNU Lesser General Public
+    You should have received a copy of the GNU General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
     USA
 
     Permission is hereby granted to use or copy this program under the
-    terms of the GNU LGPL, provided that the Copyright, this License,
+    terms of the GNU GPL, provided that the Copyright, this License,
     and the Availability of the original version is retained on all copies.
     User documentation of any code that uses this code or any modified
     version of this code must cite the Copyright, this License, the
@@ -95,7 +95,7 @@ UMFPACK is available under alternate licences; contact T. Davis for details.
 %-------------------------------------------------------------------------------
 
 UMFPACK\footnote{Pronounced with two syllables: umph-pack}
-Version 5.0 is a set of routines for solving systems of linear
+is a set of routines for solving systems of linear
 equations, $\m{Ax}=\m{b}$, when $\m{A}$ is sparse and unsymmetric.  It is based
 on the Unsymmetric-pattern MultiFrontal method \cite{DavisDuff97,DavisDuff99}.
 UMFPACK factorizes
@@ -275,7 +275,7 @@ Version 4.0 (in MATLAB 6.5)
 does not have the symmetric or 2-by-2 strategies and it takes
 less advantage of the level-3
 BLAS \cite{DaydeDuff99,ACM679a,ATLAS,GotoVandeGeijn02}.
-Versions 5.0 through v4.1 tend to be much faster than Version 4.0,
+Versions 5.x through v4.1 tend to be much faster than Version 4.0,
 particularly on unsymmetric matrices with mostly symmetric
 nonzero pattern (such as finite element and circuit simulation matrices).
 Version 3.0 and following make
@@ -290,6 +290,9 @@ are available at http://www.cise.ufl.edu/research/sparse and as
 MA38 (functionally equivalent to Version 2.2.1) in the Harwell
 Subroutine Library.
 
+{\bf NOTE: you must use the correct version of AMD with UMFPACK; using
+an old version of AMD with a newer version of UMFPACK can fail.}
+
 %-------------------------------------------------------------------------------
 \section{Primary changes from prior versions}
 %-------------------------------------------------------------------------------
@@ -297,6 +300,12 @@ Subroutine Library.
 A detailed list of changes is in the {\tt ChangeLog} file.
 
 %-------------------------------------------------------------------------------
+\subsection{Version 5.2.0}
+%-------------------------------------------------------------------------------
+
+Change of license from GNU Lesser GPL to the GNU GPL.
+
+%-------------------------------------------------------------------------------
 \subsection{Version 5.1.0}
 %-------------------------------------------------------------------------------
 
@@ -628,11 +637,15 @@ Factorizing {\tt A'} (or {\tt A.'}) and using the transposed factors can
 sometimes be faster than factorizing {\tt A}.  It can also be preferable to
 factorize {\tt A'} if {\tt A} is rectangular.  UMFPACK pre-orders the columns
 to maintain sparsity; the row ordering is not determined until the matrix
-is factorized.  Thus, if {\tt A} is {\tt m} by {\tt n} with rank {\tt m}
+is factorized.  Thus, if {\tt A} is {\tt m} by {\tt n} with structural
+rank {\tt m}
 and {\tt m} $<$ {\tt n}, then {\tt umfpack} might not find a factor
-{\tt U} with a zero-free diagonal.  Unless the matrix ill-conditioned or
+{\tt U} with a structurally zero-free diagonal.
+Unless the matrix ill-conditioned or
 poorly scaled, factorizing {\tt A'} in this case will guarantee that both
-factors will have zero-free diagonals.  Here's how you can factorize {\tt A'}
+factors will have zero-free diagonals.  Note that there is no guarantee
+as to the size of the diagonal entries of {\tt U}; UMFPACK does not do a
+rank-revealing factorization.  Here's how you can factorize {\tt A'}
 and get the factors of {\tt A} instead:
 
 \begin{verbatim}
@@ -2036,7 +2049,7 @@ Unix, or in Windows with Cygwin\footnote{www.cygwin.com}.
 You can skip this section and go to next one if all you want to use is
 the UMFPACK and AMD mexFunctions in MATLAB.
 
-You will need to install both UMFPACK v5.0 and AMD v2.0 to use UMFPACK.
+You will need to install both UMFPACK and AMD to use UMFPACK.
 The {\tt UMFPACK} and {\tt AMD} subdirectories must be placed side-by-side
 within the same directory.  AMD is a stand-alone package that
 is required by UMFPACK.  UMFPACK can be compiled without the
@@ -2212,14 +2225,6 @@ to compile the stand-alone AMD mexFunction (this is not required to
 compile the UMFPACK mexFunction).  This works on any computer with MATLAB,
 including Windows.
 
-% You will be prompted to select several configuration options, including
-% whether or not to use the BLAS.
-% MATLAB 5.3 (or earlier) does not include the BLAS, so you either have to
-% compile UMFPACK without the BLAS (UMFPACK will be slow), or modify your
-% {\tt <matlab>/bin/mexopts.sh} by adding your BLAS library
-% to the {\tt CLIBS} string,
-% where {\tt <matlab>} is the directory in which MATLAB is installed.
-
 If you are using Windows and the {\tt lcc} compiler bundled with
 MATLAB 6.1, then you may need to copy the
 {\tt UMFPACK}$\backslash${\tt MATLAB}$\backslash${\tt lcc\_lib}$\backslash${\tt libmwlapack.lib}
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/gpl.txt b/src/C/SuiteSparse/UMFPACK/Doc/gpl.txt
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/src/C/SuiteSparse/UMFPACK/Doc/gpl.txt
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/src/C/SuiteSparse/UMFPACK/Doc/lesser.txt b/src/C/SuiteSparse/UMFPACK/Doc/lesser.txt
deleted file mode 100644
index 8add30a..0000000
--- a/src/C/SuiteSparse/UMFPACK/Doc/lesser.txt
+++ /dev/null
@@ -1,504 +0,0 @@
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-

-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-

-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-

-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-

-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-

-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-

-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-

-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-

-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-

-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/src/C/SuiteSparse/UMFPACK/Include/umfpack.h b/src/C/SuiteSparse/UMFPACK/Include/umfpack.h
index d0eb203..c720aba 100644
--- a/src/C/SuiteSparse/UMFPACK/Include/umfpack.h
+++ b/src/C/SuiteSparse/UMFPACK/Include/umfpack.h
@@ -97,7 +97,7 @@ extern "C" {
 /* Version, copyright, and license */
 /* -------------------------------------------------------------------------- */
 
-#define UMFPACK_VERSION "UMFPACK V5.1.0 (May 31, 2007)"
+#define UMFPACK_VERSION "UMFPACK V5.2.0 (Nov 1, 2007)"
 
 #define UMFPACK_COPYRIGHT \
 "UMFPACK:  Copyright (c) 2005-2006 by Timothy A. Davis.  All Rights Reserved.\n"
@@ -112,16 +112,16 @@ extern "C" {
 "   UMFPACK implies that you agree to this License.\n" \
 "\n" \
 "   This library is free software; you can redistribute it and/or\n" \
-"   modify it under the terms of the GNU Lesser General Public\n" \
+"   modify it under the terms of the GNU General Public\n" \
 "   License as published by the Free Software Foundation; either\n" \
-"   version 2.1 of the License, or (at your option) any later version.\n" \
+"   version 2 of the License, or (at your option) any later version.\n" \
 "\n" \
 "   This library is distributed in the hope that it will be useful,\n" \
 "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
 "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n" \
-"   Lesser General Public License for more details.\n" \
+"   General Public License for more details.\n" \
 "\n" \
-"   You should have received a copy of the GNU Lesser General Public\n" \
+"   You should have received a copy of the GNU General Public\n" \
 "   License along with this library; if not, write to the Free Software\n" \
 "   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301\n" \
 "   USA\n" \
@@ -129,7 +129,7 @@ extern "C" {
 #define UMFPACK_LICENSE_PART2 \
 "\n" \
 "   Permission is hereby granted to use or copy this program under the\n" \
-"   terms of the GNU LGPL, provided that the Copyright, this License,\n" \
+"   terms of the GNU GPL, provided that the Copyright, this License,\n" \
 "   and the Availability of the original version is retained on all copies.\n" \
 "   User documentation of any code that uses this code or any modified\n" \
 "   version of this code must cite the Copyright, this License, the\n" \
@@ -163,10 +163,10 @@ extern "C" {
  * above.
  */
 
-#define UMFPACK_DATE "May 31, 2007"
+#define UMFPACK_DATE "Nov 1, 2007"
 #define UMFPACK_VER_CODE(main,sub) ((main) * 1000 + (sub))
 #define UMFPACK_MAIN_VERSION 5
-#define UMFPACK_SUB_VERSION 1
+#define UMFPACK_SUB_VERSION 2
 #define UMFPACK_SUBSUB_VERSION 0
 #define UMFPACK_VER UMFPACK_VER_CODE(UMFPACK_MAIN_VERSION,UMFPACK_SUB_VERSION)
 
diff --git a/src/C/SuiteSparse/UMFPACK/Makefile b/src/C/SuiteSparse/UMFPACK/Makefile
index 80f2f73..a707234 100644
--- a/src/C/SuiteSparse/UMFPACK/Makefile
+++ b/src/C/SuiteSparse/UMFPACK/Makefile
@@ -72,3 +72,8 @@ ccode: library
 mex:
 	( cd ../AMD/MATLAB ; $(MAKE) )
 	( cd MATLAB ; $(MAKE) )
+
+# statement coverage (requires Linux; takes a lot of time and disk space)
+cov: purge
+	( cd Tcov ; ./DO.linux ; ./covall )
+
diff --git a/src/C/SuiteSparse/UMFPACK/README.txt b/src/C/SuiteSparse/UMFPACK/README.txt
index eec0f74..d4f9d7b 100644
--- a/src/C/SuiteSparse/UMFPACK/README.txt
+++ b/src/C/SuiteSparse/UMFPACK/README.txt
@@ -1,4 +1,4 @@
-UMFPACK Version 5.0.2:  a set of routines solving sparse linear systems via LU
+UMFPACK :  a set of routines solving sparse linear systems via LU
     factorization.  Requires three other packages:  the BLAS (dense matrix
     operations), AMD (sparse matrix minimum degree ordering), and UFconfig.
     Includes a C-callable and MATLAB interface, and a basic FORTRAN 77
@@ -42,22 +42,22 @@ UMFPACK License:
     UMFPACK implies that you agree to this License.
 
     This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
+    modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
+    version 2 of the License, or (at your option) any later version.
 
     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
+    General Public License for more details.
 
-    You should have received a copy of the GNU Lesser General Public
+    You should have received a copy of the GNU General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
     USA
 
     Permission is hereby granted to use or copy this program under the
-    terms of the GNU LGPL, provided that the Copyright, this License,
+    terms of the GNU GPL, provided that the Copyright, this License,
     and the Availability of the original version is retained on all copies.
     User documentation of any code that uses this code or any modified
     version of this code must cite the Copyright, this License, the
@@ -85,7 +85,7 @@ Availability:
 
 Refer to ../AMD/README for the License for AMD, which is a separate
 package for ordering sparse matrices that is required by UMFPACK.
-UMFPACK v4.5 cannot use AMD v1.1 or earlier.  UMFPACK 5.0
+UMFPACK v4.5 cannot use AMD v1.1 or earlier.  UMFPACK 5.x
 requires AMD v2.0 or later.
 
 --------------------------------------------------------------------------------
diff --git a/src/C/SuiteSparse/UMFPACK/Source/cholmod_blas.h b/src/C/SuiteSparse/UMFPACK/Source/cholmod_blas.h
index 709f2d0..7957968 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/cholmod_blas.h
+++ b/src/C/SuiteSparse/UMFPACK/Source/cholmod_blas.h
@@ -4,7 +4,7 @@
 
 /* -----------------------------------------------------------------------------
  * CHOLMOD/Include/cholmod_blas.h.
- * Copyright (C) Univ. of Florida.  Author: Timothy A. Davis
+ * Copyright (C) 2005-2006, Univ. of Florida.  Author: Timothy A. Davis
  * CHOLMOD/Include/cholmod_blas.h is licensed under Version 2.1 of the GNU
  * Lesser General Public License.  See lesser.txt for a text of the license.
  * CHOLMOD is also available under other licenses; contact authors for details.
@@ -430,7 +430,7 @@ void BLAS_DGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
     } \
 }
 
-void BLAS_ZGERU (BLAS_INT *m, BLAS_INT *n, double *alpha,
+void BLAS_ZGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
 	double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy,
 	double *A, BLAS_INT *lda) ;
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_2by2.c b/src/C/SuiteSparse/UMFPACK/Source/umf_2by2.c
index 42616dc..0e31011 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_2by2.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_2by2.c
@@ -58,6 +58,7 @@
  */
 
 #include "umf_internal.h"
+#include "umf_2by2.h"
 
 #ifndef NDEBUG
 #include "umf_is_permutation.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_analyze.c b/src/C/SuiteSparse/UMFPACK/Source/umf_analyze.c
index 7744635..62e65d6 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_analyze.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_analyze.c
@@ -27,6 +27,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_analyze.h"
 #include "umf_apply_order.h"
 #include "umf_fsize.h"
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_apply_order.c b/src/C/SuiteSparse/UMFPACK/Source/umf_apply_order.c
index 8e90d3a..6192af4 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_apply_order.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_apply_order.c
@@ -13,6 +13,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_apply_order.h"
 
 GLOBAL void UMF_apply_order
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_assemble.c b/src/C/SuiteSparse/UMFPACK/Source/umf_assemble.c
index 8618be4..04a3de3 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_assemble.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_assemble.c
@@ -13,6 +13,7 @@
  *  versions.*/
 
 #include "umf_internal.h"
+#include "umf_assemble.h"
 #include "umf_mem_free_tail_block.h"
 
 /* ========================================================================== */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_blas3_update.c b/src/C/SuiteSparse/UMFPACK/Source/umf_blas3_update.c
index 8ff3bc4..c4e9ee7 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_blas3_update.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_blas3_update.c
@@ -9,6 +9,7 @@
 /* -------------------------------------------------------------------------- */
 
 #include "umf_internal.h"
+#include "umf_blas3_update.h"
 
 GLOBAL void UMF_blas3_update
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_build_tuples.c b/src/C/SuiteSparse/UMFPACK/Source/umf_build_tuples.c
index 36feed6..c2ab324 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_build_tuples.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_build_tuples.c
@@ -18,6 +18,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_build_tuples.h"
 #include "umf_mem_alloc_tail_block.h"
 
 GLOBAL Int UMF_build_tuples
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_create_element.c b/src/C/SuiteSparse/UMFPACK/Source/umf_create_element.c
index 581ba62..bb487ec 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_create_element.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_create_element.c
@@ -15,6 +15,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_create_element.h"
 #include "umf_mem_alloc_element.h"
 #include "umf_mem_alloc_tail_block.h"
 #include "umf_mem_free_tail_block.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_extend_front.c b/src/C/SuiteSparse/UMFPACK/Source/umf_extend_front.c
index 08cdc38..317c0c6 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_extend_front.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_extend_front.c
@@ -11,6 +11,7 @@
 /* Called by kernel. */
 
 #include "umf_internal.h"
+#include "umf_extend_front.h"
 #include "umf_grow_front.h"
 
 /* ========================================================================== */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_free.c b/src/C/SuiteSparse/UMFPACK/Source/umf_free.c
index b5321f7..867ab22 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_free.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_free.c
@@ -15,6 +15,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_free.h"
 
 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
 #include "umf_malloc.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_fsize.c b/src/C/SuiteSparse/UMFPACK/Source/umf_fsize.c
index d464071..634b525 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_fsize.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_fsize.c
@@ -13,6 +13,7 @@
  * node prior to AMD_postorder. */
 
 #include "umf_internal.h"
+#include "umf_fsize.h"
 
 GLOBAL void UMF_fsize
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_garbage_collection.c b/src/C/SuiteSparse/UMFPACK/Source/umf_garbage_collection.c
index 73c40f1..716270b 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_garbage_collection.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_garbage_collection.c
@@ -46,6 +46,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_garbage_collection.h"
 
 GLOBAL void UMF_garbage_collection
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_get_memory.c b/src/C/SuiteSparse/UMFPACK/Source/umf_get_memory.c
index 01bc940..696955b 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_get_memory.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_get_memory.c
@@ -17,6 +17,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_get_memory.h"
 #include "umf_garbage_collection.h"
 #include "umf_tuple_lengths.h"
 #include "umf_build_tuples.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_grow_front.c b/src/C/SuiteSparse/UMFPACK/Source/umf_grow_front.c
index 566b2b7..611c3a1 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_grow_front.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_grow_front.c
@@ -11,6 +11,7 @@
 /* Current frontal matrix is too small.  Make it bigger. */
 
 #include "umf_internal.h"
+#include "umf_grow_front.h"
 #include "umf_mem_free_tail_block.h"
 #include "umf_mem_alloc_tail_block.h"
 #include "umf_get_memory.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_init_front.c b/src/C/SuiteSparse/UMFPACK/Source/umf_init_front.c
index c8344db..201f1f8 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_init_front.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_init_front.c
@@ -9,6 +9,7 @@
 /* -------------------------------------------------------------------------- */
 
 #include "umf_internal.h"
+#include "umf_init_front.h"
 #include "umf_grow_front.h"
 
 /* ========================================================================== */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_is_permutation.c b/src/C/SuiteSparse/UMFPACK/Source/umf_is_permutation.c
index 7120736..689c65e 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_is_permutation.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_is_permutation.c
@@ -12,6 +12,7 @@
 /* P [0..r-1] must be an r-permutation of 0..n-1 */
 
 #include "umf_internal.h"
+#include "umf_is_permutation.h"
 
 GLOBAL Int UMF_is_permutation
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel.c b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel.c
index 54e756f..6168829 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel.c
@@ -18,6 +18,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_kernel.h"
 #include "umf_kernel_init.h"
 #include "umf_init_front.h"
 #include "umf_start_front.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_init.c b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_init.c
index 7ec3ed6..ff1c69f 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_init.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_init.c
@@ -20,6 +20,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_kernel_init.h"
 #include "umf_tuple_lengths.h"
 #include "umf_build_tuples.h"
 #include "umf_mem_init_memoryspace.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_wrapup.c b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_wrapup.c
index 1609c2c..d9c3cd5 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_wrapup.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_kernel_wrapup.c
@@ -11,6 +11,7 @@
 /* The matrix is factorized.  Finish the LU data structure. */
 
 #include "umf_internal.h"
+#include "umf_kernel_wrapup.h"
 
 GLOBAL void UMF_kernel_wrapup
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_local_search.c b/src/C/SuiteSparse/UMFPACK/Source/umf_local_search.c
index d81491b..4e7cabe 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_local_search.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_local_search.c
@@ -18,6 +18,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_local_search.h"
 #include "umf_row_search.h"
 #include "umf_mem_free_tail_block.h"
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_lsolve.c b/src/C/SuiteSparse/UMFPACK/Source/umf_lsolve.c
index cf3bf9f..7e1943c 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_lsolve.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_lsolve.c
@@ -13,6 +13,7 @@
 /*  Returns the floating point operation count */
 
 #include "umf_internal.h"
+#include "umf_lsolve.h"
 
 GLOBAL double UMF_lsolve
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_ltsolve.c b/src/C/SuiteSparse/UMFPACK/Source/umf_ltsolve.c
index b259d27..1792dfa 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_ltsolve.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_ltsolve.c
@@ -13,6 +13,7 @@
 /*  Returns the floating point operation count */
 
 #include "umf_internal.h"
+#include "umf_ltsolve.h"
 
 GLOBAL double
 #ifdef CONJUGATE_SOLVE
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_malloc.c b/src/C/SuiteSparse/UMFPACK/Source/umf_malloc.c
index 09ef770..d7ff561 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_malloc.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_malloc.c
@@ -16,6 +16,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_malloc.h"
 
 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_element.c b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_element.c
index cef3ba7..cac0db8 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_element.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_element.c
@@ -14,6 +14,7 @@
 /* Returns the index into Numeric->Memory if successful, or 0 on failure. */
 
 #include "umf_internal.h"
+#include "umf_mem_alloc_element.h"
 #include "umf_mem_alloc_tail_block.h"
 
 GLOBAL Int UMF_mem_alloc_element
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_head_block.c b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_head_block.c
index 2600182..6d7355c 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_head_block.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_head_block.c
@@ -14,6 +14,7 @@
 /* Returns the index into Numeric->Memory if successful, or 0 on failure. */
 
 #include "umf_internal.h"
+#include "umf_mem_alloc_head_block.h"
 
 GLOBAL Int UMF_mem_alloc_head_block
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_tail_block.c b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_tail_block.c
index 8499644..a16698a 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_tail_block.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_alloc_tail_block.c
@@ -11,6 +11,7 @@
 /* The UMF_mem_* routines manage the Numeric->Memory memory space. */
 
 #include "umf_internal.h"
+#include "umf_mem_alloc_tail_block.h"
 
 /* allocate nunits from tail of Numeric->Memory */
 /* (requires nunits+1, for header). */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_free_tail_block.c b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_free_tail_block.c
index 05a6313..9bec421 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_free_tail_block.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_free_tail_block.c
@@ -13,6 +13,7 @@
 /* free a block from the tail of Numeric->memory */
 
 #include "umf_internal.h"
+#include "umf_mem_free_tail_block.h"
 
 GLOBAL void UMF_mem_free_tail_block
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_init_memoryspace.c b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_init_memoryspace.c
index 8981dd2..0e05f5c 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_mem_init_memoryspace.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_mem_init_memoryspace.c
@@ -11,6 +11,7 @@
 /* The UMF_mem_* routines manage the Numeric->Memory memory space. */
 
 #include "umf_internal.h"
+#include "umf_mem_init_memoryspace.h"
 
 /* initialize the LU and element workspace (Numeric->Memory) */
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_realloc.c b/src/C/SuiteSparse/UMFPACK/Source/umf_realloc.c
index ee0f70d..feae25a 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_realloc.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_realloc.c
@@ -15,6 +15,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_realloc.h"
 
 #if defined (UMF_MALLOC_COUNT) || !defined (NDEBUG)
 #include "umf_malloc.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_report_perm.c b/src/C/SuiteSparse/UMFPACK/Source/umf_report_perm.c
index c97052c..aa5260d 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_report_perm.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_report_perm.c
@@ -9,6 +9,7 @@
 /* -------------------------------------------------------------------------- */
 
 #include "umf_internal.h"
+#include "umf_report_perm.h"
 
 #define PRINTF4U(params) { if (user || prl >= 4) PRINTF (params) ; }
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_report_vector.c b/src/C/SuiteSparse/UMFPACK/Source/umf_report_vector.c
index 4b602d1..5533683 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_report_vector.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_report_vector.c
@@ -9,6 +9,7 @@
 /* -------------------------------------------------------------------------- */
 
 #include "umf_internal.h"
+#include "umf_report_vector.h"
 
 /* ========================================================================== */
 /* === print_value ========================================================== */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_scale.c b/src/C/SuiteSparse/UMFPACK/Source/umf_scale.c
index 98fb3ba..04f09df 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_scale.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_scale.c
@@ -11,6 +11,7 @@
 /* Divide a vector of stride 1 by the pivot value. */
 
 #include "umf_internal.h"
+#include "umf_scale.h"
 
 GLOBAL void UMF_scale
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_scale_column.c b/src/C/SuiteSparse/UMFPACK/Source/umf_scale_column.c
index 782b716..9fd3796 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_scale_column.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_scale_column.c
@@ -14,6 +14,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_scale_column.h"
 #include "umf_mem_free_tail_block.h"
 #include "umf_scale.h"
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_set_stats.c b/src/C/SuiteSparse/UMFPACK/Source/umf_set_stats.c
index 8dfe2ca..fb1f232 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_set_stats.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_set_stats.c
@@ -17,6 +17,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_set_stats.h"
 #include "umf_symbolic_usage.h"
 
 GLOBAL void UMF_set_stats
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_singletons.c b/src/C/SuiteSparse/UMFPACK/Source/umf_singletons.c
index 9d1617d..8288220 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_singletons.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_singletons.c
@@ -38,6 +38,7 @@
  */
 
 #include "umf_internal.h"
+#include "umf_singletons.h"
 
 #ifndef NDEBUG
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_solve.c b/src/C/SuiteSparse/UMFPACK/Source/umf_solve.c
index fc78586..42bf879 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_solve.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_solve.c
@@ -27,6 +27,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_solve.h"
 #include "umf_lsolve.h"
 #include "umf_usolve.h"
 #include "umf_ltsolve.h"
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_start_front.c b/src/C/SuiteSparse/UMFPACK/Source/umf_start_front.c
index aa581d4..47aa354 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_start_front.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_start_front.c
@@ -13,6 +13,7 @@
  * reallocated.  The size computed here is just an estimate. */
 
 #include "umf_internal.h"
+#include "umf_start_front.h"
 #include "umf_grow_front.h"
 
 GLOBAL Int UMF_start_front    /* returns TRUE if successful, FALSE otherwise */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_store_lu.c b/src/C/SuiteSparse/UMFPACK/Source/umf_store_lu.c
index 0d0ea09..97e1081 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_store_lu.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_store_lu.c
@@ -14,6 +14,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_store_lu.h"
 #include "umf_mem_alloc_head_block.h"
 #include "umf_get_memory.h"
 
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_symbolic_usage.c b/src/C/SuiteSparse/UMFPACK/Source/umf_symbolic_usage.c
index 8c417cd..31abdf9 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_symbolic_usage.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_symbolic_usage.c
@@ -11,6 +11,7 @@
 /* Returns the final size of the Symbolic object, in Units */
 
 #include "umf_internal.h"
+#include "umf_symbolic_usage.h"
 
 GLOBAL double UMF_symbolic_usage
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_transpose.c b/src/C/SuiteSparse/UMFPACK/Source/umf_transpose.c
index 061c97b..6ac7435 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_transpose.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_transpose.c
@@ -19,6 +19,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_transpose.h"
 #include "umf_is_permutation.h"
 
 GLOBAL Int UMF_transpose
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_triplet.c b/src/C/SuiteSparse/UMFPACK/Source/umf_triplet.c
index b1f0b30..aaca50c 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_triplet.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_triplet.c
@@ -19,6 +19,7 @@
 */
 
 #include "umf_internal.h"
+#include "umf_triplet.h"
 
 #ifdef DO_MAP
 #ifdef DO_VALUES
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_tuple_lengths.c b/src/C/SuiteSparse/UMFPACK/Source/umf_tuple_lengths.c
index c0680de..8dd349e 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_tuple_lengths.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_tuple_lengths.c
@@ -15,6 +15,7 @@
 /* overwritten) */
 
 #include "umf_internal.h"
+#include "umf_tuple_lengths.h"
 
 GLOBAL Int UMF_tuple_lengths	    /* return memory usage */
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_usolve.c b/src/C/SuiteSparse/UMFPACK/Source/umf_usolve.c
index ca2e4ad..f5a127d 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_usolve.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_usolve.c
@@ -13,6 +13,7 @@
 /*  Returns the floating point operation count */
 
 #include "umf_internal.h"
+#include "umf_usolve.h"
 
 GLOBAL double UMF_usolve
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_utsolve.c b/src/C/SuiteSparse/UMFPACK/Source/umf_utsolve.c
index ba78364..3d557b6 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_utsolve.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_utsolve.c
@@ -13,6 +13,7 @@
 /*  Returns the floating point operation count */
 
 #include "umf_internal.h"
+#include "umf_utsolve.h"
 
 GLOBAL double
 #ifdef CONJUGATE_SOLVE
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_valid_numeric.c b/src/C/SuiteSparse/UMFPACK/Source/umf_valid_numeric.c
index ea3bb07..76855e3 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_valid_numeric.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_valid_numeric.c
@@ -12,6 +12,7 @@
 /* Does not check everything.  UMFPACK_report_numeric checks more. */
 
 #include "umf_internal.h"
+#include "umf_valid_numeric.h"
 
 GLOBAL Int UMF_valid_numeric
 (
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umf_valid_symbolic.c b/src/C/SuiteSparse/UMFPACK/Source/umf_valid_symbolic.c
index 2f65a0c..dd81851 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umf_valid_symbolic.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umf_valid_symbolic.c
@@ -9,6 +9,7 @@
 /* -------------------------------------------------------------------------- */
 
 #include "umf_internal.h"
+#include "umf_valid_symbolic.h"
 
 /* Returns TRUE if the Symbolic object is valid, FALSE otherwise. */
 /* The UMFPACK_report_symbolic routine does a more thorough check. */
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_numeric.c b/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_numeric.c
index ddd6447..a234902 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_numeric.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_numeric.c
@@ -27,7 +27,7 @@
 	fclose (f) ; \
 	return (UMFPACK_ERROR_out_of_memory) ; \
     } \
-    if (fread (object, sizeof (type), n, f) != n) \
+    if (fread (object, sizeof (type), n, f) != (size_t) n) \
     { \
 	UMFPACK_free_numeric ((void **) &Numeric) ; \
 	fclose (f) ; \
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_symbolic.c b/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_symbolic.c
index ac3076d..10db361 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_symbolic.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umfpack_load_symbolic.c
@@ -27,7 +27,7 @@
 	fclose (f) ; \
 	return (UMFPACK_ERROR_out_of_memory) ; \
     } \
-    if (fread (object, sizeof (type), n, f) != n) \
+    if (fread (object, sizeof (type), n, f) != (size_t) n) \
     { \
 	UMFPACK_free_symbolic ((void **) &Symbolic) ; \
 	fclose (f) ; \
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_numeric.c b/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_numeric.c
index dc2ae32..0e4d8a2 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_numeric.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_numeric.c
@@ -19,7 +19,7 @@
 #define WRITE(object,type,n) \
 { \
     ASSERT (object != (type *) NULL) ; \
-    if (fwrite (object, sizeof (type), n, f) != n) \
+    if (fwrite (object, sizeof (type), n, f) != (size_t) n) \
     { \
 	fclose (f) ; \
 	return (UMFPACK_ERROR_file_IO) ; \
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_symbolic.c b/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_symbolic.c
index 7469e04..ae00189 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_symbolic.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umfpack_save_symbolic.c
@@ -19,7 +19,7 @@
 #define WRITE(object,type,n) \
 { \
     ASSERT (object != (type *) NULL) ; \
-    if (fwrite (object, sizeof (type), n, f) != n) \
+    if (fwrite (object, sizeof (type), n, f) != (size_t) n) \
     { \
 	fclose (f) ; \
 	return (UMFPACK_ERROR_file_IO) ; \
diff --git a/src/C/SuiteSparse/UMFPACK/Source/umfpack_timer.c b/src/C/SuiteSparse/UMFPACK/Source/umfpack_timer.c
index f4f245c..8e46687 100644
--- a/src/C/SuiteSparse/UMFPACK/Source/umfpack_timer.c
+++ b/src/C/SuiteSparse/UMFPACK/Source/umfpack_timer.c
@@ -15,6 +15,8 @@
     See umfpack_tictoc.h, which is the timer used internally by UMFPACK.
 */
 
+#include "umfpack_timer.h"
+
 #ifdef NO_TIMER
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/C/amd.c b/src/C/amd.c
index 848c56f..884290b 100644
--- a/src/C/amd.c
+++ b/src/C/amd.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/base.c b/src/C/base.c
index d03e6d2..02c5e2f 100644
--- a/src/C/base.c
+++ b/src/C/base.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,13 +27,13 @@
 
 PyDoc_STRVAR(base__doc__,"Convex optimization package");
 
-PyTypeObject matrix_tp ;
+extern PyTypeObject matrix_tp ;
 matrix * Matrix_New(int, int, int) ;
 matrix * Matrix_NewFromMatrix(matrix *, int) ;
 matrix * Matrix_NewFromSequence(PyObject *, int) ; 
 matrix * Matrix_NewFromArrayStruct(PyObject *, int, int *) ;
 
-PyTypeObject spmatrix_tp ;
+extern PyTypeObject spmatrix_tp ;
 spmatrix * SpMatrix_New(int_t, int_t, int, int ) ;
 spmatrix * SpMatrix_NewFromMatrix(matrix *, int) ;
 spmatrix * SpMatrix_NewFromSpMatrix(spmatrix *, int, int) ; 
@@ -841,12 +841,7 @@ sparse(PyTypeObject *type, PyObject *args, PyObject *kwds)
     }
     
     for (jk=0; jk<SP_NCOLS(Objx); jk++) 
-      SP_COL(ret)[jk+1] += SP_COL(ret)[jk];
-    
-    /*
-    ret = SpMatrix_NewFromSpMatrix((spmatrix *)Objx, 0, 
-	(id == -1 ? SP_ID(Objx) : id));
-    */
+      SP_COL(ret)[jk+1] += SP_COL(ret)[jk];    
   }
 
   /* x is a list of lists */
@@ -858,6 +853,129 @@ sparse(PyTypeObject *type, PyObject *args, PyObject *kwds)
   return (PyObject *)ret;
 }
 
+static char doc_spdiag[] =
+    "Constructs a square block diagonal sparse matrix.\n\n"
+    "spdiag(diag)\n\n"
+    "ARGUMENTS\n"
+    "diag      a matrix with a single row or column,  or a list of matrices\n"
+    "          and scalars.";
+
+static PyObject *
+spdiag(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+  PyObject *diag = NULL, *Dk;
+  static char *kwlist[] = { "diag", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &diag))
+    return NULL;
+  
+  if ((!PyList_Check(diag) && !Matrix_Check(diag)) ||
+      (Matrix_Check(diag) && 
+	  (MAT_LGT(diag) != MAX(MAT_NROWS(diag),MAT_NCOLS(diag)))))
+    PY_ERR_TYPE("invalid diag argument");
+  
+  if (Matrix_Check(diag)) {
+    int j, id = MAX(DOUBLE, MAT_ID(diag)), n = MAT_LGT(diag);
+
+    spmatrix *ret = SpMatrix_New(n, n, n, id);
+    if (!ret) return PyErr_NoMemory();
+    SP_COL(ret)[0] = 0;
+    
+    for (j=0; j<n; j++) {
+      SP_COL(ret)[j+1] = j+1;
+      SP_ROW(ret)[j] = j;
+
+      if (MAT_ID(diag) == INT)	
+	SP_VALD(ret)[j] = MAT_BUFI(diag)[j];
+      else if (MAT_ID(diag) == DOUBLE)
+	SP_VALD(ret)[j] = MAT_BUFD(diag)[j];
+      else
+	SP_VALZ(ret)[j] = MAT_BUFZ(diag)[j];
+    }
+    return (PyObject *)ret;
+  }
+
+  int j, k, l, idx, id=DOUBLE, n=0, nnz=0;
+
+  for (k=0; k<PyList_GET_SIZE(diag); k++) {
+    Dk = PyList_GET_ITEM(diag, k);
+    if (!Matrix_Check(Dk) && !SpMatrix_Check(Dk) && !PyNumber_Check(Dk))
+      PY_ERR_TYPE("invalid element in diag");
+    
+    if (PyNumber_Check(Dk)) {
+      int scalarid = (PyComplex_Check(Dk) ? COMPLEX :
+	  (PyFloat_Check(Dk) ? DOUBLE : INT));
+      id = MAX(id, scalarid);
+      nnz += 1;
+      n += 1;
+    } else {
+      if (X_NROWS(Dk) != X_NCOLS(Dk))
+	PY_ERR_TYPE("the elements in diag must be square");
+
+      n   += X_NCOLS(Dk);
+      nnz += (Matrix_Check(Dk) ? X_NROWS(Dk)*X_NROWS(Dk) : SP_NNZ(Dk));
+      id   = MAX(id, X_ID(Dk));
+    }
+  }
+
+  spmatrix *ret = SpMatrix_New(n, n, nnz, id);
+  if (!ret) return PyErr_NoMemory();
+  SP_COL(ret)[0] = 0;
+
+  n = 0, idx = 0;
+  for (k=0; k<PyList_GET_SIZE(diag); k++) {
+    Dk = PyList_GET_ITEM(diag, k);
+  
+    if (PyNumber_Check(Dk)) {
+      SP_COL(ret)[n+1] = SP_COL(ret)[n] + 1;
+      SP_ROW(ret)[idx] = n;
+
+      number val;
+      convert_num[id](&val, Dk, 1, 0);
+      write_num[id](SP_VAL(ret), idx, &val, 0);
+      idx += 1;
+      n   += 1;
+    }
+    else {
+      for (j=0; j<X_NCOLS(Dk); j++) {
+
+	if (Matrix_Check(Dk)) {
+	  
+	  SP_COL(ret)[j+n+1] = SP_COL(ret)[j+n] + X_NROWS(Dk);
+	  for (l=0; l<X_NROWS(Dk); l++) {
+	    SP_ROW(ret)[idx] = n + l;
+	    if (id == DOUBLE) 
+	      SP_VALD(ret)[idx] = (MAT_ID(Dk) == DOUBLE ? 
+		  MAT_BUFD(Dk)[l + j*MAT_NROWS(Dk)] :
+		  MAT_BUFI(Dk)[l + j*MAT_NROWS(Dk)]);
+	    else
+	      SP_VALZ(ret)[idx] = (MAT_ID(Dk) == COMPLEX ?
+		  MAT_BUFZ(Dk)[l + j*MAT_NROWS(Dk)] :
+		  (MAT_ID(Dk) == DOUBLE ? MAT_BUFD(Dk)[l + j*MAT_NROWS(Dk)] :
+		      MAT_BUFI(Dk)[l + j*MAT_NROWS(Dk)]));
+	    
+	    idx++;
+	  }      
+	} else {
+	  
+	  SP_COL(ret)[j+n+1] = SP_COL(ret)[j+n] + SP_COL(Dk)[j+1]-SP_COL(Dk)[j];
+	  for (l=SP_COL(Dk)[j]; l<SP_COL(Dk)[j+1]; l++) {
+	    SP_ROW(ret)[idx] = n + SP_ROW(Dk)[l];
+	    if (id == DOUBLE) 
+	      SP_VALD(ret)[idx] = SP_VALD(Dk)[l];
+	    else
+	      SP_VALZ(ret)[idx] = (SP_ID(Dk) == COMPLEX ?
+		  SP_VALZ(Dk)[l] : SP_VALD(Dk)[l]);	  
+	    idx++;
+	  }
+	}
+      }
+      n += X_NCOLS(Dk);    
+    }
+  }
+  return (PyObject *)ret;
+}
+
 extern PyObject * matrix_exp(matrix *, PyObject *, PyObject *) ;
 extern PyObject * matrix_log(matrix *, PyObject *, PyObject *) ;
 extern PyObject * matrix_sqrt(matrix *, PyObject *, PyObject *) ;
@@ -888,6 +1006,7 @@ static PyMethodDef base_functions[] = {
    "elementwise division between two matrices"},
   {"sparse", (PyCFunction)sparse, METH_VARARGS|METH_KEYWORDS, 
    "convenience function for creating sparse matrices"},
+  {"spdiag", (PyCFunction)spdiag, METH_VARARGS|METH_KEYWORDS, doc_spdiag},
   {NULL}		/* sentinel */
 };
 
diff --git a/src/C/blas.c b/src/C/blas.c
index d4792c7..3e7af0c 100644
--- a/src/C/blas.c
+++ b/src/C/blas.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -984,7 +984,7 @@ static char doc_symv[] =
     "     offsety=0)\n\n"
     "PURPOSE\n"
     "Computes y := alpha*A*x + beta*y with A real symmetric of order n."
-    "n\n"
+    "\n\n"
     "ARGUMENTS\n"
     "A         'd' matrix\n\n"
     "x         'd' matrix\n\n"
@@ -3221,7 +3221,7 @@ static PyObject* trsm(PyObject *self, PyObject *args, PyObject *kwrds)
         "alpha", "m", "n", "ldA", "ldB", "offsetA", "offsetB", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ccccOiiiiii", 
-        kwlist, &A, &B, &side, &uplo, &transA, &ao, &diag, &m, &n, &ldA,
+        kwlist, &A, &B, &side, &uplo, &transA, &diag, &ao, &m, &n, &ldA,
         &ldB, &oA, &oB))
         return NULL;
 
diff --git a/src/C/cholmod.c b/src/C/cholmod.c
index eab380d..46e6dc1 100644
--- a/src/C/cholmod.c
+++ b/src/C/cholmod.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/cvxopt.h b/src/C/cvxopt.h
index ebed7ee..60c5d31 100644
--- a/src/C/cvxopt.h
+++ b/src/C/cvxopt.h
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,7 +58,6 @@ typedef struct {
   int_t *colptr;      /* column pointer list */
   int_t *rowind;      /* row index list */
   int_t nrows, ncols; /* number of rows and columns */
-  int   nzmax;        /* number of allocated elements */
   int   id;           /* DOUBLE, COMPLEX */
 } ccs;
 
@@ -126,7 +125,6 @@ import_cvxopt(void)
 #define SP_NROWS(O)  ((spmatrix *)O)->obj->nrows
 #define SP_LGT(O)    (SP_NROWS(O)*SP_NCOLS(O))
 #define SP_NNZ(O)    ((spmatrix *)O)->obj->colptr[SP_NCOLS(O)]
-#define SP_NZMAX(O)  ((spmatrix *)O)->obj->nzmax
 #define SP_ID(O)     ((spmatrix *)O)->obj->id    
 #define SP_COL(O)    ((spmatrix *)O)->obj->colptr
 #define SP_ROW(O)    ((spmatrix *)O)->obj->rowind
diff --git a/src/C/dense.c b/src/C/dense.c
index d4e12eb..b171b30 100644
--- a/src/C/dense.c
+++ b/src/C/dense.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@ typedef struct {
 static const char PY_ARRAY_TC[3] = { 'i', 'f', 'c' }; 
 
 /* prototyping and forward declarations */
-PyObject *base_mod;
+extern PyObject *base_mod;
 extern void (*axpy[])(int *, number *, void *, int *, void *, int *) ;
 extern void (*scal[])(int *, number *, void *, int *) ;
 extern void (*gemm[])(char *, char *, int *, int *, int *, void *, void *, 
@@ -61,7 +61,7 @@ extern const char PRINTOPT[][15];
 extern number One[3], MinusOne[3], Zero[3];
 
 
-PyTypeObject spmatrix_tp ;
+extern PyTypeObject spmatrix_tp ;
 /*
 spmatrix * SpMatrix_New(int_t, int_t, int, int ) ;
 spmatrix * SpMatrix_NewFromSpMatrix(spmatrix *, int, int) ; 
diff --git a/src/C/dsdp.c b/src/C/dsdp.c
index c0a9120..d55cb22 100644
--- a/src/C/dsdp.c
+++ b/src/C/dsdp.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/fftw.c b/src/C/fftw.c
index 4b0585a..bc40eaa 100644
--- a/src/C/fftw.c
+++ b/src/C/fftw.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/glpk.c b/src/C/glpk.c
index 3b2a470..ccc9d3b 100644
--- a/src/C/glpk.c
+++ b/src/C/glpk.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/lapack.c b/src/C/lapack.c
index 4bd3f10..7852ab1 100644
--- a/src/C/lapack.c
+++ b/src/C/lapack.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/misc.h b/src/C/misc.h
index 4072847..a70763f 100644
--- a/src/C/misc.h
+++ b/src/C/misc.h
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/C/mosek.c b/src/C/mosek.c
deleted file mode 100644
index b0882ec..0000000
--- a/src/C/mosek.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
- *
- * This file is part of CVXOPT version 0.9.
- *
- * CVXOPT is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * CVXOPT is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "cvxopt.h"
-#include "misc.h"
-#include "mosek.h"
-
-PyDoc_STRVAR(mosek__doc__,
-"Interface to the LP and QP solvers in MOSEK.\n\n" 
-"The MOSEK control parameters have the default values listed in \n"
-"the MOSEK documentation at\n"
-"  http://www.mosek.com/products/3/tools/doc/html/tools/node22.html.\n"
-"They can be modified by making an entry in the dictionary\n"
-"mosek.options.  For example, the command\n"
-"  mosek.options['MSK_IPAR_LOG']=0\n"
-"turns off the printed output during execution of mosek.solvelp().");
-
-static PyObject *mosek_module;
-
-static void MSKAPI printstr(void *handle, char str[])
-{
-  printf("%s",str);
-} /* printstr */
-
-static char doc_mosek_solvelp[] = 
-    "Solves a linear program using MOSEK.\n\n"
-    "(prosta, solsta, x, z, y) = solvelp(c, G, h, A, b)\n"
-    "(prosta, solsta, x, z) = solvelp(c, G, h)\n\n"
-    "PURPOSE\n"
-    "(prosta, solsta, x, z, y) = solvelp(c, G, h, A, b) solves the pair\n"
-    "of primal and dual LPs\n\n"
-    "    minimize    c'*x            maximize    -h'*z + b'*y\n"
-    "    subject to  G*x <= h        subject to  G'*z + A'*y + c = 0\n"
-    "                A*x = b                     z >= 0.\n\n"
-    "(prosta, solsta, x, z) = solvelp(c, G, h) solves the pair of\n"
-    "primal and dual LPs\n\n"
-    "    minimize    c'*x            maximize    -h'*z \n"
-    "    subject to  G*x <= h        subject to  G'*z + c = 0\n"
-    "                                            z >= 0.\n\n"
-    "ARGUMENTS\n"
-    "c         nx1 'd' matrix with n>=1\n\n" 
-    "G         mxn 'd' or nonsymmetric sparse matrix with m>=1\n\n"
-    "h         mx1 'd' matrix\n\n"
-    "A         pxn 'd' or nonsymmetric sparse matrix with p>=0\n\n"
-    "b         px1 'd' matrix\n\n"
-    "prosta    the problem status string returned by MOSEK\n\n"
-    "solsta    the solution status string returned by MOSEK\n\n"
-    "x         the primal solution\n\n"
-    "z,y       the dual solution.";
-
-static PyObject *
-mosek_solvelp(PyObject *self, PyObject *args, PyObject *kwrds)
-{
-    matrix *c, *h, *b=NULL, *x=NULL, *z=NULL, *yu=NULL, *yl=NULL;
-    PyObject *G, *A=NULL, *t=NULL;
-    int m, n, p, i, j, k, nnz=0, nnzmax;
-    char *kwlist[] = {"c", "G", "h", "A", "b", NULL};
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OO", kwlist, &c,
-        &G, &h, &A, &b)) return NULL;
-
-    if (!((Matrix_Check(G) && MAT_ID(G) == DOUBLE) || 
-	    (SpMatrix_Check(G) && SP_ID(G) == DOUBLE))) {
-      PY_ERR(PyExc_ValueError, "G must be a dense or sparse matrix"
-	  " with typecode 'd'");
-        return NULL;
-    }
-    if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) <= 0) 
-        err_p_int("m");
-    if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0) 
-        err_p_int("n");
-
-    if (!Matrix_Check(h) || h->id != DOUBLE) 
-        err_dbl_mtrx("h");
-    if (h->nrows != m || h->ncols != 1){
-        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
-        return NULL;
-    }
-
-    if (A){
-      if (!((Matrix_Check(A) && MAT_ID(A) == DOUBLE) || 
-	      (SpMatrix_Check(A) && SP_ID(A) == DOUBLE))) {
-	PyErr_SetString(PyExc_ValueError, "A must be a dense "
-                    "or sparse matrix with typecode 'd'");
-                return NULL;
-	}
-        if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0)
-            err_p_int("p");
-        if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){
-            PyErr_SetString(PyExc_ValueError, "incompatible "
-                "dimensions");
-            return NULL;
-	}
-    }
-    else p = 0;
-    if (b && (!Matrix_Check(b) || b->id != DOUBLE)) 
-        err_dbl_mtrx("b");
-    if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0 )){
-        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
-        return NULL;
-    }
-
-
-    /* Setting up MOSEK environment */
-    nnzmax = (SpMatrix_Check(G) ? SP_NNZ(G) : m*n ) + 
-        ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n);
-
-    int *bkc, *bkx, *ptrb, *ptre, *sub; 
-    bkc  = malloc((m+p)*sizeof(int));
-    bkx  = malloc(n*sizeof(int));
-    ptrb = malloc(n*sizeof(int));
-    ptre = malloc(n*sizeof(int));
-    sub  = malloc(nnzmax*sizeof(int));
-
-    double *blc, *buc, *blx, *bux, *val;
-    blc = malloc((m+p)*sizeof(double));
-    buc = malloc((m+p)*sizeof(double));
-    blx = malloc(n*sizeof(double));
-    bux = malloc(n*sizeof(double));
-    val = malloc(nnzmax*sizeof(double));
-
-    int r;
-    MSKenv_t  env;
-    MSKtask_t task;
-    
-    /* Make mosek environment. */
-    r = MSK_makeenv(&env,NULL,NULL,NULL,NULL); 
-    if (!bkc || !blc || !buc || !bkx || !blx || !buc ||
-	!ptrb || !ptre || !sub || !val || r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      return PyErr_NoMemory();
-    }
-
-    /* Directs the env log stream to the user
-       specified procedure 'printstr'. */
-    MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr);
-    
-    /* Initialize the environment. */   
-    r = MSK_initenv(env);
-    if (r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      return PyErr_NoMemory();
-    }
-
-    /* Make the optimization task. */
-    r = MSK_maketask(env, (m+p), n, &task);
-    if (r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      MSK_deleteenv(&env);
-      return PyErr_NoMemory();
-    }
-      
-    /* Directs the log task stream to the user
-       specified procedure 'printstr'. */    
-    MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
-        
-    /* Define bounds for the constraints
-       
-      -infty  <=  G*x  <=   h
-         b    <=  A*x  <=   b
-    */
-    
-    for (i=0; i<m; i++) {
-      bkc[i] =  MSK_BK_UP;  
-      blc[i] = -MSK_INFINITY;
-      buc[i] =  MAT_BUFD(h)[i];
-    }
-    
-    for (i=0; i<p; i++) {
-      bkc[m+i] = MSK_BK_FX;  
-      blc[m+i] = MAT_BUFD(b)[i];
-      buc[m+i] = MAT_BUFD(b)[i];
-    }
-
-    /* bounds on the variables (none) */
-    for (i=0; i<n; i++) {
-      bkx[i] =  MSK_BK_FR;		  
-      blx[i] = -MSK_INFINITY;
-      bux[i] =  MSK_INFINITY;
-    }
-    
-    /* constraint matrix */       
-    for (j=0; j<n; j++) {
-      
-      if (SpMatrix_Check(G)) {
-	for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++) {
-	  val[nnz]   = SP_VALD(G)[k];
-	  sub[nnz++] = SP_ROW(G)[k];
-	}
-      }
-      else {
-	for (k=0; k<m; k++) {
-	  if (MAT_BUFD(G)[j*m+k] != 0.0) {
-	    val[nnz]   = MAT_BUFD(G)[j*m+k];
-	    sub[nnz++] = k;
-	  }
-	}
-      }
-
-      if (A) {
-	if (SpMatrix_Check(A)) {
-	  for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++) {
-	    val[nnz]   = SP_VALD(A)[k];
-	    sub[nnz++] = m+SP_ROW(A)[k];
-	  }
-	}
-	else {
-	  for (k=0; k<p; k++) {
-	    if (MAT_BUFD(A)[j*p+k] != 0.0) {
-	      val[nnz]   = MAT_BUFD(A)[j*p+k];
-	      sub[nnz++] = m+k;
-	    }
-	  }
-	}	
-      }
-      
-      ptrb[j] = (j>0 ? ptre[j-1] : 0);
-      ptre[j] = nnz;
-    }
-    
-    r = MSK_inputdata(task,
-	(m+p),n,
-	(m+p),n,
-	MAT_BUFD(c),0.0,
-	ptrb, ptre,
-	sub, val,
-	bkc, blc, buc,
-	bkx, blx, bux);
-    
-    free(bkc); free(blc); free(buc); 
-    free(bkx); free(blx); free(bux); 
-    free(ptrb); free(ptre);
-    free(sub); free(val);
-    
-    MSK_putintparam(task,MSK_IPAR_OBJECTIVE_SENSE,MSK_OBJECTIVE_SENSE_MIN);
-    
-    PyObject *param;
-    if (!(param = PyObject_GetAttrString(mosek_module, "options")) ||
-	!PyDict_Check(param)) {
-      MSK_deletetask(&task);
-      MSK_deleteenv(&env);
-      PY_ERR(PyExc_AttributeError,err_msk_noparam);
-    }
-    
-    PyObject *key, *value;
-    int param_id;
-    int_compat pos = 0;    
-
-    while (PyDict_Next(param, &pos, &key, &value)) {
-      MSK_isintparname(task, PyString_AS_STRING(key), &param_id);
-      if (param_id < MSK_IPAR_SOLUTION_CALLBACK) {
-	if (!PyInt_Check(value)) 
-	{
-	  char err_str[100] = "invalid integer parameter: ";
-	  strncat(err_str, PyString_AS_STRING(key), 100);
-	  MSK_deletetask(&task);
-	  MSK_deleteenv(&env);
-	  Py_DECREF(param);
-	  PY_ERR(PyExc_ValueError,err_str);
-	}
-	  
-	MSK_putintparam(task, param_id, PyInt_AsLong(value)); 
-	continue;
-      } 
-      MSK_isdouparname(task, PyString_AS_STRING(key), &param_id);
-      if (param_id < MSK_DPAR_NONCONVEX_TOL_OPT) {
-	if (!PyInt_Check(value) && !PyFloat_Check(value)) 
-	{
-	  char err_str[100] = "invalid floating point parameter: ";
-	  strncat(err_str, PyString_AS_STRING(key), 100);
-	  MSK_deletetask(&task);
-	  MSK_deleteenv(&env);
-	  Py_DECREF(param);
-	  PY_ERR(PyExc_ValueError,err_str);
-	}
-
-	MSK_putdouparam(task, param_id, PyFloat_AsDouble(value)); 	
-	continue;
-      }      
-    }
-    Py_DECREF(param);
-
-    r = MSK_optimize(task);    
-    if (r==MSK_RES_OK) {
-
-      if (!(t = PyTuple_New(A ? 5 : 4))) {
-	MSK_deletetask(&task);
-	MSK_deleteenv(&env);
-	return PyErr_NoMemory();
-      }
-    
-      x = (matrix *) Matrix_New(n,1,DOUBLE);
-      z = (matrix *) Matrix_New(m,1,DOUBLE);
-      if (A) {
-	yu = (matrix *) Matrix_New(p,1,DOUBLE);
-	yl = (matrix *) Matrix_New(p,1,DOUBLE);
-      }
-      if (!x || !z || (A && (!yu || !yl))){
-	Py_XDECREF(x);
-	Py_XDECREF(z);
-	Py_XDECREF(yu);
-	Py_XDECREF(yl);
-	Py_XDECREF(t);
-	MSK_deletetask(&task);
-	MSK_deleteenv(&env);
-	return PyErr_NoMemory();
-      }
-      
-      char statstr[50];
-      int solsta, prosta;
-      double tmp;
-
-      MSK_getsolutioninf(task, 0, &prosta, &solsta, 
-	  &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp);
-      
-      MSK_prostatostr (task, prosta, statstr);
-      PyTuple_SET_ITEM(t, 0, PyString_FromString(statstr));
-
-      MSK_solstatostr (task, solsta, statstr);
-      PyTuple_SET_ITEM(t, 1, PyString_FromString(statstr));
-
-      MSK_getsolutionslice(task, 0, MSK_SOL_ITEM_XX, 0, n, MAT_BUFD(x));
-      PyTuple_SET_ITEM(t, 2, (PyObject *) x);
-	
-      MSK_getsolutionslice(task, 0, MSK_SOL_ITEM_SUC, 0, m, MAT_BUFD(z));
-      PyTuple_SET_ITEM(t, 3, (PyObject *) z);
-	
-      if (A) {	  
-	MSK_getsolutionslice(task,0,MSK_SOL_ITEM_SUC,m,m+p,MAT_BUFD(yu));
-	MSK_getsolutionslice(task,0,MSK_SOL_ITEM_SLC,m,m+p,MAT_BUFD(yl));
-
-	for (i=0; i<yu->nrows; i++) MAT_BUFD(yu)[i] -= MAT_BUFD(yl)[i];
-
-	Py_DECREF(yl);
-	PyTuple_SET_ITEM(t, 4, (PyObject *) yu);
-      }
-
-      MSK_deletetask(&task);
-      MSK_deleteenv(&env);     
-
-      return (PyObject *) t;
-    } 
-      
-    MSK_deletetask(&task);
-    MSK_deleteenv(&env);
-    t = PyString_FromString("internal mosek error");        
-    return (PyObject *) t;    
-}
-
-static char doc_mosek_solveqp[] = 
-    "Solves a convex quadratic program using MOSEK.\n\n"
-    "(prosta, solsta, x, z, y) = solveqp(P, q, G, h, A, b)\n"
-    "(prosta, solsta, x, z) = solveqp(P, q, G, h)\n\n"
-    "PURPOSE\n"
-    "(prosta, solsta, x, z, y) = solveqp(P, q, G, h, A, b) solves the QP\n\n"
-    "    minimize    (1/2)*x'*P*x + q'*x\n"
-    "    subject to  G*x <= h\n"
-    "                A*x = b\n\n"
-    "and its dual\n\n" 
-    "    maximize    (1/2)*(q+G'*z+A'*y)'*Pinv*(q+G'*z+A'*y) - h'*z - b'*y\n"
-    "    subject to  G*x <= h\n"
-    "                A*x = b\n"
-    "                z >= 0\n"
-    "                (I-P*Pinv)*(q+G'*z+A'*y) = 0\n\n"
-    "where Pinv is the Moore-Penrose pseudoinverse of P.\n\n"
-    "(prosta, solsta, x, z) = solveqp(P, q, G, h) solves the LP\n\n"
-    "    minimize    (1/2)*x'*P*q + q'*x\n"
-    "    subject to  G*x <= h\n\n"
-    "and its dual\n\n"
-    "    maximize    (1/2)*(q+G'*z)'*Pinv*(q+G'*z) - h'*z\n"
-    "    subject to  G*x <= h\n"
-    "                z >= 0\n"
-    "                (I-P*Pinv)*(q+G'*z) = 0\n\n"
-    "where Pinv is the Moore-Penrose pseudoinverse of P.\n\n"
-    "ARGUMENTS\n"
-    "P         nxn 'd' matrix with \n\n" 
-    "q         nx1 'd' matrix with n>=1\n\n" 
-    "G         mxn 'd' or nonsymmetric sparse matrix with m>=0\n\n"
-    "h         mx1 'd' matrix\n\n"
-    "A         pxn 'd' or nonsymmetric sparse matrix with p>=0\n\n"
-    "b         px1 'd' matrix\n\n"
-    "prosta    the problem status string returned by MOSEK\n\n"
-    "solsta    the solution status string returned by MOSEK\n\n"
-    "x         the primal solution\n\n"
-    "z,y       the dual solution.";
-
-static PyObject *
-mosek_solveqp(PyObject *self, PyObject *args, PyObject *kwrds)
-{
-    matrix *q, *h=NULL, *b=NULL, *x=NULL, *z=NULL, *yu=NULL, *yl=NULL;
-    PyObject *P, *G=NULL, *A=NULL, *t=NULL;
-    int m, n, p, i, j, k, nnz=0, nnzmax, numqonz;
-    char *kwlist[] = {"P", "q", "G", "h", "A", "b", NULL};
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OOOO", kwlist, 
-	    &P, &q, &G, &h, &A, &b)) return NULL;
-
-    if (!(Matrix_Check(P) && MAT_ID(P) == DOUBLE && 
-	    MAT_NCOLS(P) == MAT_NROWS(P)) &&
-        !(SpMatrix_Check(P) && SP_ID(P) == DOUBLE)) {
-      PyErr_SetString(PyExc_ValueError, "P must be a square symmetric"
-	  " sparse or dense matrix with typecode 'd'");
-      return NULL;
-    }
-    
-    if (G && ((Matrix_Check(G) && MAT_ID(G) != DOUBLE) || 
-	    (SpMatrix_Check(G) && SP_ID(G) != DOUBLE))) {
-      PyErr_SetString(PyExc_ValueError, "G must be a sparse or dense"
-	  " matrix with typecode 'd'");
-      return NULL;
-    }
-
-    if (!(SpMatrix_Check(P) && ((G && SpMatrix_Check(G)) || !G) && 
-	    ((A && SpMatrix_Check(A)) || !A)) &&
-	!(Matrix_Check(P) && ((G && Matrix_Check(G)) || !G) && 
-	    ((A && Matrix_Check(A)) || !A))) 
-      PY_ERR(PyExc_ValueError, "P, G and A must all be either sparse"
-	  " or dense matrices");      
-
-    int nP = (Matrix_Check(P) ? MAT_NROWS(P) : SP_NROWS(P));    
-    if (!Matrix_Check(q) || MAT_ID(q) != DOUBLE) 
-      PY_ERR(PyExc_ValueError, "q must be a 'd' matrix");
-
-    if (G) {
-      if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) < 0)
-        err_nn_int("m");
-      if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0)
-        err_p_int("n");
-
-      if (!h || !Matrix_Check(h) || h->id != DOUBLE) 
-        err_dbl_mtrx("h");
-      if (h->nrows != m || h->ncols != 1 || nP != n || 
-	  q->nrows != n || q->ncols != 1) {
-        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
-        return NULL;
-      }
-    } 
-    else {
-      m = 0; n = nP;
-    }
-      
-    if (A) {
-        if ((Matrix_Check(A) && MAT_ID(A) != DOUBLE) || 
-            (SpMatrix_Check(A) && SP_ID(A) != DOUBLE)) {
-                PyErr_SetString(PyExc_ValueError, "A must be a sparse "
-                    "or dense matrix with typecode 'd'");
-                return NULL;
-	}
-        if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0)
-            err_nn_int("p");
-        if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){
-            PyErr_SetString(PyExc_ValueError, "incompatible "
-                "dimensions");
-            return NULL;
-	}
-    }
-    else p = 0;
-    if (b && (!Matrix_Check(b) || b->id != DOUBLE)) 
-        err_dbl_mtrx("b");
-    if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0)) {
-        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
-        return NULL;
-    }
-
-    /* Setting up MOSEK environment */
-    numqonz = (SpMatrix_Check(P) ? SP_NNZ(P) : n*(n+1)/2);
-    nnzmax = ((G && SpMatrix_Check(G)) ? SP_NNZ(G) : m*n ) + 
-      ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n);
-
-    int *bkc, *bkx, *ptrb, *ptre, *sub, *qosubi, *qosubj; 
-    bkc    = malloc((m+p)*sizeof(int));
-    bkx    = malloc(n*sizeof(int));
-    ptrb   = malloc(n*sizeof(int));
-    ptre   = malloc(n*sizeof(int));
-    sub    = malloc(nnzmax*sizeof(int));
-    qosubi = malloc(numqonz*sizeof(int));
-    qosubj = malloc(numqonz*sizeof(int));
-
-    double *blc, *buc, *blx, *bux, *val, *qoval;
-    blc = malloc((m+p)*sizeof(double));
-    buc = malloc((m+p)*sizeof(double));
-    blx = malloc(n*sizeof(double));
-    bux = malloc(n*sizeof(double));
-    val = malloc(nnzmax*sizeof(double));
-    qoval = malloc(numqonz*sizeof(double));
-
-    int r;
-    MSKenv_t  env;
-    MSKtask_t task;
-
-    /* Make mosek environment. */
-    r = MSK_makeenv(&env,NULL,NULL,NULL,NULL); 
-    if (!bkc || !blc || !buc || !bkx || !blx || !buc ||
-	!ptrb || !ptre || !sub || !val || 
-	!qosubi || !qosubj || !qoval || r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      free(qosubi); free(qosubj); free(qoval);
-      return PyErr_NoMemory();
-    }
-
-    /* Directs the env log stream to the user
-       specified procedure 'printstr'. */
-    MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr);
-    
-    /* Initialize the environment. */   
-    r = MSK_initenv(env);
-    if (r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      free(qosubi); free(qosubj); free(qoval);
-      return PyErr_NoMemory();
-    }
-
-    /* Make the optimization task. */
-    r = MSK_maketask(env, (m+p), n, &task);
-    if (r!=MSK_RES_OK) {
-      free(bkc); free(bkx); free(ptrb); free(ptre); free(sub); 
-      free(blc); free(buc); free(blx); free(bux); free(val);
-      free(qosubi); free(qosubj); free(qoval);
-      MSK_deleteenv(&env);
-      return PyErr_NoMemory();
-    }
-    
-    /* Directs the log task stream to the user
-       specified procedure 'printstr'. */    
-    MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
-
-    /* Setup quadratic term of objective */
-    if (Matrix_Check(P)) {
-      for (j=0, k=0; j<n; j++) 
-	for (i=j; i<n; i++, k++) {
-	  qosubi[k] = i;
-	  qosubj[k] = j;
-	  qoval[k]  = MAT_BUFD(P)[j*n+i];
-	}
-    } else {
-      for (j=0, k=0; j<n; j++) {
-	for (i=SP_COL(P)[j]; i<SP_COL(P)[j+1]; i++, k++) {
-	  qosubi[k] = SP_ROW(P)[k];
-	  qosubj[k] = j;
-	  qoval[k]  = SP_VALD(P)[k];	  
-	}
-      }
-    }
-
-    /* Define bounds for the constraints
-       
-      -infty  <=  G*x  <=   h
-         b    <=  A*x  <=   b
-    */
-    
-    for (i=0; i<m; i++) {
-      bkc[i] =  MSK_BK_UP;  
-      blc[i] = -MSK_INFINITY;
-      buc[i] =  MAT_BUFD(h)[i];
-    }
-    
-    for (i=0; i<p; i++) {
-      bkc[m+i] = MSK_BK_FX;  
-      blc[m+i] = MAT_BUFD(b)[i];
-      buc[m+i] = MAT_BUFD(b)[i];
-    }
-
-    /* bounds on the variables (none) */
-    for (i=0; i<n; i++) {
-      bkx[i] =  MSK_BK_FR;		  
-      blx[i] = -MSK_INFINITY;
-      bux[i] =  MSK_INFINITY;
-    }
-    
-    /* constraint matrix */       
-    for (j=0; j<n; j++) {
-      
-      if (G && SpMatrix_Check(G)) {
-	for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++) {
-	  val[nnz]   = SP_VALD(G)[k];
-	  sub[nnz++] = SP_ROW(G)[k];
-	}
-      }
-      else {
-	for (k=0; k<m; k++) {
-	  if (MAT_BUFD(G)[j*m+k] != 0.0) {
-	    val[nnz]   = MAT_BUFD(G)[j*m+k];
-	    sub[nnz++] = k;
-	  }
-	}
-      }
-
-      if (A) {
-	if (SpMatrix_Check(A)) {
-	  for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++) {
-	    val[nnz]   = SP_VALD(A)[k];
-	    sub[nnz++] = m+SP_ROW(A)[k];
-	  }
-	}
-	else {
-	  for (k=0; k<p; k++) {
-	    if (MAT_BUFD(A)[j*p+k] != 0.0) {
-	      val[nnz]   = MAT_BUFD(A)[j*p+k];
-	      sub[nnz++] = m+k;
-	    }
-	  }
-	}	
-      }
-      
-      ptrb[j] = (j>0 ? ptre[j-1] : 0);
-      ptre[j] = nnz;
-    }
-    
-    r = MSK_inputdata(task,
-	(m+p),n,
-	(m+p),n,
-	MAT_BUFD(q),0.0,
-	ptrb, ptre,
-	sub, val,
-	bkc, blc, buc,
-	bkx, blx, bux);
-
-    r = MSK_putqobj (task, numqonz, qosubi, qosubj, qoval); 
-
-    free(bkc); free(blc); free(buc); 
-    free(bkx); free(blx); free(bux); 
-    free(ptrb); free(ptre);
-    free(sub); free(val);
-    free(qosubi); free(qosubj); free(qoval);
-
-    MSK_putintparam(task,MSK_IPAR_OBJECTIVE_SENSE,MSK_OBJECTIVE_SENSE_MIN);
-          
-    PyObject *param;
-    if (!(param = PyObject_GetAttrString(mosek_module, "options")) ||
-	!PyDict_Check(param)) {
-      MSK_deletetask(&task);
-      MSK_deleteenv(&env);
-      PY_ERR(PyExc_AttributeError,err_msk_noparam);
-    }
-    
-    PyObject *key, *value;
-    int param_id;
-    int_compat pos = 0;    
-
-    while (PyDict_Next(param, &pos, &key, &value)) {
-      MSK_isintparname(task, PyString_AS_STRING(key), &param_id);
-      if (param_id < MSK_IPAR_SOLUTION_CALLBACK) {
-	if (!PyInt_Check(value)) 
-	{
-	  char err_str[100] = "invalid integer parameter: ";
-	  strncat(err_str, PyString_AS_STRING(key), 100);
-	  MSK_deletetask(&task);
-	  MSK_deleteenv(&env);
-	  Py_DECREF(param);
-	  PY_ERR(PyExc_ValueError,err_str);
-	}
-	  
-	MSK_putintparam(task, param_id, PyInt_AsLong(value)); 
-	continue;
-      } 
-      MSK_isdouparname(task, PyString_AS_STRING(key), &param_id);
-      if (param_id < MSK_DPAR_NONCONVEX_TOL_OPT) {
-	if (!PyInt_Check(value) && !PyFloat_Check(value)) 
-	{
-	  char err_str[100] = "invalid floating point parameter: ";
-	  strncat(err_str, PyString_AS_STRING(key), 100);
-	  MSK_deletetask(&task);
-	  MSK_deleteenv(&env);
-	  Py_DECREF(param);
-	  PY_ERR(PyExc_ValueError,err_str);
-	}
-
-	MSK_putdouparam(task, param_id, PyFloat_AsDouble(value)); 	
-	continue;
-      }      
-    }
-    Py_DECREF(param);
-
-    r = MSK_optimize(task);    
-    if (r==MSK_RES_OK) {
-
-      if (!(t = PyTuple_New(A ? 5 : 4))) {
-	MSK_deletetask(&task);
-	MSK_deleteenv(&env);
-	return PyErr_NoMemory();
-      }
-    
-      x = (matrix *) Matrix_New(n,1,DOUBLE);
-      z = (matrix *) Matrix_New(m,1,DOUBLE);
-      if (A) {
-	yu = (matrix *) Matrix_New(p,1,DOUBLE);
-	yl = (matrix *) Matrix_New(p,1,DOUBLE);
-      }
-      if (!x || !z || (A && (!yu || !yl))){
-	Py_XDECREF(x);
-	Py_XDECREF(z);
-	Py_XDECREF(yu);
-	Py_XDECREF(yl);
-	Py_XDECREF(t);
-	MSK_deletetask(&task);
-	MSK_deleteenv(&env);
-	return PyErr_NoMemory();
-      }
-      
-      char statstr[50];
-      int solsta, prosta;
-      double tmp;
-
-      MSK_getsolutioninf(task, 0, &prosta, &solsta, 
-	  &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp);
-      
-      MSK_prostatostr (task, prosta, statstr);
-      PyTuple_SET_ITEM(t, 0, PyString_FromString(statstr));
-
-      MSK_solstatostr (task, solsta, statstr);
-      PyTuple_SET_ITEM(t, 1, PyString_FromString(statstr));
-
-      MSK_getsolutionslice(task, 0, MSK_SOL_ITEM_XX, 0, n, MAT_BUFD(x));
-      PyTuple_SET_ITEM(t, 2, (PyObject *) x);
-	
-      MSK_getsolutionslice(task, 0, MSK_SOL_ITEM_SUC, 0, m, MAT_BUFD(z));
-      PyTuple_SET_ITEM(t, 3, (PyObject *) z);
-	
-      if (A) {	  
-	MSK_getsolutionslice(task,0,MSK_SOL_ITEM_SUC,m,m+p,MAT_BUFD(yu));
-	MSK_getsolutionslice(task,0,MSK_SOL_ITEM_SLC,m,m+p,MAT_BUFD(yl));
-
-	for (i=0; i<yu->nrows; i++) MAT_BUFD(yu)[i] -= MAT_BUFD(yl)[i];
-
-	Py_DECREF(yl);
-	PyTuple_SET_ITEM(t, 4, (PyObject *) yu);
-      }
-
-      MSK_deletetask(&task);
-      MSK_deleteenv(&env);     
-
-      return (PyObject *) t;
-    } 
-
-    MSK_deletetask(&task);
-    MSK_deleteenv(&env);
- 
-    char err_str[50];
-
-    switch (r) {
-    case MSK_RES_ERR_INV_PROBLEM:
-      PY_ERR(PyExc_ValueError,"MOSEK error: probably a non-convex "
-	  "problem was specified");
-      break;
-    default:      
-      sprintf(err_str, "Internal MOSEK error. Error code %i",r);
-      PY_ERR(PyExc_Exception,err_str);
-    }
-   
-}
-
-
-static PyMethodDef mosek_functions[] = {
-  {"solvelp", (PyCFunction) mosek_solvelp, METH_VARARGS|METH_KEYWORDS, 
-   doc_mosek_solvelp},
- {"solveqp", (PyCFunction) mosek_solveqp, METH_VARARGS|METH_KEYWORDS, 
-   doc_mosek_solveqp}, 
-  {NULL}  /* Sentinel */
-};
-
-PyMODINIT_FUNC
-initmosek(void)
-{
-  mosek_module = Py_InitModule3("cvxopt.mosek", mosek_functions, mosek__doc__);
-
-  PyModule_AddObject(mosek_module, "options", PyDict_New());
-  
-  if (import_cvxopt() < 0)
-    return;
-}
diff --git a/src/C/random.c b/src/C/random.c
index ce1e714..aac8c69 100644
--- a/src/C/random.c
+++ b/src/C/random.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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,63 +22,71 @@
 #include <complex.h>
 
 #include "misc.h"
-#include "rngs/rngs.h"
-#include "rngs/rvgs.h"
+
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include <time.h>
 
 PyDoc_STRVAR(random__doc__,"Random Module.");
 
+static unsigned long seed = 0;
+static const gsl_rng_type *rng_type;
+static gsl_rng *rng; 
+
 static char doc_getseed[] =
-    "Returns the seed value for the random number generator.\n\n"
-    "getseed()";
-static PyObject *
-getseed(PyObject *self) 
-{
-  long seed;
-  GetSeed(&seed);
+  "Returns the seed value for the random number generator.\n\n"
+  "getseed()";
 
+static PyObject * getseed(PyObject *self) 
+{
   return Py_BuildValue("l",seed);
 }
 
 static char doc_setseed[] =
-    "Sets the seed value for the random number generator.\n\n"
-    "setseed(value = 0.0)\n\n"
-    "ARGUMENTS\n"
-    "value     a nonnegative number that specifies the seed value.\n"
-    "          If value is 0, the system clock is used.";
+  "Sets the seed value for the random number generator.\n\n"
+  "setseed(value = 0)\n\n"
+  "ARGUMENTS\n"
+  "value     integer seed. If the value is 0, then the system clock\n"
+  "          measured in seconds is used instead";
 
-static PyObject *
-setseed(PyObject *self, PyObject *args) 
+static PyObject * setseed(PyObject *self, PyObject *args) 
 {
-  long seed = 0;
-
-  if (!PyArg_ParseTuple(args, "|l", &seed))
+  unsigned long seed_ = 0;
+  time_t seconds;
+  
+  if (!PyArg_ParseTuple(args, "|l", &seed_))
     return NULL;
 
-  if (seed < 0) PY_ERR(PyExc_ValueError, "seed value must be non-negative");
+  if (!seed_) {
+    time(&seconds);
+    seed = (unsigned long)seconds;
+  } 
+  else seed = seed_;
 
-  PutSeed( (seed>0 ? seed : -1));
   return Py_BuildValue("");
 }
 
+
 static char doc_normal[] =
-    "Randomly generates a matrix with normally distributed entries.\n\n"
-    "normal(nrows, ncols=1, mean=0, std=1)\n\n"
-    "PURPOSE\n"
-    "Returns a matrix with typecode 'd' and size nrows by ncols, with\n"
-    "its entries randomly generated from a normal distribution with mean\n"
-    "m and standard deviation std.\n\n"
-    "ARGUMENTS\n"
-    "nrows     number of rows\n\n"
-    "ncols     number of columns\n\n"
-    "mean      approximate mean of the distribution\n\n"
-    "std       standard deviation of the distribution";
+  "Randomly generates a matrix with normally distributed entries.\n\n"
+  "normal(nrows, ncols=1, mean=0, std=1)\n\n"
+  "PURPOSE\n"
+  "Returns a matrix with typecode 'd' and size nrows by ncols, with\n"
+  "its entries randomly generated from a normal distribution with mean\n"
+  "m and standard deviation std.\n\n"
+  "ARGUMENTS\n"
+  "nrows     number of rows\n\n"
+  "ncols     number of columns\n\n"
+  "mean      approximate mean of the distribution\n\n"
+  "std       standard deviation of the distribution";
 static PyObject *
 normal(PyObject *self, PyObject *args, PyObject *kwrds) 
 {
   matrix *obj;
   int i, nrows, ncols = 1;
   double m = 0, s = 1;
-  char *kwlist[] = {"nrows", "ncols", "mean", "std", NULL};
+  char *kwlist[] = {"nrows", "ncols", "mean", "std",  NULL};
 
   if (!PyArg_ParseTupleAndKeywords(args, kwrds, "i|idd", kwlist, 
 	  &nrows, &ncols, &m, &s)) return NULL;
@@ -92,25 +100,33 @@ normal(PyObject *self, PyObject *args, PyObject *kwrds)
 
   if (!(obj = Matrix_New(nrows, ncols, DOUBLE)))
     return PyErr_NoMemory();
-  
-  for (i= 0; i < nrows*ncols; i++)
-    MAT_BUFD(obj)[i] = Normal(m,s);
-  
+
+  gsl_rng_env_setup();
+  rng_type = gsl_rng_default;
+  rng = gsl_rng_alloc (rng_type);
+  gsl_rng_set(rng, seed);
+     
+  for (i = 0; i < nrows*ncols; i++) 
+    MAT_BUFD(obj)[i] = gsl_ran_gaussian (rng, s) + m;
+
+  seed = gsl_rng_get (rng);
+  gsl_rng_free(rng);
+
   return (PyObject *)obj;
 }
 
 static char doc_uniform[] =
-    "Randomly generates a matrix with uniformly distributed entries.\n\n"
-    "uniform(nrows, ncols=1, a=0, b=1)\n\n"
-    "PURPOSE\n"
-    "Returns a matrix with typecode 'd' and size nrows by ncols, with\n"
-    "its entries randomly generated from a uniform distribution on the\n"
-    "interval (a,b).\n\n"
-    "ARGUMENTS\n"
-    "nrows     number of rows\n\n"
-    "ncols     number of columns\n\n"
-    "a         lower bound\n\n"
-    "b         upper bound";
+  "Randomly generates a matrix with uniformly distributed entries.\n\n"
+  "uniform(nrows, ncols=1, a=0, b=1)\n\n"
+  "PURPOSE\n"
+  "Returns a matrix with typecode 'd' and size nrows by ncols, with\n"
+  "its entries randomly generated from a uniform distribution on the\n"
+  "interval (a,b).\n\n"
+  "ARGUMENTS\n"
+  "nrows     number of rows\n\n"
+  "ncols     number of columns\n\n"
+  "a         lower bound\n\n"
+  "b         upper bound";
 
 static PyObject *
 uniform(PyObject *self, PyObject *args, PyObject *kwrds) 
@@ -131,18 +147,26 @@ uniform(PyObject *self, PyObject *args, PyObject *kwrds)
   
   if (!(obj = (matrix *)Matrix_New(nrows, ncols, DOUBLE)))
     return PyErr_NoMemory();
-  
+
+  gsl_rng_env_setup();
+  rng_type = gsl_rng_default;
+  rng = gsl_rng_alloc (rng_type);
+  gsl_rng_set(rng, seed);
+ 
   for (i= 0; i < nrows*ncols; i++)
-    MAT_BUFD(obj)[i] = Uniform(a,b);
+    MAT_BUFD(obj)[i] = gsl_ran_flat (rng, a, b);
+
+  seed = gsl_rng_get (rng);
+  gsl_rng_free(rng);
   
   return (PyObject *)obj;
 }
 
 static PyMethodDef random_functions[] = {
-  {"getseed",(PyCFunction)getseed,METH_NOARGS, doc_getseed},  
-  {"setseed",(PyCFunction)setseed,METH_VARARGS, doc_setseed},  
+  {"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},  
+  {"uniform", (PyCFunction)uniform, METH_VARARGS|METH_KEYWORDS, doc_uniform},  
   {NULL}  /* Sentinel */
 };
 
diff --git a/src/C/rngs/README.cvxopt b/src/C/rngs/README.cvxopt
deleted file mode 100644
index 43eab85..0000000
--- a/src/C/rngs/README.cvxopt
+++ /dev/null
@@ -1,3 +0,0 @@
-The files in this directory are from the random number generator 
-library by Steve Park & Dave Geyer. 
-See www.cs.wm.edu/~va/software/park/park.html.
diff --git a/src/C/rngs/rngs.c b/src/C/rngs/rngs.c
deleted file mode 100644
index a55f176..0000000
--- a/src/C/rngs/rngs.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -------------------------------------------------------------------------
- * This is an ANSI C library for multi-stream random number generation.  
- * The use of this library is recommended as a replacement for the ANSI C 
- * rand() and srand() functions, particularly in simulation applications 
- * where the statistical 'goodness' of the random number generator is 
- * important.  The library supplies 256 streams of random numbers; use 
- * SelectStream(s) to switch between streams indexed s = 0,1,...,255.
- *
- * The streams must be initialized.  The recommended way to do this is by
- * using the function PlantSeeds(x) with the value of x used to initialize 
- * the default stream and all other streams initialized automatically with
- * values dependent on the value of x.  The following convention is used 
- * to initialize the default stream:
- *    if x > 0 then x is the state
- *    if x < 0 then the state is obtained from the system clock
- *    if x = 0 then the state is to be supplied interactively.
- *
- * The generator used in this library is a so-called 'Lehmer random number
- * generator' which returns a pseudo-random number uniformly distributed
- * 0.0 and 1.0.  The period is (m - 1) where m = 2,147,483,647 and the
- * smallest and largest possible values are (1 / m) and 1 - (1 / m)
- * respectively.  For more details see:
- * 
- *       "Random Number Generators: Good Ones Are Hard To Find"
- *                   Steve Park and Keith Miller
- *              Communications of the ACM, October 1988
- *
- * Name            : rngs.c  (Random Number Generation - Multiple Streams)
- * Authors         : Steve Park & Dave Geyer
- * Language        : ANSI C
- * Latest Revision : 09-22-98
- * ------------------------------------------------------------------------- 
- */
-
-#include <stdio.h>
-#include <time.h>
-#include "rngs.h"
-
-#define MODULUS    2147483647 /* DON'T CHANGE THIS VALUE                  */
-#define MULTIPLIER 48271      /* DON'T CHANGE THIS VALUE                  */
-#define CHECK      399268537  /* DON'T CHANGE THIS VALUE                  */
-#define STREAMS    256        /* # of streams, DON'T CHANGE THIS VALUE    */
-#define A256       22925      /* jump multiplier, DON'T CHANGE THIS VALUE */
-#define DEFAULT    123456789  /* initial seed, use 0 < DEFAULT < MODULUS  */
-      
-static long seed[STREAMS] = {DEFAULT};  /* current state of each stream   */
-static int  stream        = 0;          /* stream index, 0 is the default */
-static int  initialized   = 0;          /* test for stream initialization */
-
-
-   double Random(void)
-/* ----------------------------------------------------------------
- * Random returns a pseudo-random real number uniformly distributed 
- * between 0.0 and 1.0. 
- * ----------------------------------------------------------------
- */
-{
-  const long Q = MODULUS / MULTIPLIER;
-  const long R = MODULUS % MULTIPLIER;
-        long t;
-
-  t = MULTIPLIER * (seed[stream] % Q) - R * (seed[stream] / Q);
-  if (t > 0) 
-    seed[stream] = t;
-  else 
-    seed[stream] = t + MODULUS;
-  return ((double) seed[stream] / MODULUS);
-}
-
-
-   void PlantSeeds(long x)
-/* ---------------------------------------------------------------------
- * Use this function to set the state of all the random number generator 
- * streams by "planting" a sequence of states (seeds), one per stream, 
- * with all states dictated by the state of the default stream. 
- * The sequence of planted states is separated one from the next by 
- * 8,367,782 calls to Random().
- * ---------------------------------------------------------------------
- */
-{
-  const long Q = MODULUS / A256;
-  const long R = MODULUS % A256;
-        int  j;
-        int  s;
-
-  initialized = 1;
-  s = stream;                            /* remember the current stream */
-  SelectStream(0);                       /* change to stream 0          */
-  PutSeed(x);                            /* set seed[0]                 */
-  stream = s;                            /* reset the current stream    */
-  for (j = 1; j < STREAMS; j++) {
-    x = A256 * (seed[j - 1] % Q) - R * (seed[j - 1] / Q);
-    if (x > 0)
-      seed[j] = x;
-    else
-      seed[j] = x + MODULUS;
-   }
-}
-
-
-   void PutSeed(long x)
-/* ---------------------------------------------------------------
- * Use this function to set the state of the current random number 
- * generator stream according to the following conventions:
- *    if x > 0 then x is the state (unless too large)
- *    if x < 0 then the state is obtained from the system clock
- *    if x = 0 then the state is to be supplied interactively
- * ---------------------------------------------------------------
- */
-{
-  char ok = 0;
-
-  if (x > 0)
-    x = x % MODULUS;                       /* correct if x is too large  */
-  if (x < 0)                                 
-    x = ((unsigned long) time((time_t *) NULL)) % MODULUS;              
-  if (x == 0)                                
-    while (!ok) {
-      printf("\nEnter a positive integer seed (9 digits or less) >> ");
-      scanf("%ld", &x);
-      ok = (0 < x) && (x < MODULUS);
-      if (!ok)
-        printf("\nInput out of range ... try again\n");
-    }
-  seed[stream] = x;
-}
-
-
-   void GetSeed(long *x)
-/* ---------------------------------------------------------------
- * Use this function to get the state of the current random number 
- * generator stream.                                                   
- * ---------------------------------------------------------------
- */
-{
-  *x = seed[stream];
-}
-
-
-   void SelectStream(int index)
-/* ------------------------------------------------------------------
- * Use this function to set the current random number generator
- * stream -- that stream from which the next random number will come.
- * ------------------------------------------------------------------
- */
-{
-  stream = ((unsigned int) index) % STREAMS;
-  if ((initialized == 0) && (stream != 0))   /* protect against        */
-    PlantSeeds(DEFAULT);                     /* un-initialized streams */
-}
-
-
-   void TestRandom(void)
-/* ------------------------------------------------------------------
- * Use this (optional) function to test for a correct implementation.
- * ------------------------------------------------------------------    
- */
-{
-  long   i;
-  long   x;
-  double u;
-  char   ok = 0;  
-
-  SelectStream(0);                  /* select the default stream */
-  PutSeed(1);                       /* and set the state to 1    */
-  for(i = 0; i < 10000; i++)
-    u = Random();
-  GetSeed(&x);                      /* get the new state value   */
-  ok = (x == CHECK);                /* and check for correctness */
-
-  SelectStream(1);                  /* select stream 1                 */ 
-  PlantSeeds(1);                    /* set the state of all streams    */
-  GetSeed(&x);                      /* get the state of stream 1       */
-  ok = ok && (x == A256);           /* x should be the jump multiplier */    
-  if (ok)
-    printf("\n The implementation of rngs.c is correct.\n\n");
-  else
-    printf("\n\a ERROR -- the implementation of rngs.c is not correct.\n\n");
-}
diff --git a/src/C/rngs/rngs.h b/src/C/rngs/rngs.h
deleted file mode 100644
index 4bc7c06..0000000
--- a/src/C/rngs/rngs.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* ----------------------------------------------------------------------- 
- * Name            : rngs.h  (header file for the library file rngs.c) 
- * Author          : Steve Park & Dave Geyer
- * Language        : ANSI C
- * Latest Revision : 09-22-98
- * ----------------------------------------------------------------------- 
- */
-
-#if !defined( _RNGS_ )
-#define _RNGS_
-
-double Random(void);
-void   PlantSeeds(long x);
-void   GetSeed(long *x);
-void   PutSeed(long x);
-void   SelectStream(int index);
-void   TestRandom(void);
-
-#endif
diff --git a/src/C/rngs/rvgs.c b/src/C/rngs/rvgs.c
deleted file mode 100644
index 265ade6..0000000
--- a/src/C/rngs/rvgs.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* -------------------------------------------------------------------------- 
- * This is an ANSI C library for generating random variates from six discrete 
- * distributions
- *
- *      Generator         Range (x)     Mean         Variance
- *
- *      Bernoulli(p)      x = 0,1       p            p*(1-p)
- *      Binomial(n, p)    x = 0,...,n   n*p          n*p*(1-p)
- *      Equilikely(a, b)  x = a,...,b   (a+b)/2      ((b-a+1)*(b-a+1)-1)/12
- *      Geometric(p)      x = 0,...     p/(1-p)      p/((1-p)*(1-p))
- *      Pascal(n, p)      x = 0,...     n*p/(1-p)    n*p/((1-p)*(1-p))
- *      Poisson(m)        x = 0,...     m            m
- * 
- * and seven continuous distributions
- *
- *      Uniform(a, b)     a < x < b     (a + b)/2    (b - a)*(b - a)/12 
- *      Exponential(m)    x > 0         m            m*m
- *      Erlang(n, b)      x > 0         n*b          n*b*b
- *      Normal(m, s)      all x         m            s*s
- *      Lognormal(a, b)   x > 0            see below
- *      Chisquare(n)      x > 0         n            2*n 
- *      Student(n)        all x         0  (n > 1)   n/(n - 2)   (n > 2)
- *
- * For the a Lognormal(a, b) random variable, the mean and variance are
- *
- *                        mean = exp(a + 0.5*b*b)
- *                    variance = (exp(b*b) - 1) * exp(2*a + b*b)
- *
- * Name              : rvgs.c  (Random Variate GeneratorS)
- * Author            : Steve Park & Dave Geyer
- * Language          : ANSI C
- * Latest Revision   : 10-28-98
- * --------------------------------------------------------------------------
- */
-
-#include <math.h>
-#include "rngs.h"
-#include "rvgs.h"
-
-
-   long Bernoulli(double p)
-/* ========================================================
- * Returns 1 with probability p or 0 with probability 1 - p. 
- * NOTE: use 0.0 < p < 1.0                                   
- * ========================================================
- */ 
-{
-  return ((Random() < (1.0 - p)) ? 0 : 1);
-}
-
-   long Binomial(long n, double p)
-/* ================================================================ 
- * Returns a binomial distributed integer between 0 and n inclusive. 
- * NOTE: use n > 0 and 0.0 < p < 1.0
- * ================================================================
- */
-{ 
-  long i, x = 0;
-
-  for (i = 0; i < n; i++)
-    x += Bernoulli(p);
-  return (x);
-}
-
-   long Equilikely(long a, long b)
-/* ===================================================================
- * Returns an equilikely distributed integer between a and b inclusive. 
- * NOTE: use a < b
- * ===================================================================
- */
-{
-  return (a + (long) ((b - a + 1) * Random()));
-}
-
-   long Geometric(double p)
-/* ====================================================
- * Returns a geometric distributed non-negative integer.
- * NOTE: use 0.0 < p < 1.0
- * ====================================================
- */
-{
-  return ((long) (log(1.0 - Random()) / log(p)));
-}
-
-   long Pascal(long n, double p)
-/* ================================================= 
- * Returns a Pascal distributed non-negative integer. 
- * NOTE: use n > 0 and 0.0 < p < 1.0
- * =================================================
- */
-{ 
-  long i, x = 0;
-
-  for (i = 0; i < n; i++)
-    x += Geometric(p);
-  return (x);
-}
-
-   long Poisson(double m)
-/* ================================================== 
- * Returns a Poisson distributed non-negative integer. 
- * NOTE: use m > 0
- * ==================================================
- */
-{ 
-  double t = 0.0;
-  long   x = 0;
-
-  while (t < m) {
-    t += Exponential(1.0);
-    x++;
-  }
-  return (x - 1);
-}
-
-   double Uniform(double a, double b)
-/* =========================================================== 
- * Returns a uniformly distributed real number between a and b. 
- * NOTE: use a < b
- * ===========================================================
- */
-{ 
-  return (a + (b - a) * Random());
-}
-
-   double Exponential(double m)
-/* =========================================================
- * Returns an exponentially distributed positive real number. 
- * NOTE: use m > 0.0
- * =========================================================
- */
-{
-  return (-m * log(1.0 - Random()));
-}
-
-   double Erlang(long n, double b)
-/* ================================================== 
- * Returns an Erlang distributed positive real number.
- * NOTE: use n > 0 and b > 0.0
- * ==================================================
- */
-{ 
-  long   i;
-  double x = 0.0;
-
-  for (i = 0; i < n; i++) 
-    x += Exponential(b);
-  return (x);
-}
-
-   double Normal(double m, double s)
-/* ========================================================================
- * Returns a normal (Gaussian) distributed real number.
- * NOTE: use s > 0.0
- *
- * Uses a very accurate approximation of the normal idf due to Odeh & Evans, 
- * J. Applied Statistics, 1974, vol 23, pp 96-97.
- * ========================================================================
- */
-{ 
-  const double p0 = 0.322232431088;     const double q0 = 0.099348462606;
-  const double p1 = 1.0;                const double q1 = 0.588581570495;
-  const double p2 = 0.342242088547;     const double q2 = 0.531103462366;
-  const double p3 = 0.204231210245e-1;  const double q3 = 0.103537752850;
-  const double p4 = 0.453642210148e-4;  const double q4 = 0.385607006340e-2;
-  double u, t, p, q, z;
-
-  u   = Random();
-  if (u < 0.5)
-    t = sqrt(-2.0 * log(u));
-  else
-    t = sqrt(-2.0 * log(1.0 - u));
-  p   = p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)));
-  q   = q0 + t * (q1 + t * (q2 + t * (q3 + t * q4)));
-  if (u < 0.5)
-    z = (p / q) - t;
-  else
-    z = t - (p / q);
-  return (m + s * z);
-}
-
-   double Lognormal(double a, double b)
-/* ==================================================== 
- * Returns a lognormal distributed positive real number. 
- * NOTE: use b > 0.0
- * ====================================================
- */
-{
-  return (exp(a + b * Normal(0.0, 1.0)));
-}
-
-   double Chisquare(long n)
-/* =====================================================
- * Returns a chi-square distributed positive real number. 
- * NOTE: use n > 0
- * =====================================================
- */
-{ 
-  long   i;
-  double z, x = 0.0;
-
-  for (i = 0; i < n; i++) {
-    z  = Normal(0.0, 1.0);
-    x += z * z;
-  }
-  return (x);
-}
-
-   double Student(long n)
-/* =========================================== 
- * Returns a student-t distributed real number.
- * NOTE: use n > 0
- * ===========================================
- */
-{
-  return (Normal(0.0, 1.0) / sqrt(Chisquare(n) / n));
-}
-
diff --git a/src/C/rngs/rvgs.h b/src/C/rngs/rvgs.h
deleted file mode 100644
index d3768d6..0000000
--- a/src/C/rngs/rvgs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* ------------------------------------------------------------- 
- * Name            : rvgs.h (header file for the library rvgs.c)
- * Author          : Steve Park & Dave Geyer
- * Language        : ANSI C
- * Latest Revision : 11-03-96
- * -------------------------------------------------------------- 
- */
-
-#if !defined( _RVGS_ )
-#define _RVGS_
-
-long Bernoulli(double p);
-long Binomial(long n, double p);
-long Equilikely(long a, long b);
-long Geometric(double p);
-long Pascal(long n, double p);
-long Poisson(double m);
-
-double Uniform(double a, double b);
-double Exponential(double m);
-double Erlang(long n, double b);
-double Normal(double m, double s);
-double Lognormal(double a, double b);
-double Chisquare(long n);
-double Student(long n);
-
-#endif
-
diff --git a/src/C/sparse.c b/src/C/sparse.c
index 9541cd9..71b9f7d 100644
--- a/src/C/sparse.c
+++ b/src/C/sparse.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * CVXOPT is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -176,7 +176,6 @@ ccs * alloc_ccs(int_t nrows, int_t ncols, int nnz, int id)
   obj->nrows = nrows;
   obj->ncols = ncols;
   obj->id = id;
-  obj->nzmax = nnz;
 
   obj->values = malloc(E_SIZE[id]*nnz);
   obj->colptr = calloc(ncols+1,sizeof(int_t));    
@@ -198,22 +197,21 @@ void free_ccs(ccs *obj) {
 }
 
 static int
-realloc_ccs(ccs *obj, int nzmax) {
+realloc_ccs(ccs *obj, int nnz) {
 
   int_t *rowind;
   void *values;
 
-  if ((rowind = realloc(obj->rowind, nzmax*sizeof(int_t))))
+  if ((rowind = realloc(obj->rowind, nnz*sizeof(int_t))))
     obj->rowind = rowind;
   else  
     return 0;
 
-  if ((values = realloc(obj->values, nzmax*E_SIZE[obj->id])))
+  if ((values = realloc(obj->values, nnz*E_SIZE[obj->id])))
     obj->values = values;
   else 
     return 0;
   
-  obj->nzmax = nzmax;
   return 1;
 }
 
@@ -223,11 +221,11 @@ static ccs * convert_ccs(ccs *src, int id) {
 
   if (id != MAX(id,src->id)) PY_ERR_TYPE("incompatible matrix types");
     
-  ccs *ret = alloc_ccs(src->nrows,src->ncols,src->nzmax,id);
+  ccs *ret = alloc_ccs(src->nrows,src->ncols,CCS_NNZ(src),id);
   if (!ret) return (ccs *)PyErr_NoMemory();
   
-  convert_array(ret->values, src->values, id, src->id, src->nzmax);
-  memcpy(ret->rowind, src->rowind, src->nzmax*sizeof(int_t));
+  convert_array(ret->values, src->values, id, src->id, CCS_NNZ(src));
+  memcpy(ret->rowind, src->rowind, CCS_NNZ(src)*sizeof(int_t));
   memcpy(ret->colptr, src->colptr, (src->ncols+1)*sizeof(int_t));
   return ret;
 }
@@ -442,7 +440,7 @@ spmatrix * sparse_concat(PyObject *L, int id_arg)
 
 static ccs * transpose(ccs *A, int conjugate) {
 
-  ccs *B = alloc_ccs(A->ncols, A->nrows, A->nzmax, A->id);
+  ccs *B = alloc_ccs(A->ncols, A->nrows, CCS_NNZ(A), A->id);
   if (!B) return NULL;
 
   int_t i, j, *buf = calloc(A->nrows,sizeof(int_t));
@@ -1208,7 +1206,7 @@ static int sp_dgemm(char tA, char tB, number alpha, void *a, void *b,
     }   
     
     int nnz = colptr_new[n]; 
-    ccs *Z = alloc_ccs(m, n, MAX(nnz,C->nzmax), C->id);
+    ccs *Z = alloc_ccs(m, n, MAX(nnz,CCS_NNZ(C)), C->id);
     if (!Z) {
       if (A != a) free_ccs(A); 
       if (B != b) free_ccs(B); 
@@ -2092,9 +2090,9 @@ static int sp_dsyrk(char uplo, char trans, number alpha, void *a,
    and Il,Jl,V must be of same length (V can also be NULL) */
 static spmatrix * 
 triplet2dccs(matrix *Il, matrix *Jl, matrix *V,
-    int_t nrows, int_t ncols, int nzmax)     
+    int_t nrows, int_t ncols)     
 {    
-  spmatrix *ret = SpMatrix_New(nrows,ncols, MAX(MAT_LGT(Il),nzmax), DOUBLE);
+  spmatrix *ret = SpMatrix_New(nrows,ncols, MAT_LGT(Il), DOUBLE);
   double_list *dlist = malloc(MAT_LGT(Jl)*sizeof(double_list));
   int_t *colcnt = calloc(ncols,sizeof(int_t));
 
@@ -2160,9 +2158,9 @@ triplet2dccs(matrix *Il, matrix *Jl, matrix *V,
 
 static spmatrix * 
 triplet2zccs(matrix *Il, matrix *Jl, matrix *V,
-    int_t nrows, int_t ncols, int nzmax)     
+    int_t nrows, int_t ncols)     
 {    
-  spmatrix *ret = SpMatrix_New(nrows,ncols, MAX(MAT_LGT(Il),nzmax), COMPLEX);
+  spmatrix *ret = SpMatrix_New(nrows,ncols, MAT_LGT(Il), COMPLEX);
   complex_list *zlist = malloc(MAT_LGT(Jl)*sizeof(complex_list));
   int_t *colcnt = calloc(ncols,sizeof(int_t));
 
@@ -2233,17 +2231,17 @@ triplet2zccs(matrix *Il, matrix *Jl, matrix *V,
   
   Arguments:  
   mrows,nrows  : Dimension of spmatrix. 
-  nzmax        : Number of nonzero elements.
+  nnz          : Number of nonzero elements.
   id           : DOUBLE/COMPLEX
 */
 spmatrix *
-SpMatrix_New(int nrows, int ncols, int nzmax, int id) 
+SpMatrix_New(int nrows, int ncols, int nnz, int id) 
 {  
   spmatrix *ret;  
   if (!(ret = (spmatrix *)spmatrix_tp.tp_alloc(&spmatrix_tp, 0)))
     return (spmatrix *)PyErr_NoMemory();
 
-  ret->obj = alloc_ccs(nrows, ncols, nzmax, id);
+  ret->obj = alloc_ccs(nrows, ncols, nnz, id);
   if (!ret->obj) { Py_DECREF(ret); return (spmatrix *)PyErr_NoMemory(); }
     
   return ret;  
@@ -2266,17 +2264,15 @@ static spmatrix * SpMatrix_NewFromCCS(ccs *x)
   
   Arguments:  
   A            : spmatrix object 
-  nzmax        : Number of nonzero elements. If nzmax is smaller than
-                 the actual size, it is ignored.
   id           : DOUBLE/COMPLEX
 */
-spmatrix * SpMatrix_NewFromSpMatrix(spmatrix *A, int nzmax, int id) 
+spmatrix * SpMatrix_NewFromSpMatrix(spmatrix *A, int id) 
 {  
   if ((id == DOUBLE) && (SP_ID(A) == COMPLEX))
     PY_ERR_TYPE("cannot convert complex to double");
   
   spmatrix *ret = SpMatrix_New
-    (SP_NROWS(A), SP_NCOLS(A), MAX(SP_NNZ(A),nzmax), id);
+    (SP_NROWS(A), SP_NCOLS(A), SP_NNZ(A), id);
   
   if (!ret) return (spmatrix *)PyErr_NoMemory();
   
@@ -2296,12 +2292,10 @@ spmatrix * SpMatrix_NewFromSpMatrix(spmatrix *A, int nzmax, int id)
   Il,Jl,V : (INT,INT,DOUBLE/COMPLEX) triplet description
   m,n     : Dimension of spmatrix. If either m==0 or n==0, then
             the dimension is taken as MAX(I) x MAX(Jl).
-  nzmax   : Number of nonzero elements. If nzmax is less than the nnz of 
-            the resulting matrix then nzmax is ignored.
   id      : DOUBLE, COMPLEX
 */
 spmatrix * SpMatrix_NewFromIJV(matrix *Il, matrix *Jl, matrix *V, 
-    int_t m, int_t n, int nzmax, int id)
+    int_t m, int_t n, int id)
 {   
 
   if (MAT_ID(Il) != INT || MAT_ID(Jl) != INT)
@@ -2318,7 +2312,7 @@ spmatrix * SpMatrix_NewFromIJV(matrix *Il, matrix *Jl, matrix *V,
   if (V && (MAT_LGT(V) != MAT_LGT(Il)))
     PY_ERR_TYPE("I, J and V must have same length");
   
-  if (!Il || !Jl) return SpMatrix_New(0,0,nzmax,id);
+  if (!Il || !Jl) return SpMatrix_New(0,0,0,id);
 
   int_t k, Imax=-1, Jmax=-1;
   for (k=0; k<MAT_LGT(Il); k++) {
@@ -2335,8 +2329,8 @@ spmatrix * SpMatrix_NewFromIJV(matrix *Il, matrix *Jl, matrix *V,
 	(MAT_BUFI(Jl)[k] < 0) || (MAT_BUFI(Jl)[k] >= n) ) 
       PY_ERR_TYPE("index out of range");      
   
-  return (id == DOUBLE ? triplet2dccs(Il,Jl,V,m,n,nzmax) : 
-      triplet2zccs(Il,Jl,V,m,n,nzmax));  
+  return (id == DOUBLE ? triplet2dccs(Il,Jl,V,m,n) : 
+      triplet2zccs(Il,Jl,V,m,n));  
 }
 
 static void spmatrix_dealloc(spmatrix* self)
@@ -2352,13 +2346,13 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
   PyObject *size = NULL;
   matrix *Il=NULL, *Jl=NULL, *V=NULL;
-  int_t nrows = -1, ncols = -1, nzmax = 0;
+  int_t nrows = -1, ncols = -1;
   char tc = 0;
 
-  static char *kwlist[] = { "V", "I", "J", "size","tc","nzmax", NULL};
+  static char *kwlist[] = { "V", "I", "J", "size","tc", NULL};
   
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|Ocl:spmatrix", kwlist, 
-	  &V, &Il, &Jl, &size, &tc, &nzmax))
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|Oc:spmatrix", kwlist, 
+	  &V, &Il, &Jl, &size, &tc))
     return NULL;
   
   if (!(PySequence_Check((PyObject *)V) || Matrix_Check(V) || PY_NUMBER(V))) {
@@ -2374,8 +2368,6 @@ 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 (nzmax < 0) PY_ERR_TYPE("nzmax must be non-negative");
-
   int_t ndim = 0;
   /* convert lists to matrices */
   if (Matrix_Check(Il)) 
@@ -2384,46 +2376,71 @@ spmatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     if (!(Il = Matrix_NewFromArrayStruct((PyObject *)Il, INT, &ndim)))
       return NULL;
   }
-  else if (PySequence_Check((PyObject *)Il))     
-    Il = Matrix_NewFromSequence((PyObject *)Il, INT);
-  
+  else if (PySequence_Check((PyObject *)Il)) {
+    if (!(Il = Matrix_NewFromSequence((PyObject *)Il, INT)))
+      return NULL;
+  } 
+  else PY_ERR_TYPE("invalid type for I");
 
   if (Matrix_Check(Jl)) 
     Py_INCREF(Jl);
   else if (PyObject_HasAttrString((PyObject *)Jl,"__array_struct__")) {
-    if (!(Jl = Matrix_NewFromArrayStruct((PyObject *)Jl, INT, &ndim)))
+    if (!(Jl = Matrix_NewFromArrayStruct((PyObject *)Jl, INT, &ndim))) {
+      Py_DECREF(Il); 
       return NULL;
+    }
+  }
+  else if (PySequence_Check((PyObject *)Jl)) {    
+    if (!(Jl = Matrix_NewFromSequence((PyObject *)Jl, INT))) {
+      Py_DECREF(Il); 
+      return NULL;
+    }
+  }
+  else {
+    Py_DECREF(Il);
+    PY_ERR_TYPE("invalid type for J");
   }
-  else if (PySequence_Check((PyObject *)Jl))     
-    Jl = Matrix_NewFromSequence((PyObject *)Jl, INT);
-
 
   if (Matrix_Check(V)) 
     Py_INCREF(V);
   else if (PyObject_HasAttrString((PyObject *)V,"__array_struct__")) {
     int_t ndim = 0;
-    if (!(V = Matrix_NewFromArrayStruct((PyObject *)V, id, &ndim)))
+    if (!(V = Matrix_NewFromArrayStruct((PyObject *)V, id, &ndim))) {
+      Py_DECREF(Il); 
+      Py_DECREF(Jl); 
       return NULL;
+    }
   }
   else if (PySequence_Check((PyObject *)V)) 
   {  
-    if (!(V = Matrix_NewFromSequence((PyObject *)V, id)))
+    if (!(V = Matrix_NewFromSequence((PyObject *)V, id))) {
+      Py_DECREF(Il); 
+      Py_DECREF(Jl); 
       return NULL;
+    }
   }
   else if (PY_NUMBER(V)) 
   {
-    if (!(V = Matrix_NewFromNumber(MAT_LGT(Il), 1, get_id(V, 1), V, 1)))
+    if (!(V = Matrix_NewFromNumber(MAT_LGT(Il), 1, get_id(V, 1), V, 1))) {
+      Py_DECREF(Il); 
+      Py_DECREF(Jl); 
       return PyErr_NoMemory();
+    }
+  }
+  else {
+    Py_DECREF(Il);
+    Py_DECREF(Jl);
+    PY_ERR_TYPE("invalid type for V");
   }
 
   id = (id == -1 ? MAX(get_id(V, !Matrix_Check(V)), DOUBLE) : id);
 
-  spmatrix *ret = SpMatrix_NewFromIJV(Il, Jl, V, nrows, ncols, nzmax,
+  spmatrix *ret = SpMatrix_NewFromIJV(Il, Jl, V, nrows, ncols, 
       id == -1 ? MAX(MAT_ID(V),DOUBLE) : id);
 
-  if (Matrix_Check(Il)) { Py_DECREF(Il); }
-  if (Matrix_Check(Jl)) { Py_DECREF(Jl); }
-  if (Matrix_Check(V))  { Py_DECREF(V); }
+  Py_DECREF(Il); 
+  Py_DECREF(Jl); 
+  Py_DECREF(V); 
 
   return (PyObject *)ret;
 } 
@@ -2584,6 +2601,32 @@ static PyObject * spmatrix_get_J(spmatrix *self, void *closure)
   return (PyObject *)A;
 }
 
+static PyObject *spmatrix_get_CCS(spmatrix *self, void *closure)
+{
+  matrix *colptr = Matrix_New( SP_NCOLS(self)+1, 1, INT);
+  matrix *rowind = Matrix_New( SP_NNZ(self), 1, INT);
+  matrix *val    = Matrix_New( SP_NNZ(self), 1, SP_ID(self));
+  PyObject *ret  = PyTuple_New(3);
+  
+  if (!colptr || !rowind || !val || !ret) {
+    Py_XDECREF(colptr);
+    Py_XDECREF(rowind);
+    Py_XDECREF(val);
+    Py_XDECREF(ret);
+    return PyErr_NoMemory();
+  }
+  
+  memcpy(MAT_BUF(colptr), SP_COL(self), (SP_NCOLS(self)+1)*sizeof(int_t));
+  memcpy(MAT_BUF(rowind), SP_ROW(self), SP_NNZ(self)*sizeof(int_t));
+  memcpy(MAT_BUF(val),    SP_VAL(self), SP_NNZ(self)*E_SIZE[SP_ID(self)]);
+
+  PyTuple_SET_ITEM(ret, 0, (PyObject *)colptr);
+  PyTuple_SET_ITEM(ret, 1, (PyObject *)rowind);
+  PyTuple_SET_ITEM(ret, 2, (PyObject *)val);
+
+  return ret;
+}
+
 static spmatrix * spmatrix_get_T(spmatrix *self, void *closure)
 {
   return SpMatrix_NewFromCCS(transpose(((spmatrix *)self)->obj,0));
@@ -2607,6 +2650,7 @@ static PyGetSetDef spmatrix_getsets[] = {
    "the J (column) list of the matrix in triplet form"},
   {"T", (getter) spmatrix_get_T, NULL, "transpose"},
   {"H", (getter) spmatrix_get_H, NULL, "conjugate transpose"},
+  {"CCS", (getter) spmatrix_get_CCS, NULL, "CCS representation"},
   {NULL}  /* Sentinel */
 };
 
@@ -2645,7 +2689,7 @@ static PyObject * spmatrix_ctrans(spmatrix *self) {
 static PyObject * spmatrix_real(spmatrix *self) {
 
   if (SP_ID(self) != COMPLEX) 
-    return (PyObject *)SpMatrix_NewFromSpMatrix(self, 0, SP_ID(self));
+    return (PyObject *)SpMatrix_NewFromSpMatrix(self, SP_ID(self));
   
   spmatrix *ret = SpMatrix_New(SP_NROWS(self), SP_NCOLS(self), 
       SP_NNZ(self), DOUBLE);
@@ -2663,7 +2707,7 @@ static PyObject * spmatrix_real(spmatrix *self) {
 static PyObject * spmatrix_imag(spmatrix *self) {
 
   if (SP_ID(self) != COMPLEX) 
-    return (PyObject *)SpMatrix_NewFromSpMatrix(self, 0, SP_ID(self));
+    return (PyObject *)SpMatrix_NewFromSpMatrix(self, SP_ID(self));
   
   spmatrix *ret = SpMatrix_New(SP_NROWS(self), SP_NCOLS(self), 
       SP_NNZ(self), DOUBLE);
@@ -2955,9 +2999,8 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     if (spmatrix_getitem_i(self, i, &tempval)) 
       spmatrix_setitem_i(self, i, &val);
     else {
-      if (SP_NNZ(self) == SP_NZMAX(self)) 
-	if (!realloc_ccs(self->obj, SP_NZMAX(self)+1)) 
-	  PY_ERR_INT(PyExc_MemoryError, "Cannot reallocate sparse matrix");
+      if (!realloc_ccs(self->obj, SP_NNZ(self)+1)) 
+	PY_ERR_INT(PyExc_MemoryError, "Cannot reallocate sparse matrix");
       spmatrix_setitem_i(self, i, &val); 
     }
     return 0;
@@ -2972,7 +3015,7 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     }
 
     int_t i, lgtI = MAT_LGT(Il);
-    int_t nnz = MAX(SP_NNZ(self)+MAT_LGT(Il),SP_NZMAX(self));    
+    int_t nnz = SP_NNZ(self)+MAT_LGT(Il);    
     
     if (((itype == 'd') && 
 	    ((lgtI != MAT_LGT(value) || MAT_NCOLS(value) != 1))) ||
@@ -3074,8 +3117,7 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
       free(SP_VAL(self)); SP_VAL(self) = val_merge;      
       free(ilist); 
 
-      int_t nzmax = MAX(SP_NNZ(self),SP_NZMAX(self));
-      if (nnz > nzmax) realloc_ccs(self->obj, nzmax);
+      realloc_ccs(self->obj, SP_NNZ(self)); //XXX
     }
     /* ass. argument is a sparse matrix */
     else 
@@ -3170,14 +3212,12 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
       free(SP_VAL(self)); SP_VAL(self) = val_merge;      
       free(ilist); 
 
-      int_t nzmax = MAX(SP_NNZ(self),SP_NZMAX(self));
-      if (nnz > nzmax) realloc_ccs(self->obj, nzmax);
+      realloc_ccs(self->obj, SP_NNZ(self));
     }
     
     if (!Matrix_Check(args)) { Py_DECREF(Il); }
     if (decref_val) { Py_DECREF(value); }
 
-    SP_NZMAX(self) = MAX(SP_NNZ(self),SP_NZMAX(self));
     return 0;
   }
 
@@ -3200,9 +3240,8 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     if (spmatrix_getitem_ij(self, i, j, &tempval))
       spmatrix_setitem_ij(self, i, j, &val);
     else {
-      if (SP_NNZ(self) == SP_NZMAX(self)) 
-	if (!realloc_ccs(self->obj, SP_NZMAX(self)+1)) 
-	  PY_ERR_INT(PyExc_MemoryError, "insufficient memory");
+      if (!realloc_ccs(self->obj, SP_NNZ(self)+1)) 
+	PY_ERR_INT(PyExc_MemoryError, "insufficient memory");
       
       spmatrix_setitem_ij(self, i, j, &val);
     }
@@ -3235,7 +3274,7 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
   /* ass. argument is dense matrix or number */
   if  ((itype == 'd' || itype == 'n') && lgtI*lgtJ> 0) {
 
-    int_t nnz = MAX(SP_NNZ(self)+lgtI*lgtJ,SP_NZMAX(self));    
+    int_t nnz = SP_NNZ(self)+lgtI*lgtJ;    
       
     int_t *col_merge = calloc(SP_NCOLS(self)+1,sizeof(int_t));
     int_t *row_merge = malloc(nnz*sizeof(int_t));
@@ -3340,14 +3379,13 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     free(SP_VAL(self)); SP_VAL(self) = val_merge;      
     free(Is); free(Js); 
 
-    int nzmax = MAX(SP_NNZ(self),SP_NZMAX(self));
-    if (nnz > nzmax) realloc_ccs(self->obj, nzmax);    
+    realloc_ccs(self->obj, SP_NNZ(self));    
 
   }
   /* ass. argument is a sparse matrix */
   else if (itype == 's' && lgtI*lgtJ > 0) {
 
-    int_t nnz = MAX(SP_NNZ(self)+SP_NNZ(value),SP_NZMAX(self));    
+    int_t nnz = SP_NNZ(self)+SP_NNZ(value);    
     
     int_t *col_merge = calloc((SP_NCOLS(self)+1),sizeof(int_t));
     int_t *row_merge = malloc(nnz*sizeof(int_t));
@@ -3451,15 +3489,12 @@ spmatrix_ass_subscr(spmatrix* self, PyObject* args, PyObject* value)
     free(SP_VAL(self)); SP_VAL(self) = val_merge;      
     free(Is); free(Js); 
 
-    int_t nzmax = MAX(SP_NNZ(self),SP_NZMAX(self));
-    if (nnz > nzmax) realloc_ccs(self->obj, nzmax);    
-    
+    realloc_ccs(self->obj, SP_NNZ(self));    
   }
   if (!Matrix_Check(argI)) { Py_DECREF(Il); }
   if (!Matrix_Check(argJ)) { Py_DECREF(Jl); }
   if (decref_val) { Py_DECREF(value); }
   
-  SP_NZMAX(self) = MAX(SP_NNZ(self),SP_NZMAX(self));
   return 0;
   
 }
@@ -3473,7 +3508,7 @@ static PyMappingMethods spmatrix_as_mapping = {
 
 static PyObject * spmatrix_neg(spmatrix *self)
 {  
-  spmatrix *x = SpMatrix_NewFromSpMatrix(self,0,SP_ID(self));
+  spmatrix *x = SpMatrix_NewFromSpMatrix(self,SP_ID(self));
   if (!x) return PyErr_NoMemory();
 
   int n=SP_NNZ(x);
@@ -3484,7 +3519,7 @@ static PyObject * spmatrix_neg(spmatrix *self)
 
 static PyObject * spmatrix_pos(spmatrix *self)
 {  
-  spmatrix *x = SpMatrix_NewFromSpMatrix(self,0,SP_ID(self));
+  spmatrix *x = SpMatrix_NewFromSpMatrix(self,SP_ID(self));
   if (!x) return PyErr_NoMemory();
   
   return (PyObject *)x;
@@ -3699,7 +3734,7 @@ spmatrix_mul(PyObject *self, PyObject *other)
       PY_NUMBER(other) || (Matrix_Check(other) && MAT_LGT(other) == 1)) {
     
     spmatrix *ret = SpMatrix_NewFromSpMatrix((spmatrix *)
-	(SpMatrix_Check(self) ? self : other), 0, id);
+	(SpMatrix_Check(self) ? self : other), id);
 
     number val;
     convert_num[id](&val, !SpMatrix_Check(self) ? self : other, 
@@ -3796,7 +3831,7 @@ spmatrix_div_generic(spmatrix *A, PyObject *B, int inplace)
   convert_num[id](&n, B, (Matrix_Check(B) ? 0 : 1), 0);
 
   if (!inplace) {      
-    PyObject *ret = (PyObject *)SpMatrix_NewFromSpMatrix((spmatrix *)A, 0, id);
+    PyObject *ret = (PyObject *)SpMatrix_NewFromSpMatrix((spmatrix *)A, id);
     if (!ret) return NULL;
 
     if (div_array[id](SP_VAL(ret), n, SP_NNZ(ret))) { 
diff --git a/src/C/umfpack.c b/src/C/umfpack.c
index 4908204..2e8af4a 100644
--- a/src/C/umfpack.c
+++ b/src/C/umfpack.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2004-2007 J. Dahl and L. Vandenberghe.
  *
- * This file is part of CVXOPT version 0.9.
+ * This file is part of CVXOPT version 0.9.1.
  *
  * 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/python/__init__.py b/src/python/__init__.py
index 896a33c..46ca8ae 100644
--- a/src/python/__init__.py
+++ b/src/python/__init__.py
@@ -1,2 +1,2 @@
-__all__ = ['base', 'random', 'blas', 'lapack', 'amd', 'umfpack', 
-    'cholmod', 'solvers', 'modeling', 'info']
+__all__ = ['base', 'random', 'blas', 'lapack', 'amd', 'umfpack', 'cholmod',
+    'solvers', 'modeling', 'info', 'mosek']
diff --git a/src/python/coneprog.py b/src/python/coneprog.py
index 04c9a44..8c416e1 100644
--- a/src/python/coneprog.py
+++ b/src/python/coneprog.py
@@ -4,7 +4,7 @@ Solver for linear, second-order cone and semidefinite programming.
 
 # Copyright 2004-2007 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 0.9.
+# This file is part of CVXOPT version 0.9.1.
 #
 # 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,7 @@ Solver for linear, second-order cone and semidefinite programming.
 
 
 import math
-from cvxopt import base, blas, lapack, cholmod, misc
+from cvxopt import base, blas, lapack, cholmod
 from cvxopt.base import matrix, spmatrix
 
 __all__ = []
@@ -277,6 +277,32 @@ def sdot(x, y, dims):
     return a
 
 
+def sdot2(x, y):
+    """
+    Inner product of two block-diagonal symmetric dense 'd' matrices.
+
+    x and y are square dense 'd' matrices, or lists of N square dense
+    'd' matrices.
+    """
+
+    a = 0.0
+    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):
+	    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)):
+	    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):
+		a += 2.0 * blas.dot(x[k], y[k], incx=n+1, incy=n+1, 
+		    offsetx=j, offsety=j, n=n-j)
+    return a
+
+
 def snrm2(x, dims): 
 
     # Returns the norm of a vector in S
@@ -1901,10 +1927,10 @@ def conelp(c, G, h, dims, A = None, b = None, primalstart = None,
 
             # Solve 
             #
-            #  [  0   A'  G'    0   ] [dx  ]   [ rhsx                  ]
-            #  [ -A   0   0     b   ] [dy  ]   [ rhsy                  ]
-            #  [ -G   0   W'*W  h   ] [dz  ] = [ rhsz - lambda o\ rhss ]
-            #  [ -c'  -b' -h'   k/t ] [dtau]   [ rhst - rhsk/tau       ].
+            #  [  0  A'  G'   0   ] [dx  ]   [ rhsx                     ]
+            #  [ -A  0   0    b   ] [dy  ]   [ rhsy                     ]
+            #  [ -G  0   W'*W h   ] [dz  ] = [ rhsz - W'*(lmbda o\ rhss)]
+            #  [ -c' -b' -h'  k/t ] [dtau]   [ rhst - rhsk/tau          ].
 
             f(dx, dy, dz)
 
@@ -2081,6 +2107,7 @@ def conelp(c, G, h, dims, A = None, b = None, primalstart = None,
 
         solve_newton(dx, dy, dz, dtau, ds, dkappa)
 
+
         # Maximum step to boundary.
         # Compute eigenvalue decomposition of symmetric matrices in ds, dz.
         # The eigenvectors of dsk, dzk are stored in dsk, dzk.  
@@ -2511,22 +2538,28 @@ def lp(c, G, h, A = None, b = None, solver = None, primalstart = None,
         return {'status': status, 'x': x, 's': s, 'y': y, 'z': z}
 
     if solver == 'mosek':
-        try: from cvxopt import mosek
-        except ImportError: raise ValueError, "invalid option "\
-            "(solver='mosek'): cvxopt.mosek is not installed" 
-        mosek.options = options
-        prosta, solsta, x, z, y  = mosek.solvelp(c,G,h,A,b)
-        if solsta == 'OPTIMAL':
+        try: 
+            from cvxopt import mosek
+            import pymosek as msk
+        except ImportError: 
+            raise ValueError, "invalid option (solver = 'mosek'): "\
+                "cvxopt.mosek is not installed" 
+        if 'MOSEK' in options:
+            mosek.options = options['MOSEK']
+        else:
+            mosek.options = {}
+        solsta, x, z, y  = mosek.solvelp(c, G, h, A, b)
+        if solsta is msk.solsta.optimal:
             s = matrix(h)
             base.gemv(G, x, s, alpha=-1.0, beta=1.0)
             status = 'optimal'
-        elif solsta == 'PRIMAL_INFEASIBLE_CER':
+        elif solsta is msk.solsta.prim_infeas_cer:
             status = 'primal infeasible'
             ducost = -blas.dot(h,z) - blas.dot(b,y)
             blas.scal(1.0/ducost, y)
             blas.scal(1.0/ducost, z)
             x, s = None, None
-        elif solsta == 'DUAL_INFEASIBLE_CER':
+        elif solsta == msk.solsta.dual_infeas_cer:
             status = 'dual infeasible'
             pcost = blas.dot(c,x)
             blas.scal(-1.0/pcost, x)
@@ -2544,7 +2577,7 @@ def lp(c, G, h, A = None, b = None, solver = None, primalstart = None,
 
 
 def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
-    primalstart = None, dualstart = None):
+    solver = None, primalstart = None, dualstart = None):
 
     """
     Solves a pair of primal and dual SOCPs
@@ -2582,6 +2615,13 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
         matrix of size (p,1).  The default values of A and b are matrices 
         with zero rows.
 
+        solver is None or 'mosek'.  The default solver (None) uses the 
+        cvxopt conelp() function.  The 'mosek' solver is the LP solver 
+        from MOSEK.
+
+        The arguments primalstart and dualstart are ignored when solver
+        is 'mosek', and are optional when solver is None.  
+
         The argument primalstart is a dictionary with keys 'x', 'sl', 'sq',
         and specifies an optional primal starting point.  
         primalstart['x'] is a dense 'd' matrix of size (n,1).  
@@ -2677,6 +2717,58 @@ def socp(c, Gl = None, hl = None, Gq = None, hq = None, A = None, b = None,
     if type(b) is not matrix or b.typecode != 'd' or b.size != (p,1): 
         raise TypeError, "'b' must be a dense matrix of size (%d,1)" %p
 
+    if solver == 'mosek':
+        try: 
+            from cvxopt import mosek
+            import pymosek as msk
+        except ImportError: 
+            raise ValueError, "invalid option (solver = 'mosek'): "\
+                "cvxopt.mosek is not installed" 
+        if 'MOSEK' in options:
+            mosek.options = options['MOSEK']
+        else:
+            mosek.options = {}
+        if p: raise ValueError, "socp() with the solver = 'socp' option "\
+            "does not handle problems with equality constraints"
+
+        solsta, x, zl, zq  = mosek.socp(c, Gl, hl, Gq, hq)
+
+        if solsta is msk.solsta.optimal:
+            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)):
+                base.gemv(Gq[k], x, sq[k], alpha = -1.0, beta = 1.0)
+            y = matrix(0.0, (0,1))
+            status = 'optimal'
+
+        elif solsta is msk.solsta.prim_infeas_cer:
+            status = 'primal infeasible'
+            ducost = -blas.dot(hl,zl) - sum([ blas.dot(hq[k], zq[k]) for
+                k in xrange(len(hq)) ])
+            y = matrix(0.0, (0,1))
+            blas.scal(1.0/ducost, zl)
+            for zqk in zq: blas.scal(1.0/ducost, zqk)
+            x, sl, sq = None, None, None
+
+        elif solsta == msk.solsta.dual_infeas_cer:
+            status = 'dual infeasible'
+            pcost = blas.dot(c,x)
+            blas.scal(-1.0/pcost, x)
+            sl = matrix(0.0, (ml,1))
+            base.gemv(Gl, x, sl, alpha = -1.0)
+            sq = [ matrix(0.0, (m,1)) for m in mq ]
+            for k in xrange(len(mq)):
+                base.gemv(Gq[k], x, sq[k], alpha = -1.0)
+            zl, zq, y = None, None, None
+
+        else: 
+            status = 'unknown'
+            x, sl, sq, y, zl, zq = None, None, None, None, None, None
+
+        return {'status': status, 'x': x, 'sl': sl, 'sq': sq, 'y': y, 
+            'zl': zl, 'zq': zq}
+
     dims = {'l': ml, 'q': mq, 's': []}
     N = ml + sum(mq)
     h = matrix(0.0, (N,1))
@@ -2926,7 +3018,7 @@ def sdp(c, Gl = None, hl = None, Gs = None, hs = None, A = None, b = None,
             zl, zs = None, None
             status = 'dual infeasible'
         elif dsdpstatus == 'DSDP_INFEASIBLE':
-            dcost = -blas.dot(hl,zl) - misc.sdot(hs, zs)
+            dcost = -blas.dot(hl,zl) - sdot2(hs, zs)
             zl /= -dcost 
             zs = [zs / -docst for zk in zs]
             y = matrix(0.0, (0,1))
diff --git a/src/python/cvxprog.py b/src/python/cvxprog.py
index d014f56..6ba8cb0 100644
--- a/src/python/cvxprog.py
+++ b/src/python/cvxprog.py
@@ -8,7 +8,7 @@ to the quadratic programming solver from MOSEK.
 
 # Copyright 2004-2007 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 0.9.
+# This file is part of CVXOPT version 0.9.1.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -25,14 +25,424 @@ to the quadratic programming solver from MOSEK.
 
 import math 
 from cvxopt import base, blas, lapack, misc
-from cvxopt.base import matrix, spmatrix, sqrt, exp, mul, div
+from cvxopt.base import matrix, spmatrix 
 
 __all__ = []
 options = {}
 
-def nlclp(c, kktsolver, F=None, G=None, h=None, A=None, b=None, 
-    xnewcopy=matrix, xdot=blas.dot, xaxpy=blas.axpy, xscal=blas.scal,
-    ynewcopy=matrix, ydot=blas.dot, yaxpy=blas.axpy, yscal=blas.scal):
+
+def kkt_ldl(mnl, G, dims, A):
+
+    # Returns a function that (1) computes the LDL factorization of
+    #
+    #     [ H           A'   GG'*W^{-1} ] 
+    #     [ A           0    0          ],
+    #     [ W^{-T}*GG   0   -I          ] 
+    #
+    # given H, Df, W, where GG = [Df; G], and (2) returns a function for 
+    # solving 
+    #
+    #     [ H     A'   GG'   ]   [ ux ]   [ bx ]
+    #     [ A     0    0     ] * [ uy ] = [ by ].
+    #     [ GG    0   -W'*W  ]   [ uz ]   [ bz ]
+    
+    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'] ])
+    ldK = n + p + cdim_pckd 
+    K = matrix(0.0, (ldK, ldK))
+    ipiv = matrix(0, (ldK, 1))
+    u = matrix(0.0, (ldK, 1))
+    g = matrix(0.0, (cdim, 1))
+
+    def factor(H, Df, W):
+        blas.scal(0.0, K)
+        K[:n, :n] = H
+        K[n:n+p, :n] = A
+        for k in xrange(n):
+            g[:mnl] = Df[:,k]
+            g[mnl:] = G[:,k]
+            misc.scale(g, W, trans = 'T', inverse = 'I')
+            misc.pack(g, K, mnl, dims, offsety = k*ldK + n + p)
+        K[(ldK+1)*(p+n) :: ldK+1]  = -1.0
+        lapack.sytrf(K, ipiv)
+
+        def solve(x, y, z):
+
+            # Solve
+            #
+            #     [ H          A'   GG'*W^{-1} ]   [ ux   ]   [ bx        ]
+            #     [ A          0    0          ] * [ uy   [ = [ by        ]
+            #     [ W^{-T}*GG  0   -I          ]   [ W*uz ]   [ W^{-T}*bz ]
+            #
+            # and return ux, uy, W*uz.
+            #
+            # On entry, x, y, z contain bx, by, bz.  On exit, they contain
+            # the solution ux, uy, W*uz.
+
+            blas.copy(x, u)
+            blas.copy(y, u, offsety = n)
+            misc.scale(z, W, trans = 'T', inverse = 'I') 
+            misc.pack(z, u, mnl, dims, offsety = n + p)
+            lapack.sytrs(K, ipiv, u)
+            blas.copy(u, x, n = n)
+            blas.copy(u, y, offsetx = n, n = p)
+            misc.unpack(u, z, mnl, dims, offsetx = n + p)
+    
+        return solve
+
+    return factor
+
+
+def kkt_qr(mnl, G, dims, A):
+
+    # Computes the QR factorization
+    #
+    #     A' = [Q1, Q2] * [R; 0]
+    #
+    # and returns a function that (1) computes the Cholesky factorization 
+    #
+    #     Q_2^T * (H + GG^T * W^{-1} * W^{-T} * GG) * Q2 = L * L^T, 
+    #
+    # given H, Df, W, where GG = [Df; G], and (2) returns a function for 
+    # solving 
+    #
+    #     [ H    A'   GG'    ]   [ ux ]   [ bx ]
+    #     [ A    0    0      ] * [ uy ] = [ by ].
+    #     [ GG   0    -W'*W  ]   [ uz ]   [ bz ]
+
+    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'] ])
+
+    # A' = [Q1, Q2] * [R; 0]  (Q1 is n x p, Q2 is n x n-p).
+    if type(A) is matrix: 
+        QA = A.T
+    else: 
+        QA = matrix(A.T)
+    tauA = matrix(0.0, (p,1))
+    lapack.geqrf(QA, tauA)
+
+    Gs = matrix(0.0, (cdim, n))
+    g = matrix(0.0, (cdim, 1))
+    K = matrix(0.0, (n,n)) 
+    bzp = matrix(0.0, (cdim_pckd, 1))
+    yy = matrix(0.0, (p,1))
+
+    def factor(H, Df, W):
+
+        # Compute 
+        #
+        #     K = [Q1, Q2]' * (H + GG' * W^{-1} * W^{-T} * GG) * [Q1, Q2]
+        #
+        # and take the Cholesky factorization of the 2,2 block
+        #
+        #     Q_2' * (H + GG^T * W^{-1} * W^{-T} * GG) * Q2.
+
+        # Gs = W^{-T} * GG in packed storage.
+        Gs[:mnl, :] = Df
+        Gs[mnl:, :] = G
+        misc.scale(Gs, W, trans = 'T', inverse = 'I')
+        for k in xrange(n):
+            g[:] = Gs[:, k]
+            misc.pack(g, Gs, mnl, dims, offsety = k*Gs.size[0])
+
+        # K = [Q1, Q2]' * (H + Gs' * Gs) * [Q1, Q2].
+        K[:,:] = H
+        blas.syrk(Gs, K, beta = 1.0, k = cdim_pckd, trans = 'T')
+        misc.symm(K, n)
+        lapack.ormqr(QA, tauA, K, side = 'L', trans = 'T')
+        lapack.ormqr(QA, tauA, K, side = 'R')
+
+        # Cholesky factorization of 2,2 block of K.
+        lapack.potrf(K, n = n-p, offsetA = p*(n+1))
+
+        def solve(x, y, z):
+
+            # Solve
+            #
+            #     [ 0          A'  GG'*W^{-1} ]   [ ux   ]   [ bx        ]
+            #     [ A          0   0          ] * [ uy   ] = [ by        ]
+            #     [ W^{-T}*GG  0   -I         ]   [ W*uz ]   [ W^{-T}*bz ]
+            #
+            # and return ux, uy, W*uz.
+            #
+            # On entry, x, y, z contain bx, by, bz.  On exit, they contain
+            # the solution ux, uy, W*uz.
+            #
+            # If we change variables ux = Q1*v + Q2*w, the system becomes 
+            # 
+            #     [ K11 K12 R ]   [ v  ]   [Q1'*(bx+GG'*W^{-1}*W^{-T}*bz)]
+            #     [ K21 K22 0 ] * [ w  ] = [Q2'*(bx+GG'*W^{-1}*W^{-T}*bz)]
+            #     [ R^T 0   0 ]   [ uy ]   [by                           ]
+            # 
+            #     W*uz = W^{-T} * ( GG*ux - bz ).
+
+            # bzp := W^{-T} * bz in packed storage 
+            misc.scale(z, W, trans = 'T', inverse = 'I')
+            misc.pack(z, bzp, mnl, dims)
+
+            # x := [Q1, Q2]' * (x + Gs' * bzp)
+            #    = [Q1, Q2]' * (bx + Gs' * W^{-T} * bz)
+            blas.gemv(Gs, bzp, x, beta = 1.0, trans = 'T', m = cdim_pckd)
+            lapack.ormqr(QA, tauA, x, side = 'L', trans = 'T')
+
+            # y := x[:p] 
+            #    = Q1' * (bx + Gs' * W^{-T} * bz)
+            blas.copy(y, yy)
+            blas.copy(x, y, n = p)
+
+            # x[:p] := v = R^{-T} * by 
+            blas.copy(yy, x)
+            lapack.trtrs(QA, x, uplo = 'U', trans = 'T', n = p)
+
+            # x[p:] := K22^{-1} * (x[p:] - K21*x[:p])
+            #        = K22^{-1} * (Q2' * (bx + Gs' * W^{-T} * bz) - K21*v)
+            blas.gemv(K, x, x, alpha = -1.0, beta = 1.0, m = n-p, n = p,
+                offsetA = p, offsety = p)
+            lapack.potrs(K, x, n = n-p, offsetA = p*(n+1), offsetB = p)
+
+            # y := y - [K11, K12] * x
+            #    = Q1' * (bx + Gs' * W^{-T} * bz) - K11*v - K12*w
+            blas.gemv(K, x, y, alpha = -1.0, beta = 1.0, m = p, n = n)
+
+            # y := R^{-1}*y
+            #    = R^{-1} * (Q1' * (bx + Gs' * W^{-T} * bz) - K11*v 
+            #      - K12*w)
+            lapack.trtrs(QA, y, uplo = 'U', n = p)
+           
+            # x := [Q1, Q2] * x
+            lapack.ormqr(QA, tauA, x, side = 'L')
+
+            # bzp := Gs * x - bzp.
+            #      = W^{-T} * ( GG*ux - bz ) in packed storage.
+            # Unpack and copy to z.
+            blas.gemv(Gs, x, bzp, alpha = 1.0, beta = -1.0, m = cdim_pckd)
+            misc.unpack(bzp, z, mnl, dims)
+
+        return solve
+
+    return factor
+
+
+def kkt_chol(mnl, G, dims, A):
+
+    # This works only for problems with no second-order or semidefinite
+    # cone constraints.
+    #
+    # Returns a function that (1) computes Cholesky factorizations of
+    # the matrices 
+    #
+    #     S = H + GG' * W^{-1} * W^{-T} * GG,  
+    #     K = A * S^{-1} *A'
+    #
+    # or (if K is singular in the first call to the function), the matrices
+    #
+    #     S = H + GG' * W^{-1} * W^{-T} * GG + A' * A,  
+    #     K = A * S^{-1} * A',
+    #
+    # given H, Df, W, where GG = [Df; G], and (2) returns a function for 
+    # solving 
+    #
+    #     [ H     A'   GG'   ]   [ ux ]   [ bx ]
+    #     [ A     0    0     ] * [ uy ] = [ by ].
+    #     [ GG    0   -W'*W  ]   [ uz ]   [ bz ]
+
+    p, n = A.size
+    ml = dims['l']
+    F = {'firstcall': True, 'singular': False}
+    if dims['q'] or dims['s']:
+        raise ValueError, "kktsolver option 'chol' is only allowed for "\
+            "problems with no second-order or semidefinite cone "\
+            "constraints"
+
+    def factor(H, Df, W):
+
+        if F['firstcall']:
+            if type(G) is matrix: 
+                F['Gs'] = matrix(0.0, G.size) 
+            else:
+                F['Gs'] = spmatrix(0.0, G.I, G.J, G.size) 
+            if type(Df) is matrix:
+                F['Dfs'] = matrix(0.0, Df.size) 
+            else:
+                F['Dfs'] = spmatrix(0.0, Df.I, Df.J, Df.size) 
+            if type(Df) is matrix or type(G) is matrix or type(H) is \
+                matrix:
+                F['S'] = matrix(0.0, (n,n))
+                F['K'] = matrix(0.0, (p,p))
+            else:
+                F['S'] = spmatrix([], [], [], (n,n), 'd')
+                F['Sf'] = None
+                if type(A) is matrix:
+                    F['K'] = matrix(0.0, (p,p))
+                else:
+                    F['K'] = spmatrix([], [], [], (p,p), 'd')
+
+        # Dfs = Wnl^{-1} * Df and Gs = Wl^{-1} * G.
+        base.gemm(spmatrix(W['dnli'], range(mnl), range(mnl)), Df, 
+            F['Dfs'], partial = True)
+        base.gemm(spmatrix(W['dli'], range(ml), range(ml)), G, F['Gs'], 
+            partial = True)
+
+        if F['firstcall']:
+            base.syrk(F['Dfs'], F['S'], trans = 'T')
+            base.syrk(F['Gs'], F['S'], trans = 'T', beta = 1.0) 
+            F['S'] += H
+            try:
+                if type(F['S']) is matrix: 
+                    lapack.potrf(F['S']) 
+                else:
+                    F['Sf'] = cholmod.symbolic(F['S'])
+                    cholmod.numeric(F['S'], F['Sf'])
+            except ArithmeticError:
+                F['singular'] = True 
+                if type(A) is matrix and type(F['S']) is spmatrix:
+                    F['S'] = matrix(0.0, (n,n))
+                base.syrk(F['Dfs'], F['S'], trans = 'T')
+                base.syrk(F['Gs'], F['S'], trans = 'T', beta = 1.0) 
+                base.syrk(A, F['S'], trans = 'T', beta = 1.0) 
+                F['S'] += H
+                if type(F['S']) is matrix: 
+                    lapack.potrf(F['S']) 
+                else:
+                    F['Sf'] = cholmod.symbolic(F['S'])
+                    cholmod.numeric(F['S'], F['Sf'])
+            F['firstcall'] = False
+
+        else:
+            # S := H but do not remove nonzeros from sparsity pattern if S
+            # is sparse.
+            if type(F['S']) is spmatrix and type(H) is spmatrix:
+                F['S'] *= 0.0
+                F['S'] += H
+            else:
+                F['S'][:,:] = H
+            base.syrk(F['Dfs'], F['S'], trans = 'T', beta = 1.0, 
+                partial = True)
+            base.syrk(F['Gs'], F['S'], trans = 'T', beta = 1.0, 
+                partial = True)
+            if F['singular']:
+                base.syrk(A, F['S'], trans = 'T', beta = 1.0, partial = 
+                    True) 
+            if type(F['S']) is matrix: 
+                lapack.potrf(F['S']) 
+            else:
+                cholmod.numeric(F['S'], F['Sf'])
+
+        if type(F['S']) is matrix: 
+            # Asct := L^{-1}*A'.  Factor K = Asct'*Asct.
+            if type(A) is matrix: 
+                Asct = A.T
+            else: 
+                Asct = matrix(A.T)
+            blas.trsm(F['S'], Asct)
+            blas.syrk(Asct, F['K'], trans = 'T')
+            lapack.potrf(F['K'])
+
+        else:
+            # Asct := L^{-1}*P*A'.  Factor K = Asct'*Asct.
+            if type(A) is matrix:
+                Asct = A.T
+                cholmod.solve(F['Sf'], Asct, sys = 7)
+                cholmod.solve(F['Sf'], Asct, sys = 4)
+                blas.syrk(Asct, F['K'], trans = 'T')
+                lapack.potrf(F['K']) 
+            else:
+                Asct = cholmod.spsolve(F['Sf'], A.T, sys = 7)
+                Asct = cholmod.spsolve(F['Sf'], Asct, sys = 4)
+                base.syrk(Asct, F['K'], trans = 'T')
+                Kf = cholmod.symbolic(F['K'])
+                cholmod.numeric(K, Kf)
+
+        def solve(x, y, z):
+
+            # Solve
+            #
+            #     [ H          A'  GG'*W^{-1} ]   [ ux   ]   [ bx        ]
+            #     [ A          0   0          ] * [ uy   ] = [ by        ]
+            #     [ W^{-T}*GG  0   -I         ]   [ W*uz ]   [ W^{-T}*bz ]
+            #
+            # and return ux, uy, W*uz.
+            #
+            # If not F['singular']:
+            #
+            #     K*uy = A * S^{-1} * ( bx + GG'*W^{-1}*W^{-T}*bz ) - by
+            #     S*ux = bx + GG'*W^{-1}*W^{-T}*bz - A'*uy
+            #     W*uz = W^{-T} * ( GG*ux - bz ).
+            #    
+            # If F['singular']:
+            #
+            #     K*uy = A * S^{-1} * ( bx + GG'*W^{-1}*W^{-T}*bz + A'*by )
+            #            - by
+            #     S*ux = bx + GG'*W^{-1}*W^{-T}*bz + A'*by - A'*y.
+            #     W*uz = W^{-T} * ( GG*ux - bz ).
+
+            # z := W^{-1} * z = W^{-1} * bz
+            misc.scale(z, W, trans = 'T', inverse = 'I') 
+
+            # If not F['singular']:
+            #     x := L^{-1} * P * (x + GGs'*z)
+            #        = L^{-1} * P * (x + GG'*W^{-1}*W^{-T}*bz)
+            #
+            # If F['singular']:
+            #     x := L^{-1} * P * (x + GGs'*z + A'*y))
+            #        = L^{-1} * P * (x + GG'*W^{-1}*W^{-T}*bz + A'*y)
+
+            base.gemv(F['Dfs'], z, x, trans = 'T', beta = 1.0)
+            base.gemv(F['Gs'], z, x, offsetx = mnl, trans = 'T', 
+                beta = 1.0)
+            if F['singular']:
+                base.gemv(A, y, x, trans = 'T', beta = 1.0)
+            if type(F['S']) is matrix:
+                blas.trsv(F['S'], x)
+            else:
+                cholmod.solve(F['Sf'], x, sys = 7)
+                cholmod.solve(F['Sf'], x, sys = 4)
+
+            # y := K^{-1} * (Asc*x - y)
+            #    = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz) - by)
+            #      (if not F['singular'])
+            #    = K^{-1} * (A * S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz + 
+            #      A'*by) - by)  
+            #      (if F['singular']).
+
+            base.gemv(Asct, x, y, trans = 'T', beta = -1.0)
+            if type(F['K']) is matrix:
+                lapack.potrs(F['K'], y)
+            else:
+                cholmod.solve(Kf, y)
+
+            # x := P' * L^{-T} * (x - Asc'*y)
+            #    = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz - A'*y) 
+            #      (if not F['singular'])  
+            #    = S^{-1} * (bx + GG'*W^{-1}*W^{-T}*bz + A'*by - A'*y) 
+            #      (if F['singular'])
+
+            base.gemv(Asct, y, x, alpha = -1.0, beta = 1.0)
+            if type(F['S']) is matrix:
+                blas.trsv(F['S'], x, trans='T')
+            else:
+                cholmod.solve(F['Sf'], x, sys = 5)
+                cholmod.solve(F['Sf'], x, sys = 8)
+
+            # W*z := GGs*x - z = W^{-T} * (GG*x - bz)
+            base.gemv(F['Dfs'], x, z, beta = -1.0)
+            base.gemv(F['Gs'], x, z, beta = -1.0, offsety = mnl)
+
+        return solve
+
+    return factor
+
+
+def cpl(c, F, G = None, h = None, dims = None, A = None, b = None, 
+    kktsolver = None, xnewcopy = matrix, xdot = blas.dot, xaxpy = 
+    blas.axpy, xscal = blas.scal, ynewcopy = matrix, ydot = blas.dot, 
+    yaxpy = blas.axpy, yscal = blas.scal):
 
     """
     Solves a nonlinearly constrained convex optimization problem with a
@@ -40,122 +450,276 @@ def nlclp(c, kktsolver, F=None, G=None, h=None, A=None, b=None,
 
         minimize    c'*x 
         subject to  f(x) <= 0
-                    G(x) <= h
-                    A(x) = b.                      
-
-    f: V -> R^mnl is convex and twice differentiable,  G: V -> R^ml and
-    A: V -> W are linear mappings, where V and W are real vector spaces.
-    The default choices for V and W are Euclidean vector spaces V=R^n 
-    and W=R^p, with elements represented as 'd' matrices of size (n,1) 
-    and (p,1).
+                    G*x <= h
+                    A*x = b.                      
 
+    f is vector valued, convex and twice differentiable.  The linear 
+    inequalities are with respect to a cone C defined as the Cartesian 
+    product of N + M + 1 cones:
+    
+        C = C_0 x C_1 x .... x C_N x C_{N+1} x ... x C_{N+M}.
 
-    Input arguments 
+    The first cone C_0 is the nonnegative orthant of dimension ml.  The 
+    next N cones are second order cones of dimension mq[0], ..., mq[N-1].
+    The second order cone of dimension m is defined as
+    
+        { (u0, u1) in R x R^{m-1} | u0 >= ||u1||_2 }.
 
-        c is an element in V (stored as a matrix, list, dictionary,...).
+    The next M cones are positive semidefinite cones of order ms[0], ...,
+    ms[M-1] >= 0.  
 
-        kktsolver is a function for the factorization of a KKT system
 
-            [ H   *   *    *  ] [ ux   ]   [ bx   ]
-            [ A   0   *    *  ] [ uy   ] = [ by   ]
-            [ Df  0  -Dnl  *  ] [ uznl ]   [ bznl ]
-            [ G   0   0   -Dl ] [ uzl  ]   [ bzl  ] 
- 
-        where H = sum_k z[k]*Hk, Hk is the Hessian of fk, Df is the 
-        derivative matrix of f, and Dnl and Dl are positive diagonal 
-        matrices.
-        Called as g = kktsolver(x, z, dnl, dl), it returns a function g 
-        that can be used to solve the system with Df and H evaluated 
-        at x and z, Dnl = diag(dnl)^-2, and Dl = diag(dl)^-2.  It can 
-        be assumed that x is in the domain of f and that z is positive.
-        The function call g(bx, by, bznl, bzl) replaces its arguments 
-        with the solution ux, uy, uznl, uzl.
+    Input arguments (basic usage).
 
+        c is a dense 'd' matrix of size (n,1), where n is the dimension 
+        of the primal variable x.
 
         F is a function that handles the following arguments.
 
-            F() returns a tuple (mnl, x0).  mnl is the number of 
-            nonlinear inequality constraints.  x0 is a point in the
-            domain of f.
+            F() returns a tuple (mnl, x0).  mnl is the number of nonlinear 
+            inequality constraints.  x0 is a point in the domain of f.
 
-            F(x), with x an element in V, returns a tuple (f, Df).
+            F(x) returns a tuple (f, Df).
 
-                f is  a dense 'd' matrix of size (mnl,1) with the 
-                function values f(x). 
+                f is  a dense 'd' matrix of size (mnl, 1) containing f(x). 
 
-                Df is a function or a dense or sparse 'd' matrix.   
-                When Df is a function, Df(u, v) where u is a 'd' matrix 
-                of size (mnl,1) and v an element in V, updates v as 
+                Df is a dense or sparse 'd' matrix of size (mnl, n), 
+                containing the derivatives of f at x:  Df[k,:] is the 
+                transpose of the gradient of fk at x.  If x is not in 
+                dom f, F(x) returns None or (None, None).
 
-                    v := sum_k u[k] * grad fk(x) + v.
+            F(x, z) with z a positive 'd' matrix of size (mnl,1), returns 
+            a tuple (f, Df, H).
+            
+                f and Df are defined as above.
+                
+                H is a dense or sparse 'd' matrix of size (n,n).  The 
+                lower triangular part of H contains the lower triangular
+                part of sum_k z[k] * Hk where Hk is the Hessian of fk at x.
 
-                When V=R^n, Df can also be passed as 'd' matrix of 
-                size (mnl,n) that contains the derivative matrix of f 
-                at x, i.e., Df[k,:] is the transpose of the gradient of 
-                fk at x.  
+                If F is called with two arguments, it can be assumed that 
+                x is dom f. 
 
-                If x is not in dom f, F(x) should return (None, None) 
-                or None.
+            If Df and H are returned as sparse matrices, their sparsity
+            patterns must be the same for each call to F(x) or F(x,z). 
 
-            If F is None, it is assumed that mnl = 0.
+        dims is a dictionary with the dimensions of the components of C.  
+        It has three fields.
+        - dims['l'] = ml, the dimension of the nonnegative orthant C_0.
+          (ml >= 0.)
+        - dims['q'] = mq = [ mq[0], mq[1], ..., mq[N-1] ], a list of N 
+          integers with the dimensions of the second order cones 
+          C_1, ..., C_N.  (N >= 0 and mq[k] >= 1.)
+        - dims['s'] = ms = [ ms[0], ms[1], ..., ms[M-1] ], a list of M  
+          integers with the orders of the semidefinite cones 
+          C_{N+1}, ..., C_{N+M}.  (M >= 0 and ms[k] >= 0.)
+        The default value of dims = {'l': G.size[0], 'q': [], 's': []}.
 
+        G is a dense or sparse 'd' matrix of size (K,n), where
 
-        G is None, a function, or a sparse or dense 'd' matrix. 
+            K = ml + mq[0] + ... + mq[N-1] + ms[0]**2 + ... + ms[M-1]**2.
 
-            If G is None, it is assumed that ml = 0.  
+        Each column of G describes a vector 
 
-            If G is a function, then
+            v = ( v_0, v_1, ..., v_N, vec(v_{N+1}), ..., vec(v_{N+M}) ) 
 
-                G(u, v, alpha=1.0, beta=0.0, trans='N')
+        in V = R^ml x R^mq[0] x ... x R^mq[N-1] x S^ms[0] x ... x S^ms[M-1]
+        stored as a column vector
 
-            evaluates
+            [ v_0; v_1; ...; v_N; vec(v_{N+1}); ...; vec(v_{N+M}) ].
 
-                v := alpha*G(u) + beta*v if trans is 'N'
-                v := alpha*G'(u) + beta*v if trans is 'T'.
+        Here, if u is a symmetric matrix of order m, then vec(u) is the 
+        matrix u stored in column major order as a vector of length m**2.
+        We use BLAS unpacked 'L' storage, i.e., the entries in vec(u) 
+        corresponding to the strictly upper triangular entries of u are 
+        not referenced.
 
-            
-        h is None, or a dense 'd' matrix with one column.  If h is None,
-        it is interpreted as a 0x1 matrix.
+        h is a dense 'd' matrix of size (K,1), representing a vector in V,
+        in the same format as the columns of G.
+    
+        A is a dense or sparse 'd' matrix of size (p,n).  The default
+        value is a sparse 'd' matrix of size (0,n).
+
+        b is a dense 'd' matrix of size (p,1).  The default value is a 
+        dense 'd' matrix of size (0,1).
+
+        It is assumed that rank(A) = p and rank([H; A; Df; G]) = n at all 
+        x in dom f.
+
+        The other arguments are normally not needed.  They make it possible
+        to exploit certain types of structure, as described further below.
+
+
+    Output arguments.
+
+        cpl() returns a dictionary with keys 'status', 'x', 'snl', 'sl',
+        'znl', 'zl', 'y'.
+
+        If status is 'optimal', x, snl, sl are approximate solutions of
+        the primal problem 
+
+            minimize    c'*x 
+            subject to  f(x) + snl = 0
+                        G*x + sl  = h
+                        A*x =  b,
+                        snl >= 0, sl >= 0
+
+        and y, znl, zl are approximate solutions of the dual problem
+
+            maximize    inf_x (c'*x + znl'*f(x) + zl'*(G*x-h) + y'*(A*x-b))
+            subject to  znl >= 0, zl >= 0.
+
+        If status is 'unknown', x, s, snl, sl, y, znl, zl are None.
+
+
+    Advanced usage.
+
+        Three mechanisms are provided to express problem structure.
+
+        1.  The user can provide a customized routine for solving 
+        linear equations ('KKT systems')
+
+            [ sum_k zk*Hk(x)  A'  GG'   ] [ ux ]   [ bx ]
+            [ A               0   0     ] [ uy ] = [ by ]
+            [ GG              0   -W'*W ] [ uz ]   [ bz ]
+
+        where GG = [ Df(x);  G ], uz = (uznl, uzl), bz = (bznl, bzl).  
+
+        z is a positive vector of length mnl and x is a point in the domain
+        of f.   W is a scaling matrix, i.e., a block diagonal mapping
+
+           W*u = ( Wnl*unl, W0*u_0, ..., W_{N+M}*u_{N+M} )
+
+        defined as follows.
+
+        - For the nonlinear block (Wnl):
+
+              Wnl = diag(dnl),
+
+          with dnl a positive vector of length mnl.
+
+        - For the 'l' block (W_0):
+
+              W_0 = diag(dl),
+
+          with dl a positive vector of length ml.
+
+        - For the 'q' blocks (W_{k+1}, k = 0, ..., N-1):
 
+              W_{k+1} = beta_k * ( 2 * v_k * v_k' - J )
 
-        A is None, a function, or a dense or sparse 'd' matrix.  
+          where beta_k is a positive scalar, v_k is a vector in R^mq[k]
+          with v_k[0] > 0 and v_k'*J*v_k = 1, and J = [1, 0; 0, -I].
 
-            If A is None, it is assumed that dim W  = 0.  
+        - For the 's' blocks (W_{k+N}, k = 0, ..., M-1):
 
-            If A is a function then
+              W_k * u = vec(r_k' * mat(u) * r_k)
 
-                A(u, v, alpha=1.0, beta=0.0, trans='N')
+          where r_k is a nonsingular matrix of order ms[k], and mat(x) is
+          the inverse of the vec operation.
 
-            evaluates
+        The optional argument kktsolver is a Python function that will be
+        called as g = kktsolver(x, z, W).  W is a dictionary that contains
+        the parameters of the scaling:
 
-                v := alpha*A(u) + beta*v if trans is 'N'
-                v := alpha*A'(u) + beta*v if trans is 'T'.
+        - W['dnl'] is a positive 'd' matrix of size (mnl, 1).
+        - W['dnli'] is a positive 'd' matrix with the elementwise inverse 
+          of W['dnl'].
+        - W['dl'] is a positive 'd' matrix of size (ml, 1).
+        - W['dli'] is a positive 'd' matrix with the elementwise inverse of
+          W['dl'].
+        - W['beta'] is a list [ beta_0, ..., beta_{N-1} ]
+        - W['v'] is a list [ v_0, ..., v_{N-1} ]
+        - W['r'] is a list [ r_0, ..., r_{M-1} ]
+        - W['rti'] is a list [ rti_0, ..., rti_{M-1} ], with rti_k the
+          inverse of the transpose of r_k.
 
+        The call g = kktsolver(x, z, W) should return a function g that
+        solves the KKT system by g(ux, uy, uz).  On entry, ux, uy, uz 
+        contain the righthand side bx, by, bz.  On exit, they contain the 
+        solution, with uz scaled: W*uz is returned instead of uz.
 
-        b is None, or an element in W.  If b is None, it is assumed 
-        that dim W = 0.
 
+        2.  The linear operators Df*u, H*u, G*u and A*u can be specified 
+        by providing Python functions instead of matrices.  This can only 
+        be done in combination with 1. above, i.e., it also requires the 
+        kktsolver argument.
+        
+        If G is a function, the call G(u, v, alpha, beta, trans) should 
+        evaluate the matrix-vector products
 
-    Returns a dictionary with keys 'status', 'x', 'snl', 'sl', 'y', 
-    'znl', 'zl'.  
+            v := alpha * G * u + beta * v  if trans is 'N'
+            v := alpha * G' * u + beta * v  if trans is 'T'.
 
-        status is 'optimal' or 'unknown'.
+        The arguments u and v are required.  The other arguments have
+        default values alpha = 1.0, beta = 0.0, trans = 'N'.
+
+        If A is a function, the call A(u, v, alpha, beta, trans) should
+        evaluate the matrix-vectors products
+
+            v := alpha * A * u + beta * v if trans is 'N'
+            v := alpha * A' * u + beta * v if trans is 'T'.
+
+        The arguments u and v are required.  The other arguments
+        have default values alpha = 1.0, beta = 0.0, trans = 'N'.
+
+        If Df is a function, the call Df(u, v, alpha, beta, trans) should
+        evaluate the matrix-vectors products
+
+            v := alpha * Df(x) * u + beta * v if trans is 'N'
+            v := alpha * Df(x)' * u + beta * v if trans is 'T'.
+
+        If H is a function, the call H(u, v, alpha, beta) should evaluate 
+        the matrix-vectors product
+
+            v := alpha * H * u + beta * v.
+
+
+        3.  Instead of using the default representation of the primal 
+        variable x and the dual variable y as one-column 'd' matrices, 
+        we can represent these variables and the corresponding parameters 
+        c and b by arbitrary Python objects (matrices, lists, dictionaries,
+        etc).  This can only be done in combination with 1. and 2. above,
+        i.e., it requires a user-provided KKT solver and a function
+        description of the linear mappings.   It also requires the 
+        arguments xnewcopy, xdot, xscal, xaxpy, ynewcopy, ydot, yscal, 
+        yaxpy.  These arguments are functions defined as follows.
+   
+        If X is the vector space of primal variables x, then:
+        - xnewcopy(u) creates a new copy of the vector u in X.
+        - xdot(u, v) returns the inner product of two vectors u and v in X.
+        - xscal(alpha, u) computes u := alpha*u, where alpha is a scalar
+          and u is a vector in X.
+        - xaxpy(u, v, alpha = 1.0, beta = 0.0) computes v := alpha*u + v
+          for a scalar alpha and two vectors u and v in X.
+
+        If Y is the vector space of primal variables y:
+        - ynewcopy(u) creates a new copy of the vector u in Y.
+        - ydot(u, v) returns the inner product of two vectors u and v in Y.
+        - yscal(alpha, u) computes u := alpha*u, where alpha is a scalar
+          and u is a vector in Y.
+        - yaxpy(u, v, alpha = 1.0, beta = 0.0) computes v := alpha*u + v
+          for a scalar alpha and two vectors u and v in Y.
+
+
+    Control parameters.
+
+       The following control parameters can be modified by adding an
+       entry to the dictionary options.
+
+       options['show_progress'] True/False (default: True)
+       options['maxiters'] positive integer (default: 100)
+       options['abstol'] scalar (default: 1e-7)
+       options['reltol'] scalar (default: 1e-6)
+       options['feastol'] scalar (default: 1e-7).
 
-        x, s, snl, sl, y, znl, zl are None if status is 'unknown'.  
-        Otherwise x is the optimal solution;  snl, sl are the optimal 
-        slacks for the nonlinear and linear inequalities;  y is the 
-        optimal dual variable associated with the equality constraints; 
-        znl, zl are the optimal dual variables associated with the 
-        nonlinear and linear inequalities.
     """
 
     STEP = 0.99
     BETA = 0.5
     ALPHA = 0.01
-    GAMMA1 = 1e5
-    GAMMA2 = 1e-5
-    GAMMA3 = 0.5
-    GAMMA4 = 1.0
+    EXPON = 3
+    MAX_RELAXED_ITERS = 8
 
     try: MAXITERS = options['maxiters']
     except KeyError: MAXITERS = 100
@@ -171,7 +735,7 @@ def nlclp(c, kktsolver, F=None, G=None, h=None, A=None, b=None,
             raise ValueError, "options['abstol'] must be a scalar"
 
     try: RELTOL = options['reltol']
-    except KeyError: RELTOL = 1e-7
+    except KeyError: RELTOL = 1e-6
     else: 
         if type(RELTOL) is not float and type(RELTOL) is not int: 
             raise ValueError, "options['reltol'] must be a scalar"
@@ -185,653 +749,1772 @@ def nlclp(c, kktsolver, F=None, G=None, h=None, A=None, b=None,
     try: show_progress = options['show_progress']
     except KeyError: show_progress = True
 
-    if F is None:  # There are no nonlinear inequality constraints.
-        def F(x=None, z=None):
-            if x is None: 
-                x0 = xnewcopy(c)
-                xscal(0.0, x0)
-                return 0, x0
-            def Df(u, v): pass
-            return matrix(0.0, (0,1)), Df
+    try: refinement = options['refinement']
+    except KeyError: refinement = True
 
-    mnl, x0 = F()
-
-    def fzero(x, y, alpha=1.0, beta=0.0, trans='N'):
-        if trans == 'T':  xscal(beta, y)
+    if kktsolver is None: 
+        if dims and (dims['q'] or dims['s']):  
+            kktsolver = 'qr'            
+        else:
+            kktsolver = 'chol'            
+    defaultsolvers = ('ldl', 'qr', 'chol')
 
-    if G is None: G = fzero
+    try: mnl, x0 = F()   
+    except: raise ValueError, "function call 'F()' failed"
+    
+    # Argument error checking depends on level of customization.
+    customkkt = type(kktsolver) is not str
+    operatorG = G is not None and type(G) not in (matrix, spmatrix)
+    operatorA = A is not None and type(A) not in (matrix, spmatrix)
+    if (operatorG or operatorA) and not customkkt:
+        raise ValueError, "use of function valued G, A requires a "\
+            "user-provided kktsolver"
+    customx = xnewcopy != matrix or xdot != blas.dot or xaxpy != blas.axpy\
+        or xscal != blas.scal 
+    if customx and (not operatorG or not operatorA or not customkkt):
+        raise ValueError, "use of non-vector type for x requires "\
+            "function valued G, A and user-provided kktsolver"
+    customy = ynewcopy != matrix or ydot != blas.dot or yaxpy != blas.axpy\
+        or yscal != blas.scal  
+    if customy and (not operatorA or not customkkt):
+        raise ValueError, "use of non vector type for y requires "\
+            "function valued A and user-provided kktsolver"
+
+    if not customx:  
+        if type(x0) is not matrix or x0.typecode != 'd' or x0.size[1] != 1:
+            raise TypeError, "'x0' must be a 'd' matrix with one column"
+        if type(c) is not matrix or c.typecode != 'd' or c.size != x0.size:
+            raise TypeError, "'c' must be a 'd' matrix of size (%d,%d)"\
+                %(x0.size[0],1)
+        
     if h is None: h = matrix(0.0, (0,1))
-    ml = h.size[0]
-    if type(G) in (matrix, spmatrix):
-        if G.typecode != 'd' or G.size[0] != ml:
-            raise TypeError, "'G' must be a 'd' matrix with %d rows" %ml
-        def fG(u, v, alpha=1.0, beta=0.0, trans='N'):
-            base.gemv(G, u, v, alpha=alpha, beta=beta, trans=trans)
-    else:    
-        fG = G 
-
-    if (mnl+ml == 0):
-        raise ValueError, "problem must have at least one inequality "\
-            "constraint"
-
-    if A is None: A = fzero 
-    if b is None: b = matrix(0.0, (0,1))
-    if type(A) in (matrix,spmatrix):
-        if A.typecode != 'd' or A.size[0] != b.size[0]:
-            raise TypeError, "'A' must be a 'd' matrix with %d rows" \
-            %b.size[0]
-        def fA(u, v, alpha=1.0, beta=0.0, trans='N'):
-            base.gemv(A, u, v, alpha=alpha, beta=beta, trans=trans)
+    if type(h) is not matrix or h.typecode != 'd' or h.size[1] != 1:
+        raise TypeError, "'h' must be a 'd' matrix with 1 column" 
+    if not dims:  dims = {'l': h.size[0], 'q': [], 's': []}
+
+    # Logarithmic degree of the product cone.
+    cdeg = mnl + dims['l'] + len(dims['q']) + sum(dims['s'])
+
+    # Dimension of the product cone of the linear inequalities. with 's' 
+    # components unpacked.
+    cdim = dims['l'] + sum(dims['q']) + sum([ k**2 for k in dims['s'] ])
+    if h.size[0] != cdim:
+        raise TypeError, "'h' must be a 'd' matrix of size (%d,1)" %cdim
+
+    # Dimension of the product cone of the linear inequalities, with 's' 
+    # components packed.
+    cdim_pckd = dims['l'] + sum(dims['q']) + sum([ k*(k+1)/2 for k in 
+        dims['s'] ])
+
+    # Dimension of the product cone of the linear inequalities, with 
+    # diagonal 's' components.
+    cdim_diag = dims['l'] + sum(dims['q']) + sum(dims['s'])
+
+    if G is None:
+        if customx:
+            def G(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+                if trans == 'N': pass
+                else: xscal(beta, y)
+        else:
+            G = spmatrix([], [], [], (0, c.size[0]))
+    if type(G) is matrix or type(G) is spmatrix:
+        if G.typecode != 'd' or G.size != (cdim, c.size[0]):
+            raise TypeError, "'G' must be a 'd' matrix with size (%d, %d)"\
+                %(cdim, c.size[0])
+        def fG(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+            misc.sgemv(G, x, y, dims, trans = trans, alpha = alpha, 
+                beta = beta)
     else:
-        fA = A
+        fG = G
 
-    def xcopy(x, y):  xscal(0.0, y);  xaxpy(x, y)
-    def ycopy(x, y):  yscal(0.0, y);  yaxpy(x, y)
+    if A is None:
+        if customy:
+            def A(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+                if trans == 'N': pass
+                else: xscal(beta, y)
+        else:
+            A = spmatrix([], [], [], (0, c.size[0]))
+    if type(A) is matrix or type(A) is spmatrix:
+        if A.typecode != 'd' or A.size[1] != c.size[0]:
+            raise TypeError, "'A' must be a 'd' matrix with %d columns" \
+                %c.size[0]
+        def fA(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+            base.gemv(A, x, y, trans = trans, alpha = alpha, beta = beta)
+    else:
+        fA = A
+    if not customy:
+        if b is None: b = matrix(0.0, (0,1))
+        if type(b) is not matrix or b.typecode != 'd' or b.size[1] != 1:
+            raise TypeError, "'b' must be a 'd' matrix with one column"
+        if not operatorA and b.size[0] != A.size[0]:
+            raise TypeError, "'b' must have length %d" %A.size[0]
+    if b is None and customy:  
+        raise ValueEror, "use of non vector type for y requires b"
+
+
+    def xcopy(x, y):  
+        xscal(0.0, y) 
+        xaxpy(x, y)
+    def ycopy(x, y):  
+        yscal(0.0, y)  
+        yaxpy(x, y)
+
+    if kktsolver in defaultsolvers:
+         if kktsolver == 'ldl': 
+             factor = kkt_ldl(mnl, G, dims, A)
+         elif kktsolver == 'qr':
+             factor = kkt_qr(mnl, G, dims, A)
+         else:
+             factor = kkt_chol(mnl, G, dims, A)
+         def kktsolver(x, znl, W):
+             f, Df, H = F(x, znl)
+             return factor(H, Df, W)             
+             
 
+    # Initial points
     x = xnewcopy(x0)
     y = ynewcopy(b);  yscal(0.0, y)
-    znl, zl = matrix(1.0, (mnl,1)), matrix(1.0, (ml,1)) 
-    snl, sl = matrix(1.0, (mnl,1)), matrix(1.0, (ml,1))
-    rx, rx2 = xnewcopy(x0), xnewcopy(x0)
-    ry = ynewcopy(b)
-    rznl, rznl2 = matrix(0.0, (mnl,1)), matrix(0.0, (mnl,1))
-    rzl = matrix(0.0, (ml,1))
+    z, s = matrix(0.0, (mnl + cdim, 1)), matrix(0.0, (mnl + cdim, 1))
+    z[: mnl+dims['l']] = 1.0 
+    s[: mnl+dims['l']] = 1.0 
+    ind = mnl + dims['l']
+    for m in dims['q']:
+        z[ind] = 1.0
+        s[ind] = 1.0
+        ind += m
+    for m in dims['s']:
+        z[ind : ind + m*m : m+1] = 1.0
+        s[ind : ind + m*m : m+1] = 1.0
+        ind += m**2
+    
+    rx, ry = xnewcopy(x0), ynewcopy(b)
+    rznl, rzl = matrix(0.0, (mnl, 1)), matrix(0.0, (cdim, 1)), 
     dx, dy = xnewcopy(x), ynewcopy(y)   
+    dz, ds = matrix(0.0, (mnl + cdim, 1)), matrix(0.0, (mnl + cdim, 1))
+    ds1 = matrix(0.0, (mnl + cdim, 1))
+    dx2, dy2 = xnewcopy(x), ynewcopy(y)   
+    dz2, ds2 = matrix(0.0, (mnl + cdim, 1)), matrix(0.0, (mnl + cdim, 1))
+    dz2nl, dz2l = matrix(0.0, (mnl,1)), matrix(0.0, (cdim, 1))
+    duz, dus = matrix(0.0, (mnl + cdim, 1)), matrix(0.0, (mnl + cdim, 1))
     newx, newy = xnewcopy(x),  ynewcopy(y)
+    newz, news = matrix(0.0, (mnl + cdim, 1)), matrix(0.0, (mnl + cdim, 1))
+    newrx = xnewcopy(x0)
+    newrznl = matrix(0.0, (mnl, 1))
+    lmbda = matrix(0.0, (mnl + cdim_diag, 1))
+    lmbdasq = matrix(0.0, (mnl + cdim_diag, 1))
+    sigs = matrix(0.0, (sum(dims['s']), 1))
+    sigz = matrix(0.0, (sum(dims['s']), 1))
+    work = matrix(0.0, (max( [0] + dims['s'] )**2, 1))
+
+    rx0, ry0 = xnewcopy(x0), ynewcopy(b)
+    rznl0, rzl0 = matrix(0.0, (mnl, 1)), matrix(0.0, (cdim, 1)), 
+    x0, dx0 = xnewcopy(x), xnewcopy(dx)
+    y0, dy0 = ynewcopy(y), ynewcopy(dy)
+    z0 = matrix(0.0, (mnl + cdim, 1))
+    dz0 = matrix(0.0, (mnl + cdim, 1))
+    dz20 = matrix(0.0, (mnl + cdim, 1))
+    s0 = matrix(0.0, (mnl + cdim, 1))
+    ds0 = matrix(0.0, (mnl + cdim, 1))
+    ds20 = matrix(0.0, (mnl + cdim, 1))
+    W0 = {}
+    W0['dnl'] = matrix(0.0, (mnl, 1))
+    W0['dnli'] = matrix(0.0, (mnl, 1))
+    W0['dl'] = matrix(0.0, (dims['l'], 1))
+    W0['dli'] = matrix(0.0, (dims['l'], 1))
+    W0['v'] = [ matrix(0.0, (m, 1)) for m in dims['q'] ]
+    W0['beta'] = len(dims['q']) * [ 0.0 ]
+    W0['r'] = [ matrix(0.0, (m, m)) for m in dims['s'] ]
+    W0['rti'] = [ matrix(0.0, (m, m)) for m in dims['s'] ]
+    lmbda0 = matrix(0.0, (mnl + cdim_diag, 1))
+    lmbdasq0 = matrix(0.0, (mnl + cdim_diag, 1))
+    
+    
 
     if show_progress: 
-        print "% 10s% 12s% 10s% 8s% 7s" %("pcost", "dcost", "gap", 
-            "pres", "dres")
+        print "% 10s% 12s% 10s% 8s% 7s" %("pcost", "dcost", "gap", "pres",
+            "dres")
 
+    relaxed_iters = 0
     for iters in xrange(MAXITERS):  
 
-        f, Df = F(x)
+        if refinement:  
+            # We need H to compute residuals of KKT equations.
+            f, Df, H = F(x, z[:mnl])
+        else:
+            f, Df = F(x)
+       
         f = matrix(f, tc='d')
-        if f.typecode != 'd' or f.size != (mnl,1):
+        if f.typecode != 'd' or f.size != (mnl, 1):
             raise TypeError, "first output argument of F() must be a "\
-                "'d' matrix of size (%d,%d)" %(mnl,1)
-        if type(Df) in (matrix, spmatrix):
-            if Df.typecode != 'd' or Df.size[0] != mnl:
+                "'d' matrix of size (%d, %d)" %(mnl, 1)
+
+        if type(Df) is matrix or type(Df) is spmatrix:
+            if customx: raise ValueError, "use of non-vector type for x "\
+                "requires function valued Df"
+            if Df.typecode != 'd' or Df.size != (mnl, c.size[0]):
                 raise TypeError, "second output argument of F() must "\
-                    "be a 'd' matrix with %d rows" %mnl
-            def fDf(u, v): 
-                base.gemv(Df, u, v, beta=1.0, trans='T')
+                    "be a 'd' matrix of size (%d,%d)" %(mnl, c.size[0])
+            def fDf(u, v, alpha = 1.0, beta = 0.0, trans = 'N'): 
+                base.gemv(Df, u, v, alpha = alpha, beta = beta, trans = 
+                    trans)
         else: 
+            if not customkkt:
+                raise ValueError, "use of function valued Df requires "\
+                    "a user-provided kktsolver"
             fDf = Df
 
-        gap = blas.dot(snl, znl) + blas.dot(sl, zl) 
-        mu = gap / (mnl + ml)
+        if refinement:
+            if type(H) is matrix or type(H) is spmatrix:
+                if customx: raise ValueError, "use of non-vector type "\
+                    "for  x requires function valued H"
+                if H.typecode != 'd' or H.size != (c.size[0], c.size[0]):
+                    raise TypeError, "third output argument of F() must "\
+                        "be a 'd' matrix of size (%d,%d)" \
+                        %(c.size[0], c.size[0])
+                def fH(u, v, alpha = 1.0, beta = 0.0): 
+                    base.symv(H, u, v, alpha = alpha, beta = beta)
+            else: 
+                if not customkkt:
+                    raise ValueError, "use of function valued H requires "\
+                        "a user-provided kktsolver"
+                fH = H
+           
+
+        gap = misc.sdot(s, z, mnl, dims) 
+        mu = gap / cdeg
 
-        # rx = c + A'*y + Df'*znl + G'*zl
+        # rx = c + A'*y + Df'*z[:mnl] + G'*z[mnl:]
         xcopy(c, rx) 
-        fA(y, rx, beta=1.0, trans='T')
-        fDf(znl, rx)
-        fG(zl, rx, beta=1.0, trans='T')
+        fA(y, rx, beta = 1.0, trans = 'T')
+        fDf(z[:mnl], rx, beta = 1.0, trans = 'T')
+        fG(z[mnl:], rx, beta = 1.0, trans = 'T')
         resx = math.sqrt(xdot(rx, rx))
            
         # ry = A*x - b
         ycopy(b, ry)
-        fA(x, ry, alpha=1.0, beta=-1.0)
+        fA(x, ry, alpha = 1.0, beta = -1.0)
         resy = math.sqrt(ydot(ry, ry))
 
-        # rznl = snl + f 
-        blas.copy(snl, rznl)
+        # rznl = s[:mnl] + f 
+        blas.copy(s[:mnl], rznl)
         blas.axpy(f, rznl)
         resznl = blas.nrm2(rznl)
 
-        # rzl = sl + G*x - h
-        blas.copy(sl, rzl)
-        blas.axpy(h, rzl, alpha=-1.0)
-        fG(x, rzl, beta=1.0)
-        reszl = blas.nrm2(rzl)
+        # rzl = s[mnl:] + G*x - h
+        blas.copy(s[mnl:], rzl)
+        blas.axpy(h, rzl, alpha = -1.0)
+        fG(x, rzl, beta = 1.0)
+        reszl = misc.snrm2(rzl, 0, dims)
 
         # pcost = c'*x
-        # dcost = c'*x + y'*(Ax-b) + znl'*f(x) + zl'*(G*x-h)
-        #       = c'*x + y'*(Ax-b) + znl'*(f(x)+snl) + zl'*(G*x-h+sl) 
-        #         - znl'*snl - zl'*sl
+        # dcost = c'*x + y'*(A*x-b) + znl'*f(x) + zl'*(G*x-h)
+        #       = c'*x + y'*(A*x-b) + znl'*(f(x)+snl) + zl'*(G*x-h+sl) 
+        #         - z'*s
+        #       = c'*x + y'*ry + znl'*rznl + zl'*rzl - gap
         pcost = xdot(c,x)
-        dcost = pcost + ydot(y, ry) + blas.dot(znl, rznl) + \
-            blas.dot(zl, rzl) - gap
+        dcost = pcost + ydot(y, ry) + blas.dot(z[:mnl], rznl) + \
+            misc.sdot(z[mnl:], rzl, 0, dims) - gap
 
         pres = math.sqrt( resy**2 + resznl**2 + reszl**2 )
         dres = resx
         if iters == 0: 
+            resx0 = max(1.0, resx)
+            resznl0 = max(1.0, resznl)
             pres0 = max(1.0, pres)
-            pres0_nl = max(1.0, resznl)
             dres0 = max(1.0, dres)
+            gap0 = gap
+            theta1 = 1.0 / gap0
+            theta2 = 1.0 / resx0
+            theta3 = 1.0 / resznl0
 
+        phi = theta1 * gap + theta2 * resx + theta3 * resznl
         if show_progress:
             print "%2d: % 8.4e % 8.4e % 4.0e% 7.0e% 7.0e" \
                 %(iters, pcost, dcost, gap, pres/pres0, dres/dres0) 
 
         # Stopping criteria.    
         if pres/pres0 <= FEASTOL and dres/dres0 <= FEASTOL and \
-            (gap <= ABSTOL or (dcost > 0 and gap/dcost <= RELTOL) or
-            (pcost < 0 and gap/(-pcost) <= RELTOL)):
-            return {'status': 'optimal', 'x': x,  'y': y, 'znl': znl,  
-                'zl': zl, 'snl': snl, 'sl': sl}
+            ( gap <= ABSTOL or (dcost > 0 and gap/dcost <= RELTOL) or
+            (pcost < 0 and gap/(-pcost) <= RELTOL) ):
+            sl, zl = s[mnl:], z[mnl:]
+            ind = dims['l'] + sum(dims['q'])
+            for m in dims['s']:
+                misc.symm(sl, m, ind)
+                misc.symm(zl, m, ind)
+                ind += m**2
+            return {'status': 'optimal', 'x': x,  'y': y, 'znl': z[:mnl],  
+                'zl': zl, 'snl': s[:mnl], 'sl': sl}
 
-        dnl, dl = sqrt(div(znl, snl)), sqrt(div(zl, sl)), 
-        g = kktsolver(x, znl, dnl, dl)
 
-        sigma = 0.0    
-        for i in [0,1]:
+        if iters == 0:
 
-            # Solve
+            # Compute initial scaling W:
+            # 
+            #     W * z = W^{-T} * s = lambda.
+
+            W = {}
+
+
+            # For the nonlinear and 'l' blocks: 
+            #
+            #     W['dnl'] = sqrt( s[:mnl] ./ z[:mnl] )
+            #     W['dnli'] = sqrt( z[:mnl] ./ s[:mnl] )
+            #     W['dl'] = sqrt( s[mnl:m] ./ z[mnl:m] )
+            #     W['dli'] = sqrt( z[mnl:m] ./ s[mnl:m] )
+            #     lambda[:m] = sqrt( s[:m] .* z[:m] )
+            # 
+            # where m = mnl + dims['l'].
+             
+            m = mnl + dims['l']
+            W['dnl'] = base.sqrt( base.div( s[:mnl], z[:mnl] ))
+            W['dnli'] = W['dnl']**-1
+            W['dl'] = base.sqrt( base.div( s[mnl:m], z[mnl:m] ))
+            W['dli'] = W['dl']**-1
+            lmbda[:m] = base.sqrt( base.mul( s[:m], z[:m] )) 
+
+
+            # For the 'q' blocks, compute lists 'v', 'beta' of the same
+            # length as dims['q'].
+            #
+            # The vector v[k] has unit hyperbolic norm: 
+            # 
+            #     (sqrt( v[k]' * J * v[k] ) = 1 with J = [1, 0; 0, -I]).
+            # 
+            # beta[k] is a positive scalar.
+            #
+            # The hyperbolic Householder matrix H = 2*v[k]*v[k]' - J
+            # defined by v[k] satisfies 
+            # 
+            #     (beta[k] * H) * zk  = (beta[k] * H) \ sk = lambda_k
+           
+            ind = mnl + dims['l']
+            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'])):
+                m = dims['q'][k]
+                v = W['v'][k]
+
+                # a = sqrt( sk' * J * sk )  where J = [1, 0; 0, -I]
+                aa = misc.jnrm2(s, offset = ind, n = m)
+
+                # b = sqrt( zk' * J * zk )
+                bb = misc.jnrm2(z, offset = ind, n = m) 
+
+                # beta[k] = ( a / b )**1/2
+                W['beta'][k] = math.sqrt( aa / bb )
+
+                # c = sqrt( (sk/a)' * (zk/b) + 1 ) / sqrt(2)    
+                cc = math.sqrt( ( blas.dot(s, z, n = m, offsetx = ind, 
+                    offsety = ind) / aa / bb + 1.0 ) / 2.0 )
+
+                # vk = 1/(2*c) * ( (sk/a) + J * (zk/b) )
+                blas.copy(z, v, offsetx = ind, n = m)
+                blas.scal(-1.0/bb, v)
+                v[0] *= -1.0 
+                blas.axpy(s, v, 1.0/aa, offsetx = ind, n = m)
+                blas.scal(1.0/2.0/cc, v)
+
+                # v[k] = 1/sqrt(2*(vk0 + 1)) * ( vk + e ),  e = [1; 0]
+                v[0] += 1.0
+                blas.scal(1.0/math.sqrt(2.0 * v[0]), v)
+            
+
+                # To get the scaled variable lambda_k
+                # 
+                #     d =  sk0/a + zk0/b + 2*c
+                #     lambda_k = [ c;  (c + zk0/b)/d * sk1/a + 
+                #         (c + sk0/a)/d * zk1/b ]
+                #     lambda_k *= sqrt(a * b)
+
+                lmbda[ind] = cc
+                dd = 2*cc + s[ind]/aa + z[ind]/bb
+                blas.copy(s, lmbda, offsetx = ind+1, offsety = ind+1,
+                    n = m-1) 
+                blas.scal((cc + z[ind]/bb)/dd/aa, lmbda, n = m-1, offset 
+                    = ind+1)
+                blas.axpy(z, lmbda, (cc + s[ind]/aa)/dd/bb, n = m-1, 
+                    offsetx = ind+1, offsety = ind+1)
+                blas.scal(math.sqrt(aa*bb), lmbda, offset = ind, n = m)
+
+                ind += m
+
+
+            # For the 's' blocks: compute two lists 'r' and 'rti' of 
+            # the same length as dims['s'].
             #
-            # [0 ]   [ hessian  A^T  [Df;G]' ]   [dx]
-            # [0 ] + [ A        0    0       ] * [dy] = -r  
-            # [ds]   [ [Df;G]   0    0       ]   [dz]
+            #     r[k]' * sk^{-1} * r[k] = diag(lambda_k)^{-1}
+            #     r[k]' * zk * r[k] = diag(lambda_k)
             #
-            # s.*dz + z.*ds = -s.*z + sigma*mu  
+            # where sk and zk are the corresponding blocks of s and z, 
+            # reshaped into symmetric matrices.
             #
-            # by solving
+            # rti[k] is the inverse of r[k]', so 
             #
-            # [ hessian   A^T   [Df;G]^T    ]   [dx]      
-            # [ A         0     0           ] * [dy] = rhs 
-            # [ [Df;G]    0     -diag(s./z) ]   [dz]     
-            #         
-            # with rhs = -r + (0,0,0, (s*z - sigma*mu)./z).
-            # Take  ds = -(s.*z - sigma*mu + s.*dz) ./ z.
-       
-            rcpnl = mul(snl, znl) - sigma*mu
-            rcpl = mul(sl, zl) - sigma*mu
-            xscal(0.0, dx);  xaxpy(rx, dx, alpha=-1.0)
-            yscal(0.0, dy);  yaxpy(ry, dy, alpha=-1.0)
-            dznl = -rznl + div(rcpnl, znl)
-            dzl = -rzl + div(rcpl, zl)
-            g(dx, dy, dznl, dzl)
-            dsnl = -div( rcpnl + mul(snl,dznl), znl ) 
-            dsl = -div( rcpl + mul(sl,dzl), zl ) 
-
-            # line search 
-            step = min( 1.0, STEP / max( list(-div(dsnl,snl)) + 
-                list(-div(dsl, sl)) + list(-div(dznl,znl)) 
-                + list(-div(dzl,zl))) )
-            rescpnl, rescpl = blas.nrm2(rcpnl), blas.nrm2(rcpl) 
-            aa, bb = max(rescpnl, rescpl), min(rescpnl, rescpl)
-            if aa: rescp = aa * math.sqrt( 1.0 + (bb/aa)**2 )
-            else: rescp = 0.0
-            phi = resx  + resznl + rescp
-
-            for lsiters in xrange(50):
+            #     rti[k]' * sk * rti[k] = diag(lambda_k)^{-1}
+            #     rti[k]' * zk^{-1} * rti[k] = diag(lambda_k).
+            #
+            # The vectors lambda_k are stored in 
+            # 
+            #     lmbda[ dims['l'] + sum(dims['q']) : -1 ]
+            
+            W['r'] = [ matrix(0.0, (m,m)) for m in dims['s'] ]
+            W['rti'] = [ matrix(0.0, (m,m)) for m in dims['s'] ]
+
+            ind2 = ind
+            for k in xrange(len(dims['s'])):
+                m = dims['s'][k]
+                r, rti = W['r'][k], W['rti'][k]
+
+                # Factor sk = L1*L1'; store L1 in block k of ds.
+                blas.copy(s, ds, offsetx = ind2, offsety = ind2, n = m**2) 
+                lapack.potrf(ds, n = m, ldA = m, offsetA = ind2)
+
+                # Factor zs[k] = L2*L2'; store L2 in block k of dz.
+                blas.copy(z, dz, offsetx = ind2, offsety = ind2, n = m**2) 
+                lapack.potrf(dz, n = m, ldA = m, offsetA = ind2)
+	 
+                # SVD L2'*L1 = U*diag(lambda_k)*V'.  Keep U in work. 
+                for i in xrange(m): 
+                    blas.scal(0.0, ds, offset = ind2 + i*m, n = i)
+                blas.copy(ds, work, offsetx = ind2, n = m**2)
+                blas.trmm(dz, work, transA = 'T', ldA = m, ldB = m, n = m,
+                    m = m, offsetA = ind2)
+                lapack.gesvd(work, lmbda, jobu = 'O', ldA = m, m = m, 
+                    n = m, offsetS = ind)
+	       
+                # r = L2^{-T} * U 
+                blas.copy(work, r, n = m*m)
+                blas.trsm(dz, r, transA = 'T', m = m, n = m, ldA = m,
+                    offsetA = ind2)
+
+                # rti = L2 * U 
+                blas.copy(work, rti, n = m*m)
+                blas.trmm(dz, rti, m = m, n = m, ldA = m, offsetA = ind2)
+
+                # r := r * diag(sqrt(lambda_k))
+                # rti := rti * diag(1 ./ sqrt(lambda_k))
+                for i in xrange(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)
+
+                ind += m
+                ind2 += m*m
+
+
+        # lmbdasq = lambda o lambda 
+        blas.copy(lmbda, lmbdasq)
+        blas.tbmv(lmbda, lmbdasq, n = mnl + dims['l'], k = 0, ldA = 1) 
+        ind = mnl + dims['l']
+        for m in dims['q']:
+            lmbdasq[ind] = blas.nrm2(lmbda, offset = ind, n = m)**2
+            blas.scal(2.0*lmbda[ind], lmbdasq, n = m-1, offset = ind+1)
+            ind += m
+        # Diagonal symmetric matrices are stored as vectors in lmbdasq.
+        blas.tbmv(lmbda, lmbdasq, n = sum(dims['s']), k = 0, ldA = 1, 
+            offsetA = ind, offsetx = ind) 
+
+
+        # Define a function solvenewton(dx, dy, dz, ds) for solving
+        # 
+        #     [ 0  ]   [ H   A'  GG' ]   [ dx ]   [ rhsx ]
+        #     [ 0  ] + [ A   0   0   ] * [ dy ] = [ rhsy ]
+        #     [ ds ]   [ GG  0   0   ]   [ dz ]   [ rhsz ]
+        #
+        #     s o dz + z o ds = rhss
+        #
+        # where GG = [ Df(x); G ].
+        #
+        # The last equation in scaled variables:
+        #
+        #     lmbda o (W*dz + W^{-T}*ds) = rhss.
+
+        try: g = kktsolver(x, z[:mnl], W)
+        except ArithmeticError: 
+            if iters == 0:
+                raise ValueError, "Rank(A) < p or "\
+                    "Rank([H(x); A; Df(x); G]) < n"
+
+            elif 0 < relaxed_iters < MAX_RELAXED_ITERS > 0:
+                # The arithmetic error may be caused by a relaxed line 
+                # search in the previous iteration.  Therefore we restore 
+                # the last saved state and require a standard line search. 
+                phi, gap = phi0, gap0
+                mu = gap / cdeg
+                blas.copy(W0['dnl'], W['dnl'])
+                blas.copy(W0['dnli'], W['dnli'])
+                blas.copy(W0['dl'], W['dl'])
+                blas.copy(W0['dli'], W['dli'])
+                for k in xrange(len(dims['q'])):
+                    blas.copy(W0['v'][k], W['v'][k])
+                    W['beta'][k] = W0['beta'][k]
+                for k in xrange(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);
+                ycopy(y0, y); ycopy(dy0, dy);
+                blas.copy(s0, s); blas.copy(z0, z)
+                blas.copy(lmbda0, lmbda)
+                blas.copy(lmbdasq, lmbdasq0)
+                xcopy(rx0, rx); ycopy(ry0, ry)
+                resx = math.sqrt(xdot(rx, rx))
+                blas.copy(rznl0, rznl);  blas.copy(rzl0, rzl);
+                resznl = blas.nrm2(rznl)
+
+                relaxed_iters = -1
+
+                try: g = kktsolver(x, z[:mnl], W)
+                except ArithmeticError: 
+                    raise ArithmeticError, "singular KKT matrix"
+
+            else:  
+                raise ArithmeticError, "singular KKT matrix"
+
+        def solve_newton1(dx, dy, dz, ds):
+
+            # Solve without refinement
+            #        
+            #     [ 0  ]   [ H   A'  GG' ]   [ dx ]   [ rhsx ]
+            #     [ 0  ] + [ A   0   0   ] * [ dy ] = [ rhsy ]
+            #     [ ds ]   [ GG  0   0   ]   [ dz ]   [ rhsz ]
+            #
+            #     lmbda o (W*dz + W^{-T}*ds) = rhss.
+            #
+            # On entry, the righthand sides are stored in dx, dy, dz.  
+            # On exit, scaled quantities are returned for ds and dz.
+
+
+            # Solve 
+            #
+            #     [ H  A' GG'   ]   [ dx ]   [ rhsx                      ]
+            #     [ A  0  0     ] * [ dy ] = [ rhsy                      ]
+            #     [ GG 0  -W'*W ]   [ dz ]   [ rhsz - W'*(lmbda o\ rhss) ]
+            #
+            #     ds = W' * (lmbda o\ rhss - W*dz).
+            
+            # ds := lmbda o\ ds = lmbda o\ rhss
+            misc.sinv(ds, lmbda, mnl, dims)
+
+            # dz := dz - W'*ds = rhsz - W' * (lambda o\ rhss)
+            ds1 = +ds 
+            misc.scale(ds1, W, trans = 'T')
+            blas.axpy(ds1, dz, alpha = -1.0)
+
+            g(dx, dy, dz)
+
+            # ds := ds - dz = lambda o\ rhss - dz.
+            blas.axpy(dz, ds, alpha = -1.0)
+
+
+        if refinement:
+            def solve_newton(dx, dy, dz, ds):
+                
+                # Copy righthand sides to dx2, dy2, ds2, dz2.
+                xcopy(dx, dx2)
+                ycopy(dy, dy2)
+                blas.copy(ds, ds2)
+                blas.copy(dz, dz2)
+
+                solve_newton1(dx, dy, dz, ds)
+
+                # Store residuals in dx2, dy2, dz2, ds2
+                #        
+                #     [ 0  ]   [ H   A'  GG' ]   [ dx ]   [ rhsx ]
+                #     [ 0  ] + [ A   0   0   ] * [ dy ] = [ rhsy ]
+                #     [ ds ]   [ GG  0   0   ]   [ dz ]   [ rhsz ]
+                #
+                #     s o dz + z o ds = rhss
+                #                
+                # Last equation in scaled variables:
+                #
+                #     lmbda o (W*dz + W^{-T}*ds) = rhss.
                 
-                xcopy(x, newx);  xaxpy(dx, newx, alpha=step)
-                ycopy(y, newy);  yaxpy(dy, newy, alpha=step)
-                newznl, newzl = znl + step*dznl, zl+step*dzl
-                newsnl, newsl = snl + step*dsnl, sl+step*dsl
-                newgap = blas.dot(newsnl, newznl) + \
-                    blas.dot(newsl, newzl)
+                # Store unscaled steps in dus, duz
+                blas.copy(dz, duz)
+                misc.scale(duz, W, inverse = 'I')
+                blas.copy(ds, dus)
+                misc.scale(dus, W, trans = 'T')
+
+                # Store rhs minus lhs in in dx2, dy2, ds2, dz2.
+                fH(dx, dx2, alpha = -1.0, beta = 1.0)
+                fA(dy, dx2, alpha = -1.0, beta = 1.0, trans = 'T') 
+                fDf(duz[:mnl], dx2, alpha = -1.0, beta = 1.0, trans = 'T')
+                fG(duz[mnl:], dx2, alpha = -1.0, beta = 1.0, trans = 'T') 
+
+                fA(dx, dy2, alpha = -1.0, beta = 1.0)
+
+                fDf(dx, dz2nl)
+                blas.axpy(dz2nl, dz2, alpha = -1.0)
+                fG(dx, dz2l)
+                blas.axpy(dz2l, dz2, alpha = -1.0, offsety = mnl)
+                blas.axpy(dus, dz2, alpha = -1.0)
+ 
+                # dus := lmbda o (W*dz + W^{-T}*ds)
+                blas.copy(ds, dus)
+                blas.axpy(dz, dus)
+                misc.sprod(dus, lmbda, mnl, dims, diag = 'D')
+                blas.axpy(dus, ds2, alpha = -1.0)
+            
+                solve_newton1(dx2, dy2, dz2, ds2)
+
+                xaxpy(dx2, dx, alpha = -1.0)
+                yaxpy(dy2, dy, alpha = -1.0)
+                blas.axpy(dz2, dz, alpha = -1.0)
+                blas.axpy(ds2, ds, alpha = -1.0)
+
+        else:
+            solve_newton = solve_newton1
+
+        sigma, eta = 0.0, 0.0
+        for i in [0, 1]:
+
+            # Solve
+            #
+            #     [ 0  ]   [ H   A'  GG' ]   [ dx ]
+            #     [ 0  ] + [ A   0   0   ] * [ dy ] = -(1 - eta) * r  
+            #     [ ds ]   [ GG  0   0   ]   [ dz ]
+            #
+            #     lmbda o (W*dz + W^{-T}*ds) = -lmbda o lmbda + sigma*mu*e.
+            #
+            # Compute scaled variables W*dz, W^{-T}*ds instead of dz, ds.
+
+            # ds = -lmbdasq + sigma * mu * e  
+            blas.scal(0.0, ds)
+            blas.axpy(lmbdasq, ds, n = mnl + dims['l'] + sum(dims['q']), 
+                alpha = -1.0)
+            ds[:mnl + dims['l']] += sigma*mu
+            ind = mnl + dims['l']
+            for m in dims['q']:
+                ds[ind] += sigma*mu
+                ind += m
+            ind2 = ind
+            for m in dims['s']:
+                blas.axpy(lmbdasq, ds, n = m, offsetx = ind2, offsety =  
+                    ind, incy = m + 1, alpha = -1.0)
+                ds[ind : ind + m*m : m+1] += sigma*mu
+                ind += m*m
+                ind2 += m
+       
+            # (dx, dy, dz) := -(1-eta) * (rx, ry, rz)
+            xscal(0.0, dx);  xaxpy(rx, dx, alpha = -1.0 + eta)
+            yscal(0.0, dy);  yaxpy(ry, dy, alpha = -1.0 + eta)
+            blas.scal(0.0, dz) 
+            blas.axpy(rznl, dz, alpha = -1.0 + eta)
+            blas.axpy(rzl, dz, alpha = -1.0 + eta, offsety = mnl)
+            
+            try: solve_newton(dx, dy, dz, ds)
+            except ArithmeticError: 
+                if iters == 0:
+                    raise ValueError, "Rank(A) < p or "\
+                        "Rank([H(x); A; Df(x); G]) < n"
+                else:
+                    raise ArithmeticError, "singular KKT matrix"
+
+            # Inner product ds'*dz and unscaled steps are needed in the 
+            # line search.
+            dsdz = misc.sdot(ds, dz, mnl, dims)
+            blas.copy(dz, dz2)
+            misc.scale(dz2, W, inverse = 'I')
+            blas.copy(ds, ds2)
+            misc.scale(ds2, W, trans = 'T')
+
+            # Maximum steps to boundary.  (This scales ds and dz.) 
+            misc.scale2(lmbda, ds, mnl, dims)
+            ts = misc.max_step(ds, mnl, dims, sigs)
+            misc.scale2(lmbda, dz, mnl, dims)
+            tz = misc.max_step(dz, mnl, dims, sigz)
+            t = max([ 0.0, ts, tz ])
+            if t == 0:
+                step = 1.0
+            else:
+                step = min(1.0, STEP / t)
+
+            # Backtrack until newx is in domain of f.
+            backtrack = True
+            while backtrack:
+                xcopy(x, newx);  xaxpy(dx, newx, alpha = step)
                 t = F(newx)
                 if t is None: newf = None
                 else: newf, newDf = t[0], t[1]
-
                 if newf is not None:
-                    newf = matrix(newf, tc='d')
-                    if type(newDf) in (matrix, spmatrix):
-                        def fDf(u, v):
-                            base.gemv(newDf, u, v, beta=1.0, trans='T')
-                    else: 
-                        fDf = newDf
-
-                    # rx2 = c + A'*newy + newDf'*newznl + G'*newzl
-                    xcopy(c, rx2) 
-                    fA(newy, rx2, beta=1.0, trans='T')
-                    fDf(newznl, rx2)
-                    fG(newzl, rx2, beta=1.0, trans='T')
-                    resx2 = math.sqrt(xdot(rx2, rx2))
-
-                    # rznl2 = newsnl + newf
-                    blas.copy(newsnl, rznl2)
-                    blas.axpy(newf, rznl2)
-                    resznl2 = blas.nrm2(rznl2)
-
-                    # rcpnl = newsnl .* newznl
-                    # rcpl = newsl .* newzl
-                    rcpnl = mul(newsnl, newznl)
-                    rcpl = mul(newsl, newzl)
-                    rescpnl = blas.nrm2(rcpnl - sigma*mu)
-                    rescpl = blas.nrm2(rcpl - sigma*mu)
-                    aa, bb = max(rescpnl, rescpl), min(rescpnl, rescpl)
-                    if aa: rescp = aa * math.sqrt( 1.0 + (bb/aa)**2 )
-                    else: rescp = 0.0
-
-                    newphi = resx2  + resznl2 + rescp
-                    newmu = newgap / (mnl+ml)
-
-                    if resx2 <= GAMMA1 * dres0 * newgap and \
-                        resznl2 <= GAMMA1 * pres0_nl * newgap and \
-                        (not rcpnl or min(rcpnl) >= GAMMA2*newmu) \
-                        and (not rcpl or min(rcpl) >= GAMMA2*newmu) \
-                        and newphi <= (1.0 - ALPHA*step) * phi: 
-                        break
-                
-                step *= BETA
+                    backtrack = False
+                else:
+                    step *= BETA
 
-            else: raise StandardError, "line search did not terminate"
 
-            if i == 0:  sigma = min(GAMMA3*newmu/mu, (newmu/mu)**GAMMA4)
+            # Merit function 
+            #
+            #     phi = theta1 * gap + theta2 * norm(rx) + 
+            #         theta3 * norm(rznl)
+            #
+            # and its directional derivative dphi.
+
+            phi = theta1 * gap + theta2 * resx + theta3 * resznl
+            if i == 0:
+                dphi = -phi 
+            else:
+                dphi = -theta1 * (1 - sigma) * gap -  \
+                    theta2 * (1 - eta) * resx - \
+                    theta3 * (1 - eta) * resznl  
+
 
-        xaxpy(dx, x, alpha=step)
-        yaxpy(dy, y, alpha=step)
-        blas.axpy(dznl, znl, alpha=step)
-        blas.axpy(dzl, zl, alpha=step)
-        blas.axpy(dsnl, snl, alpha=step)
-        blas.axpy(dsl, sl, alpha=step)
+            # Line search.
+            #
+            # We use two types of line search.  In a standard iteration we
+            # use is a normal backtracking line search terminating with a 
+            # sufficient decrease of phi.  In a "relaxed" iteration the 
+            # line search is terminated after one step, regardless of the 
+            # value of phi.  We make at most MAX_RELAXED_ITERS consecutive
+            # relaxed iterations.  When starting a series of relaxed 
+            # iteration, we save the state at the end of the first line 
+            # search in the series (scaling, primal and dual iterates, 
+            # steps, sigma, eta, i.e., all information needed to resume 
+            # the line search at some later point).  If a series of
+            # MAX_RELAXED_ITERS relaxed iterations does not result in a 
+            # sufficient decrease compared to the value of phi at the start
+            # of the series, then we resume the first line search in the 
+            # series as a standard line search (using the saved state).
+            # On the other hand, if at some point during the series of 
+            # relaxed iterations we obtain a sufficient decrease of phi 
+            # compared with the value at the start of the series, then we 
+            # start a new series of relaxed line searches. 
+            #  
+            # To implement this we use a counter relaxed_iters.
+            #
+            # 1. If 0 <= relaxed_iters < MAX_RELAXED_ITERS, we use a 
+            #    relaxed line search (one full step).  If relaxed_iters 
+            #    is 0, we save the value phi0 of the merit function at the
+            #    current point, as well as the state at the end of the 
+            #    line search.  If the relaxed line search results in a 
+            #    sufficient decrease w.r.t. phi0, we reset relaxed_iters 
+            #    to 0.  Otherwise we increment relaxed_iters.
+            #
+            # 2. If relaxed_iters is MAX_RELAXED_ITERS, we use a standard
+            #    line search.  If this results in a sufficient decrease 
+            #    of the merit function compared with phi0, we set 
+            #    relaxed_iters to 0.  If phi decreased compared with phi0,
+            #    but not sufficiently, we set relaxed_iters to -1.  
+            #    If phi increased compared with phi0, we resume the 
+            #    backtracking at the last saved iteration, and after 
+            #    completing the line search, set relaxed_iters to 0.
+            # 
+            # 3. If relaxed_iters is -1, we use a standard line search
+            #    and increment relaxed_iters to 0. 
+
+
+            backtrack = True
+            while backtrack:
+                xcopy(x, newx);  xaxpy(dx, newx, alpha = step)
+                ycopy(y, newy);  yaxpy(dy, newy, alpha = step)
+                blas.copy(z, newz);  blas.axpy(dz2, newz, alpha = step) 
+                blas.copy(s, news);  blas.axpy(ds2, news, alpha = step) 
+
+                t = F(newx)
+                newf, newDf = matrix(t[0], tc = 'd'), t[1]
+                if type(newDf) is matrix or type(Df) is spmatrix:
+                    if newDf.typecode != 'd' or \
+                        newDf.size != (mnl, c.size[0]):
+                            raise TypeError, "second output argument "\
+                                "of F() must be a 'd' matrix of size "\
+                                "(%d,%d)" %(mnl, c.size[0])
+                    def newfDf(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
+                        base.gemv(newDf, u, v, alpha = alpha, beta = 
+                                beta, trans = trans)
+                else: 
+                    newfDf = newDf
+
+                # newrx = c + A'*newy + newDf'*newz[:mnl] + G'*newz[mnl:]
+                xcopy(c, newrx) 
+                fA(newy, newrx, beta = 1.0, trans = 'T')
+                newfDf(newz[:mnl], newrx, beta = 1.0, trans = 'T')
+                fG(newz[mnl:], newrx, beta = 1.0, trans = 'T')
+                newresx = math.sqrt(xdot(newrx, newrx))
+           
+                # newrznl = news[:mnl] + newf 
+                blas.copy(news[:mnl], newrznl)
+                blas.axpy(newf, newrznl)
+                newresznl = blas.nrm2(newrznl)
+
+                newgap = (1.0 - (1.0 - sigma) * step) * gap \
+                    + step**2 * dsdz
+                newphi = theta1 * newgap  + theta2 * newresx + \
+                    theta3 * newresznl
+
+                if i == 0:
+                    if newgap <= (1.0 - ALPHA * step) * gap and \
+                        ( 0 <= relaxed_iters < MAX_RELAXED_ITERS or \
+                        newphi <= phi + ALPHA * step * dphi ):
+                        backtrack = False
+                        sigma = min(newgap/gap, (newgap/gap) ** EXPON)
+                        eta = 0.0 
+                    else:
+                        step *= BETA
+
+                else:
+                    if relaxed_iters == -1 or ( relaxed_iters == 0 == 
+                        MAX_RELAXED_ITERS ):
+                        # Do a standard line search.
+                        if newphi <= phi + ALPHA * step * dphi:
+                            relaxed_iters == 0
+                            backtrack = False
+                        else:
+                            step *= BETA
+
+                    elif relaxed_iters == 0 < MAX_RELAXED_ITERS:
+                        if newphi <= phi + ALPHA * step * dphi:
+                            # Relaxed l.s. gives sufficient decrease.
+                            relaxed_iters = 0
+
+                        else:
+                            # Save state.
+                            phi0, dphi0, gap0 = phi, dphi, gap
+                            step0 = step
+                            blas.copy(W['dnl'], W0['dnl'])
+                            blas.copy(W['dnli'], W0['dnli'])
+                            blas.copy(W['dl'], W0['dl'])
+                            blas.copy(W['dli'], W0['dli'])
+                            for k in xrange(len(dims['q'])):
+                                blas.copy(W['v'][k], W0['v'][k])
+                                W0['beta'][k] = W['beta'][k]
+                            for k in xrange(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)
+                            ycopy(y, y0); ycopy(dy, dy0)
+                            blas.copy(s, s0); blas.copy(z, z0)
+                            blas.copy(ds, ds0)
+                            blas.copy(dz, dz0)
+                            blas.copy(ds2, ds20)
+                            blas.copy(dz2, dz20)
+                            blas.copy(lmbda, lmbda0)
+                            blas.copy(lmbdasq, lmbdasq0)
+                            dsdz0 = dsdz
+                            sigma0, eta0 = sigma, eta
+                            xcopy(rx, rx0);  ycopy(ry, ry0)
+                            blas.copy(rznl, rznl0); blas.copy(rzl, rzl0)
+                            relaxed_iters = 1
+
+                        backtrack = False
+
+                    elif 0 <= relaxed_iters < MAX_RELAXED_ITERS > 0:
+                        if newphi <= phi0 + ALPHA * step0 * dphi0:
+                            # Relaxed l.s. gives sufficient decrease.
+                            relaxed_iters = 0
+
+                        else: 
+                            # Relaxed line search 
+                            relaxed_iters += 1
+
+                        backtrack = False
+
+                    elif relaxed_iters == MAX_RELAXED_ITERS > 0:
+                        if newphi <= phi0 + ALPHA * step0 * dphi0:
+                            # Series of relaxed line searches ends 
+                            # with sufficient decrease w.r.t. phi0.
+                            backtrack = False
+                            relaxed_iters = 0
+
+                        elif newphi >= phi0:
+                            # Resume last saved line search.
+                            phi, dphi, gap = phi0, dphi0, gap0
+                            step = step0
+                            blas.copy(W0['dnl'], W['dnl'])
+                            blas.copy(W0['dnli'], W['dnli'])
+                            blas.copy(W0['dl'], W['dl'])
+                            blas.copy(W0['dli'], W['dli'])
+                            for k in xrange(len(dims['q'])):
+                                blas.copy(W0['v'][k], W['v'][k])
+                                W['beta'][k] = W0['beta'][k]
+                            for k in xrange(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);
+                            ycopy(y0, y); ycopy(dy0, dy);
+                            blas.copy(s0, s); blas.copy(z0, z)
+                            blas.copy(ds0, ds)
+                            blas.copy(dz0, dz)
+                            blas.copy(ds20, ds2)
+                            blas.copy(dz20, dz2)
+                            blas.copy(lmbda0, lmbda)
+                            dsdz = dsdz0
+                            sigma, eta = sigma0, eta0
+                            relaxed_iters = -1
+
+                        elif newphi <= phi + ALPHA * step * dphi:
+                            # Series of relaxed line searches ends with
+                            # with insufficient decrease w.r.t. phi0" 
+                            backtrack = False
+                            relaxed_iters = -1
+
+
+        # ds := e + step*ds for nonlinear, 'l' and 'q' blocks.
+        # dz := e + step*dz for nonlinear, 'l' and 'q' blocks.
+        blas.scal(step, ds, n = mnl + dims['l'] + sum(dims['q']))
+        blas.scal(step, dz, n = mnl + dims['l'] + sum(dims['q']))
+        ind = mnl + dims['l']
+        ds[:ind] += 1.0
+        dz[:ind] += 1.0
+        for m in dims['q']:
+            ds[ind] += 1.0
+            dz[ind] += 1.0
+            ind += m
+
+        # sigs := e + step*sigs for 's' blocks.
+        blas.scal(step, sigs)
+        sigs += 1.0
+
+        # sigz := e + step*sigz for 's' blocks.
+        blas.scal(step, sigz)
+        sigz += 1.0
+
+        # ds := H(lambda)^{-1/2} * ds and dz := H(lambda)^{-1/2} * dz.
+        misc.scale2(lmbda, ds, mnl, dims, inverse = 'I')
+        misc.scale2(lmbda, dz, mnl, dims, inverse = 'I')
+
+        # The nonlinear, 'l' and 'q' components of ds and dz now contain 
+        # the updated variables in the current scaling.  The 's' 
+        # components of ds and dz contain 
+        #
+        #     Lambda^1/2 * Qs * Lambda^1/2
+        #     Lambda^1/2 * Qz * Lambda^1/2
+        #
+        # where Lambda^1/2 * (Qs * diag(sigs) * Qs') * Lambda^1/2 and 
+        # Lambda^1/2 * (Qz * diag(sigs) * Qz') * Lambda^1/2 are the 
+        # updated variablaes in the current scaling.
+
+
+        # Update lambda and scaling.
+
+        # Nonlinear and 'l' blocks
+        #
+        #    d :=  d .* sqrt( ds ./ dz )
+        #    lmbda := lmbda .* sqrt(ds) .* sqrt(dz)
+
+        m = mnl + dims['l']
+        ds[:m] = base.sqrt( ds[:m] )
+        dz[:m] = base.sqrt( dz[:m] )
+ 
+        # d := d .* ds .* dz 
+        blas.tbmv(ds, W['dnl'], n = mnl, k = 0, ldA = 1)
+        blas.tbsv(dz, W['dnl'], n = mnl, k = 0, ldA = 1)
+        W['dnli'][:] = W['dnl'] ** -1
+        blas.tbmv(ds, W['dl'], n = dims['l'], k = 0, ldA = 1, offsetA 
+            = mnl)
+        blas.tbsv(dz, W['dl'], n = dims['l'], k = 0, ldA = 1, offsetA 
+            = mnl)
+        W['dli'][:] = W['dl'] ** -1
+
+        # lmbda := ds .* dz
+        blas.copy(ds, lmbda, n = m)
+        blas.tbmv(dz, lmbda, n = m, k = 0, ldA = 1)
+
+
+        # 'q' blocks.
+        # 
+        # Let st and zt be the new variables in the old scaling:
+        #
+        #     st = ds_k,   zt = dz_k
+        #
+        # and a = sqrt(st' * J * st),  b = sqrt(zt' * J * zt).
+        #
+        # 1. Compute the hyperbolic Householder transformation 2*q*q' - J 
+        #    that maps st/a to zt/b.
+        # 
+        #        c = sqrt( (1 + st'*zt/(a*b)) / 2 ) 
+        #        q = (st/a + J*zt/b) / (2*c). 
+        #
+        #    The new scaling point is 
+        #
+        #        wk := betak * sqrt(a/b) * (2*v[k]*v[k]' - J) * q 
+        #
+        #    with betak = W['beta'][k].
+        # 
+        # 3. The scaled variable:
+        #
+        #        lambda_k0 = sqrt(a*b) * c
+        #        lambda_k1 = sqrt(a*b) * ( (2vk*vk' - J) * (-d*q + u/2) )_1
+        #
+        #    where 
+        #
+        #        u = st/a - J*zt/b 
+        #        d = ( vk0 * (vk'*u) + u0/2 ) / (2*vk0 *(vk'*q) - q0 + 1).
+        #
+        # 4. Update scaling
+        #   
+        #        v[k] := wk^1/2 
+        #              = 1 / sqrt(2*(wk0 + 1)) * (wk + e).
+        #        beta[k] *=  sqrt(a/b)
+
+
+        ind = mnl + dims['l']
+        for k in xrange(len(dims['q'])):
+
+            m = dims['q'][k]
+            v = W['v'][k]
+
+            # ln = sqrt( lambda_k' * J * lambda_k )
+            ln = misc.jnrm2(lmbda, n = m, offset = ind) 
+
+            # a = sqrt( dsk' * J * dsk ) = sqrt( st' * J * st ) 
+            # ds := ds / a = st / a
+            aa = misc.jnrm2(ds, offset = ind, n = m)
+            blas.scal(1.0/aa, ds, offset = ind, n = m)
+
+            # b = sqrt( dzk' * J * dzk ) = sqrt( zt' * J * zt )
+            # dz := dz / a = zt / b
+            bb = misc.jnrm2(dz, offset = ind, n = m) 
+            blas.scal(1.0/bb, dz, offset = ind, n = m)
+
+            # c = sqrt( ( 1 + (st'*zt) / (a*b) ) / 2 )
+            cc = math.sqrt( ( 1.0 + blas.dot(ds, dz, offsetx = ind,
+                offsety = ind, n = m) ) / 2.0 )
+
+            # vs = v' * st / a 
+            vs = blas.dot(v, ds, offsety = ind, n = m) 
+
+            # vz = v' * J *zt / b
+            vz = misc.jdot(v, dz, offsety = ind, n = m) 
+
+            # vq = v' * q where q = (st/a + J * zt/b) / (2 * c)
+            vq = (vs + vz ) / 2.0 / cc
+
+            # vu = v' * u  where u =  st/a - J * zt/b 
+            vu = vs - vz  
+
+            # lambda_k0 = c
+            lmbda[ind] = cc
+
+            # wk0 = 2 * vk0 * (vk' * q) - q0 
+            wk0 = 2 * v[0] * vq - ( ds[ind] + dz[ind] ) / 2.0 / cc 
+
+            # d = (v[0] * (vk' * u) - u0/2) / (wk0 + 1)
+            dd = (v[0] * vu - ds[ind]/2.0 + dz[ind]/2.0) / (wk0 + 1.0)
+
+            # lambda_k1 = 2 * v_k1 * vk' * (-d*q + u/2) - d*q1 + u1/2
+            blas.copy(v, lmbda, offsetx = 1, offsety = ind+1, n = m-1)
+            blas.scal(2.0 * (-dd * vq + 0.5 * vu), lmbda, offset = ind+1, 
+                n = m-1)
+            blas.axpy(ds, lmbda, 0.5 * (1.0 - dd/cc), offsetx = ind+1,
+                offsety = ind+1, n = m-1)
+            blas.axpy(dz, lmbda, 0.5 * (1.0 + dd/cc), offsetx = ind+1,
+                offsety = ind+1, n = m-1)
+
+            # Scale so that sqrt(lambda_k' * J * lambda_k) = sqrt(aa*bb).
+            blas.scal(math.sqrt(aa*bb), lmbda, offset = ind, n = m)
+            
+            # v := (2*v*v' - J) * q 
+            #    = 2 * (v'*q) * v' - (J* st/a + zt/b) / (2*c)
+            blas.scal(2.0 * vq, v)
+            v[0] -= ds[ind] / 2.0 / cc
+            blas.axpy(ds, v,  0.5/cc, offsetx = ind+1, offsety = 1,
+                n = m-1)
+            blas.axpy(dz, v, -0.5/cc, offsetx = ind, n = m)
+
+            # v := v^{1/2} = 1/sqrt(2 * (v0 + 1)) * (v + e)
+            v[0] += 1.0
+            blas.scal(1.0 / math.sqrt(2.0 * v[0]), v)
+
+            # beta[k] *= ( aa / bb )**1/2
+            W['beta'][k] *= math.sqrt( aa / bb )
+            
+            ind += m
+
+
+        # 's' blocks
+        # 
+        # Let st, zt be the updated variables in the old scaling:
+        # 
+        #     st = ds * diag(sigs ./ lambda) * ds'
+        #     zt = dz * diag(sigs ./ lambda) * dz'.
+        #
+        # 1.  Compute 
+        #
+        #         L1 = dsk * diag(sigs_k ./ lambda_k)^{1/2}
+        #         L2 = dzk * diag(sigz_k ./ lambda_k)^{1/2}.
+        #
+        #     We have 
+        #
+        #         L1 * L1' = st,  L2 * L2' = zt.
+        #
+        # 2.  SVD L2'*L1 = Uk * lambda_k^+ * Vk'.
+        #
+        # 3.  New scaling is 
+        #
+        #         r[k] := r[k] * L1 * Vk * diag(lambda_k^+)^{-1/2}
+        #         rti[k] := r[k] * L2 * Uk * diag(lambda_k^+)^{-1/2}.
+
+        ind = mnl + dims['l'] + sum(dims['q'])
+        ind2, ind3 = ind, 0
+
+        # sigs := sigs./lambda.  sigz := sigz./lambda.
+        blas.tbsv(lmbda, sigs, n = sum(dims['s']), k = 0, ldA = 1, 
+            offsetA = ind)
+        blas.tbsv(lmbda, sigz, n = sum(dims['s']), k = 0, ldA = 1, 
+            offsetA = ind)
+
+        for k in xrange(len(dims['s'])):
+            m = dims['s'][k]
+            r, rti = W['r'][k], W['rti'][k]
+
+            # dsk := L1 = dsk * sqrt(sigs).  dzk := L2 = dzk * sqrt(sigz).
+            for i in xrange(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,
+                    n = m)
+
+            # r := r*dsk = r*L1
+            blas.gemm(r, ds, work, m = m, n = m, k = m, ldB = m, ldC = m,
+                offsetB = ind2)
+            blas.copy(work, r, n = m**2)
+
+            # rti := rti*dzk = rti*L2
+            blas.gemm(rti, dz, work, m = m, n = m, k = m, ldB = m, ldC = m,
+                offsetB = ind2)
+            blas.copy(work, rti, n = m**2)
+
+            # SVD L2'*L1 = U * lmbds^+ * V'; store U in dsk and V' in dzk.
+            blas.gemm(dz, ds, work, transA = 'T', m = m, n = m, k = m,
+                ldA = m, ldB = m, ldC = m, offsetA = ind2, offsetB = ind2)
+            lapack.gesvd(work, lmbda, jobu = 'A', jobvt = 'A', m = m,
+                n = m, ldA = m, U = ds, Vt = dz, ldU = m, ldVt = m,
+                offsetS = ind, offsetU = ind2, offsetVt = ind2)
+
+            # r := r*V
+            blas.gemm(r, dz, work, transB = 'T', m = m, n = m, k = m, 
+                ldB = m, ldC = m, offsetB = ind2)
+            blas.copy(work, r, n = m**2)
+
+            # rti := rti*U
+            blas.gemm(rti, ds, work, n = m, m = m, k = m, ldB = m, ldC = m,
+                offsetB = ind2)
+            blas.copy(work, rti, n = m**2)
+
+            # r := r*lambda^{-1/2}; rti := rti*lambda^{-1/2}
+            for i in xrange(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)
+
+            ind += m
+            ind2 += m*m
+            ind3 += m
+
+        xaxpy(dx, x, alpha = step)
+        yaxpy(dy, y, alpha = step)
+
+
+        # Unscale s, z (unscaled variables are used only to compute 
+        # feasibility residuals).
+
+        blas.copy(lmbda, s, n = mnl + dims['l'] + sum(dims['q']))
+        ind = mnl + dims['l'] + sum(dims['q'])
+        ind2 = ind
+        for m in dims['s']:
+            blas.scal(0.0, s, offset = ind2)
+            blas.copy(lmbda, s, offsetx = ind, offsety = ind2, n = m, 
+                incy = m+1)
+            ind += m
+            ind2 += m*m
+        misc.scale(s, W, trans = 'T')
+
+        blas.copy(lmbda, z, n = mnl + dims['l'] + sum(dims['q']))
+        ind = mnl + dims['l'] + sum(dims['q'])
+        ind2 = ind
+        for m in dims['s']:
+            blas.scal(0.0, z, offset = ind2)
+            blas.copy(lmbda, z, offsetx = ind, offsety = ind2, n = m, 
+                incy = m+1)
+            ind += m
+            ind2 += m*m
+        misc.scale(z, W, inverse = 'I')
+
+        gap = blas.dot(lmbda, lmbda, n = cdeg) 
 
     return {'status': 'unknown', 'x': None,  'y': None, 'znl': None, 
         'zl': None, 'snl': None, 'sl': None}
 
 
-
-def nlcp(kktsolver, F, G=None, h=None, A=None, b=None,
-    xnewcopy=matrix, xdot=blas.dot, xaxpy=blas.axpy, xscal=blas.scal,
-    ynewcopy=matrix, ydot=blas.dot, yaxpy=blas.axpy, yscal=blas.scal):
+def cp(F, G = None, h = None, dims = None, A = None, b = None,
+    kktsolver = None, xnewcopy = matrix, xdot = blas.dot, xaxpy = 
+    blas.axpy, xscal = blas.scal, ynewcopy = matrix, ydot = blas.dot, 
+    yaxpy = blas.axpy, yscal = blas.scal):
 
     """
     Solves a convex optimization problem
     
         minimize    f0(x)
-        subject to  fk(x) <= 0, k=1,...,mnl
-                    G(x) <= h
-                    A(x) = b.                      
+        subject to  fk(x) <= 0, k = 1, ..., mnl
+                    G*x   <= h
+                    A*x   =  b.                      
 
-    fk: V -> R is convex and twice differentiable.  
-    G: V -> R^ml and A: V -> W are linear mappings, where V and W are 
-    real vector spaces.  The default choices for V and W are Euclidean 
-    vector spaces V=R^n and W=R^p, with elements stored as 'd' matrices 
-    of size (n,1) and (p,1).
+    f = (f0, f1, ..., fmnl) is convex and twice differentiable.  The linear
+    inequalities are with respect to a cone C defined as the Cartesian 
+    product of N + M + 1 cones:
+    
+        C = C_0 x C_1 x .... x C_N x C_{N+1} x ... x C_{N+M}.
 
-    Input arguments
+    The first cone C_0 is the nonnegative orthant of dimension ml.  The 
+    next N cones are second order cones of dimension mq[0], ..., mq[N-1].
+    The second order cone of dimension m is defined as
+    
+        { (u0, u1) in R x R^{m-1} | u0 >= ||u1||_2 }.
 
-        kktsolver is a function for the factorization of a KKT system
+    The next M cones are positive semidefinite cones of order ms[0], ...,
+    ms[M-1] >= 0.  
 
-            [ H       *   *    *  ] [ ux   ]    [ bx   ]
-            [ A       0   *    *  ] [ uy   ] =  [ by   ]
-            [ Df[1:]  0  -Dnl  *  ] [ uznl ]    [ bznl ]
-            [ G       0   0   -Dl ] [ uzl  ]    [ bzl  ] 
- 
-        where H = sum_{k=0}^mnl z[k]*Hk and H[k] is the Hessian 
-        of fk,  Df is the derivative of f and Dnl and Dl are positive 
-        diagonal matrices.
-        g = kktsolver(x, z, dnl, dl) returns a function g that can be 
-        used to solve the system with H and Df evaluated at x and z, 
-        Dnl = diag(dnl)^-2, Dl = diag(dl)^-2.
-        It can be assumed that x is in the domain of f0 and f.
-        The function calll g(bx, by, bznl, bzl) replaces the
-        arguments with the solution ux, uy, uznl, uzl.
 
-        F: a function that handles the following arguments.
+    Input arguments (basic usage).
 
-            F() returns a tuple (mnl, x0).  
+        c is a dense 'd' matrix of size (n,1), where n is the dimension 
+        of the primal variable x.
 
-                mnl is the number of nonlinear inequality constraints.
-                x0 is a point in dom f.
+        F is a function that handles the following arguments.
 
-            F(x), with x a point in V, returns (f, Df).
+            F() returns a tuple (mnl, x0).  mnl is the number of nonlinear 
+            inequality constraints.  x0 is a point in the domain of f.
 
-                f is  a dense 'd' matrix of size (mnl+1,1) with the 
-                function values f0(x), ...., fmnl(x). 
-                Df is a function or a sparse or dense 'd' matrix.  
-                If Df is a function, Df(u, v) evaluates 
- 
-                    v := sum_k=0^mnl u[k]*gradfk + v.
+            F(x) returns a tuple (f, Df).
 
-                If V = Rn, Df can also be a 'd' matrix or sparse matrix
-                of size (mnl, n).  In this case Df[k,:] contains the 
-                transpose of gradfk.  
- 
-                If x is not in dom f, F(x) returns None or (None, None).
- 
+                f is  a dense 'd' matrix of size (mnl+1,1) containing f(x).
 
-        G is None, a function, or a sparse or dense 'd' matrix. 
+                Df is a dense or sparse 'd' matrix of size (mnl+1, n), 
+                containing the derivatives of f at x:  Df[k,:] is the 
+                transpose of the gradient of fk at x.  If x is not in 
+                dom f, F(x) returns None or (None, None).
 
-            If G is a function then
+            F(x, z) with z a positive 'd' matrix of size (mnl+1,1), returns
+            a tuple (f, Df, H).
+            
+                f and Df are defined as above.
+                
+                H is a dense or sparse 'd' matrix of size (n,n).  The lower
+                triangular part of H contains the lower triangular part of
+                sum_k z[k] * Hk where Hk is the Hessian of fk at x.
 
-                G(u, v, alpha=1.0, beta=0.0, trans='N')
+                If F is called with two arguments, it can be assumed that 
+                x is dom f. 
 
-            evaluates
+            If Df and H are returned as sparse matrices, their sparsity
+            patterns must be the same for each call to F(x) or F(x,z). 
 
-                v := alpha * G(u)  + beta * v if trans is 'N'
-                v := alpha * G'(u) + beta * v if trans is 'T'.
+        dims is a dictionary with the dimensions of the components of C.  
+        It has three fields.
+        - dims['l'] = ml, the dimension of the nonnegative orthant C_0.
+          (ml >= 0.)
+        - dims['q'] = mq = [ mq[0], mq[1], ..., mq[N-1] ], a list of N 
+          integers with the dimensions of the second order cones 
+          C_1, ..., C_N.  (N >= 0 and mq[k] >= 1.)
+        - dims['s'] = ms = [ ms[0], ms[1], ..., ms[M-1] ], a list of M  
+          integers with the orders of the semidefinite cones 
+          C_{N+1}, ..., C_{N+M}.  (M >= 0 and ms[k] >= 0.)
+        The default value of dims = {'l': G.size[0], 'q': [], 's': []}.
 
-            If G is None, it is assumed that ml = 0.
+        G is a dense or sparse 'd' matrix of size (K,n), where
 
-            
-        h is None, or a dense 'd' matrix with one column.  If h is None,
-        it is interpreted as a 0x1 matrix.
+            K = ml + mq[0] + ... + mq[N-1] + ms[0]**2 + ... + ms[M-1]**2.
 
+        Each column of G describes a vector 
 
-        A is None, a function, or a dense or sparse 'd' matrix. 
+            v = ( v_0, v_1, ..., v_N, vec(v_{N+1}), ..., vec(v_{N+M}) ) 
 
-            If A is a function then
+        in V = R^ml x R^mq[0] x ... x R^mq[N-1] x S^ms[0] x ... x S^ms[M-1]
+        stored as a column vector
 
-                A(u, v, alpha=1.0, beta=0.0, trans='N')
+            [ v_0; v_1; ...; v_N; vec(v_{N+1}); ...; vec(v_{N+M}) ].
 
-            evaluates
+        Here, if u is a symmetric matrix of order m, then vec(u) is the 
+        matrix u stored in column major order as a vector of length m**2.
+        We use BLAS unpacked 'L' storage, i.e., the entries in vec(u) 
+        corresponding to the strictly upper triangular entries of u are 
+        not referenced.
 
-                v := alpha * A(u)  + beta * v if trans is 'N'
-                v := alpha * A'(u) + beta * v if trans is 'T'.
+        h is a dense 'd' matrix of size (K,1), representing a vector in V,
+        in the same format as the columns of G.
+    
+        A is a dense or sparse 'd' matrix of size (p,n).   The default
+        value is a sparse 'd' matrix of size (0,n).
 
-            If A is None, it is assumed that dim W  = 0.
+        b is a dense 'd' matrix of size (p,1).  The default value is a 
+        dense 'd' matrix of size (0,1).
 
+        It is assumed that rank(A) = p and rank([H; A; Df; G]) = n at all 
+        x in dom f.
 
-        b is None, or an element in W.  If b is None, it is assumed 
-        that dim W = 0.
+        The other arguments are normally not needed.  They make it possible
+        to exploit certain types of structure, as described below.
 
 
-    Returns a dictionary with keys 'status', 'x', 'snl', 'sl', 'y', 
-    'znl', 'zl'.  
+    Output arguments.
 
-        status is 'optimal' or 'unknown'.
+        cpl() returns a dictionary with keys 'status', 'x', 'snl', 'sl',
+        'znl', 'zl', 'y'.
 
-        x, s, snl, sl, y, znl, zl are None if status is 'unknown'.  
-        Otherwise x is the optimal solution;  snl, sl are the optimal 
-        slacks for the nonlinear and linear inequalities;  y is the 
-        optimal dual variable associated with the equality constraints; 
-        znl, zl are the optimal dual variables associated with the 
-        nonlinear and linear inequalities.
-    """
+        If status is 'optimal', x, snl, sl are approximate solutions of
+        the primal problem 
 
-    mnl, x0 = F()
-    if type(mnl) is not int or mnl < 0:
-        raise TypeError, "invalid return value for 'mnl, x = F()'"
+            minimize    f0(x)  
+            subject to  fk(x) + snl_k = 0, k = 1,...,mnl
+                        G*x + sl  = h
+                        A*x =  b,
+                        snl >= 0, sl >= 0
 
-    def fzero(x, y, alpha=1.0, beta=0.0, trans='N'):
-        if trans == 'T':  xscal(beta, y)
+        and y, znl, zl are approximate solutions of the dual problem
 
-    if G is None: G = fzero
-    if h is None: h = matrix(0.0, (0,1))
-    ml = h.size[0]
-    if type(G) in (matrix, spmatrix):
-        if G.typecode != 'd' or G.size[0] != ml:
-            raise TypeError, "'G' must be a 'd' matrix with %d rows" %ml
-        def fG(u, v, alpha=1.0, beta=0.0, trans='N'):
-            base.gemv(G, u, v, alpha=alpha, beta=beta, trans=trans)
-    else:    
-        fG = G 
-
-    if A is None: A = fzero
-    if b is None: b = matrix(0.0, (0,1))
-    if type(A) in (matrix,spmatrix):
-        if A.typecode != 'd' or A.size[0] != b.size[0]:
-            raise TypeError, "'A' must be a 'd' matrix with %d rows" \
-            %b.size[0]
-        def fA(u, v, alpha=1.0, beta=0.0, trans='N'):
-            base.gemv(A, u, v, alpha=alpha, beta=beta, trans=trans)
-    else:
-        fA = A
+            maximize    inf_x ( (1,znl)'*f(x) + zl'*(G*x-h) + y'*(A*x-b) )
+            subject to  znl >= 0, zl >= 0.
 
-    def xcopy(x, y):  xscal(0.0, y);  xaxpy(x, y)
-    def ycopy(x, y):  yscal(0.0, y);  yaxpy(x, y)
+        If status is 'unknown' x, s, snl, sl, y, znl, zl are None.
 
 
-    # Apply nlclp() to problem in epigraph form:
-    #    
-    #     minimize    t
-    #     subject to  f0(x) - t <= 0
-    #                 fk(x) <= 0,  k=1,...,mnl
-    #                 G(x) <= h
-    #                 A(x) = b.
-    #
-    # Store the variable as a list [ x, t ].
+    Advanced usage.
 
-    # c = [0, 1.0]
-    c = [ xnewcopy(x0), 1.0 ]
-    xscal(0.0, c[0])
+        Three mechanisms are provided to express problem structure.
 
-    ux, uznl = xnewcopy(x0), matrix(0.0, (mnl,1))
+        1.  The user can provide a customized routine for solving linear 
+        equations (`KKT systems')
 
-    def kktsolver_epi(x, z, dnl, dl):
-             
-        # g(x, y, znl, zl) is a solver for the smaller KKT system
-        #
-        #     [ H         *   *     *  ] [ x   ]   [ bx   ]
-        #     [ A         0   *     *  ] [ y   ] = [ by   ]
-        #     [ Df[1:,:]  0  -Dnl   *  ] [ znl ]   [ bznl ]
-        #     [ G         0   0    -Dl ] [ zl  ]   [ bzl  ]
-        #
-        # where H = sum_k=0^mnl zk*Hk, Df is the derivative matrix of
-        # (f0, ..., fmnl), Dnl = diag(dnl[1:])^-2, and Dl = diag(dl)^-2.
-        # The variables are x (in V), y (in W), znl (in R^mnl), 
-        # zl (in R^ml).
+            [ sum_k zk*Hk(x)  A'  GG'   ] [ ux ]   [ bx ]
+            [ A               0   0     ] [ uy ] = [ by ]
+            [ GG              0   -W'*W ] [ uz ]   [ bz ]
 
-        g = kktsolver(x[0], z, dnl[1:], dl)
- 
-        f, Df = F(x[0])
-        if type(Df) in (matrix, spmatrix):
-            gradf0 = Df[0,:].T
-        else: 
-            gradf0 = xnewcopy(x[0])
-            xscal(0.0, gradf0)
-            e0 = matrix(0.0, (mnl+1,1))
-            e0[0] = 1.0
-            Df(e0, gradf0)
- 
-        def g_epi(x, y, znl, zl):
+        where GG = [ Df[1:,:]; G ], uz = (uznl, uzl), bz = (bznl, bzl). 
 
-            # g_epi(x, y, znl, zl) solves the augmented KKT system
-            #
-            #    [ [H,    0;               ] [ x   ]    [ bx   ]
-            #    [  0,    0]  *   *    *   ] [     ]    [      ]
-            #    [ [A,    0]  0   *    *   ] [ y   ] =  [ by   ]
-            #    [ [Df, -e0]  0  -Dnl  *   ] [ znl ]    [ bznl ]
-            #    [ [G,    0]  0   0    -Dl ] [ zl  ]    [ bzl  ]
-            #
-            # The variables are x (a tuple (x[0], x[1]) with x[0] in
-            # V and x[1] in R), y (in W), znl (in R^(mnl+1)) and
-            # zl (in R^ml).
-            #
-            # The system is solved as follows:
-            #
-            # x[0], y, znl[1:], zl solve the smaller KKT system
-            # with rhs (bx[0] + bx[1]*Df[0,:]', by, bnl[1:], bl).
-            #
-            # Take znl[0] = -bx[1] and 
-            # x[1] = Df[0,:]*x[0] + bx[1]/dnl[0]**2 - bnl[0].
+        z is a positive vector of length mnl+1 and x is a point in the 
+        domain of f.   W is a scaling matrix, a block diagonal mapping
 
-            a = znl[0]
-            xcopy(x[0], ux)
-            xaxpy(gradf0, ux, alpha=x[1])
-            uznl[:] = znl[1:] 
-            g(ux, y, uznl, zl)
-            znl[1:] = uznl
-            znl[0] = -x[1]
-            xcopy(ux , x[0])
-            x[1] = xdot(gradf0, x[0]) - znl[0] / dnl[0]**2 - a
+           W*u = ( Wnl*unl, W0*u_0, ..., W_{N+M}*u_{N+M} )
 
-        return g_epi
+        defined as follows.
 
-    
-    # fA_epi evaluates [A, 0] * [x[0]; x[1]] and its adjoint.
-    #
-    #      v := alpha * A(u[0]) + beta*v if trans is 'N'
-    #      v := alpha * ( A'(u), 0 ) + beta*v if trans is 'N'
- 
-    def fA_epi(u, v, alpha=1.0, beta=0.0, trans='N'):
-        if trans == 'N':
-            fA(u[0], v, alpha=alpha, beta=beta) 
-        else:
-            fA(u, v[0], alpha=alpha, beta=beta, trans='T') 
-            v[1] *= beta
+        - For the nonlinear block (Wnl):
 
+              Wnl = diag(dnl),
 
-    # fG_epi evaluates  [G, 0] * [x[0]; x[1]] and its adjoint
-    #
-    #     v := alpha * G(u[0]) + beta*v  if trans is 'N' 
-    #     v := alpha * ( G'(u), 0 )  + beta*v  if trans is 'T'.
+          with dnl a positive vector of length mnl.
 
-    def fG_epi(u, v, alpha=1.0, beta=0.0, trans='N'):
-        if trans == 'N':
-            fG(u[0], v, alpha=alpha, beta=beta) 
-        else:
-            fG(u, v[0], alpha=alpha, beta=beta, trans='T') 
-            v[1] *= beta
+        - For the 'l' block (W_0):
 
+              W_0 = diag(dl),
 
-    # F_epi evaluates nonlinear constraint functions and derivatives.
-    
-    def F_epi(x=None, z=None):
-        if x is None: 
-            x0_epi = (x0, 0.0)
-            return mnl+1, x0_epi 
-        else:
-            t = F(x[0])
-            if t is None or t[0] is None:  return None, None
-            f_epi, Df = matrix(t[0]), t[1]
-            f_epi[0] -= x[1]
-            def Df_epi(u, v):  
-                # Evaluates v := [Df, -e0]' * u + v
-                if type(Df) in (matrix, spmatrix):
-                    base.gemv(Df, u, v[0], beta=1.0, trans='T')
-                else:
-                    Df(u, v[0])
-                v[1] -= u[0]
-            return f_epi, Df_epi
+          with dl a positive vector of length ml.
 
-    def xnewcopy_epi(x):
-        return [ xnewcopy(x[0]), 0.0 ]
+        - For the 'q' blocks (W_{k+1}, k = 0, ..., N-1):
 
-    def xdot_epi(x, y):
-        return xdot(x[0], y[0]) + x[1]*y[1]
+              W_{k+1} = beta_k * ( 2 * v_k * v_k' - J )
 
-    def xaxpy_epi(x, y, alpha=1.0):
-        xaxpy(x[0], y[0], alpha=alpha)
-        y[1] += alpha*x[1]
+          where beta_k is a positive scalar, v_k is a vector in R^mq[k]
+          with v_k[0] > 0 and v_k'*J*v_k = 1, and J = [1, 0; 0, -I].
 
-    def xscal_epi(alpha, x):
-        xscal(alpha, x[0])
-        x[1] *= alpha
+        - For the 's' blocks (W_{k+N}, k = 0, ..., M-1):
 
-    sol = nlclp(c, kktsolver_epi, F_epi, fG_epi, h, fA_epi, b, 
-        xnewcopy_epi, xdot_epi, xaxpy_epi, xscal_epi, ynewcopy, ydot, 
-        yaxpy, yscal) 
-    if sol['status'] == 'optimal':
-        sol['x'] = sol['x'][0]
-        sol['znl'], sol['snl'] = sol['znl'][1:], sol['snl'][1:]
-    else:
-        sol['x'] = None
-        sol['znl'], sol['snl'] = None, None 
-    return sol
+              W_k * u = vec(r_k' * mat(u) * r_k)
 
+          where r_k is a nonsingular matrix of order ms[k], and mat(x) is
+          the inverse of the vec operation.
 
-def cp(F, G=None, h=None, A=None, b=None):
+        The optional argument kktsolver is a Python function that will be
+        called as g = kktsolver(x, z, W).  W is a dictionary that contains
+        the parameters of the scaling:
 
-    """
-    Solves a convex optimization problem
-    
-        minimize    f0(x)
-        subject to  fk(x) <= 0, k=1,...,m
-                    G*x <= h
-                    A*x = b.                      
+        - W['dnl'] is a positive 'd' matrix of size (mnl, 1).
+        - W['dnli'] is a positive 'd' matrix with the elementwise inverse 
+          of W['dnl'].
+        - W['dl'] is a positive 'd' matrix of size (ml, 1).
+        - W['dli'] is a positive 'd' matrix with the elementwise inverse of
+          W['dl'].
+        - W['beta'] is a list [ beta_0, ..., beta_{N-1} ]
+        - W['v'] is a list [ v_0, ..., v_{N-1} ]
+        - W['r'] is a list [ r_0, ..., r_{M-1} ]
+        - W['rti'] is a list [ rti_0, ..., rti_{M-1} ], with rti_k the
+          inverse of the transpose of r_k.
 
-    f: R^n -> R^(m+1) is convex and twice differentiable.  
+        The call g = kktsolver(x, z, W) should return a function g that
+        solves the KKT system by g(ux, uy, uz).  On entry, ux, uy, uz 
+        contain the righthand side bx, by, bz.  On exit, they contain the 
+        solution, with uz scaled: (Wnl*uznl, Wl*uzl) is returned instead 
+        of (uznl, uzl).
 
-    Input arguments
+        2.  The linear operators Df*u, H*u, G*u and A*u can be specified 
+        by providing Python functions instead of matrices.  This can only 
+        be done in combination with 1. above, i.e., it requires the 
+        kktsolver argument.
+        
+        If G is a function, the call G(u, v, alpha, beta, trans) should 
+        evaluate the matrix-vector products
 
-        F is a function that handles the following arguments.
+            v := alpha * G * u + beta * v  if trans is 'N'
+            v := alpha * G' * u + beta * v  if trans is 'T'.
 
-            F() returns a tuple (m, x0).  
+        The arguments u and v are required.  The other arguments have
+        default values alpha = 1.0, beta = 0.0, trans = 'N'.
 
-                m is the number of nonlinear inequality constraints.
-                x0 is an nx1 dense 'd' matrix specifying a point in 
-                dom f.
+        If A is a function, the call A(u, v, alpha, beta, trans) should
+        evaluate the matrix-vectors products
 
-            F(x), with x a 'd' matrix of size (n,1), returns (f, Df).
+            v := alpha * A * u + beta * v if trans is 'N'
+            v := alpha * A' * u + beta * v if trans is 'T'.
 
-                f is  a dense 'd' matrix of size (m+1,1) with the 
-                function values f(x). 
+        The arguments u and v are required.  The other arguments
+        have default values alpha = 1.0, beta = 0.0, trans = 'N'.
 
-                Df is a dense or sparse 'd' matrix of size (m+1,n). 
-                Its kth row contains the transpose of the gradient
-                of fk at x.
+        If Df is a function, the call Df(u, v, alpha, beta, trans) should
+        evaluate the matrix-vectors products
 
-                If x is not in dom f, F(x) returns None or (None, None).
- 
-            F(x, z), with x a 'd' matrix of size (n,1) and z a positive 
-            'd' matrix of size (m+1,1), returns (f, Df, H).
-            
-                f and Df are defined as above.
-                
-                H is a dense or sparse 'd' matrix of size (n,n).  The 
-                lower triangular part of H contains the lower triangular
-                part of sum_{k=0}^m z[k]*Hk where Hk is the Hessian of 
-                fk at x.  
+            v := alpha * Df(x) * u + beta * v if trans is 'N'
+            v := alpha * Df(x)' * u + beta * v if trans is 'T'.
 
-                If F is called with two arguments, it can be assumed
-                that x is dom f. 
+        If H is a function, the call H(u, v, alpha, beta) should evaluate 
+        the matrix-vectors product
 
-        G is None or a sparse or dense 'd' matrix.  If G is None, it 
-        is interpreted as a 0xn matrix.  
+            v := alpha * H * u + beta * v.
 
-        h is None or a dense 'd' matrix with one column.  If h is None, 
-        it is interpreted as a 0x1 matrix.
 
-        A is None, or a dense or sparse 'd' matrix.  If A is None, it 
-        is interpreted as a 0xn matrix.  
+        3.  Instead of using the default representation of the primal 
+        variable x and the dual variable y as one-column 'd' matrices, 
+        we can represent these variables and the corresponding parameters 
+        c and b by arbitrary Python objects (matrices, lists, dictionaries,
+        etc).  This can only be done in combination with 1. and 2. above,
+        i.e., it requires a user-provided KKT solver and a function
+        description of the linear mappings.   It also requires the 
+        arguments xnewcopy, xdot, xscal, xaxpy, ynewcopy, ydot, yscal, 
+        yaxpy.  These arguments are functions defined as follows.
+   
+        If X is the vector space of primal variables x, then:
+        - xnewcopy(u) creates a new copy of the vector u in X.
+        - xdot(u, v) returns the inner product of two vectors u and v in X.
+        - xscal(alpha, u) computes u := alpha*u, where alpha is a scalar
+          and u is a vector in X.
+        - xaxpy(u, v, alpha = 1.0, beta = 0.0) computes v := alpha*u + v
+          for a scalar alpha and two vectors u and v in X.
 
-        b is a dense 'd' matrix with one column or None.  If b is None,
-        it is interpreted as a 0x1 matrix.
+        If Y is the vector space of primal variables y:
+        - ynewcopy(u) creates a new copy of the vector u in Y.
+        - ydot(u, v) returns the inner product of two vectors u and v in Y.
+        - yscal(alpha, u) computes u := alpha*u, where alpha is a scalar
+          and u is a vector in Y.
+        - yaxpy(u, v, alpha = 1.0, beta = 0.0) computes v := alpha*u + v
+          for a scalar alpha and two vectors u and v in Y.
 
-    Returns a dictionary with keys 'status', 'x', 'snl', 'sl', 'y', 
-    'znl', 'zl'.  
 
-        status is 'optimal' or 'unknown'.
+    Control parameters.
 
-        x, s, snl, sl, y, znl, zl are None if status is 'unknown'.  
-        Otherwise x is the optimal solution;  snl, sl are the optimal 
-        slacks for the nonlinear and linear inequalities;  y is the 
-        optimal dual variable associated with the equality constraints; 
-        znl, zl are the optimal dual variables associated with the 
-        nonlinear and linear inequalities.
-    """
+       The following control parameters can be modified by adding an
+       entry to the dictionary options.
+
+       options['show_progress'] True/False (default: True)
+       options['maxiters'] positive integer (default: 100)
+       options['abstol'] scalar (default: 1e-7)
+       options['reltol'] scalar (default: 1e-6)
+       options['feastol'] scalar (default: 1e-7).
 
-    try: kktmethod = options['kktmethod']
-    except KeyError: kktmethod = 3
-    else: 
-        if type(kktmethod) is not int or kktmethod not in [1,2,3]:
-            raise ValueError, "options['kktmethod'] must be 1, 2 or 3"
+    """
 
     mnl, x0 = F()
-    if type(mnl) is not int or mnl < 0 or type(x0) is not matrix or \
-        x0.typecode != 'd' or x0.size[1] != 1:
-        raise TypeError, "invalid return values for '(m, x) = F()'"
-    n = x0.size[0]
 
-    if G is None: G = spmatrix([], [], [], (0,n))
+    # Argument error checking depends on level of customization.
+    customkkt = type(kktsolver) is not str
+    operatorG = G is not None and type(G) not in (matrix, spmatrix)
+    operatorA = A is not None and type(A) not in (matrix, spmatrix)
+    if (operatorG or operatorA) and not customkkt:
+        raise ValueError, "use of function valued G, A requires a "\
+            "user-provided kktsolver"
+    customx = xnewcopy != matrix or xdot != blas.dot or xaxpy != blas.axpy\
+        or xscal != blas.scal 
+    if customx and (not operatorG or not operatorA or not customkkt):
+        raise ValueError, "use of non-vector type for x requires "\
+            "function valued G, A and user-provided kktsolver"
+    customy = ynewcopy != matrix or ydot != blas.dot or yaxpy != blas.axpy\
+        or yscal != blas.scal  
+    if customy and (not operatorA or not customkkt):
+        raise ValueError, "use of non vector type for y requires "\
+            "function valued A and user-provided kktsolver"
+
+    if not customx:  
+        if type(x0) is not matrix or x0.typecode != 'd' or x0.size[1] != 1:
+            raise TypeError, "'x0' must be a 'd' matrix with one column"
+        
     if h is None: h = matrix(0.0, (0,1))
-    if type(G) not in (matrix, spmatrix) or G.typecode != 'd' or \
-        G.size[1] != n:
-        raise TypeError, "'G' must be a dense or sparse 'd' matrix "\
-            "with %d columns" %n 
-    ml = G.size[0]
-    if type(h) is not matrix or h.typecode != 'd' or h.size != (ml,1):
-        raise TypeError, "'h' must be a dense 'd' matrix of size "\
-            "(%d,1)" %ml
+    if type(h) is not matrix or h.typecode != 'd' or h.size[1] != 1:
+        raise TypeError, "'h' must be a 'd' matrix with one column" 
+    if not dims: dims = {'l': h.size[0], 'q': [], 's': []}
+
+    # Dimension of the product cone of the linear inequalities. with 's' 
+    # components unpacked.
+    cdim = dims['l'] + sum(dims['q']) + sum([ k**2 for k in dims['s'] ])
+    if h.size[0] != cdim:
+        raise TypeError, "'h' must be a 'd' matrix of size (%d,1)" %cdim
+
+    if G is None:
+        if customx:
+            def G(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+                if trans == 'N': pass
+                else: xscal(beta, y)
+        else:
+            G = spmatrix([], [], [], (0, x0.size[0]))
+    if type(G) is matrix or type(G) is spmatrix:
+        if G.typecode != 'd' or G.size != (cdim, x0.size[0]):
+            raise TypeError, "'G' must be a 'd' matrix with size (%d, %d)"\
+                %(cdim, x0.size[0])
+        def fG(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+            misc.sgemv(G, x, y, dims, trans = trans, alpha = alpha, 
+                beta = beta)
+    else:
+        fG = G
 
-    if A is None: A = spmatrix([], [], [], (0,n))
-    if b is None: b = matrix(0.0, (0,1))
-    if type(A) not in (matrix,  spmatrix) or A.typecode != 'd' or \
-        A.size[1] != n: 
-        raise TypeError, "'A' must be a dense or sparse 'd' matrix "\
-            "with %d columns" %n
-    p = A.size[0]
-    if type(b) is not matrix or b.typecode != 'd' or b.size != (p,1): 
-        raise TypeError, "'b' must be a dense 'd' matrix of "\
-            "size (%d,1)" %p
+    if A is None:
+        if customy:
+            def A(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+                if trans == 'N': pass
+                else: xscal(beta, y)
+        else:
+            A = spmatrix([], [], [], (0, x0.size[0]))
+    if type(A) is matrix or type(A) is spmatrix:
+        if A.typecode != 'd' or A.size[1] != x0.size[0]:
+            raise TypeError, "'A' must be a 'd' matrix with %d columns" \
+                %x0.size[0]
+        def fA(x, y, trans = 'N', alpha = 1.0, beta = 0.0):
+            base.gemv(A, x, y, trans = trans, alpha = alpha, beta = beta)
+    else:
+        fA = A
+    if not customy:
+        if b is None: b = matrix(0.0, (0,1))
+        if type(b) is not matrix or b.typecode != 'd' or b.size[1] != 1:
+            raise TypeError, "'b' must be a 'd' matrix with one column"
+        if not operatorA and b.size[0] != A.size[0]:
+            raise TypeError, "'b' must have length %d" %A.size[0]
+    if b is None and customy:  
+        raise ValueEror, "use of non vector type for y requires b"
+
+
+    def xcopy(x, y):  
+        xscal(0.0, y) 
+        xaxpy(x, y)
+    def ycopy(x, y):  
+        yscal(0.0, y)  
+        yaxpy(x, y)
+
+
+    # The problem is solved by applying cpl() to the epigraph form 
+    #
+    #     minimize   t 
+    #     subject to f0(x) - t <= 0
+    #                f1(x) <= 0
+    #                ...
+    #                fmnl(x) <= 0.
+    #
+    # The epigraph form variable is stored as a list [x, t].
+
+    # Epigraph form objective c = (0, 1).
+    c = [ xnewcopy(x0), 1 ] 
+    xscal(0.0, c[0])
+
+    # Nonlinear inequalities for the epigraph problem
+    #
+    #     f_e(x,t) = (f0(x) - t, f1(x), ..., fmnl(x)).
+    #     
+
+    def F_e(x = None, z = None):
+
+        if x is None: 
+            return mnl+1, [ x0, 0.0 ]
+
+        else:
+            if z is None:
+                v = F(x[0])
+                if v is None or v[0] is None: return None, None
+                val = matrix(v[0], tc = 'd')
+                val[0] -= x[1]
+                Df = v[1]
+            else:
+                val, Df, H = F(x[0], z)
+                val = matrix(val, tc = 'd')
+                val[0] -= x[1]
+
+            if type(Df) in (matrix, spmatrix):
+                def Df_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):  
+                    if trans == 'N':
+                        base.gemv(Df, u[0], v, alpha = alpha, beta = beta,
+                            trans = 'N')
+                        v[0] -= alpha * u[1]
+                    else:
+                        base.gemv(Df, u, v[0], alpha = alpha, beta = beta,
+                            trans = 'T')
+                        v[1] = -alpha * u[0] + beta * v[1]
+            else:
+                def Df_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):  
+                    if trans == 'N':
+                        Df(u[0], v, alpha = alpha, beta = beta, 
+                            trans = 'N')
+                        v[0] -= alpha * u[1]
+                    else:
+                        Df(u, v[0], alpha = alpha, beta = beta, 
+                            trans = 'T')
+                        v[1] = -alpha * u[0] + beta * v[1]
+
+            if z is None:
+                return val, Df_e
+            else:
+                if type(H) in (matrix, spmatrix):
+                    def H_e(u, v, alpha = 1.0, beta = 1.0):
+                        base.symv(H, u[0], v[0], alpha = alpha, 
+                            beta = beta) 
+                        v[1] += beta*v[1]
+                else:
+                    def H_e(u, v, alpha = 1.0, beta = 1.0):
+                        H(u[0], v[0], alpha = alpha, beta = beta)
+                        v[1] += beta*v[1]
+                return val, Df_e, H_e
+
+
+    # Linear inequality constraints.
+    #
+    #     G_e  = [ G, 0 ]
+    #
+
+    if type(G) in (matrix, spmatrix):
+        def G_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
+            if trans == 'N':
+                misc.sgemv(G, u[0], v, dims, alpha = alpha, beta = beta) 
+            else:
+                misc.sgemv(G, u, v[0], dims, alpha = alpha, beta = beta, 
+                    trans = 'T') 
+                v[1] *= beta
+    else:
+        def G_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
+            if trans == 'N':
+                G(u[0], v, alpha = alpha, beta = beta) 
+            else:
+                G(u, v[0], alpha = alpha, beta = beta, trans = 'T') 
+                v[1] *= beta
+
+
+    # Linear equality constraints.
+    #
+    #     A_e = [ A, 0 ]
+    #
+
+    if type(A) in (matrix, spmatrix):
+        def A_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
+            if trans == 'N':
+                base.gemv(A, u[0], v, alpha = alpha, beta = beta) 
+            else:
+                base.gemv(A, u, v[0], alpha = alpha, beta = beta, 
+                    trans = 'T') 
+                v[1] *= beta
+    else:
+        def A_e(u, v, alpha = 1.0, beta = 0.0, trans = 'N'):
+            if trans == 'N':
+                A(u[0], v, alpha = alpha, beta = beta) 
+            else:
+                A(u, v[0], alpha = alpha, beta = beta, trans = 'T') 
+                v[1] *= beta
+ 
+
+    # kktsolver(x, z, W) returns a routine for solving equations with 
+    # coefficient matrix
+    #
+    #         [ H             A'   [Df[1:]; G]' ]
+    #     K = [ A             0    0            ]. 
+    #         [ [Df[1:]; G]   0    -W'*W        ]
+ 
+    if kktsolver is None: 
+        if dims and (dims['q'] or dims['s']):  
+            kktsolver = 'qr'            
+        else:
+            kktsolver = 'chol'            
+    if kktsolver in ('ldl', 'chol', 'qr'):
+        if kktsolver == 'ldl':
+            factor = kkt_ldl(mnl, G, dims, A)
+        elif kktsolver == 'qr':
+            factor = kkt_qr(mnl, G, dims, A)
+        else: 
+            factor = kkt_chol(mnl, G, dims, A)
+        def kktsolver(x, z, W):
+            f, Df, H = F(x, z)
+            return factor(H, Df[1:,:], W)             
+
+    ux, uz = xnewcopy(x0), matrix(0.0, (mnl + cdim, 1))
+    def kktsolver_e(x, znl, W):
+
+        We = W.copy()
+        We['dnl'] = W['dnl'][1:]
+        We['dnli'] = W['dnli'][1:]
+        g = kktsolver(x[0], znl, We)
+
+        f, Df = F(x[0])
+        if type(Df) is matrix or type(Df) is spmatrix:
+            gradf0 = Df[0,:].T
+        else:
+            gradf0 = xnewcopy(x[0])
+            e0 = matrix(0.0, (mnl + 1, 1))
+            e0[0] = 1.0
+            Df(e0, gradf0, trans = 'T')
+
+        def solve(x, y, z):
+
+            # Solves 
+            #
+            #    [ [ H   0  ]   [ A' ]  [ Df'  G'] ] [ ux ]    [ bx ]
+            #    [ [ 0   0  ]   [ 0  ]  [ -e0' 0 ] ] [    ]    [    ]
+            #    [                                 ] [    ]    [    ]
+            #    [ [ A   0  ]   0       0          ] [ uy ] =  [ by ].
+            #    [                                 ] [    ]    [    ]
+            #    [ [ Df -e0 ]   0       -W'*W      ] [ uz ]    [ bz ]
+            #    [ [ G   0  ]                      ] [    ]    [    ]
+            # 
+            # The solution is:
+            #
+            #     uz[0] = -bx[1] 
+            #
+            #     [ ux[0]  ]          [ bx[0] + bx[1] * gradf0 ]
+            #     [ uy     ] = K^-1 * [ by                     ].
+            #     [ uz[1:] ]          [ bz[1:]                 ]
+            #
+            #     ux[1] = gradf0' * ux[0] - W['dnl'][0]**2 * uz[0] - bz[0]
+            #           = gradf0' * ux[0] + W['dnl'][0]**2 * bx[1] - bz[0].
+            #
+            # Instead of uz we return the scaled solution W*uz.
+
+            a = z[0]
+            xcopy(x[0], ux)
+            xaxpy(gradf0, ux, alpha = x[1])
+            blas.copy(z, uz, offsetx = 1)
+            g(ux, y, uz)
+            z[0] = -x[1] * W['dnl'][0]
+            blas.copy(uz, z, offsety = 1)
+            xcopy(ux, x[0])
+            x[1] = xdot(gradf0, x[0]) + W['dnl'][0]**2 * x[1] - a
+
+        return solve
+
+    def xnewcopy_e(x):
+        return [ xnewcopy(x[0]), x[1] ]
+
+    def xdot_e(x, y):
+        return xdot(x[0], y[0]) + x[1]*y[1]
+
+    def xaxpy_e(x, y, alpha = 1.0):
+        xaxpy(x[0], y[0], alpha = alpha)
+        y[1] += alpha*x[1]
+
+    def xscal_e(alpha, x):
+        xscal(alpha, x[0])
+        x[1] *= alpha
+
+    sol = cpl(c, F_e, G_e, h, dims, A_e, b, kktsolver_e, xnewcopy_e, 
+         xdot_e, xaxpy_e, xscal_e)
+
+    if sol['status'] == 'optimal':
+        sol['x'] = sol['x'][0]
+        sol['znl'], sol['snl'] = sol['znl'][1:], sol['snl'][1:]
+    else:
+        sol['x'] = None
+        sol['zl'], sol['sl'] = None, None
+        sol['znl'], sol['snl'] = None, None 
+    return sol
 
-    status = {'kkt_num': None}  # 'pointer' to numeric factorization
-    def kkt(x, z, dnl, dl):
-        f, Df, H = F(x, z)
-        if mnl==0:  
-            Df2 = spmatrix([],[],[],(0,n))
-        else:  
-            Df2 = Df[1:,:]
-        if status['kkt_num'] is None:
-            status['kkt_num'] = misc.kkt(H, A, Df2, G, kktmethod)
-        return status['kkt_num'](H, Df2, dnl, dl)
-    
-    return nlcp(kkt, F, G, h, A, b) 
 
 
 def qp(P, q, G=None, h=None, A=None, b=None, solver=None):
@@ -889,24 +2572,31 @@ def qp(P, q, G=None, h=None, A=None, b=None, solver=None):
     """
 
     if solver == 'mosek':
-        try: from cvxopt import mosek
+        try: 
+            from cvxopt import mosek
+            import pymosek 
         except ImportError: raise ValueError, "invalid option "\
             "(solver='mosek'): cvxopt.mosek is not installed" 
-        mosek.options = options
-        prosta, solsta, x, z, y = mosek.solveqp(P, q, G, h, A, b)
+
+        if 'MOSEK' in options:
+            mosek.options = options['MOSEK']
+        else:
+            mosek.options = {}
+        solsta, x, z, y = mosek.solveqp(P, q, G, h, A, b)
         m = G.size[0]
-        if solsta == 'OPTIMAL':
+
+        if solsta == pymosek.solsta.optimal:
             s = matrix(0.0, (m,1))
             blas.copy(h, s)    
-            base.gemv(G, x, s, alpha=-1.0, beta=1.0)
+            base.gemv(G, x, s, alpha = -1.0, beta = 1.0)
             status = 'optimal'
-        elif solsta == 'PRIMAL_INFEASIBLE_CER':
+        elif solsta == pymosek.solsta.prim_infeas_cer:
             status = 'primal infeasible'
             ducost = -blas.dot(h,z) - blas.dot(b,y)
             blas.scal(1.0/ducost, y);
             blas.scal(1.0/ducost, z);
             x, s = None, None
-        elif solsta == 'DUAL_INFEASIBLE_CER':
+        elif solsta == pymosek.solsta_dual_infeas_cer:
             status = 'dual infeasible'
             qx = blas.dot(q,x)
             if qx:  x /= (-qx)
@@ -927,8 +2617,9 @@ def qp(P, q, G=None, h=None, A=None, b=None, solver=None):
         raise TypeError, "'q' must be a dense 'd' matrix of "\
             "size (%d,1)" %n
 
-    def F(x=None, z=None):
-        if x is None: return 0, matrix(0.0, (n,1))
+    def F(x = None, z = None):
+        if x is None: 
+            return 0, matrix(0.0, (n,1))
         grad = matrix(0.0, (1,n))
         base.symv(P, x, grad) 
         f = .5 * blas.dot(grad, x) + blas.dot(q, x) 
@@ -936,7 +2627,8 @@ def qp(P, q, G=None, h=None, A=None, b=None, solver=None):
         if z is None: return f, grad
         else: return f, grad, z[0]*P
 
-    sol =  cp(F, G, h, A, b)
+    dims = {'l': G.size[0], 'q': [], 's': []}
+    sol =  cp(F, G, h, dims, A, b)
     return {'status': sol['status'], 'x': sol['x'], 's': sol['sl'],
         'y': sol['y'], 'z': sol['zl']}
 
@@ -1012,6 +2704,7 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
     if type(h) is not matrix or h.typecode != 'd' or h.size != (ml,1):
         raise TypeError, "'h' must be a dense 'd' matrix of "\
             "size (%d,1)" %ml
+    dims = {'l': ml, 's': [], 'q': []}
 
     if A is None: A = spmatrix([], [], [], (0,n))
     if b is None: b = matrix(0.0, (0,1))
@@ -1032,7 +2725,7 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
     cs2 = [ cs1[i] + K[i] for i in xrange(mnl+1) ]
     ind = zip(range(mnl+1), cs1, cs2)
 
-    def Fgp(x=None, z=None):
+    def Fgp(x = None, z = None):
 
         if x is None: return mnl, matrix(0.0, (n,1))
 	
@@ -1049,7 +2742,7 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
 
             # yi := exp(yi) = exp(Fi*x+gi) 
             ymax = max(y[start:stop])
-            y[start:stop] = exp(y[start:stop] - ymax)
+            y[start:stop] = base.exp(y[start:stop] - ymax)
 
             # fi = log sum yi = log sum exp(Fi*x+gi)
             ysum = blas.asum(y, n=stop-start, offset=start)
@@ -1085,4 +2778,4 @@ def gp(K, F, g, G=None, h=None, A=None, b=None):
         if z is None: return f, Df
         else: return f, Df, H
 
-    return cp(Fgp, G, h, A, b)
+    return cp(Fgp, G, h, dims, A, b)
diff --git a/src/python/info.py b/src/python/info.py
index 3911d7f..f45bb11 100644
--- a/src/python/info.py
+++ b/src/python/info.py
@@ -1,8 +1,8 @@
-version = '0.9'
+version = '0.9.1'
 
 def license(): print(
 """
-CVXOPT version 0.9.  Copyright (c) 2004-2007 J. Dahl and L. Vandenberghe.
+CVXOPT version 0.9.1.  Copyright (c) 2004-2007 J. Dahl and L. Vandenberghe.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,29 +17,24 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-The CVXOPT distribution includes source code for the following software 
-libraries. 
-
-1. Part of the SuiteSparse suite of sparse matrix algorithms, including:
-   - AMD Version 2.1. Copyright (c) 2007 by Timothy A. Davis, Patrick R. 
-     Amestoy, and Iain S. Duff.
-   - CHOLMOD Version 1.5. Copyright (c) 2005-2007 by University of Florida,
-     Timothy A. Davis and W. Hager.
-   - COLAMD version 2.7. Copyright (c) 1998-2007 by Timothy A. Davis.
-   - UMFPACK Version 5.0.2. Copyright (c) 1995-2006 by Timothy A. Davis.
-
-   These packages are licensed under the terms of the GNU Lesser General 
-   Public License, version 2.1 or higher (UMFPACK, parts of CHOLMOD, AMD, 
-   COLAMD) and the GNU General Public License, version 2 or higher 
-   (the Supernodal module of CHOLMOD). For copyright and license details, 
-   consult the README files in the source directories or the website 
-   listed below.
-
-   Availability: www.cise.ufl.edu/research/sparse. 
-
-2. RNGS Random Number Generation -- Multiple Streams (Sep. 22, 1998) by 
-   Steve Park & Dave Geyer.
-
-   Availability: www.cs.wm.edu/~va/software/park/park.html. 
+---
+The CVXOPT distribution includes source code for part of the SuiteSparse
+suite of sparse matrix algorithms, including:
+
+- AMD Version 2.2.0. Copyright (c) 2007 by Timothy A. Davis, Patrick R. 
+  Amestoy, and Iain S. Duff.
+- CHOLMOD Version 1.6.0. Copyright (c) 2005-2007 by University of Florida, 
+  Timothy A. Davis and W. Hager.
+- COLAMD version 2.7.0. Copyright (c) 1998-2007 by Timothy A. Davis.
+- UMFPACK Version 5.2.0. Copyright (c) 1995-2006 by Timothy A. Davis.
+
+These packages are licensed under the terms of the GNU General Public 
+License, version 2 or higher (UMFPACK, the Supernodal module of CHOLMOD),
+and the GNU Lesser General Public License, version 2.1 or higher 
+(the other CHOLMOD modules, AMD, COLAMD).  For copyright and license 
+details, consult the README files in the source directories or the website 
+listed below.
+
+Availability: www.cise.ufl.edu/research/sparse. 
 """
 )
diff --git a/src/python/misc.py b/src/python/misc.py
index 7dc0ca1..cb553f2 100644
--- a/src/python/misc.py
+++ b/src/python/misc.py
@@ -1,10 +1,6 @@
-"""
-Miscellaneous functions used by the CVXOPT solvers.
-"""
-
 # Copyright 2004-2007 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 0.9.
+# This file is part of CVXOPT version 0.9.1.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -20,510 +16,510 @@ Miscellaneous functions used by the CVXOPT solvers.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import math
-from cvxopt import base, blas, lapack, cholmod
-from cvxopt.base import matrix, spmatrix
-cholmod.options['supernodal'] = 2
-
+from cvxopt import base, blas, lapack
+from cvxopt.base import matrix
 __all__ = []
 
-def had(x,y):  
-    """
-    Returns Hadamard product x.*y of dense 'd' matrices x and y.
-
-    x and y are 'd' matrices of equal size.
+def scale(x, W, trans = 'N', inverse = 'N'):  
+
+    # Computes 
+    #
+    #     x := W*x        (trans is 'N', inverse = 'N')  
+    #     x := W^T*x      (trans is 'T', inverse = 'N')  
+    #     x := W^{-1}*x   (trans is 'N', inverse = 'I')  
+    #     x := W^{-T}*x   (trans is 'T', inverse = 'I'). 
+    #
+    # x is a dense 'd' matrix.
+    #
+    # W is a dictionary with entries:
+    #
+    # - W['dnl']: positive vector 
+    # - W['dnli']: componentwise inverse of W['dnl']
+    # - W['dl']: positive vector 
+    # - W['dli']: componentwise inverse of W['dl']
+    # - W['v']: lists of second order cone vectors with unit hyperbolic 
+    #   norms
+    # - W['beta']: list of positive numbers
+    # - W['r']: list of square matrices 
+    # - W['rti']: list of square matrices.  rti[k] is the inverse  
+    #   transpose of r[k].
+
+
+    # Scaling for nonlinear component xk is xk := dnl .* xk; inverse 
+    # scaling is xk ./ dnl = dnli .* xk, where dnl = W['dnl'], 
+    # dnli = W['dnli'].
+
+    if inverse == 'N': w = W['dnl']
+    else: w = W['dnli']
+    mnl = w.size[0]
+    for k in xrange(x.size[1]):
+        blas.tbmv(w, x, n = mnl, k = 0, ldA = 1, offsetx = k*x.size[0])
+
+
+    # Scaling for linear 'l' component xk is xk := dl .* xk; inverse 
+    # scaling is xk ./ dl = dli .* xk, where dl = W['dl'], dli = W['dli'].
+
+    if inverse == 'N': w = W['dl']
+    else: w = W['dli']
+    ml = w.size[0]
+    for k in xrange(x.size[1]):
+        blas.tbmv(w, x, n = ml, k = 0, ldA = 1, offsetx = k*x.size[0] + 
+            mnl)
+
+
+    # Scaling for 'q' component is 
+    #
+    #     xk := beta * (2*v*v' - J) * xk
+    #         = beta * (2*v*(xk'*v)' - J*xk)
+    #
+    # where beta = W['beta'][k], v = W['v'][k], J = [1, 0; 0, -I].
+    #
+    # Inverse scaling is
+    #
+    #     xk := 1/beta * (2*J*v*v'*J - J) * xk
+    #         = 1/beta * (-J) * (2*v*((-J*xk)'*v)' + xk). 
+
+    w = matrix(0.0, (x.size[1], 1))
+    ind = mnl + ml
+    for k in xrange(len(W['v'])):
+        v = W['v'][k]
+        m = v.size[0]
+        if inverse == 'I':  
+            blas.scal(-1.0, x, offset = ind, inc = x.size[0])
+        blas.gemv(x, v, w, trans = 'T', m = m, n = x.size[1], offsetA = 
+            ind, ldA = x.size[0])
+        blas.scal(-1.0, x, offset = ind, inc = x.size[0])
+        blas.ger(v, w, x, alpha = 2.0, m = m, n = x.size[1], ldA = 
+            x.size[0], offsetA = ind)
+        if inverse == 'I': 
+            blas.scal(-1.0, x, offset = ind, inc = x.size[0])
+            a = 1.0 / W['beta'][k] 
+        else:
+            a = W['beta'][k] 
+        for i in xrange(x.size[1]):
+            blas.scal(a, x, n = m, offset = ind + i*x.size[0])
+        ind += m
+
+
+    # Scaling for 's' component xk is
+    #
+    #     xk := vec( r' * mat(xk) * r )  if trans = 'N'
+    #     xk := vec( r * mat(xk) * r' )  if trans = 'T'.
+    #
+    # r is kth element of W['r'].
+    #
+    # Inverse scaling is
+    #
+    #     xk := vec( rti * mat(xk) * rti' )  if trans = 'N'
+    #     xk := vec( rti' * mat(xk) * rti )  if trans = 'T'.
+    #
+    # rti is kth element of W['rti'].
+
+    maxn = max( [0] + [ r.size[0] for r in W['r'] ] )
+    a = matrix(0.0, (maxn, maxn))
+    for k in xrange(len(W['r'])):
+
+        if inverse == 'N':
+            r = W['r'][k]
+            if trans == 'N': t = 'T'
+            else: t = 'N'
+        else:
+            r = W['rti'][k]
+            t = trans
+
+        n = r.size[0]
+        for i in xrange(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)
+
+            # a = r*tril(x) (t is 'N') or a = tril(x)*r  (t is 'T')
+            blas.copy(r, a)
+            if t == 'N':   
+                blas.trmm(x, a, side = 'R', m = n, n = n, ldA = n, ldB = n,
+                    offsetA = ind + i*x.size[0])
+            else:    
+                blas.trmm(x, a, side = 'L', m = n, n = n, ldA = n, ldB = n,
+                    offsetA = ind + i*x.size[0])
+ 
+            # x := (r*a' + a*r')  if t is 'N'
+            # x := (r'*a + a'*r)  if t is 'T'
+            blas.syr2k(r, a, x, trans = t, n = n, k = n, ldB = n, ldC = n,
+                offsetC = ind + i*x.size[0])
+ 
+        ind += n**2
 
-    Returns x .* y as a new matrix.
-    """ 
 
-    if x.size != y.size:
-        raise ValueError, "x and y must have the same size"
-    z = +x 
-    blas.tbmv(y, z, n=len(y), k=0, ldA=1) 
-    return z
 
+def scale2(lmbda, x, mnl, dims, inverse = 'N'):
 
-def had2(x, y, n=None):  
-    """
-    In-place Hadamard product x.*y of dense 'd' matrices x and y.
+    # x := H(lambda^{1/2}) * x   (inverse is 'N')
+    # x := H(lambda^{-1/2}) * x  (inverse is 'I')
+    #
+    # H is the Hessian of the logarithmic barrier.
+      
 
-    x and y are 'd' matrices of equal size.
-    
-    n is a nonnegative integer, with default value len(x).  If the
-    default value is used, len(x) must be equal to len(y).
+    # For the nonlinear and 'l' block, 
+    #
+    #     xk := xk ./ l   (inverse is 'N')
+    #     xk := xk .* l   (inverse is 'I')
+    #
+    # where l is lmbda[:mnl+dims['l']].
 
-    On exit x[:n] is replaced with  x[:n].*y[:n].
-    """ 
+    if inverse == 'N':
+        blas.tbsv(lmbda, x, n = mnl + dims['l'], k = 0, ldA = 1)
+    else:
+        blas.tbmv(lmbda, x, n = mnl + dims['l'], k = 0, ldA = 1)
+   
+  
+    # For 'q' blocks, if inverse is 'N',
+    #
+    #     xk := 1/a * [ l'*J*xk;  
+    #         xk[1:] - (xk[0] + l'*J*xk) / (l[0] + 1) * l[1:] ].
+    #
+    # If inverse is 'I',
+    #
+    #     xk := a * [ l'*xk; 
+    #         xk[1:] + (xk[0] + l'*xk) / (l[0] + 1) * l[1:] ].
+    #
+    # a = sqrt(lambda_k' * J * lambda_k), l = lambda_k / a.
+
+    ind = mnl + dims['l']
+    for m in dims['q']:
+        a = jnrm2(lmbda, n = m, offset = ind)
+        if inverse == 'N':
+            lx = jdot(lmbda, x, n = m, offsetx = ind, offsety = ind)/a
+        else:
+            lx = blas.dot(lmbda, x, n = m, offsetx = ind, offsety = ind)/a
+        x0 = x[ind]
+        x[ind] = lx
+        c = (lx + x0) / (lmbda[ind]/a + 1) / a 
+        if inverse == 'N':  c *= -1.0
+        blas.axpy(lmbda, x, alpha = c, n = m-1, offsetx = ind+1, offsety =
+            ind+1)
+        if inverse == 'N': a = 1.0/a 
+        blas.scal(a, x, offset = ind, n = m)
+        ind += m
+        
+
+    # For the 's' blocks, if inverse is 'N',
+    #
+    #     xk := vec( diag(l)^{-1/2} * mat(xk) * diag(k)^{-1/2}).
+    #
+    # If inverse is 'I',
+    #
+    #     xk := vec( diag(l)^{1/2} * mat(xk) * diag(k)^{1/2}).
+    #
+    # where l is kth block of lambda.
+    # 
+    # We scale upper and lower triangular part of mat(xk) because the
+    # inverse operation will be applied to nonsymmetric matrices.
+
+    ind2 = ind
+    for k in xrange(len(dims['s'])):
+        m = dims['s'][k]
+        for j in xrange(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)
+            else:
+                blas.tbmv(c, x, n = m, k = 0, ldA = 1, offsetx = ind + j*m)
+        ind += m*m
+        ind2 += m
+
+
+def max_step(x, mnl, dims, sigma = None):
+
+    # Returns min {t | x + t*e >= 0}.
+    # When called with the argument sigma, also returns the eigenvalues 
+    # (in sigma) and the eigenvectors (in x) of the 's' components of x.
+
+    t = []
+    ind = mnl + dims['l']
+    if ind: t += [ -min(x[:ind]) ] 
+    for m in dims['q']:
+        if m: t += [ blas.nrm2(x, offset = ind + 1, n = m-1) - x[ind] ]
+        ind += m
+    if sigma is None and dims['s']:  
+        Q = matrix(0.0, (max(dims['s']), max(dims['s'])))
+        w = matrix(0.0, (max(dims['s']),1))
+    ind2 = 0
+    for m in dims['s']:
+        if sigma is None:
+            blas.copy(x, Q, offsetx = ind, n = m**2)
+            lapack.syevr(Q, w, range = 'I', il = 1, iu = 1, n = m, ldA = m)
+            if m:  t += [ -w[0] ]
+        else:            
+            lapack.syevd(x, sigma, jobz = 'V', n = m, ldA = m, offsetA = 
+                ind, offsetW = ind2)
+            if m:  t += [ -sigma[ind2] ] 
+        ind += m*m
+        ind2 += m
+    if t: return max(t)
+    else: return 0.0
+
+
+
+def sgemv(A, x, y, dims, trans = 'N', alpha = 1.0, beta = 0.0, m = None, 
+    n = None, offsetA = 0, offsety = 0): 
+
+    # A is a matrix or spmatrix of size (N, n) where 
+    #
+    #     N = dims['l'] + sum(dims['q']) + sum( k**2 for k in dims['s'] ). 
+    #
+    # If trans is 'N': 
+    #
+    #     y := alpha*A*x + beta * y   (trans = 'N').
+    #
+    # x is a vector of length n.  y is a vector of length N.
+    #
+    # If trans is 'T':
+    #
+    #     y := alpha*A'*x + beta * y  (trans = 'T').
+    #
+    # x is a vector of length N.  y is a vector of length n.
+    #
+    # The 's' components in S are stored in unpacked 'L' storage.
+
+    if m is None: m = A.size[0]
+    if n is None: n = A.size[1]
+
+    if trans == 'T' and alpha:
+        ind = dims['l'] + sum(dims['q'])
+        for mk in dims['s']:
+            # Set upper triangular part of x to zero and scale strict 
+            # lower triangular part by 2.
+            for j in xrange(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) 
+            ind += mk**2
+
+    base.gemv(A, x, y, trans = trans, alpha = alpha, beta = beta, m = m,
+        n = n, offsetA = offsetA, offsety = offsety)
+
+    if trans == 'T' and alpha:
+        ind = dims['l'] + sum(dims['q'])
+        for mk in dims['s']:
+            # Scale strict lower triangular part of x by 0.5.
+            for j in xrange(1, mk):  
+                blas.scal(0.5, x, offset = ind + mk*(j-1) + j, n = mk-j) 
+            ind += mk**2
+
+
+
+def jdot(x, y, n = None, offsetx = 0, offsety = 0):
+
+    # Returns x' * J * y, where J = [1, 0; 0, -I].
 
     if n is None: 
-        if x.size != y.size:
-            raise ValueError, "x and y must have the same size"
-        else:
-            n = len(x)
-    if len(x) < n or len(y) < n:
-        raise ValueError, "x and y must have length at least n"
-    blas.tbmv(y, x, n=n, k=0, ldA=1) 
+         if len(x) != len(y): raise ValueError, "x and y must have the "\
+             "same length"
+         n = len(x)
+    return x[offsetx] * y[offsety] - blas.dot(x, y, n = n-1, 
+        offsetx = offsetx + 1, offsety = offsety + 1) 
 
 
-def ihad(x,y):  
-    """
-    Returns componentwise division x./y of dense 'd' matrices x and y.
 
-    y is a 'd' matrix.   x is a scalar or a 'd' matrix of the same
-    size as y.
+def jnrm2(x, n = None, offset = 0):
 
-    Returns x ./ y as a new matrix.
-    """ 
+    # Returns sqrt(x' * J * x) where J = [1, 0; 0, -I], for a vector
+    # x in a second order cone. 
 
-    if type(x) is float or type(x) is int:
-        z = matrix(x, y.size, tc='d')
-    else:
-        z = +x 
-    if z.size != y.size:
-        raise ValueError, "x and y must have the same size"
-    blas.tbsv(y, z, n=len(y), k=0, ldA=1) 
-    return z
+    if n is None:  n = len(x)
+    a = blas.nrm2(x, n = n-1, offset = offset+1)
+    return math.sqrt(x[offset] - a) * math.sqrt(x[offset] + a)
 
 
-def ihad2(x, y, n=None):  
-    """
-    In-place Hadamard division x./y of dense matrices x and y.
 
-    x and y are dense 'd' matrices of equal size.
-    
-    n is a nonnegative integer, with default value len(x).  If the
-    default value is used, len(x) must be equal to len(y).
+def pack(x, y, mnl, dims, offsetx = 0, offsety = 0):
 
-    On exit x[:n] is replaced with  x[:n]./y[:n].
-    """ 
+     # The vector x is an element of S, with the 's' components stored 
+     # in unpacked storage.  On return, x is copied to y with the 's' 
+     # components matrices stored in packed storage and the off-diagonal 
+     # entries scaled by sqrt(2).
 
-    if n is None: 
-        if x.size != y.size:
-            raise ValueError, "x and y must have the same size"
-        else:
-            n = len(x)
-    if len(x) < n or len(y) < n:
-        raise ValueError, "x and y must have length at least n"
-    blas.tbsv(y, x, n=n, k=0, ldA=1) 
+     nlq = mnl + dims['l'] + sum(dims['q'])
+     np = sum([ n*(n+1)/2 for n in dims['s'] ])
+     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):
+             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 
+     blas.scal(math.sqrt(2.0), y, n = np, offset = offsety+nlq)
+     
 
 
-def scopy(x, y):
-    """
-    y := x for symmetric or block-diagonal symmetric dense matrices.
-    """
+def unpack(x, y, mnl, dims, offsetx = 0, offsety = 0):
 
-    if type(x) is matrix: 
-	blas.copy(x, y)
-    else:
-	for k in xrange(len(x)): blas.copy(x[k], y[k])
+     # The vector x is an element of S, with the 's' components stored
+     # in unpacked storage and off-diagonal entries scaled by sqrt(2).
+     # On return, x is copied to y with the 's' components stored in 
+     # unpacked storage and off-diagonal entries scaled by sqrt(2).
 
-	
-def sdot(x, y):
-    """
-    Inner product of two block-diagonal symmetric dense 'd' matrices.
+     nlq = mnl + dims['l'] + sum(dims['q'])
+     nu = sum([ n**2 for n in dims['s'] ])
+     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):
+             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
+         iu += n**2 
+     blas.scal(1.0/math.sqrt(2.0), y, n = nu, offset = offsety+nlq)
 
-    x and y are square dense 'd' matrices, or lists of N square dense
-    'd' matrices.
-    """
 
-    a = 0.0
-    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):
-	    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)):
-	    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):
-		a += 2.0 * blas.dot(x[k], y[k], incx=n+1, incy=n+1, 
-		    offsetx=j, offsety=j, n=n-j)
+def sdot(x, y, mnl, dims):
+
+    # Returns the inner product of two vectors in S
+    
+    ind = mnl + dims['l'] + sum(dims['q'])
+    a = blas.dot(x, y, n = ind)
+    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):
+            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
     return a
 
 
-def sscal(alpha, x):
-    """
-    x := alpha*x for symmetric or block-diagonal symmetric dense 'd'
-    matrices.
-    """
 
-    if type(x) is matrix: 
-	blas.scal(alpha, x)
-    else:
-	for xk in x: blas.scal(alpha, xk)
+def snrm2(x, mnl, dims): 
 
+    # Returns the norm of a vector in S
 
-def saxpy(x, y, alpha=1.0):
-    """
-    y := alpha*x + y for symmetric or block-diagonal symmetric dense 
-    'd' matrices.
-    """
+    return math.sqrt(sdot(x, x, mnl, dims))
 
-    if type(x) is matrix: 
-	blas.axpy(x, y, alpha=alpha)
-    else:
-	for k in xrange(len(x)): blas.axpy(x[k], y[k], alpha=alpha)
 
+def symm(x, n, offset = 0):
+
+    # Fills in the upper triangular part of the symmetric matrix stored in
+    # x[offset : offset+n*n] using 'L' storage.
+
+    if n <= 1:  pass
+    for i in xrange(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)
 
-def snrm2(x):
-    """
-    Frobenius norm of symmetric matrix or block-diagonal symmetric 
-    dense 'd' matrix.
-    """
 
-    return math.sqrt(sdot(x,x))
+def sprod(x, y, mnl, dims, diag = 'N'):   
 
+    # The product x := (y o x).  If diag is 'D', the 's' part of y is 
+    # diagonal and only the diagonal is stored.
 
-def cngrnc(R, X, Y, trans='N', alpha=1.0, beta=0.0):
-    """
-    Congruence transformation
 
-	Y := alpha * R*X*R^T + beta*Y  if trans is 'N' 
-	Y := alpha * R^T*X*R + beta*Y  if trans is 'T'
+    # For the nonlinear and 'l' blocks:  
+    #
+    #     yk o xk = yk .* xk.
 
-    R, X and Y are lists of square dense 'd' matrices.  
-    X may be equal to Y.
-    Note that trans='T' is slightly faster than trans='N'.
-    """
+    blas.tbmv(y, x, n = mnl + dims['l'], k = 0, ldA = 1) 
 
-    maxn = max([0] + [R_k.size[0] for R_k in R])
-    W = matrix(0.0, (maxn,maxn))
-    for k in xrange(len(R)):
-        n = R[k].size[0]
 
-        # scale diagonal of X by 1/2
-        blas.scal(0.5, X[k], inc=n+1)
+    # For 'q' blocks: 
+    #
+    #               [ lo   l1'  ]
+    #     yk o xk = [           ] * xk
+    #               [ lo   l0*I ] 
+    #
+    # where yk = (l0, l1).
     
-        # W := R*tril(X) (trans is 'N') or W := tril(X)*R (trans is 'T')
-        blas.copy(R[k], W)
-        if trans == 'N': 
-	    blas.trmm(X[k], W, side='R', m=n, n=n, ldB=n)
-        else: 
-	    blas.trmm(X[k], W, side='L', m=n, n=n, ldB=n)
+    ind = mnl + dims['l']
+    for m in dims['q']:
+        dd = blas.dot(x, y, offsetx = ind, offsety = ind, n = m)
+        blas.scal(y[ind], x, offset = ind+1, n = m-1)
+        blas.axpy(y, x, alpha = x[ind], n = m-1, offsetx = ind+1, offsety 
+            = ind+1)
+        x[ind] = dd
+        ind += m
 
-        # scale diagonal of X by 2
-        blas.scal(2.0, X[k], inc=n+1)
 
-        # Y := alpha*(W*R' + R*W') + beta*Y 
-        blas.syr2k(R[k], W, Y[k], trans=trans, n=n, k=n, ldB=n, 
-            alpha=alpha, beta=beta)
+    # For the 's' blocks:
+    #
+    #    yk o sk = .5 * ( Yk * mat(xk) + mat(xk) * Yk )
+    # 
+    # where Yk = mat(yk) if diag is 'N' and Yk = diag(yk) if diag is 'D'.
 
+    if diag is 'N':
+        maxm = max([0] + dims['s'])
+        A = matrix(0.0, (maxm, maxm))
 
-def kkt(H, A, Df, G, method=3):
-    """
-    Generates a solver for the KKT system
+        for m in dims['s']:
+            blas.copy(x, A, offsetx = ind, n = m*m)
 
-        [ H   *   *     *  ] [ x   ]   [ bx   ]
-        [ A   0   *     *  ] [ y   ] = [ by   ].
-        [ Df  0  -Dnl   *  ] [ znl ]   [ bznl ] 
-        [ G   0   0    -Dl ] [ zl  ]   [ bzl  ]
+            # Write upper triangular part of A and yk.
+            for i in xrange(m-1):
+                symm(A, m)
+                symm(y, m, offset = ind)
 
-    kkt() does a symbolic factorization and returns a function for the 
-    numeric factorization.
+            # xk = 0.5 * (A*yk + yk*A)
+            blas.syr2k(A, y, x, alpha = 0.5, n = m, k = m, ldA = m,  ldB = 
+                m, ldC = m, offsetB = ind, offsetC = ind)
 
-    If f = kkt(H, A, Df, G, method) then f(H, Df, dnl, dl) does the 
-    numeric factorization of the KKT matrix, with  
-    
-        Dnl = diag(dnl)^-2,  Dl = diag(dl)^-2, 
-
-    and returns a function for solving the system.   The arguments H 
-    and Df in f() can be different from the arguments in the call to 
-    kkt() but they must have the same sparsity pattern.
-
-    If g = f(H, Df, dnl, dl) then g(x, y, znl, zl) solves the system. 
-    On entry x, y, znl, zl are the righthand side.  On exit they are 
-    overwritten with the solution.
-    """
-
-    n, p, mnl, ml = H.size[0], A.size[0], Df.size[0], G.size[0]
-
-    if method == 1:
-
-        # Factor entire matrix via dense LDL.
-
-        ldK = n + p + mnl + ml
-        K = matrix(0.0, (ldK,ldK))
-        ipiv = matrix(0, (ldK,1))
-        u = matrix(0.0, (ldK,1))
-        def f(H, Df, dnl, dl):
-            blas.scal(0.0, K)
-            K[:n, :n] = H
-            K[n:n+p, :n] = A
-            K[n+p:n+p+mnl, :n] = Df
-            K[n+p+mnl:, :n] = G
-            K[(ldK+1)*(n+p) : (ldK+1)*(n+p+mnl) : ldK+1] = -dnl**-2
-            K[(ldK+1)*(n+p+mnl) :: ldK+1] = -dl**-2
-            lapack.sytrf(K, ipiv)
-            def g(x, y, znl, zl):
-                u[:n] = x
-                u[n:n+p] = y
-                u[n+p:n+p+mnl] = znl 
-                u[n+p+mnl:] = zl 
-                lapack.sytrs(K, ipiv, u)
-                x[:] = u[:n]
-                y[:] = u[n:n+p]
-                znl[:] = u[n+p:n+p+mnl]
-                zl[:] = u[n+p+mnl:]
-            return g 
-        return f
-
-    elif method == 2:
- 
-        # Factor 
-        #
-        #        [ H + Df'*Dnl^-2*Df + G'*Dl^-2*G    * ]
-        #    S = [                                     ]
-        #        [ A                                 0 ] 
-        #
-        # via dense LDL (if p > 0) or Cholesky (if p = 0).
-        # To solve the KKT system, first solve 
-        #        
-        #        [ x ]   [ bx + Df'*Dnl^-2*bznl + G'*Dl^-2*bzl ]
-        #    S * [   ] = [                                     ]
-        #        [ y ]   [ by                                  ]
-        #
-        #    Dnl^2 * znl = Df*x - bznl
-        #    Dl^2 * zl = Dl.^-2 * (G*x - bzl).
-
-        ldK = n + p
-        K = matrix(0.0, (ldK,ldK))
-        if p: 
-            ipiv = matrix(0, (ldK,1))
-        if type(G) is matrix: 
-            Gsc = matrix(0.0, G.size) 
-        else:
-            Gsc = spmatrix(0.0, G.I, G.J, G.size) 
-        if type(Df) is matrix: 
-            Dfsc = matrix(0.0, Df.size) 
-        else:
-            Dfsc = spmatrix(0.0, Df.I, Df.J, Df.size) 
-        u = matrix(0.0, (ldK,1))
-        def f(H, Df, dnl, dl):
-            blas.scal(0.0, K)
-            K[:n, :n] = H
-            base.gemm(spmatrix(dnl, range(mnl), range(mnl), tc='d'), 
-                Df, Dfsc, partial=True)
-            base.syrk(Dfsc, K, trans='T', beta=1.0)
-            base.gemm(spmatrix(dl, range(ml), range(ml), tc='d'), G, 
-                Gsc, partial=True)
-            base.syrk(Gsc, K, trans='T', beta=1.0)
-            K[n:,:n] = A
-            if p: 
-                lapack.sytrf(K, ipiv)
-            else: 
-                lapack.potrf(K)
-            def g(x, y, znl, zl):
-                u[:n] = x
-                had2(znl, dnl)
-                base.gemv(Dfsc, znl, u, trans='T', beta=1.0)
-                had2(zl, dl)
-                base.gemv(Gsc, zl, u, trans='T', beta=1.0)
-                u[n:n+p] = y
-                if p: 
-                    lapack.sytrs(K, ipiv, u)
-                else: 
-                    lapack.potrs(K, u)
-                x[:] = u[:n]
-                y[:] = u[n:n+p]
-                base.gemv(Dfsc, x, znl, beta=-1.0)
-                had2(znl, dnl)
-                base.gemv(Gsc, x, zl, beta=-1.0)
-                had2(zl, dl)
-            return g 
-        return f
-
-    else: 
-
-        # Factor 
-        #
-        #     S = H + Df'*Dnl^-2*Df + G'*Dl^-2*G  
-        #     K = A*S^-1*A'
-        #
-        # using dense (L*L') or sparse (P'*L*L'*P) Cholesky 
-        # factorizations.  To solve the system, solve
-        #
-        #     K*y = A * S^{-1} * (bx + Df'*Dnl^-2*bznl + G'*Dl^-2*bzl) 
-        #          - by
-        #     S*x = bx + Df'*Dnl.^-2* bznl + G'*Dl^-2*bzl - A'*y
-        #     Dnl^2 * znl = Df*x - bznl
-        #     Dl^2 * zl  = G*x - bzl
-        #    
-        # If S turns out to be singular in the first factorization,
-        # then switch to the following method.
-        #
-        # Factor 
-        #
-        #     S = H + Df'*Dnl^-2*Df + G'*Dl^-2*G  + A'*A
-        #     K = A*S^-1*A'
-        #
-        # using dense (L*L') or sparse (P'*L*L'*P) Cholesky 
-        # factorizations.  To solve the system, solve
-        #
-        #    K*y = A*S^{-1} * (bx + Df'*Dnl^-2*bznl + G'*Dl^-2*bzl + 
-        #          A'*by) - by
-        #    S*x = bx + Df'*Dnl.^-2*bznl + G'*Dl^-2*bzl + A'*by - A'*y
-        #    Dnl^2*znl = Df*x - bznl
-        #    Dl^2*zl = G*x - bzl.
-
-        if type(G) is matrix: 
-            Gsc = matrix(0.0, G.size) 
-        else:
-            Gsc = spmatrix(0.0, G.I, G.J, G.size) 
-        if type(Df) is matrix: 
-            Dfsc = matrix(0.0, Df.size) 
-        else:
-            Dfsc = spmatrix(0.0, Df.I, Df.J, Df.size) 
-        F = {'firstcall': True, 'singular': False}
-        if matrix in (type(H), type(G), type(Df)):
-            F['S'] = matrix(0.0, (n,n))
-            F['K'] = matrix(0.0, (p,p))
-        else: 
-            F['S'] = spmatrix([], [], [], (n,n), 'd')
-            F['Sf'] = None
-            if type(A) is matrix:
-                F['K'] = matrix(0.0, (p,p))
-            else:
-                F['K'] = spmatrix([], [], [], (p,p), 'd')
-
-        def f(H, Df, dnl, dl):
-            base.gemm(spmatrix(dnl, range(mnl), range(mnl), tc='d'), Df,
-                Dfsc, partial=True)
-            base.gemm(spmatrix(dl, range(ml), range(ml), tc='d'), G, 
-                Gsc, partial=True)
-            if F['firstcall']:
-                F['firstcall'] = False
-                F['S'][:,:] = H
-                base.syrk(Dfsc, F['S'], trans='T', beta=1.0) 
-                base.syrk(Gsc, F['S'], trans='T', beta=1.0) 
-                try:
-                    if type(F['S']) is matrix: 
-                        lapack.potrf(F['S']) 
-                    else:
-                        F['Sf'] = cholmod.symbolic(F['S'])
-                        cholmod.numeric(F['S'], F['Sf'])
-                except ArithmeticError:
-                    F['singular'] = True 
-                    if type(A) is matrix and type(F['S']) is spmatrix:
-                        F['S'] = matrix(0.0, (n,n))
-                    F['S'][:,:] = H 
-                    base.syrk(Dfsc, F['S'], trans='T', beta=1.0) 
-                    base.syrk(Gsc, F['S'], trans='T', beta=1.0) 
-                    base.syrk(A, F['S'], trans='T', beta=1.0) 
-                    if type(F['S']) is matrix: 
-                        lapack.potrf(F['S']) 
-                    else:
-                        F['Sf'] = cholmod.symbolic(F['S'])
-                        cholmod.numeric(F['S'], F['Sf'])
+            ind += m*m
 
-            else:
-                # S := H, but do not remove nonzeros from the zero 
-                # pattern of S if S is sparse.
-                if type(F['S']) is spmatrix and type(H) is spmatrix:
-                    F['S'] *= 0.0
-                    F['S'] += H
-                else:
-                    F['S'][:,:] = H 
-
-                base.syrk(Dfsc, F['S'], trans='T', beta=1.0, 
-                    partial=True)
-                base.syrk(Gsc, F['S'], trans='T', beta=1.0, 
-                    partial=True)
-                if F['singular']:
-                    base.syrk(A, F['S'], trans='T', beta=1.0, 
-                        partial=True) 
-                if type(F['S']) is matrix: 
-                    lapack.potrf(F['S']) 
-                else:
-                    cholmod.numeric(F['S'], F['Sf'])
-
-            if type(F['S']) is matrix: 
-                # Asct := L^-1*A', factor K = Asct'*Asct.
-                if type(A) is matrix: 
-                    Asct = A.T
-                else: 
-                    Asct = matrix(A.T)
-                blas.trsm(F['S'], Asct)
-                blas.syrk(Asct, F['K'], trans='T')
-                lapack.potrf(F['K'])
+    else:
+        ind2 = ind
+        for m in dims['s']:
+            for j in xrange(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))  
+            ind += m*m
+            ind2 += m
 
-            else:
-                # Asct := L^{-1}*P*A' and factor K = Asct'*Asct.
-                if type(A) is matrix:
-                    Asct = A.T
-                    cholmod.solve(F['Sf'], Asct, sys=7)
-                    cholmod.solve(F['Sf'], Asct, sys=4)
-                    blas.syrk(Asct, F['K'], trans='T')
-                    lapack.potrf(F['K']) 
-                else:
-                    Asct = cholmod.spsolve(F['Sf'], A.T, sys=7)
-                    Asct = cholmod.spsolve(F['Sf'], Asct, sys=4)
-                    base.syrk(Asct, F['K'], trans='T')
-                    Kf = cholmod.symbolic(F['K'])
-                    cholmod.numeric(F['K'], Kf)
-
-            def g(x, y, znl, zl):
-
-                # If not F['singular']:
-                # x := L^{-1} * P * (x + Df'*(dnl.^2.*znl) + 
-                #      G'*dl.^2.*zl)
-                #    = L^{-1} * P * (bx + Df'*Dnl^-2*bznl + 
-                #      G'*Dl^-2*bzl)
-                #
-                # If F['singular']:
-                # x := L^{-1} * P * (x + Df'*(dnl.^2.*znl) + 
-                #      G'*(dl.^2.*zl) + A'*y)
-                #    = L^{-1} * P * (bx + Df'*Dnl^-2*bznl + 
-                #      G'*Dl^-2*bzl + A'*by)
-
-                had2(znl, dnl)
-                base.gemv(Dfsc, znl, x, trans='T', beta=1.0)
-                had2(zl, dl)
-                base.gemv(Gsc, zl, x, trans='T', beta=1.0)
-                if F['singular']:
-                    base.gemv(A, y, x, trans='T', beta=1.0)
-                if type(F['S']) is matrix:
-                    blas.trsv(F['S'], x)
-                else:
-                    cholmod.solve(F['Sf'], x, sys=7)
-                    cholmod.solve(F['Sf'], x, sys=4)
-
-                # y := K^{-1} * (Asc*x - y)
-                #    = K^{-1} * (A * S^{-1} * (bx + Df'*Dnl^-2*bznl +
-                #      G'*Dl^-2*bzl) - by)  (if not F['singular'])
-                #    = K^{-1} * (A * S^{-1} * (bx + Df'*Dnl^-2*bznl +
-                #      G'*Dl^-2*bzl + A'*by) - by)  (if F['singular'])
-
-                base.gemv(Asct, x, y, trans='T', beta=-1.0)
-                if type(F['K']) is matrix:
-                    lapack.potrs(F['K'], y)
-                else:
-                    cholmod.solve(Kf, y)
-
-                # x := P' * L^{-T} * (x - Asc'*y)
-                #    = S^{-1} * (bx + Df'*Dnl^-2*bznl + G'*Dl^-2*bzl 
-                #      - A'*y) (if not F['singular'])  
-                #    = S^{-1} * (bx + Df'*Dnl^-2*bznl + G'*Dl^-2*bzl
-                #      + A'*by - A'*y) (if F['singular'])
-
-                base.gemv(Asct, y, x, alpha=-1.0, beta=1.0)
-                if type(F['S']) is matrix:
-                    blas.trsv(F['S'], x, trans='T')
-                else:
-                    cholmod.solve(F['Sf'], x, sys=5)
-                    cholmod.solve(F['Sf'], x, sys=8)
-
-                # znl := dnl .* (Dfsc*x - znl) 
-                #      = Dnl^-2 * (Df*x - bznl)
-                base.gemv(Dfsc, x, znl, beta=-1.0)
-                had2(znl, dnl)
-
-                # zl := dl .* (Gsc*x - zl) 
-                #     = Dl^-2 * (G*x - bzl)
-                base.gemv(Gsc, x, zl, beta=-1.0)
-                had2(zl, dl)
-
-            return g
-
-        return f
+
+
+def sinv(x, y, mnl, dims):   
+
+    # The inverse product x := (y o\ x), when the 's' components of y are 
+    # diagonal.
+    
+    # For the nonlinear and 'l' blocks:  
+    # 
+    #     yk o\ xk = yk .\ xk.
+
+    blas.tbsv(y, x, n = mnl + dims['l'], k = 0, ldA = 1)
+
+
+    # For the 'q' blocks: 
+    #
+    #                        [ l0   -l1'              ]  
+    #     yk o\ xk = 1/a^2 * [                        ] * xk
+    #                        [ -l1  (a*I + l1*l1')/l0 ]
+    #
+    # where yk = (l0, l1) and a = l0^2 - l1'*l1.
+
+    ind = mnl + dims['l']
+    for m in dims['q']:
+        aa = jnrm2(y, n = m, offset = ind)**2
+        cc = x[ind]
+        dd = blas.dot(y, x, offsetx = ind+1, offsety = ind+1, n = m-1)
+        x[ind] = cc * y[ind] - dd
+        blas.scal(aa / y[ind], x, n = m-1, offset = ind+1)
+        blas.axpy(y, x, alpha = dd/y[ind] - cc, n = m-1, offsetx = ind+1, 
+            offsety = ind+1)
+        blas.scal(1.0/aa, x, n = m, offset = ind)
+        ind += m
+
+
+    # For the 's' blocks:
+    #
+    #     yk o\ xk =  xk ./ gamma
+    #
+    # where gammaij = .5 * (yk_i + yk_j).
+
+    ind2 = ind
+    for m in dims['s']:
+        for j in xrange(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))  
+        ind += m*m
+        ind2 += m
diff --git a/src/python/modeling.py b/src/python/modeling.py
index bc3c04b..0d9208b 100644
--- a/src/python/modeling.py
+++ b/src/python/modeling.py
@@ -7,7 +7,7 @@ piecewise-linear objective and constraint functions.
 
 # Copyright 2004-2007 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 0.9.
+# This file is part of CVXOPT version 0.9.1.
 #
 # 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/python/mosek.py b/src/python/mosek.py
new file mode 100644
index 0000000..93a3e6e
--- /dev/null
+++ b/src/python/mosek.py
@@ -0,0 +1,706 @@
+"""
+CVXOPT interface for MOSEK 5.0
+"""
+
+# Copyright 2004-2007 J. Dahl and L. Vandenberghe.
+# 
+# This file is part of CVXOPT version 0.9.1
+#
+# CVXOPT is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# CVXOPT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+from cvxopt.base import matrix, spmatrix, sparse
+
+import pymosek as msk
+from mosekarr import array, zeros, Float
+
+# Define a stream printer to grab output from MOSEK 
+def streamprinter(text): print text,
+    
+inf = 0.0  # numeric value doesn't matter
+
+options = {}
+
+def solvelp(c, G, h, A=None, b=None):
+    """
+    Solves a pair of primal and dual LPs 
+
+        minimize    c'*x             maximize    -h'*z - b'*y 
+        subject to  G*x + s = h      subject to  G'*z + A'*y + c = 0
+                    A*x = b                      z >= 0.
+                    s >= 0
+                    
+    using MOSEK 5.0.
+
+    (solsta, x, y, z) = solvelp(c, G, h, A=None, b=None).
+
+    Input arguments 
+
+        G is m x n, h is m x 1, A is p x n, b is p x 1.  G and A must be 
+        dense or sparse 'd' matrices.   h and b are dense 'd' matrices 
+        with one column.  The default values for A and b are empty 
+        matrices with zero rows.
+
+
+    Return values
+
+        solsta   the solution status.
+                 If solsta is solsta.optimal,
+                   then (x, y, z) contains the primal-dual solution.
+                 If solsta is solsta.prim_infeas_cer,
+                   then (x, y, z) is a certificate of primal infeasibility.
+                 If solsta is solsta.dual_infeas_cer,
+                   then (x, y, z) is a certificate of dual infeasibility.
+                 If solsta is solsta.unknown,
+                   then (x, y, z) are all None
+
+                 Other return values for solsta include:  
+                   solsta.dual_feas  
+                   solsta.near_dual_feas
+                   solsta.near_optimal
+                   solsta.near_prim_and_dual_feas
+                   solsta.near_prim_feas
+                   solsta.prim_and_dual_feas
+                   solsta.prim_feas
+                 in which case the (x,y,z) value may not be well-defined,
+                 c.f., the MOSEK documentation.
+        
+        x, y, z  the primal-dual solution.                    
+
+    Options are passed to MOSEK solvers via the mosek.options
+    dictionary, e.g., the following turns off output from 
+    the MOSEK solvers
+    
+    >>> mosek.options = {iparam.log:0} 
+    
+    see chapter 14 of the MOSEK Python API manual.                    
+    """
+    if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1: 
+        raise TypeError, "'c' must be a dense column matrix"
+    n = c.size[0]
+    if n < 1: raise ValueError, "number of variables must be at least 1"
+
+    if (type(G) is not matrix and type(G) is not spmatrix) or \
+        G.typecode != 'd' or G.size[1] != n:
+        raise TypeError, "'G' must be a dense or sparse 'd' matrix "\
+            "with %d columns" %n 
+    m = G.size[0]
+    if m is 0: raise ValueError, "m cannot be 0"
+
+    if type(h) is not matrix or h.typecode != 'd' or h.size != (m,1):
+        raise TypeError, "'h' must be a 'd' matrix of size (%d,1)" %m
+
+    if A is None:  A = spmatrix([], [], [], (0,n), 'd')
+    if (type(A) is not matrix and type(A) is not spmatrix) or \
+        A.typecode != 'd' or A.size[1] != n:
+        raise TypeError, "'A' must be a dense or sparse 'd' matrix "\
+            "with %d columns" %n
+    p = A.size[0]
+    if b is None: b = matrix(0.0, (0,1))
+    if type(b) is not matrix or b.typecode != 'd' or b.size != (p,1): 
+        raise TypeError, "'b' must be a dense matrix of size (%d,1)" %p
+ 
+    c   = array(c)        
+
+    bkc = m*[ msk.boundkey.up ] + p*[ msk.boundkey.fx ]
+    blc = m*[ -inf ] + [ bi for bi in b ]
+    buc = matrix([h, b])
+
+    bkx = n*[msk.boundkey.fr] 
+    blx = n*[ -inf ] 
+    bux = n*[ +inf ]
+
+    colptr, asub, acof = sparse([G,A]).CCS
+    aptrb, aptre = colptr[:-1], colptr[1:]
+
+    mskhandle = msk.mosek ()
+    env = mskhandle.Env ()
+    env.set_Stream (msk.streamtype.log, streamprinter)
+        
+    env.init () 
+    task = env.Task(0,0) 
+    task.set_Stream (msk.streamtype.log, streamprinter) 
+
+    # set MOSEK options 
+    for (param, val) in options.items():
+        if str(param)[:6] == "iparam":
+            task.putintparam(param, val)
+        elif str(param)[:6] == "dparam":
+            task.putdouparam(param, val)
+        elif str(param)[:6] == "sparam":
+            task.putstrparam(param, val)
+        else:
+            raise ValueError, "invalid MOSEK parameter: "+str(param)
+
+    task.inputdata (m+p, # number of constraints
+                    n,   # number of variables
+                    array(c), # linear objective coefficients  
+                    0.0, # objective fixed value  
+                    array(aptrb), 
+                    array(aptre), 
+                    array(asub),
+                    array(acof), 
+                    array(bkc),
+                    array(blc),
+                    array(buc), 
+                    array(bkx),
+                    array(blx),
+                    array(bux)) 
+
+    task.putobjsense(msk.objsense.minimize)
+
+    task.optimize()
+
+    task.solutionsummary (msk.streamtype.msg); 
+
+    prosta, solsta = list(), list()
+    task.getsolutionstatus(msk.soltype.bas, prosta, solsta)
+
+    x, z = zeros(n, Float), zeros(m, Float)
+    task.getsolutionslice(msk.soltype.bas, msk.solitem.xx, 0, n, x) 
+    task.getsolutionslice(msk.soltype.bas, msk.solitem.suc, 0, m, z) 
+    x, z = matrix(x), matrix(z)
+    
+    if p is not 0:
+        yu, yl = zeros(p, Float), zeros(p, Float)
+        task.getsolutionslice(msk.soltype.bas, msk.solitem.suc, m, m+p, yu) 
+        task.getsolutionslice(msk.soltype.bas, msk.solitem.slc, m, m+p, yl) 
+        y = matrix(yu) - matrix(yl)
+    else:
+        y = matrix(0.0, (0,1))
+
+    if (solsta[0] is msk.solsta.unknown):
+        return (solsta[0], None, None, None)
+    else:
+        return (solsta[0], x, z, y)
+
+
+def conelp(c, G, h, dims = None):
+    """
+    Solves a pair of primal and dual SOCPs
+
+        minimize    c'*x             
+        subject to  Gl*x + sl = hl      
+                    Gq[k]*x + sq[k] = hq[k],  k = 0, ..., N-1
+                    sl >= 0,  
+                    sq[k] >= 0, k = 0, ..., N-1
+
+        maximize    -hl'*zl - sum_k hq[k]'*zq[k] 
+        subject to  Gl'*zl + sum_k Gq[k]'*zq[k] + c = 0
+                    zl >= 0,  zq[k] >= 0, k = 0, ..., N-1.
+                    
+    using MOSEK 5.0.
+
+    (solsta, x, zl, zq) = conelp(c, G, h, dims = None)
+
+    The formats of G and h are identical to that used in the
+    solvers.conelp method, except that only carthesian and quadratic cones 
+    are allow  (dims['s'] must be zero, if defined).
+ 
+    Return values
+
+        solsta   the solution status.
+                 If solsta is solsta.optimal,
+                   then (x, zl, zq) contains the primal-dual solution.
+                 If solsta is solsta.prim_infeas_cer,
+                   then (x, zl, zq) is a certificate of primal infeasibility.
+                 If solsta is solsta.dual_infeas_cer,
+                   then (x, zl, zq) is a certificate of dual infeasibility.
+                 If solsta is solsta.unknown,
+                   then (x, zl, zq) are all None
+
+                 Other return values for solsta include:  
+                   solsta.dual_feas  
+                   solsta.near_dual_feas
+                   solsta.near_optimal
+                   solsta.near_prim_and_dual_feas
+                   solsta.near_prim_feas
+                   solsta.prim_and_dual_feas
+                   solsta.prim_feas
+                 in which case the (x,y,z) value may not be well-defined,
+                 c.f., the MOSEK documentation.
+        
+        x, zl, zq  the primal-dual solution.
+
+
+    Options are passed to MOSEK solvers via the mosek.options 
+    dictionary, e.g., the following turns off output from 
+    the MOSEK solvers
+    
+    >>> mosek.options = {iparam.log:0} 
+    
+    see chapter 14 of the MOSEK Python API manual.                    
+    """
+
+    if dims is None: 
+        (solsta, x, y, z) = solvelp(c, G, h)
+        return (solsta, x, z, None)
+
+    try:
+        if len(dims['s']) > 0: raise ValueError, "dims['s'] must be zero"
+    except:
+        pass
+
+    N, n = G.size
+    ml, mq = dims['l'], dims['q']
+    cdim = ml + sum(mq)
+    if cdim is 0: raise ValueError, "ml+mq cannot be 0"
+
+    # Data for kth 'q' constraint are found in rows indq[k]:indq[k+1] of G.
+    indq = [ dims['l'] ]  
+    for k in dims['q']:  indq = indq + [ indq[-1] + k ] 
+
+    if type(h) is not matrix or h.typecode != 'd' or h.size[1] != 1:
+        raise TypeError, "'h' must be a 'd' matrix with 1 column" 
+    if type(G) is matrix or type(G) is spmatrix:
+        if G.typecode != 'd' or G.size[0] != cdim:
+            raise TypeError, "'G' must be a 'd' matrix with %d rows " %cdim
+        if h.size[0] != cdim:
+            raise TypeError, "'h' must have %d rows" %cdim 
+    else: 
+        raise TypeError, "'G' must be a matrix"
+
+    if min(dims['q'])<1: raise TypeError, \
+            "dimensions of quadratic cones must be positive"
+
+    bkc = n*[ msk.boundkey.fx ] 
+    blc = array(-c)
+    buc = array(-c)
+
+    bkx = ml*[ msk.boundkey.lo ] + sum(mq)*[ msk.boundkey.fr ]
+    blx = ml*[ 0.0 ] + sum(mq)*[ -inf ]
+    bux = N*[ +inf ] 
+
+    c   = -h        
+    
+    colptr, asub, acof = sparse([G.T]).CCS
+    aptrb, aptre = colptr[:-1], colptr[1:]
+
+    mskhandle = msk.mosek ()
+    env = mskhandle.Env ()
+    env.set_Stream (msk.streamtype.log, streamprinter)
+        
+    env.init () 
+    task = env.Task(0,0) 
+    task.set_Stream (msk.streamtype.log, streamprinter) 
+
+    # set MOSEK options 
+    for (param, val) in options.items():
+        if str(param)[:6] == "iparam":
+            task.putintparam(param, val)
+        elif str(param)[:6] == "dparam":
+            task.putdouparam(param, val)
+        elif str(param)[:6] == "sparam":
+            task.putstrparam(param, val)
+        else:
+            raise ValueError, "invalid MOSEK parameter: "+str(param)
+
+    task.inputdata (n,   # number of constraints
+                    N,   # number of variables
+                    array(c), # linear objective coefficients  
+                    0.0, # objective fixed value  
+                    array(aptrb), 
+                    array(aptre), 
+                    array(asub),
+                    array(acof), 
+                    array(bkc),
+                    array(blc),
+                    array(buc), 
+                    array(bkx),
+                    array(blx),
+                    array(bux)) 
+
+    task.putobjsense(msk.objsense.maximize)
+
+    for k in xrange(len(mq)):
+        task.appendcone(msk.conetype.quad, 0.0, 
+                        array(range(ml+sum(mq[:k]),ml+sum(mq[:k+1]))))
+    task.optimize()
+
+    task.solutionsummary (msk.streamtype.msg); 
+
+    prosta, solsta = list(), list()
+    task.getsolutionstatus(msk.soltype.itr, prosta, solsta)
+
+    xu, xl, zq = zeros(n, Float), zeros(n, Float), zeros(sum(mq), Float)
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.slc, 0, n, xl) 
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.suc, 0, n, xu) 
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.xx, ml, N, zq) 
+    x = matrix(xu-xl)
+
+    if ml:
+        zl = zeros(ml, Float)
+        task.getsolutionslice(msk.soltype.itr, msk.solitem.xx, 0, ml, zl) 
+        zl = matrix(zl)
+    else:
+        zl = matrix(0.0, (0,1))
+
+    if (solsta[0] is msk.solsta.unknown):
+        return (solsta[0], None, None, None)
+    else:
+        return (solsta[0], x, zl, zq)
+    
+
+
+
+def socp(c, Gl = None, hl = None, Gq = None, hq = None):
+    """
+    Solves a pair of primal and dual SOCPs
+
+        minimize    c'*x             
+        subject to  Gl*x + sl = hl      
+                    Gq[k]*x + sq[k] = hq[k],  k = 0, ..., N-1
+                    sl >= 0,  
+                    sq[k] >= 0, k = 0, ..., N-1
+
+        maximize    -hl'*zl - sum_k hq[k]'*zq[k] 
+        subject to  Gl'*zl + sum_k Gq[k]'*zq[k] + c = 0
+                    zl >= 0,  zq[k] >= 0, k = 0, ..., N-1.
+                    
+    using MOSEK 5.0.
+
+    (solsta, x, zl, zq) = socp(c, Gl = None, hl = None, Gq = None, hq = None)
+
+    Return values
+
+        solsta   the solution status.
+                 If solsta is solsta.optimal,
+                   then (x, zl, zq) contains the primal-dual solution.
+                 If solsta is solsta.prim_infeas_cer,
+                   then (x, zl, zq) is a certificate of primal infeasibility.
+                 If solsta is solsta.dual_infeas_cer,
+                   then (x, zl, zq) is a certificate of dual infeasibility.
+                 If solsta is solsta.unknown,
+                   then (x, zl, zq) are all None
+
+                 Other return values for solsta include:  
+                   solsta.dual_feas  
+                   solsta.near_dual_feas
+                   solsta.near_optimal
+                   solsta.near_prim_and_dual_feas
+                   solsta.near_prim_feas
+                   solsta.prim_and_dual_feas
+                   solsta.prim_feas
+                 in which case the (x,y,z) value may not be well-defined,
+                 c.f., the MOSEK documentation.
+        
+        x, zl, zq  the primal-dual solution.
+
+
+    Options are passed to MOSEK solvers via the mosek.options 
+    dictionary, e.g., the following turns off output from 
+    the MOSEK solvers
+    
+    >>> mosek.options = {iparam.log:0} 
+    
+    see chapter 14 of the MOSEK Python API manual.                    
+    """
+    if type(c) is not matrix or c.typecode != 'd' or c.size[1] != 1: 
+        raise TypeError, "'c' must be a dense column matrix"
+    n = c.size[0]
+    if n < 1: raise ValueError, "number of variables must be at least 1"
+
+    if Gl is None:  Gl = spmatrix([], [], [], (0,n), tc='d')
+    if (type(Gl) is not matrix and type(Gl) is not spmatrix) or \
+        Gl.typecode != 'd' or Gl.size[1] != n:
+        raise TypeError, "'Gl' must be a dense or sparse 'd' matrix "\
+            "with %d columns" %n
+    ml = Gl.size[0]
+    if hl is None: hl = matrix(0.0, (0,1))
+    if type(hl) is not matrix or hl.typecode != 'd' or \
+        hl.size != (ml,1):
+        raise TypeError, "'hl' must be a dense 'd' matrix of " \
+            "size (%d,1)" %ml
+
+    if Gq is None: Gq = []
+    if type(Gq) is not list or [ G for G in Gq if (type(G) is not matrix 
+        and type(G) is not spmatrix) or G.typecode != 'd' or 
+        G.size[1] != n ]:
+        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 ] 
+    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
+        (type(h) is not matrix and type(h) is not spmatrix) or 
+        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) ]
+    if a:
+        k = a[0]
+        raise TypeError, "'hq[%d]' has size (%d,%d).  Expected size "\
+            "is (%d,1)." %(k, hq[k].size[0], hq[k].size[1], mq[k]) 
+
+    N = ml + sum(mq)
+    h = matrix(0.0, (N,1))
+    if type(Gl) is matrix or [ Gk for Gk in Gq if type(Gk) is matrix ]:
+        G = matrix(0.0, (N, n))
+    else:
+        G = spmatrix([], [], [], (N, n), 'd')
+    h[:ml] = hl
+    G[:ml,:] = Gl
+    ind = ml
+    for k in xrange(len(mq)):
+        h[ind : ind + mq[k]] = hq[k]
+        G[ind : ind + mq[k], :] = Gq[k]
+        ind += mq[k]
+
+    bkc = n*[ msk.boundkey.fx ] 
+    blc = array(-c)
+    buc = array(-c)
+
+    bkx = ml*[ msk.boundkey.lo ] + sum(mq)*[ msk.boundkey.fr ]
+    blx = ml*[ 0.0 ] + sum(mq)*[ -inf ]
+    bux = N*[ +inf ] 
+
+    c   = -h        
+    
+    colptr, asub, acof = sparse([G.T]).CCS
+    aptrb, aptre = colptr[:-1], colptr[1:]
+
+    mskhandle = msk.mosek ()
+    env = mskhandle.Env ()
+    env.set_Stream (msk.streamtype.log, streamprinter)
+        
+    env.init () 
+    task = env.Task(0,0) 
+    task.set_Stream (msk.streamtype.log, streamprinter) 
+
+    # set MOSEK options 
+    for (param, val) in options.items():
+        if str(param)[:6] == "iparam":
+            task.putintparam(param, val)
+        elif str(param)[:6] == "dparam":
+            task.putdouparam(param, val)
+        elif str(param)[:6] == "sparam":
+            task.putstrparam(param, val)
+        else:
+            raise ValueError, "invalid MOSEK parameter: "+str(param)
+
+    task.inputdata (n,   # number of constraints
+                    N,   # number of variables
+                    array(c), # linear objective coefficients  
+                    0.0, # objective fixed value  
+                    array(aptrb), 
+                    array(aptre), 
+                    array(asub),
+                    array(acof), 
+                    array(bkc),
+                    array(blc),
+                    array(buc), 
+                    array(bkx),
+                    array(blx),
+                    array(bux)) 
+
+    task.putobjsense(msk.objsense.maximize)
+
+    for k in xrange(len(mq)):
+        task.appendcone(msk.conetype.quad, 0.0, 
+                        array(range(ml+sum(mq[:k]),ml+sum(mq[:k+1]))))
+    task.optimize()
+
+    task.solutionsummary (msk.streamtype.msg); 
+
+    prosta, solsta = list(), list()
+    task.getsolutionstatus(msk.soltype.itr, prosta, solsta)
+
+    xu, xl, zq = zeros(n, Float), zeros(n, Float), zeros(sum(mq), Float)
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.slc, 0, n, xl) 
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.suc, 0, n, xu) 
+    task.getsolutionslice(msk.soltype.itr, msk.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)) ]
+    
+    if ml:
+        zl = zeros(ml, Float)
+        task.getsolutionslice(msk.soltype.itr, msk.solitem.xx, 0, ml, zl) 
+        zl = matrix(zl)
+    else:
+        zl = matrix(0.0, (0,1))
+
+    if (solsta[0] is msk.solsta.unknown):
+        return (solsta[0], None, None, None)
+    else:
+        return (solsta[0], x, zl, zq)
+
+
+def solveqp(P, q, G=None, h=None, A=None, b=None):
+    """
+    Solves a quadratic program
+
+        minimize    (1/2)*x'*P*x + q'*x 
+        subject to  G*x <= h      
+                    A*x = b.                    
+                    
+    using MOSEK 5.0.
+
+    (solsta, x, z, y) = solveqp(P, q, G=None, h=None, A=None, b=None)
+
+    Return values
+
+        solsta   the solution status.
+                 If solsta is solsta.optimal,
+                   then (x, y, z) contains the primal-dual solution.
+                 If solsta is solsta.prim_infeas_cer,
+                   then (x, y, z) is a certificate of primal infeasibility.
+                 If solsta is solsta.dual_infeas_cer,
+                   then (x, y, z) is a certificate of dual infeasibility.
+                 If solsta is solsta.unknown,
+                   then (x, y, z) are all None
+
+                 Other return values for solsta include:  
+                   solsta.dual_feas  
+                   solsta.near_dual_feas
+                   solsta.near_optimal
+                   solsta.near_prim_and_dual_feas
+                   solsta.near_prim_feas
+                   solsta.prim_and_dual_feas
+                   solsta.prim_feas
+                 in which case the (x,y,z) value may not be well-defined,
+                 c.f., the MOSEK documentation.
+        
+        x, z, y  the primal-dual solution.                    
+
+    Options are passed to MOSEK solvers via the mosek.options 
+    dictionary, e.g., the following turns off output from 
+    the MOSEK solvers
+    
+    >>> mosek.options = {iparam.log:0} 
+    
+    see chapter 14 of the MOSEK Python API manual.                    
+    """
+    if (type(P) is not matrix and type(P) is not spmatrix) or \
+        P.typecode != 'd' or P.size[0] != P.size[1]:
+        raise TypeError, "'P' must be a square dense or sparse 'd' matrix "
+    n = P.size[0]
+
+    if n < 1: raise ValueError, "number of variables must be at least 1"
+
+    if type(q) is not matrix or q.typecode != 'd' or q.size != (n,1):
+        raise TypeError, "'q' must be a 'd' matrix of size (%d,1)" %n
+
+    if G is None: G = spmatrix([], [], [], (0,n), 'd')
+    if (type(G) is not matrix and type(G) is not spmatrix) or \
+        G.typecode != 'd' or G.size[1] != n:
+        raise TypeError, "'G' must be a dense or sparse 'd' matrix "\
+            "with %d columns" %n 
+
+    m = G.size[0]
+    if h is None: h = matrix(0.0, (0,1))
+    if type(h) is not matrix or h.typecode != 'd' or h.size != (m,1):
+        raise TypeError, "'h' must be a 'd' matrix of size (%d,1)" %m
+
+    if A is None:  A = spmatrix([], [], [], (0,n), 'd')
+    if (type(A) is not matrix and type(A) is not spmatrix) or \
+        A.typecode != 'd' or A.size[1] != n:
+        raise TypeError, "'A' must be a dense or sparse 'd' matrix "\
+            "with %d columns" %n
+    p = A.size[0]
+    if b is None: b = matrix(0.0, (0,1))
+    if type(b) is not matrix or b.typecode != 'd' or b.size != (p,1): 
+        raise TypeError, "'b' must be a dense matrix of size (%d,1)" %p
+ 
+    if m+p is 0: raise ValueError, "m + p must be greater than 0"
+
+    c   = array(q)        
+
+    bkc = m*[ msk.boundkey.up ] + p*[ msk.boundkey.fx ]
+    blc = m*[ -inf ] + [ bi for bi in b ]
+    buc = matrix([h, b])
+
+    bkx = n*[msk.boundkey.fr] 
+    blx = n*[ -inf ] 
+    bux = n*[ +inf ]
+
+    colptr, asub, acof = sparse([G,A]).CCS
+    aptrb, aptre = colptr[:-1], colptr[1:]
+
+    mskhandle = msk.mosek ()
+    env = mskhandle.Env ()
+    env.set_Stream (msk.streamtype.log, streamprinter)
+        
+    env.init () 
+    task = env.Task(0,0) 
+    task.set_Stream (msk.streamtype.log, streamprinter) 
+
+    # set MOSEK options 
+    for (param, val) in options.items():
+        if str(param)[:6] == "iparam":
+            task.putintparam(param, val)
+        elif str(param)[:6] == "dparam":
+            task.putdouparam(param, val)
+        elif str(param)[:6] == "sparam":
+            task.putstrparam(param, val)
+        else:
+            raise ValueError, "invalid MOSEK parameter: "+str(param)
+
+    task.inputdata (m+p, # number of constraints
+                    n,   # number of variables
+                    array(c), # linear objective coefficients  
+                    0.0, # objective fixed value  
+                    array(aptrb), 
+                    array(aptre), 
+                    array(asub),
+                    array(acof), 
+                    array(bkc),
+                    array(blc),
+                    array(buc), 
+                    array(bkx),
+                    array(blx),
+                    array(bux)) 
+
+    Ps = sparse(P)
+    I, J = Ps.I, Ps.J
+    tril = [ k for k in xrange(len(I)) if I[k] >= J[k] ]
+    task.putqobj(array(I[tril]), array(J[tril]), array(Ps.V[tril]))
+    
+    task.putobjsense(msk.objsense.minimize)
+
+    task.optimize()
+
+    task.solutionsummary (msk.streamtype.msg); 
+
+    prosta, solsta = list(), list()
+    task.getsolutionstatus(msk.soltype.itr, prosta, solsta)
+
+    x = zeros(n, Float)
+    task.getsolutionslice(msk.soltype.itr, msk.solitem.xx, 0, n, x) 
+    x = matrix(x)
+
+    if m is not 0:
+        z = zeros(m, Float)
+        task.getsolutionslice(msk.soltype.itr, msk.solitem.suc, 0, m, z) 
+        z = matrix(z)
+    else:
+        z = matrix(0.0, (0,1))
+
+    if p is not 0:
+        yu, yl = zeros(p, Float), zeros(p, Float)
+        task.getsolutionslice(msk.soltype.itr, msk.solitem.suc, m, m+p, yu) 
+        task.getsolutionslice(msk.soltype.itr, msk.solitem.slc, m, m+p, yl) 
+        y = matrix(yu) - matrix(yl)
+    else:
+        y = matrix(0.0, (0,1))
+
+    if (solsta[0] is msk.solsta.unknown):
+        return (solsta[0], None, None, None)
+    else:
+        return (solsta[0], x, z, y)
+
+
+
+            
diff --git a/src/python/solvers.py b/src/python/solvers.py
index b8ab0da..712619d 100644
--- a/src/python/solvers.py
+++ b/src/python/solvers.py
@@ -1,20 +1,20 @@
 """
 Convex optimization solvers.
 
-conelp:  solves cone programs.
-cp:      solves nonlinear convex problems.
-lp:      solves linear programs.
-gp:      solves geometric programs.
-nlcp:    solves nonlinear convex problems specified via functions.
-qp:      solves quadratic programs.
-sdp:     solves semidefinite programs.
-socp:    solves second-order cone programs.
-options: dictionary with customizable algorithm parameters.
+conelp:   solves cone programs.
+cp:       solves nonlinear convex problem.
+cpl:      solves nonlinear convex problems with linear objectives.
+gp:       solves geometric programs.
+lp:       solves linear programs.
+qp:       solves quadratic programs.
+sdp:      solves semidefinite programs.
+socp:     solves second-order cone programs.
+options:  dictionary with customizable algorithm parameters.
 """
 
 # Copyright 2004-2007 J. Dahl and L. Vandenberghe.
 # 
-# This file is part of CVXOPT version 0.9.
+# This file is part of CVXOPT version 0.9.1.
 #
 # CVXOPT is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -30,10 +30,10 @@ options: dictionary with customizable algorithm parameters.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import cvxopt
-from cvxopt.cvxprog import cp, qp, gp, nlcp
+from cvxopt.cvxprog import cp, cpl, qp, gp
 from cvxopt.coneprog import conelp, lp, sdp, socp
 solvecp, solveqp, solvegp, solvelp, solvesdp = cp, qp, gp, lp, sdp
 options = {}
 cvxopt.cvxprog.options = options
 cvxopt.coneprog.options = options
-__all__ = ['conelp', 'cp', 'lp', 'gp', 'nlcp', 'qp', 'sdp', 'socp']
+__all__ = ['conelp', 'cp', 'cpl', 'gp', 'lp', 'qp', 'sdp', 'socp', 'conelp']
diff --git a/src/setup.py b/src/setup.py
index 96ccf9a..b180578 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -4,6 +4,15 @@ from os import listdir
 # directory containing libblas and liblapack
 ATLAS_LIB_DIR = '/usr/lib'
 
+# Set to 1 if you are installing the GSL random number generator module.
+BUILD_GSL = 0
+
+# directory containing libgsl (used only when BUILD_GSL = 1)
+GSL_LIB_DIR = '/usr/lib'       
+
+# directory containing the GSL header files (used only when BUILD_GSL = 1)
+GSL_INC_DIR = '/usr/include/gsl'  
+
 # Set to 1 if you are installing the fftw module.
 BUILD_FFTW = 0
 
@@ -22,28 +31,27 @@ GLPK_LIB_DIR = '/usr/lib'
 # directory containing glpk.h (used only when BUILD_GLPK = 1)
 GLPK_INC_DIR = '/usr/include'  
 
-# Set to 1 if you are installing the MOSEK 4.0 module.
-BUILD_MOSEK = 0
-
-# directory containing libmosek (used only when BUILD_MOSEK = 1)
-MOSEK_LIB_DIR = '/usr/local/mosek/4/tools/platform/linux32x86/bin'  
-
-# directory containing mosek.h (used only when BUILD_MOSEK = 1)
-MOSEK_INC_DIR = '/usr/local/mosek/4/tools/platform/linux32x86/h'
-
 # Set to 1 if you are installing the DSDP module.
 BUILD_DSDP = 0
 
-# directory containing libdsdp.a (used only when BUILD_DSDP = 1)
+# directory containing libdsdp (used only when BUILD_DSDP = 1)
 DSDP_LIB_DIR = '/usr/lib'
  
 # directory containing dsdp5.h (used only when BUILD_DSDP = 1)
 DSDP_INC_DIR = '/usr/include'
 
+
 extmods = []
 
 # optional modules
 
+if BUILD_GSL:
+    random = Extension('random', libraries = ['m', 'gsl', 'blas'],
+        include_dirs = [ GSL_INC_DIR ],
+        library_dirs = [ GSL_LIB_DIR ],
+        sources = ['C/random.c'] )
+    extmods += [random];
+
 if BUILD_FFTW:
     fftw = Extension('fftw', libraries = ['fftw3', 'blas'],
         include_dirs = [ FFTW_INC_DIR ],
@@ -58,17 +66,6 @@ if BUILD_GLPK:
         sources = ['C/glpk.c'] )
     extmods += [glpk];
 
-# If the MOSEK module fails to build, modify the script according to  
-# http://www.mosek.com/products/4_0/tools/doc/html/tools/node20.html,
-# section 18.13.
-if BUILD_MOSEK:
-    mosek = Extension('mosek', 
-        include_dirs = [ MOSEK_INC_DIR ],
-        library_dirs = [ MOSEK_LIB_DIR ],
-        libraries = ['mosek', 'pthread', 'c', 'dl', 'm'],
-        sources = ['C/mosek.c'] )
-    extmods += [mosek];
-
 if BUILD_DSDP:
     dsdp = Extension('dsdp', libraries = ['dsdp', 'blas', 'lapack'],
         include_dirs = [ DSDP_INC_DIR ],
@@ -88,20 +85,17 @@ if BLAS_NOUNDERSCORES:
 else:    
     MACROS = []
 
-base = Extension('base', libraries = ['m','lapack','blas','g2c'],
+base = Extension('base', libraries = ['m','lapack','blas'],
     library_dirs = [ ATLAS_LIB_DIR ],
     define_macros = MACROS,
     sources = ['C/base.c','C/dense.c','C/sparse.c']) 
 
-random = Extension('random',
-    sources = ['C/random.c', 'C/rngs/rngs.c', 'C/rngs/rvgs.c'])
-
-blas = Extension('blas', libraries = ['blas','g2c'],
+blas = Extension('blas', libraries = ['blas'],
     library_dirs = [ ATLAS_LIB_DIR ],
     define_macros = MACROS,
     sources = ['C/blas.c'] )
 
-lapack = Extension('lapack', libraries = ['lapack','blas','g2c'],
+lapack = Extension('lapack', libraries = ['lapack','blas'],
     library_dirs = [ ATLAS_LIB_DIR ],
     define_macros = MACROS,
     sources = ['C/lapack.c'] )
@@ -112,7 +106,7 @@ umfpack = Extension('umfpack',
         'C/SuiteSparse/UFconfig' ],
     library_dirs = [ ATLAS_LIB_DIR ],
     define_macros = MACROS,
-    libraries = [ 'blas', 'lapack', 'g2c'],
+    libraries = [ 'blas', 'lapack'],
     sources = [ 'C/umfpack.c',
         'C/SuiteSparse/UMFPACK/Source/umfpack_global.c',
         'C/SuiteSparse/UMFPACK/Source/umfpack_tictoc.c' ] +
@@ -125,7 +119,7 @@ if sys.maxint > 2**31: MACROS += [('DLONG','')]
 
 cholmod = Extension('cholmod',
     library_dirs = [ ATLAS_LIB_DIR ],
-    libraries = ['lapack', 'blas', 'g2c'],
+    libraries = ['lapack', 'blas'],
     include_dirs = [ 'C/SuiteSparse/CHOLMOD/Include', 
         'C/SuiteSparse/COLAMD', 'C/SuiteSparse/AMD/Include', 
         'C/SuiteSparse/UFconfig', 'C/SuiteSparse/COLAMD/Include' ],
@@ -153,11 +147,11 @@ amd = Extension('amd',
     sources = [ 'C/amd.c' ] + [ 'C/SuiteSparse/AMD/Source/' + s for s in
         listdir('C/SuiteSparse/AMD/Source') if s[-2:] == '.c' ])
 
-extmods += [base, blas, lapack, random, umfpack, cholmod, amd] 
+extmods += [base, blas, lapack, umfpack, cholmod, amd] 
 
 setup (name = 'cvxopt', 
     description = 'Convex optimization package',
-    version = '0.9', 
+    version = '0.9.1', 
     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