changeset 15076:000587f92082

rename src/DLD-FUNCTIONS directory to src/dldfcn * src/dldfcn: Rename from src/DLD-FUNCTIONS. * autogen.sh, src/Makefile.am, src/dldfcn/config-module.awk, src/dldfcn/config-module.sh: Change all uses of DLD-FUNCTIONS to be dldfcn. Change all uses of DLD_FUNCTIONS to be DLDFCN.
author John W. Eaton <jwe@octave.org>
date Tue, 31 Jul 2012 21:57:58 -0400
parents b62b0b85369c
children f0b04a20d7cf
files autogen.sh src/DLD-FUNCTIONS/__delaunayn__.cc src/DLD-FUNCTIONS/__dsearchn__.cc src/DLD-FUNCTIONS/__fltk_uigetfile__.cc src/DLD-FUNCTIONS/__glpk__.cc src/DLD-FUNCTIONS/__init_fltk__.cc src/DLD-FUNCTIONS/__init_gnuplot__.cc src/DLD-FUNCTIONS/__magick_read__.cc src/DLD-FUNCTIONS/__voronoi__.cc src/DLD-FUNCTIONS/amd.cc src/DLD-FUNCTIONS/ccolamd.cc src/DLD-FUNCTIONS/chol.cc src/DLD-FUNCTIONS/colamd.cc src/DLD-FUNCTIONS/config-module.awk src/DLD-FUNCTIONS/config-module.sh src/DLD-FUNCTIONS/convhulln.cc src/DLD-FUNCTIONS/dmperm.cc src/DLD-FUNCTIONS/eigs.cc src/DLD-FUNCTIONS/fftw.cc src/DLD-FUNCTIONS/module-files src/DLD-FUNCTIONS/oct-qhull.h src/DLD-FUNCTIONS/qr.cc src/DLD-FUNCTIONS/symbfact.cc src/DLD-FUNCTIONS/symrcm.cc src/DLD-FUNCTIONS/tsearch.cc src/DLD-FUNCTIONS/urlwrite.cc src/Makefile.am src/dldfcn/__delaunayn__.cc src/dldfcn/__dsearchn__.cc src/dldfcn/__fltk_uigetfile__.cc src/dldfcn/__glpk__.cc src/dldfcn/__init_fltk__.cc src/dldfcn/__init_gnuplot__.cc src/dldfcn/__magick_read__.cc src/dldfcn/__voronoi__.cc src/dldfcn/amd.cc src/dldfcn/ccolamd.cc src/dldfcn/chol.cc src/dldfcn/colamd.cc src/dldfcn/config-module.awk src/dldfcn/config-module.sh src/dldfcn/convhulln.cc src/dldfcn/dmperm.cc src/dldfcn/eigs.cc src/dldfcn/fftw.cc src/dldfcn/module-files src/dldfcn/oct-qhull.h src/dldfcn/qr.cc src/dldfcn/symbfact.cc src/dldfcn/symrcm.cc src/dldfcn/tsearch.cc src/dldfcn/urlwrite.cc src/link-deps.mk
diffstat 53 files changed, 15283 insertions(+), 15283 deletions(-) [+]
line wrap: on
line diff
--- a/autogen.sh	Tue Jul 31 20:46:47 2012 -0400
+++ b/autogen.sh	Tue Jul 31 21:57:58 2012 -0400
@@ -30,9 +30,9 @@
 
 (cd doc/interpreter; ./config-images.sh)
 
-echo "generating src/DLD-FUNCTIONS/module.mk..."
+echo "generating src/dldfcn/module.mk..."
 
-(cd src/DLD-FUNCTIONS; ./config-module.sh)
+(cd src/dldfcn; ./config-module.sh)
 
 echo "bootstrapping..."
 
--- a/src/DLD-FUNCTIONS/__delaunayn__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
-
-Copyright (C) 2000-2012 Kai Habel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-  16. July 2000 - Kai Habel: first release
-
-  25. September 2002 - Changes by Rafael Laboissiere <rafael@laboissiere.net>
-
-  * Added Qbb option to normalize the input and avoid crashes in Octave.
-  * delaunayn accepts now a second (optional) argument that must be a string
-  containing extra options to the qhull command.
-  * Fixed doc string.  The dimension of the result matrix is [m, dim+1], and
-  not [n, dim-1].
-
-  6. June 2006: Changes by Alexander Barth <abarth@marine.usf.edu>
-
-  * triangulate non-simplicial facets
-  * allow options to be specified as cell array of strings
-  * change the default options (for compatibility with matlab)
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <iostream>
-#include <string>
-
-#include "Cell.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-#include "unwind-prot.h"
-
-#if defined (HAVE_QHULL)
-# include "oct-qhull.h"
-# if defined (NEED_QHULL_VERSION)
-char qh_version[] = "__delaunayn__.oct 2007-08-21";
-# endif
-#endif
-
-static void
-close_fcn (FILE *f)
-{
-  gnulib::fclose (f);
-}
-
-DEFUN_DLD (__delaunayn__, args, ,
-           "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts})\n\
-@deftypefnx {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts}, @var{options})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-
-{
-  octave_value_list retval;
-
-#if defined (HAVE_QHULL)
-
-  retval(0) = 0.0;
-
-  int nargin = args.length ();
-  if (nargin < 1 || nargin > 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  Matrix p (args(0).matrix_value ());
-  const octave_idx_type dim = p.columns ();
-  const octave_idx_type n = p.rows ();
-
-  // Default options
-  std::string options;
-  if (dim <= 3)
-    options = "Qt Qbb Qc Qz";
-  else
-    options = "Qt Qbb Qc Qx";
-
-  if (nargin == 2)
-    {
-      if (args(1).is_string ())
-        options = args(1).string_value ();
-      else if (args(1).is_empty ())
-        ;  // Use default options
-      else if (args(1).is_cellstr ())
-        {
-          options = "";
-          Array<std::string> tmp = args(1).cellstr_value ();
-
-          for (octave_idx_type i = 0; i < tmp.numel (); i++)
-            options += tmp(i) + " ";
-        }
-      else
-        {
-          error ("__delaunayn__: OPTIONS argument must be a string, cell array of strings, or empty");
-          return retval;
-        }
-    }
-
-  if (n > dim + 1)
-    {
-      p = p.transpose ();
-      double *pt_array = p.fortran_vec ();
-      boolT ismalloc = false;
-
-      // Qhull flags argument is not const char*
-      OCTAVE_LOCAL_BUFFER (char, flags, 9 + options.length ());
-
-      sprintf (flags, "qhull d %s", options.c_str ());
-
-      unwind_protect frame;
-
-      // Replace the outfile pointer with stdout for debugging information.
-#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
-      FILE *outfile = gnulib::fopen ("NUL", "w");
-#else
-      FILE *outfile = gnulib::fopen ("/dev/null", "w");
-#endif
-      FILE *errfile = stderr;
-
-      if (outfile)
-        frame.add_fcn (close_fcn, outfile);
-      else
-        {
-          error ("__delaunayn__: unable to create temporary file for output");
-          return retval;
-        }
-
-      int exitcode = qh_new_qhull (dim, n, pt_array, 
-                                   ismalloc, flags, outfile, errfile);
-      if (! exitcode)
-        {
-          // triangulate non-simplicial facets
-          qh_triangulate ();
-
-          facetT *facet;
-          vertexT *vertex, **vertexp;
-          octave_idx_type nf = 0, i = 0;
-
-          FORALLfacets
-            {
-              if (! facet->upperdelaunay)
-                nf++;
-
-              // Double check.  Non-simplicial facets will cause segfault below
-              if (! facet->simplicial)
-                {
-                  error ("__delaunayn__: Qhull returned non-simplicial facets -- try delaunayn with different options");
-                  exitcode = 1;
-                  break;
-                }
-            }
-
-          if (! exitcode)
-            {
-              Matrix simpl (nf, dim+1);
-
-              FORALLfacets
-                {
-                  if (! facet->upperdelaunay)
-                    {
-                      octave_idx_type j = 0;
-
-                      FOREACHvertex_ (facet->vertices)
-                        {
-                          simpl(i, j++) = 1 + qh_pointid(vertex->point);
-                        }
-                      i++;
-                    }
-                }
-
-              retval(0) = simpl;
-            }
-        }
-      else
-        error ("__delaunayn__: qhull failed");
-
-      // Free memory from Qhull
-      qh_freeqhull (! qh_ALL);
-
-      int curlong, totlong;
-      qh_memfreeshort (&curlong, &totlong);
-
-      if (curlong || totlong)
-        warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
-                 totlong, curlong);
-    }
-  else if (n == dim + 1)
-    {
-      // one should check if nx points span a simplex
-      // I will look at this later.
-      RowVector vec (n);
-      for (octave_idx_type i = 0; i < n; i++)
-        vec(i) = i + 1.0;
-
-      retval(0) = vec;
-    }
-
-#else
-  error ("__delaunayn__: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/src/DLD-FUNCTIONS/__dsearchn__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
-
-Copyright (C) 2007-2012 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <iostream>
-#include <fstream>
-#include <string>
-
-#include "lo-math.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-
-DEFUN_DLD (__dsearchn__, args, ,
-        "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{idx}, @var{d}] =} dsearch (@var{x}, @var{xi})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  int nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin != 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  Matrix x = args(0).matrix_value ().transpose ();
-  Matrix xi = args(1).matrix_value ().transpose ();
-
-  if (! error_state)
-    {
-      if (x.rows () != xi.rows () || x.columns () < 1)
-        error ("__dsearch__: number of rows of X and XI must match");
-      else
-        {
-          octave_idx_type n = x.rows ();
-          octave_idx_type nx = x.columns ();
-          octave_idx_type nxi = xi.columns ();
-
-          ColumnVector idx (nxi);
-          double *pidx = idx.fortran_vec ();
-          ColumnVector dist (nxi);
-          double *pdist = dist.fortran_vec ();
-
-#define DIST(dd, y, yi, m) \
-  dd = 0.; \
-  for (octave_idx_type k = 0; k < m; k++) \
-   { \
-     double yd = y[k] - yi[k]; \
-     dd += yd * yd; \
-   } \
-  dd = sqrt (dd);
-
-          const double *pxi = xi.fortran_vec ();
-          for (octave_idx_type i = 0; i < nxi; i++)
-            {
-              double d0;
-              const double *px = x.fortran_vec ();
-              DIST(d0, px, pxi, n);
-              *pidx = 1.;
-              for (octave_idx_type j = 1; j < nx; j++)
-                {
-                  px += n;
-                  double d;
-                  DIST (d, px, pxi, n);
-                  if (d < d0)
-                    {
-                      d0 = d;
-                      *pidx = static_cast<double>(j + 1);
-                    }
-                  OCTAVE_QUIT;
-                }
-
-              *pdist++ = d0;
-              pidx++;
-              pxi += n;
-            }
-
-          retval(1) = dist;
-          retval(0) = idx;
-        }
-    }
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/src/DLD-FUNCTIONS/__fltk_uigetfile__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
-
-Copyright (C) 2010-2012 Kai Habel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined (HAVE_FLTK)
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#include <FL/Fl.H>
-#include <FL/Fl_File_Chooser.H>
-
-// FLTK headers may include X11/X.h which defines Complex, and that
-// conflicts with Octave's Complex typedef.  We don't need the X11
-// Complex definition in this file, so remove it before including Octave
-// headers which may require Octave's Complex typedef.
-#undef Complex
-
-#include "defun-dld.h"
-#include "file-ops.h"
-
-DEFUN_DLD (__fltk_uigetfile__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} __fltk_uigetfile__ (@dots{})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  // Expected argument list:
-  //
-  //   args(0) ... FileFilter in fltk format
-  //   args(1) ... Title
-  //   args(2) ... Default Filename
-  //   args(3) ... PostionValue [x,y]
-  //   args(4) ... SelectValue "on"/"off"/"dir"/"create"
-
-  octave_value_list retval (3, octave_value (0));
-
-  std::string file_filter = args(0).string_value ();
-  std::string title = args(1).string_value ();
-  std::string default_name = args(2).string_value ();
-  Matrix pos = args(3).matrix_value ();
-
-  int multi_type = Fl_File_Chooser::SINGLE;
-  std::string flabel = "Filename:";
-
-  std::string multi = args(4).string_value ();
-  if (multi == "on")
-    multi_type = Fl_File_Chooser::MULTI;
-  else if (multi == "dir")
-    {
-      multi_type = Fl_File_Chooser::DIRECTORY;
-      flabel = "Directory:";
-    }
-  else if (multi == "create")
-    multi_type = Fl_File_Chooser::CREATE;
-
-  Fl_File_Chooser::filename_label = flabel.c_str ();
-
-  Fl_File_Chooser fc (default_name.c_str (), file_filter.c_str (),
-                      multi_type, title.c_str ());
-
-  fc.preview (0);
-
-  if (multi_type == Fl_File_Chooser::CREATE)
-    fc.ok_label ("Save");
-
-  fc.show ();
-
-  while (fc.shown ())
-    Fl::wait ();
-
-  if (fc.value ())
-    {
-      int file_count = fc.count ();
-      std::string fname;
-
-      //fltk uses forward slash even for windows
-      std::string sep = "/";
-      std::size_t idx;
-
-      if (file_count == 1 && multi_type != Fl_File_Chooser::DIRECTORY)
-        {
-          fname = fc.value ();
-          idx = fname.find_last_of (sep);
-          retval(0) = fname.substr (idx + 1);
-        }
-      else
-        {
-          Cell file_cell = Cell (file_count, 1);
-          for (octave_idx_type n = 1; n <= file_count; n++)
-            {
-              fname = fc.value (n);
-              idx = fname.find_last_of (sep);
-              file_cell(n - 1) = fname.substr (idx + 1);
-            }
-          retval(0) = file_cell;
-        }
-
-      if (multi_type == Fl_File_Chooser::DIRECTORY)
-        retval(0) = std::string (fc.value ());
-      else
-        {
-          retval(1) = std::string (fc.directory ()) + sep;
-          retval(2) = fc.filter_value () + 1;
-        }
-    }
-
-  fc.hide ();
-  Fl::flush ();
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
-
-#endif
--- a/src/DLD-FUNCTIONS/__glpk__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,861 +0,0 @@
-/*
-
-Copyright (C) 2005-2012 Nicolo' Giorgetti
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cfloat>
-#include <csetjmp>
-#include <ctime>
-
-#include "lo-ieee.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-map.h"
-#include "oct-obj.h"
-#include "pager.h"
-
-#if defined (HAVE_GLPK)
-
-extern "C"
-{
-#if defined (HAVE_GLPK_GLPK_H)
-#include <glpk/glpk.h>
-#else
-#include <glpk.h>
-#endif
-
-#if 0
-#ifdef GLPK_PRE_4_14
-
-#ifndef _GLPLIB_H
-#include <glplib.h>
-#endif
-#ifndef lib_set_fault_hook
-#define lib_set_fault_hook lib_fault_hook
-#endif
-#ifndef lib_set_print_hook
-#define lib_set_print_hook lib_print_hook
-#endif
-
-#else
-
-void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info);
-void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info);
-
-#endif
-#endif
-}
-
-#define NIntP 17
-#define NRealP 10
-
-int lpxIntParam[NIntP] = {
-  0,
-  1,
-  0,
-  1,
-  0,
-  -1,
-  0,
-  200,
-  1,
-  2,
-  0,
-  1,
-  0,
-  0,
-  2,
-  2,
-  1
-};
-
-int IParam[NIntP] = {
-  LPX_K_MSGLEV,
-  LPX_K_SCALE,
-  LPX_K_DUAL,
-  LPX_K_PRICE,
-  LPX_K_ROUND,
-  LPX_K_ITLIM,
-  LPX_K_ITCNT,
-  LPX_K_OUTFRQ,
-  LPX_K_MPSINFO,
-  LPX_K_MPSOBJ,
-  LPX_K_MPSORIG,
-  LPX_K_MPSWIDE,
-  LPX_K_MPSFREE,
-  LPX_K_MPSSKIP,
-  LPX_K_BRANCH,
-  LPX_K_BTRACK,
-  LPX_K_PRESOL
-};
-
-
-double lpxRealParam[NRealP] = {
-  0.07,
-  1e-7,
-  1e-7,
-  1e-9,
-  -DBL_MAX,
-  DBL_MAX,
-  -1.0,
-  0.0,
-  1e-6,
-  1e-7
-};
-
-int RParam[NRealP] = {
-  LPX_K_RELAX,
-  LPX_K_TOLBND,
-  LPX_K_TOLDJ,
-  LPX_K_TOLPIV,
-  LPX_K_OBJLL,
-  LPX_K_OBJUL,
-  LPX_K_TMLIM,
-  LPX_K_OUTDLY,
-  LPX_K_TOLINT,
-  LPX_K_TOLOBJ
-};
-
-static jmp_buf mark;  //-- Address for long jump to jump to
-
-#if 0
-int
-glpk_fault_hook (void * /* info */, char *msg)
-{
-  error ("CRITICAL ERROR in GLPK: %s", msg);
-  longjmp (mark, -1);
-}
-
-int
-glpk_print_hook (void * /* info */, char *msg)
-{
-  message (0, "%s", msg);
-  return 1;
-}
-#endif
-
-int
-glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
-      double *a, double *b, char *ctype, int *freeLB, double *lb,
-      int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
-      int save_pb, double *xmin, double *fmin, double *status,
-      double *lambda, double *redcosts, double *time, double *mem)
-{
-  int errnum;
-  int typx = 0;
-  int method;
-
-  clock_t t_start = clock ();
-
-#if 0
-#ifdef GLPK_PRE_4_14
-  lib_set_fault_hook (0, glpk_fault_hook);
-#else
-  _glp_lib_fault_hook (glpk_fault_hook, 0);
-#endif
-
-  if (lpxIntParam[0] > 1)
-#ifdef GLPK_PRE_4_14
-    lib_set_print_hook (0, glpk_print_hook);
-#else
-    _glp_lib_print_hook (glpk_print_hook, 0);
-#endif
-#endif
-
-  LPX *lp = lpx_create_prob ();
-
-
-  //-- Set the sense of optimization
-  if (sense == 1)
-    lpx_set_obj_dir (lp, LPX_MIN);
-  else
-    lpx_set_obj_dir (lp, LPX_MAX);
-
-  //-- If the problem has integer structural variables switch to MIP
-  if (isMIP)
-    lpx_set_class (lp, LPX_MIP);
-
-  lpx_add_cols (lp, n);
-  for (int i = 0; i < n; i++)
-    {
-      //-- Define type of the structural variables
-      if (! freeLB[i] && ! freeUB[i])
-        {
-          if (lb[i] != ub[i])
-            lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]);
-          else
-            lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]);
-        }
-      else
-        {
-          if (! freeLB[i] && freeUB[i])
-            lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]);
-          else
-            {
-              if (freeLB[i] && ! freeUB[i])
-                lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]);
-              else
-                lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]);
-            }
-        }
-
-      // -- Set the objective coefficient of the corresponding
-      // -- structural variable. No constant term is assumed.
-      lpx_set_obj_coef(lp,i+1,c[i]);
-
-      if (isMIP)
-        lpx_set_col_kind (lp, i+1, vartype[i]);
-    }
-
-  lpx_add_rows (lp, m);
-
-  for (int i = 0; i < m; i++)
-    {
-      /* If the i-th row has no lower bound (types F,U), the
-         corrispondent parameter will be ignored.
-         If the i-th row has no upper bound (types F,L), the corrispondent
-         parameter will be ignored.
-         If the i-th row is of S type, the i-th LB is used, but
-         the i-th UB is ignored.
-      */
-
-      switch (ctype[i])
-        {
-        case 'F':
-          typx = LPX_FR;
-          break;
-
-        case 'U':
-          typx = LPX_UP;
-          break;
-
-        case 'L':
-          typx = LPX_LO;
-          break;
-
-        case 'S':
-          typx = LPX_FX;
-          break;
-
-        case 'D':
-          typx = LPX_DB;
-          break;
-        }
-
-      lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]);
-
-    }
-
-  lpx_load_matrix (lp, nz, rn, cn, a);
-
-  if (save_pb)
-    {
-      static char tmp[] = "outpb.lp";
-      if (lpx_write_cpxlp (lp, tmp) != 0)
-        {
-          error ("__glpk__: unable to write problem");
-          longjmp (mark, -1);
-        }
-    }
-
-  //-- scale the problem data (if required)
-  //-- if (scale && (!presol || method == 1)) lpx_scale_prob (lp);
-  //-- LPX_K_SCALE=IParam[1]  LPX_K_PRESOL=IParam[16]
-  if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1))
-    lpx_scale_prob (lp);
-
-  //-- build advanced initial basis (if required)
-  if (lpsolver == 1 && ! lpxIntParam[16])
-    lpx_adv_basis (lp);
-
-  for (int i = 0; i < NIntP; i++)
-    lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]);
-
-  for (int i = 0; i < NRealP; i++)
-    lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]);
-
-  if (lpsolver == 1)
-    method = 'S';
-  else
-    method = 'T';
-
-  switch (method)
-    {
-    case 'S':
-      {
-        if (isMIP)
-          {
-            method = 'I';
-            errnum = lpx_simplex (lp);
-            errnum = lpx_integer (lp);
-          }
-        else
-          errnum = lpx_simplex (lp);
-      }
-     break;
-
-    case 'T':
-      errnum = lpx_interior (lp);
-      break;
-
-    default:
-      break;
-#if 0
-#ifdef GLPK_PRE_4_14
-      insist (method != method);
-#else
-      static char tmp[] = "method != method";
-      glpk_fault_hook (0, tmp);
-#endif
-#endif
-    }
-
-  /*  errnum assumes the following results:
-      errnum = 0 <=> No errors
-      errnum = 1 <=> Iteration limit exceeded.
-      errnum = 2 <=> Numerical problems with basis matrix.
-  */
-  if (errnum == LPX_E_OK)
-    {
-      if (isMIP)
-        {
-          *status = lpx_mip_status (lp);
-          *fmin = lpx_mip_obj_val (lp);
-        }
-      else
-        {
-          if (lpsolver == 1)
-            {
-              *status = lpx_get_status (lp);
-              *fmin = lpx_get_obj_val (lp);
-            }
-          else
-            {
-              *status = lpx_ipt_status (lp);
-              *fmin = lpx_ipt_obj_val (lp);
-            }
-        }
-
-      if (isMIP)
-        {
-          for (int i = 0; i < n; i++)
-            xmin[i] = lpx_mip_col_val (lp, i+1);
-        }
-      else
-        {
-          /* Primal values */
-          for (int i = 0; i < n; i++)
-            {
-              if (lpsolver == 1)
-                xmin[i] = lpx_get_col_prim (lp, i+1);
-              else
-                xmin[i] = lpx_ipt_col_prim (lp, i+1);
-            }
-
-          /* Dual values */
-          for (int i = 0; i < m; i++)
-            {
-              if (lpsolver == 1)
-                lambda[i] = lpx_get_row_dual (lp, i+1);
-              else
-                lambda[i] = lpx_ipt_row_dual (lp, i+1);
-            }
-
-          /* Reduced costs */
-          for (int i = 0; i < lpx_get_num_cols (lp); i++)
-            {
-              if (lpsolver == 1)
-                redcosts[i] = lpx_get_col_dual (lp, i+1);
-              else
-                redcosts[i] = lpx_ipt_col_dual (lp, i+1);
-            }
-        }
-
-      *time = (clock () - t_start) / CLOCKS_PER_SEC;
-
-#ifdef GLPK_PRE_4_14
-      *mem = (lib_env_ptr () -> mem_tpeak);
-#else
-      *mem = 0;
-#endif
-
-      lpx_delete_prob (lp);
-      return 0;
-    }
-
-   lpx_delete_prob (lp);
-
-   *status = errnum;
-
-   return errnum;
-}
-
-#endif
-
-#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \
-  do \
-    { \
-      octave_value tmp = PARAM.getfield (NAME); \
- \
-      if (tmp.is_defined ()) \
-        { \
-          if (! tmp.is_empty ()) \
-            { \
-              lpxRealParam[IDX] = tmp.scalar_value (); \
- \
-              if (error_state) \
-                { \
-                  error ("glpk: invalid value in PARAM." NAME); \
-                  return retval; \
-                } \
-            } \
-          else \
-            { \
-              error ("glpk: invalid value in PARAM." NAME); \
-              return retval; \
-            } \
-        } \
-    } \
-  while (0)
-
-#define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \
-  do \
-    { \
-      octave_value tmp = PARAM.getfield (NAME); \
- \
-      if (tmp.is_defined ()) \
-        { \
-          if (! tmp.is_empty ()) \
-            { \
-              VAL = tmp.int_value (); \
- \
-              if (error_state) \
-                { \
-                  error ("glpk: invalid value in PARAM." NAME); \
-                  return retval; \
-                } \
-            } \
-          else \
-            { \
-              error ("glpk: invalid value in PARAM." NAME); \
-              return retval; \
-            } \
-        } \
-    } \
-  while (0)
-
-DEFUN_DLD (__glpk__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  // The list of values to return.  See the declaration in oct-obj.h
-  octave_value_list retval;
-
-#if defined (HAVE_GLPK)
-
-  int nrhs = args.length ();
-
-  if (nrhs != 9)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  //-- 1nd Input. A column array containing the objective function
-  //--            coefficients.
-  volatile int mrowsc = args(0).rows ();
-
-  Matrix C (args(0).matrix_value ());
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of C");
-      return retval;
-    }
-
-  double *c = C.fortran_vec ();
-  Array<int> rn;
-  Array<int> cn;
-  ColumnVector a;
-  volatile int mrowsA;
-  volatile int nz = 0;
-
-  //-- 2nd Input. A matrix containing the constraints coefficients.
-  // If matrix A is NOT a sparse matrix
-  if (args(1).is_sparse_type ())
-    {
-      SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix
-
-      if (error_state)
-        {
-          error ("__glpk__: invalid value of A");
-          return retval;
-        }
-
-      mrowsA = A.rows ();
-      octave_idx_type Anc = A.cols ();
-      octave_idx_type Anz = A.nnz ();
-      rn.resize (dim_vector (Anz+1, 1));
-      cn.resize (dim_vector (Anz+1, 1));
-      a.resize (Anz+1, 0.0);
-
-      if (Anc != mrowsc)
-        {
-          error ("__glpk__: invalid value of A");
-          return retval;
-        }
-
-      for (octave_idx_type j = 0; j < Anc; j++)
-        for (octave_idx_type i = A.cidx (j); i < A.cidx (j+1); i++)
-          {
-            nz++;
-            rn(nz) = A.ridx (i) + 1;
-            cn(nz) = j + 1;
-            a(nz) = A.data(i);
-          }
-    }
-  else
-    {
-      Matrix A (args(1).matrix_value ()); // get the matrix
-
-      if (error_state)
-        {
-          error ("__glpk__: invalid value of A");
-          return retval;
-        }
-
-      mrowsA = A.rows ();
-      rn.resize (dim_vector (mrowsA*mrowsc+1, 1));
-      cn.resize (dim_vector (mrowsA*mrowsc+1, 1));
-      a.resize (mrowsA*mrowsc+1, 0.0);
-
-      for (int i = 0; i < mrowsA; i++)
-        {
-          for (int j = 0; j < mrowsc; j++)
-            {
-              if (A(i,j) != 0)
-                {
-                  nz++;
-                  rn(nz) = i + 1;
-                  cn(nz) = j + 1;
-                  a(nz) = A(i,j);
-                }
-            }
-        }
-
-    }
-
-  //-- 3rd Input. A column array containing the right-hand side value
-  //               for each constraint in the constraint matrix.
-  Matrix B (args(2).matrix_value ());
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of B");
-      return retval;
-    }
-
-  double *b = B.fortran_vec ();
-
-  //-- 4th Input. An array of length mrowsc containing the lower
-  //--            bound on each of the variables.
-  Matrix LB (args(3).matrix_value ());
-
-  if (error_state || LB.length () < mrowsc)
-    {
-      error ("__glpk__: invalid value of LB");
-      return retval;
-    }
-
-  double *lb = LB.fortran_vec ();
-
-  //-- LB argument, default: Free
-  Array<int> freeLB (dim_vector (mrowsc, 1));
-  for (int i = 0; i < mrowsc; i++)
-     {
-       if (xisinf (lb[i]))
-         {
-           freeLB(i) = 1;
-           lb[i] = -octave_Inf;
-         }
-       else
-         freeLB(i) = 0;
-     }
-
-  //-- 5th Input. An array of at least length numcols containing the upper
-  //--            bound on each of the variables.
-  Matrix UB (args(4).matrix_value ());
-
-  if (error_state || UB.length () < mrowsc)
-    {
-      error ("__glpk__: invalid value of UB");
-      return retval;
-    }
-
-  double *ub = UB.fortran_vec ();
-
-  Array<int> freeUB (dim_vector (mrowsc, 1));
-  for (int i = 0; i < mrowsc; i++)
-    {
-      if (xisinf (ub[i]))
-        {
-          freeUB(i) = 1;
-          ub[i] = octave_Inf;
-        }
-      else
-        freeUB(i) = 0;
-    }
-
-  //-- 6th Input. A column array containing the sense of each constraint
-  //--            in the constraint matrix.
-  charMatrix CTYPE (args(5).char_matrix_value ());
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of CTYPE");
-      return retval;
-    }
-
-  char *ctype = CTYPE.fortran_vec ();
-
-  //-- 7th Input. A column array containing the types of the variables.
-  charMatrix VTYPE (args(6).char_matrix_value ());
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of VARTYPE");
-      return retval;
-    }
-
-  Array<int> vartype (dim_vector (mrowsc, 1));
-  volatile int isMIP = 0;
-  for (int i = 0; i < mrowsc ; i++)
-    {
-      if (VTYPE(i,0) == 'I')
-        {
-          isMIP = 1;
-          vartype(i) = LPX_IV;
-        }
-      else
-        vartype(i) = LPX_CV;
-    }
-
-  //-- 8th Input. Sense of optimization.
-  volatile int sense;
-  double SENSE = args(7).scalar_value ();
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of SENSE");
-      return retval;
-    }
-
-  if (SENSE >= 0)
-    sense = 1;
-  else
-    sense = -1;
-
-  //-- 9th Input. A structure containing the control parameters.
-  octave_scalar_map PARAM = args(8).scalar_map_value ();
-
-  if (error_state)
-    {
-      error ("__glpk__: invalid value of PARAM");
-      return retval;
-    }
-
-  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  //-- Integer parameters
-  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-  //-- Level of messages output by the solver
-  OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]);
-  if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3)
-    {
-      error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)");
-      return retval;
-    }
-
-  //-- scaling option
-  OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]);
-  if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2)
-    {
-      error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)");
-      return retval;
-    }
-
-  //-- Dual dimplex option
-  OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]);
-  if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1)
-    {
-      error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)");
-      return retval;
-    }
-
-  //-- Pricing option
-  OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]);
-  if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1)
-    {
-      error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])");
-      return retval;
-    }
-
-  //-- Solution rounding option
-  OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]);
-  if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1)
-    {
-      error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)");
-      return retval;
-    }
-
-  //-- Simplex iterations limit
-  OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]);
-
-  //-- Simplex iterations count
-  OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]);
-
-  //-- Output frequency, in iterations
-  OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]);
-
-  //-- Branching heuristic option
-  OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]);
-  if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2)
-    {
-      error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]");
-      return retval;
-    }
-
-  //-- Backtracking heuristic option
-  OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]);
-  if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2)
-    {
-      error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]");
-      return retval;
-    }
-
-  //-- Presolver option
-  OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]);
-  if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1)
-    {
-      error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
-      return retval;
-    }
-
-  //-- LPsolver option
-  volatile int lpsolver = 1;
-  OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver);
-  if (lpsolver < 1 || lpsolver > 2)
-    {
-      error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)");
-      return retval;
-    }
-
-  //-- Save option
-  volatile int save_pb = 0;
-  OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
-  save_pb = save_pb != 0;
-
-  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  //-- Real parameters
-  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-  //-- Ratio test option
-  OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0);
-
-  //-- Relative tolerance used to check if the current basic solution
-  //-- is primal feasible
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1);
-
-  //-- Absolute tolerance used to check if the current basic solution
-  //-- is dual feasible
-  OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2);
-
-  //-- Relative tolerance used to choose eligible pivotal elements of
-  //--  the simplex table in the ratio test
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9);
-
-  //-- Assign pointers to the output parameters
-  ColumnVector xmin (mrowsc, octave_NA);
-  double fmin = octave_NA;
-  double status;
-  ColumnVector lambda (mrowsA, octave_NA);
-  ColumnVector redcosts (mrowsc, octave_NA);
-  double time;
-  double mem;
-
-  int jmpret = setjmp (mark);
-
-  if (jmpret == 0)
-    glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
-          cn.fortran_vec (), a.fortran_vec (), b, ctype,
-          freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
-          vartype.fortran_vec (), isMIP, lpsolver, save_pb,
-          xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (),
-          redcosts.fortran_vec (), &time, &mem);
-
-  octave_scalar_map extra;
-
-  if (! isMIP)
-    {
-      extra.assign ("lambda", lambda);
-      extra.assign ("redcosts", redcosts);
-    }
-
-  extra.assign ("time", time);
-  extra.assign ("mem", mem);
-
-  retval(3) = extra;
-  retval(2) = status;
-  retval(1) = fmin;
-  retval(0) = xmin;
-
-#else
-
-  gripe_not_supported ("glpk");
-
-#endif
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/src/DLD-FUNCTIONS/__init_fltk__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2129 +0,0 @@
-/*
-
-Copyright (C) 2007-2012 Shai Ayal
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-
-To initialize:
-
-  graphics_toolkit ("fltk");
-  plot (randn (1e3, 1));
-
-*/
-
-// PKG_ADD: register_graphics_toolkit ("fltk");
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun-dld.h"
-#include "error.h"
-
-#if defined (HAVE_FLTK)
-
-#include <map>
-#include <set>
-#include <sstream>
-#include <iostream>
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#include <FL/Fl.H>
-#include <FL/Fl_Box.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Choice.H>
-#include <FL/Fl_File_Chooser.H>
-#include <FL/Fl_Gl_Window.H>
-#include <FL/Fl_Menu_Bar.H>
-#include <FL/Fl_Menu_Button.H>
-#include <FL/Fl_Output.H>
-#include <FL/Fl_Window.H>
-#include <FL/fl_ask.H>
-#include <FL/fl_draw.H>
-#include <FL/gl.h>
-
-// FLTK headers may include X11/X.h which defines Complex, and that
-// conflicts with Octave's Complex typedef.  We don't need the X11
-// Complex definition in this file, so remove it before including Octave
-// headers which may require Octave's Complex typedef.
-#undef Complex
-
-#include "cmd-edit.h"
-#include "lo-ieee.h"
-
-#include "file-ops.h"
-#include "gl-render.h"
-#include "gl2ps-renderer.h"
-#include "graphics.h"
-#include "parse.h"
-#include "sysdep.h"
-#include "toplev.h"
-#include "variables.h"
-
-#define FLTK_GRAPHICS_TOOLKIT_NAME "fltk"
-
-// Give FLTK no more than 0.01 sec to do its stuff.
-static double fltk_maxtime = 1e-2;
-
-const char* help_text = "\
-Keyboard Shortcuts\n\
-a - autoscale\n\
-p - pan/zoom\n\
-r - rotate\n\
-g - toggle grid\n\
-\n\
-Mouse\n\
-left drag - pan\n\
-mouse wheel - zoom\n\
-right drag - rectangle zoom\n\
-left double click - autoscale\n\
-";
-
-class OpenGL_fltk : public Fl_Gl_Window
-{
-public:
-  OpenGL_fltk (int xx, int yy, int ww, int hh, double num)
-    : Fl_Gl_Window (xx, yy, ww, hh, 0), number (num), renderer (),
-      in_zoom (false), zoom_box (),  print_mode (false)
-  {
-    // Ask for double buffering and a depth buffer.
-    mode (FL_DEPTH | FL_DOUBLE);
-  }
-
-  ~OpenGL_fltk (void) { }
-
-  void zoom (bool z)
-  {
-    in_zoom = z;
-    if (! in_zoom)
-      hide_overlay ();
-  }
-
-  bool zoom (void) { return in_zoom; }
-  void set_zoom_box (const Matrix& zb) { zoom_box = zb; }
-
-  void print (const std::string& cmd, const std::string& term)
-  {
-    print_mode  = true;
-    print_cmd = cmd;
-    print_term  = term;
-  }
-
-  void resize (int xx, int yy, int ww, int hh)
-  {
-    Fl_Gl_Window::resize (xx, yy, ww, hh);
-    setup_viewport (ww, hh);
-    redraw ();
-  }
-
-  bool renumber (double new_number)
-  {
-    bool retval = false;
-
-    if (number != new_number)
-      {
-        number = new_number;
-        retval = true;
-      }
-
-    return retval;
-  }
-
-private:
-  double number;
-  opengl_renderer renderer;
-  bool in_zoom;
-  // (x1,y1,x2,y2)
-  Matrix zoom_box;
-
-  bool print_mode;
-  std::string print_cmd;
-  std::string print_term;
-
-  void setup_viewport (int ww, int hh)
-  {
-    glMatrixMode (GL_PROJECTION);
-    glLoadIdentity ();
-    glViewport (0, 0, ww, hh);
-  }
-
-  void draw (void)
-  {
-    if (! valid ())
-      {
-        valid (1);
-        setup_viewport (w (), h ());
-      }
-
-    if (print_mode)
-      {
-        FILE *fp = octave_popen (print_cmd.c_str (), "w");
-        glps_renderer rend (fp, print_term);
-
-        rend.draw (gh_manager::get_object (number));
-
-        octave_pclose (fp);
-        print_mode = false;
-      }
-    else
-      {
-        renderer.draw (gh_manager::get_object (number));
-
-        if (zoom ())
-          overlay ();
-      }
-  }
-
-  void zoom_box_vertex (void)
-  {
-    glVertex2d (zoom_box(0), h () - zoom_box(1));
-    glVertex2d (zoom_box(0), h () - zoom_box(3));
-    glVertex2d (zoom_box(2), h () - zoom_box(3));
-    glVertex2d (zoom_box(2), h () - zoom_box(1));
-    glVertex2d (zoom_box(0), h () - zoom_box(1));
-  }
-
-  void overlay (void)
-  {
-    glPushMatrix ();
-
-    glMatrixMode (GL_MODELVIEW);
-    glLoadIdentity ();
-
-    glMatrixMode (GL_PROJECTION);
-    glLoadIdentity ();
-    gluOrtho2D (0.0, w (), 0.0, h ());
-
-    glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
-    glDisable (GL_DEPTH_TEST);
-
-    glBegin (GL_POLYGON);
-    glColor4f (0.45, 0.62, 0.81, 0.1);
-    zoom_box_vertex ();
-    glEnd ();
-
-    glBegin (GL_LINE_STRIP);
-    glLineWidth (1.5);
-    glColor4f (0.45, 0.62, 0.81, 0.9);
-    zoom_box_vertex ();
-    glEnd ();
-
-    glPopAttrib ();
-    glPopMatrix ();
-  }
-
-  int handle (int event)
-  {
-    int retval = Fl_Gl_Window::handle (event);
-
-    switch (event)
-      {
-      case FL_ENTER:
-        window ()->cursor (FL_CURSOR_CROSS);
-        return 1;
-
-      case FL_LEAVE:
-        window ()->cursor (FL_CURSOR_DEFAULT);
-        return 1;
-      }
-
-    return retval;
-  }
-};
-
-// Parameter controlling how fast we zoom when using the scrool wheel.
-static double wheel_zoom_speed = 0.05;
-// Parameter controlling the GUI mode.
-static enum { pan_zoom, rotate_zoom, none } gui_mode;
-
-void script_cb (Fl_Widget*, void* data)
-  {
-    static_cast<uimenu::properties*> (data)->execute_callback ();
-  }
-
-
-class fltk_uimenu
-{
-public:
-  fltk_uimenu (int xx, int yy, int ww, int hh)
-    {
-      menubar = new
-        Fl_Menu_Bar (xx, yy, ww, hh);
-    }
-
-  int items_to_show (void)
-    {
-      //returns the number of visible menu items
-      int len = menubar->size ();
-      int n = 0;
-      for (int t = 0; t < len; t++ )
-        {
-          const Fl_Menu_Item *m = static_cast<const Fl_Menu_Item*> (&(menubar->menu ()[t]));
-          if ((m->label () != NULL) && m->visible ())
-            n++;
-        }
-
-      return n;
-    }
-
-  void show (void)
-    {
-      menubar->show ();
-    }
-
-  void hide (void)
-    {
-      menubar->hide ();
-    }
-
-   bool is_visible (void)
-    {
-      return menubar->visible ();
-    }
-
-  int find_index_by_name (const std::string& findname)
-    {
-      // This function is derived from Greg Ercolano's function
-      // int GetIndexByName(...), see:
-      // http://seriss.com/people/erco/fltk/#Menu_ChangeLabel
-      // He agreed via PM that it can be included in octave using GPLv3
-      // Kai Habel (14.10.2010)
-
-      std::string menupath;
-      for (int t = 0; t < menubar->size (); t++ )
-        {
-          Fl_Menu_Item *m = const_cast<Fl_Menu_Item*> (&(menubar->menu ()[t]));
-          if (m->submenu ())
-            {
-              // item has submenu
-              if (!menupath.empty ())
-                menupath += "/";
-              menupath += m->label ();
-
-              if (menupath.compare (findname) == 0 )
-                return (t);
-            }
-          else
-            {
-              // End of submenu? Pop back one level.
-              if (m->label () == NULL)
-                {
-                  std::size_t idx = menupath.find_last_of ("/");
-                  if (idx != std::string::npos)
-                    menupath.erase (idx);
-                  else
-                    menupath.clear ();
-                  continue;
-                }
-              // Menu item?
-              std::string itempath = menupath;
-              if (!itempath.empty ())
-                itempath += "/";
-              itempath += m->label ();
-
-              if (itempath.compare (findname) == 0)
-                return (t);
-            }
-        }
-      return (-1);
-    }
-
-  Matrix find_uimenu_children (uimenu::properties& uimenup) const
-    {
-      Matrix uimenu_childs = uimenup.get_all_children ();
-      Matrix retval = do_find_uimenu_children (uimenu_childs);
-      return retval;
-    }
-
-  Matrix find_uimenu_children (figure::properties& figp) const
-    {
-      Matrix uimenu_childs = figp.get_all_children ();
-      Matrix retval = do_find_uimenu_children (uimenu_childs);
-      return retval;
-    }
-
-  Matrix do_find_uimenu_children (Matrix uimenu_childs) const
-    {
-      octave_idx_type k = 0;
-
-
-      Matrix pos = Matrix (uimenu_childs.numel (), 1);
-
-      for (octave_idx_type ii = 0; ii < uimenu_childs.numel (); ii++)
-      {
-        graphics_object kidgo = gh_manager::get_object (uimenu_childs (ii));
-
-        if (kidgo.valid_object () && kidgo.isa ("uimenu"))
-          {
-            uimenu_childs(k) = uimenu_childs(ii);
-            pos(k++) =
-              dynamic_cast<uimenu::properties&> (kidgo.get_properties ()).get_position ();
-          }
-      }
-
-      uimenu_childs.resize (k, 1);
-      pos.resize (k, 1);
-      Matrix retval = Matrix (k, 1);
-      // Don't know if this is the best method to sort.
-      // Can we avoid the for loop?
-      Array<octave_idx_type> sidx = pos.sort_rows_idx (DESCENDING);
-      for (octave_idx_type ii = 0; ii < k; ii++)
-        retval(ii) = uimenu_childs (sidx(ii));
-
-      return retval;
-    }
-
-  void delete_entry (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      int idx = find_index_by_name (fltk_label.c_str ());
-
-      if (idx >= 0)
-        menubar->remove (idx);
-    }
-
-  void update_accelerator (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
-          if (item != NULL)
-            {
-              std::string acc = uimenup.get_accelerator ();
-              if (acc.length () > 0)
-                {
-                  int key = FL_CTRL + acc[0];
-                  item->shortcut (key);
-                }
-            }
-        }
-    }
-
-  void update_callback (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
-          if (item != NULL)
-            {
-              if (!uimenup.get_callback ().is_empty ())
-                item->callback (static_cast<Fl_Callback*> (script_cb),
-                                static_cast<void*> (&uimenup));
-              else
-                item->callback (NULL, static_cast<void*> (0));
-            }
-        }
-    }
-
-  void update_enable (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
-          if (item != NULL)
-            {
-              if (uimenup.is_enable ())
-                item->activate ();
-              else
-                item->deactivate ();
-            }
-        }
-    }
-
-  void update_foregroundcolor (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
-          if (item != NULL)
-            {
-              Matrix rgb = uimenup.get_foregroundcolor_rgb ();
-
-              uchar r = static_cast<uchar> (gnulib::floor (rgb (0) * 255));
-              uchar g = static_cast<uchar> (gnulib::floor (rgb (1) * 255));
-              uchar b = static_cast<uchar> (gnulib::floor (rgb (2) * 255));
-
-              item->labelcolor (fl_rgb_color (r, g, b));
-            }
-        }
-    }
-
-  void update_seperator (const uimenu::properties& uimenup)
-    {
-      // Matlab places the separator before the current
-      // menu entry, while fltk places it after. So we need to find
-      // the previous item in this menu/submenu. (Kai)
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          int itemflags = 0, idx;
-          int curr_idx = find_index_by_name (fltk_label.c_str ());
-
-          for (idx = curr_idx - 1; idx >= 0; idx--)
-            {
-              Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (&menubar->menu () [idx]);
-              itemflags = item->flags;
-              if (item->label () != NULL)
-                break;
-            }
-
-          if (idx >= 0 && idx < menubar->size ())
-            {
-              if (uimenup.is_separator ())
-                {
-                  if (idx >= 0 && !(itemflags & FL_SUBMENU))
-                    menubar->mode (idx, itemflags | FL_MENU_DIVIDER);
-                }
-              else
-                menubar->mode (idx, itemflags & (~FL_MENU_DIVIDER));
-            }
-        }
-    }
-
-  void update_visible (uimenu::properties& uimenup)
-    {
-      std::string fltk_label = uimenup.get_fltk_label ();
-      if (!fltk_label.empty ())
-        {
-          Fl_Menu_Item* item
-            = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
-          if (item != NULL)
-            {
-              if (uimenup.is_visible ())
-                item->show ();
-              else
-                item->hide ();
-            }
-        }
-    }
-
-  void add_entry (uimenu::properties& uimenup)
-    {
-
-      std::string fltk_label = uimenup.get_fltk_label ();
-
-      if (!fltk_label.empty ())
-        {
-          bool item_added = false;
-          do
-            {
-              const Fl_Menu_Item* item
-                = menubar->find_item (fltk_label.c_str ());
-
-              if (item == NULL)
-                {
-                  Matrix uimenu_ch = find_uimenu_children (uimenup);
-                  int len = uimenu_ch.numel ();
-                  int flags = 0;
-                  if (len > 0)
-                    flags = FL_SUBMENU;
-                  if (len == 0 && uimenup.is_checked ())
-                    flags += FL_MENU_TOGGLE + FL_MENU_VALUE;
-                  menubar->add (fltk_label.c_str (), 0, 0, 0, flags);
-                  item_added = true;
-                }
-              else
-                {
-                  //avoid duplicate menulabels
-                  std::size_t idx1 = fltk_label.find_last_of ("(");
-                  std::size_t idx2 = fltk_label.find_last_of (")");
-                  int len = idx2 - idx1;
-                  int val = 1;
-                  if (len > 0)
-                    {
-                      std::string valstr = fltk_label.substr (idx1 + 1, len - 1);
-                      fltk_label.erase (idx1, len + 1);
-                      val = atoi (valstr.c_str ());
-                      if (val > 0 && val < 99)
-                        val++;
-                    }
-                  std::ostringstream valstream;
-                  valstream << val;
-                  fltk_label += "(" + valstream.str () + ")";
-                }
-            }
-          while (!item_added);
-          uimenup.set_fltk_label (fltk_label);
-        }
-    }
-
-  void add_to_menu (uimenu::properties& uimenup)
-    {
-      Matrix kids = find_uimenu_children (uimenup);
-      int len = kids.length ();
-      std::string fltk_label = uimenup.get_fltk_label ();
-
-      add_entry (uimenup);
-      update_foregroundcolor (uimenup);
-      update_callback (uimenup);
-      update_accelerator (uimenup);
-      update_enable (uimenup);
-      update_visible (uimenup);
-      update_seperator (uimenup);
-
-      for (octave_idx_type ii = 0; ii < len; ii++)
-        {
-          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
-          if (kgo.valid_object ())
-            {
-              uimenu::properties& kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
-              add_to_menu (kprop);
-            }
-        }
-    }
-
-  void add_to_menu (figure::properties& figp)
-    {
-      Matrix kids = find_uimenu_children (figp);
-      int len = kids.length ();
-      menubar->clear ();
-      for (octave_idx_type ii = 0; ii < len; ii++)
-        {
-          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
-
-          if (kgo.valid_object ())
-            {
-              uimenu::properties& kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
-              add_to_menu (kprop);
-            }
-        }
-    }
-
-  template <class T_prop>
-  void remove_from_menu (T_prop& prop)
-    {
-      Matrix kids;
-      std::string type = prop.get_type ();
-      kids = find_uimenu_children (prop);
-      int len = kids.length ();
-
-      for (octave_idx_type ii = 0; ii < len; ii++)
-        {
-          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
-
-          if (kgo.valid_object ())
-            {
-              uimenu::properties kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
-              remove_from_menu (kprop);
-            }
-        }
-
-      if (type.compare ("uimenu") == 0)
-        delete_entry (dynamic_cast<uimenu::properties&> (prop));
-      else if (type.compare ("figure") == 0)
-        menubar->clear ();
-    }
-
-  ~fltk_uimenu (void)
-    {
-      delete menubar;
-    }
-
-private:
-
-  // No copying!
-
-  fltk_uimenu (const fltk_uimenu&);
-
-  fltk_uimenu operator = (const fltk_uimenu&);
-
-  Fl_Menu_Bar* menubar;
-};
-
-class plot_window : public Fl_Window
-{
-  friend class fltk_uimenu;
-public:
-  plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp)
-    : Fl_Window (xx, yy, ww, hh, "octave"), window_label (), shift (0),
-      ndim (2), fp (xfp), canvas (0), autoscale (0), togglegrid (0),
-      panzoom (0), rotate (0), help (0), status (0),
-      ax_obj (), pos_x (0), pos_y (0)
-  {
-    callback (window_close, static_cast<void*> (this));
-    size_range (4*status_h, 2*status_h);
-
-    // FIXME: The function below is only available in FLTK >= 1.3
-    // At some point support for FLTK 1.1 will be dropped in Octave.
-    // At that point this function should be uncommented.
-    // The current solution is to call xclass() before show() for each window.
-    // Set WM_CLASS which allows window managers to properly group related
-    // windows.  Otherwise, the class is just "FLTK"
-    //default_xclass ("Octave");
-
-    begin ();
-    {
-
-      canvas = new OpenGL_fltk (0, 0, ww, hh - status_h, number ());
-
-      uimenu = new fltk_uimenu (0, 0, ww, menu_h);
-      uimenu->hide ();
-
-      bottom = new Fl_Box (0, hh - status_h, ww, status_h);
-      bottom->box (FL_FLAT_BOX);
-
-      ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
-
-      autoscale = new Fl_Button (0, hh - status_h, status_h, status_h, "A");
-      autoscale->callback (button_callback, static_cast<void*> (this));
-      autoscale->tooltip ("Autoscale");
-
-      togglegrid = new Fl_Button (status_h, hh - status_h, status_h,
-                                  status_h, "G");
-      togglegrid->callback (button_callback, static_cast<void*> (this));
-      togglegrid->tooltip ("Toggle Grid");
-
-      panzoom = new Fl_Button (2 * status_h, hh - status_h, status_h,
-                               status_h, "P");
-      panzoom->callback (button_callback, static_cast<void*> (this));
-      panzoom->tooltip ("Mouse Pan/Zoom");
-
-      rotate = new Fl_Button (3 * status_h, hh - status_h, status_h,
-                              status_h, "R");
-      rotate->callback (button_callback, static_cast<void*> (this));
-      rotate->tooltip ("Mouse Rotate");
-
-      if (ndim == 2)
-        rotate->deactivate ();
-
-      help = new Fl_Button (4 * status_h, hh - status_h, status_h,
-                            status_h, "?");
-      help->callback (button_callback, static_cast<void*> (this));
-      help->tooltip ("Help");
-
-      status = new Fl_Output (5 * status_h, hh - status_h,
-                              ww > 2*status_h ? ww - status_h : 0,
-                              status_h, "");
-
-      status->textcolor (FL_BLACK);
-      status->color (FL_GRAY);
-      status->textfont (FL_COURIER);
-      status->textsize (10);
-      status->box (FL_ENGRAVED_BOX);
-
-      // This allows us to have a valid OpenGL context right away.
-      canvas->mode (FL_DEPTH | FL_DOUBLE );
-      if (fp.is_visible ())
-        {
-          // FIXME: This code should be removed when Octave drops support
-          // for FLTK 1.1.  Search for default_xclass in this file to find
-          // code that should be uncommented to take its place.
-          //
-          // Set WM_CLASS which allows window managers to properly group
-          // related windows.  Otherwise, the class is just "FLTK"
-          xclass ("Octave");
-          show ();
-          if (fp.get_currentaxes ().ok ())
-            show_canvas ();
-          else
-            hide_canvas ();
-        }
-    }
-    end ();
-
-    status->show ();
-    autoscale->show ();
-    togglegrid->show ();
-    panzoom->show ();
-    rotate->show ();
-
-    set_name ();
-    resizable (canvas);
-    gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom);
-    uimenu->add_to_menu (fp);
-    if (uimenu->items_to_show ())
-      show_menubar ();
-    else
-      hide_menubar ();
-  }
-
-  ~plot_window (void)
-  {
-    canvas->hide ();
-    status->hide ();
-    uimenu->hide ();
-    this->hide ();
-  }
-
-  double number (void) { return fp.get___myhandle__ ().value (); }
-
-  void renumber (double new_number)
-  {
-    if (canvas)
-      {
-        if (canvas->renumber (new_number))
-          mark_modified ();
-      }
-    else
-      error ("unable to renumber figure");
-  }
-
-  void print (const std::string& cmd, const std::string& term)
-  {
-    canvas->print (cmd, term);
-
-    // Print immediately so the output file will exist when the drawnow
-    // command is done.
-    mark_modified ();
-    Fl::wait (fltk_maxtime);
-  }
-
-  void show_menubar (void)
-  {
-    if (!uimenu->is_visible ())
-      {
-        canvas->resize (canvas->x (),
-                        canvas->y () + menu_h,
-                        canvas->w (),
-                        canvas->h () - menu_h);
-        uimenu->show ();
-        mark_modified ();
-      }
-  }
-
-  void hide_menubar (void)
-  {
-    if (uimenu->is_visible ())
-      {
-        canvas->resize (canvas->x (),
-                        canvas->y () - menu_h,
-                        canvas->w (),
-                        canvas->h () + menu_h);
-        uimenu->hide ();
-        mark_modified ();
-      }
-  }
-
-  void uimenu_update (const graphics_handle& gh, int id)
-  {
-    graphics_object uimenu_obj = gh_manager::get_object (gh);
-
-    if (uimenu_obj.valid_object () && uimenu_obj.isa ("uimenu"))
-      {
-        uimenu::properties& uimenup =
-          dynamic_cast<uimenu::properties&> (uimenu_obj.get_properties ());
-        std::string fltk_label = uimenup.get_fltk_label ();
-        graphics_object fig = uimenu_obj.get_ancestor ("figure");
-        figure::properties& figp =
-          dynamic_cast<figure::properties&> (fig.get_properties ());
-
-        switch (id)
-          {
-          case base_properties::ID_BEINGDELETED:
-            uimenu->remove_from_menu (uimenup);
-            break;
-
-          case base_properties::ID_VISIBLE:
-            uimenu->update_visible (uimenup);
-            break;
-
-          case uimenu::properties::ID_ACCELERATOR:
-            uimenu->update_accelerator (uimenup);
-            break;
-
-          case uimenu::properties::ID_CALLBACK:
-            uimenu->update_callback (uimenup);
-            break;
-
-          case uimenu::properties::ID_CHECKED:
-            uimenu->add_to_menu (figp);//rebuilding entire menu
-            break;
-
-          case uimenu::properties::ID_ENABLE:
-            uimenu->update_enable (uimenup);
-            break;
-
-          case uimenu::properties::ID_FOREGROUNDCOLOR:
-            uimenu->update_foregroundcolor (uimenup);
-            break;
-
-          case uimenu::properties::ID_LABEL:
-            uimenu->add_to_menu (figp);//rebuilding entire menu
-            break;
-
-          case uimenu::properties::ID_POSITION:
-            uimenu->add_to_menu (figp);//rebuilding entire menu
-            break;
-
-          case uimenu::properties::ID_SEPARATOR:
-            uimenu->update_seperator (uimenup);
-            break;
-          }
-
-        if (uimenu->items_to_show ())
-          show_menubar ();
-        else
-          hide_menubar ();
-
-        mark_modified ();
-      }
-  }
-
-  void show_canvas (void)
-  {
-    if (fp.is_visible ())
-      {
-        canvas->show ();
-        canvas->make_current ();
-      }
-  }
-
-  void hide_canvas (void)
-  {
-    canvas->hide ();
-  }
-
-  void mark_modified (void)
-  {
-    damage (FL_DAMAGE_ALL);
-    canvas->damage (FL_DAMAGE_ALL);
-    ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
-
-    if (ndim == 3)
-      rotate->activate ();
-    else if (ndim == 2 && gui_mode == rotate_zoom)
-      {
-        rotate->deactivate ();
-        gui_mode = pan_zoom;
-      }
-  }
-
-  void set_name (void)
-  {
-    window_label = fp.get_title ();
-    label (window_label.c_str ());
-  }
-
-private:
-
-  // No copying!
-
-  plot_window (const plot_window&);
-
-  plot_window& operator = (const plot_window&);
-
-  // window name -- this must exists for the duration of the window's
-  // life
-  std::string window_label;
-
-  // Mod keys status
-  int shift;
-
-  // Number of dimensions, 2 or 3.
-  int ndim;
-
-  // Figure properties.
-  figure::properties& fp;
-
-  // Status area height.
-  static const int status_h = 20;
-
-  // Menu height
-  static const int menu_h = 20;
-
-  // Window callback.
-  static void window_close (Fl_Widget*, void* data)
-  {
-    octave_value_list args;
-    args(0) = static_cast<plot_window*> (data)->number ();
-    feval ("close", args);
-  }
-
-  // Button callbacks.
-  static void button_callback (Fl_Widget* ww, void* data)
-  {
-    static_cast<plot_window*> (data)->button_press (ww, data);
-  }
-
-  void button_press (Fl_Widget* widg, void*)
-  {
-    if (widg == autoscale)
-      axis_auto ();
-
-    if (widg == togglegrid)
-      toggle_grid ();
-
-    if (widg == panzoom)
-      gui_mode = pan_zoom;
-
-    if (widg == rotate && ndim == 3)
-      gui_mode = rotate_zoom;
-
-    if (widg == help)
-      fl_message ("%s", help_text);
-  }
-
-  fltk_uimenu* uimenu;
-  OpenGL_fltk* canvas;
-  Fl_Box*    bottom;
-  Fl_Button* autoscale;
-  Fl_Button* togglegrid;
-  Fl_Button* panzoom;
-  Fl_Button* rotate;
-  Fl_Button* help;
-  Fl_Output* status;
-  graphics_object ax_obj;
-  int pos_x;
-  int pos_y;
-
-  void axis_auto (void)
-  {
-    octave_value_list args;
-    args(0) = fp.get_currentaxes ().as_octave_value ();
-    args(1) = "auto";
-    feval ("axis", args);
-    mark_modified ();
-  }
-
-  void toggle_grid (void)
-  {
-    octave_value_list args;
-    if (fp.get_currentaxes ().ok ())
-      args(0) = fp.get_currentaxes ().as_octave_value ();
-
-    feval ("grid", args);
-    mark_modified ();
-  }
-
-  void pixel2pos (const graphics_handle& ax, int px, int py, double& xx,
-                  double& yy) const
-  {
-    pixel2pos ( gh_manager::get_object (ax), px, py, xx, yy);
-  }
-
-  void pixel2pos (graphics_object ax, int px, int py, double& xx,
-                  double& yy) const
-  {
-    if (ax && ax.isa ("axes"))
-      {
-        axes::properties& ap =
-          dynamic_cast<axes::properties&> (ax.get_properties ());
-        ColumnVector pp = ap.pixel2coord (px, py);
-        xx = pp(0);
-        yy = pp(1);
-      }
-  }
-
-  graphics_handle pixel2axes_or_ca (int px, int py )
-  {
-    Matrix kids = fp.get_children ();
-    int len = kids.length ();
-
-    for (int k = 0; k < len; k++)
-      {
-        graphics_handle hnd = gh_manager::lookup (kids(k));
-
-        if (hnd.ok ())
-          {
-            graphics_object kid = gh_manager::get_object (hnd);
-
-            if (kid.valid_object () && kid.isa ("axes"))
-              {
-                Matrix bb = kid.get_properties ().get_boundingbox (true);
-
-                if (bb(0) <= px && px < (bb(0)+bb(2))
-                    && bb(1) <= py && py < (bb(1)+bb(3)))
-                  {
-                    return hnd;
-                  }
-              }
-          }
-      }
-    return fp.get_currentaxes ();
-  }
-
-  void pixel2status (const graphics_handle& ax, int px0, int py0,
-                     int px1 = -1, int py1 = -1)
-  {
-    pixel2status (gh_manager::get_object (ax), px0, py0, px1, py1);
-  }
-
-  void pixel2status (graphics_object ax, int px0, int py0,
-                     int px1 = -1, int py1 = -1)
-  {
-    double x0, y0, x1, y1;
-    std::stringstream cbuf;
-    cbuf.precision (4);
-    cbuf.width (6);
-    pixel2pos (ax, px0, py0, x0, y0);
-    cbuf << "[" << x0 << ", " << y0 << "]";
-    if (px1 >= 0)
-      {
-        pixel2pos (ax, px1, py1, x1, y1);
-        cbuf << " -> ["<< x1 << ", " << y1 << "]";
-      }
-
-    status->value (cbuf.str ().c_str ());
-    status->redraw ();
-  }
-
-  void view2status (graphics_object ax)
-  {
-     if (ax && ax.isa ("axes"))
-       {
-         axes::properties& ap =
-           dynamic_cast<axes::properties&> (ax.get_properties ());
-         std::stringstream cbuf;
-         cbuf.precision (4);
-         cbuf.width (6);
-         Matrix v (1,2,0);
-         v = ap.get ("view").matrix_value ();
-         cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]";
-
-         status->value (cbuf.str ().c_str ());
-         status->redraw ();
-       }
-  }
-
-  void set_currentpoint (int px, int py)
-  {
-    if (!fp.is_beingdeleted ())
-      {
-        Matrix pos (1,2,0);
-        pos(0) = px;
-        pos(1) = h () - status_h - menu_h - py;
-        fp.set_currentpoint (pos);
-      }
-  }
-
-  void set_axes_currentpoint (graphics_object ax, int px, int py)
-  {
-    if (ax.valid_object ())
-      {
-        axes::properties& ap =
-          dynamic_cast<axes::properties&> (ax.get_properties ());
-
-        double xx, yy;
-        pixel2pos (ax, px, py, xx, yy);
-
-        Matrix pos (2,3,0);
-        pos(0,0) = xx;
-        pos(1,0) = yy;
-        pos(0,1) = xx;
-        pos(1,1) = yy;
-
-        ap.set_currentpoint (pos);
-      }
-  }
-
-  int key2shift (int key)
-  {
-    if (key == FL_Shift_L || key == FL_Shift_R)
-      return FL_SHIFT;
-
-    if (key == FL_Control_L || key == FL_Control_R)
-      return FL_CTRL;
-
-    if (key == FL_Alt_L || key == FL_Alt_R)
-      return FL_ALT;
-
-    if (key == FL_Meta_L || key == FL_Meta_R)
-      return FL_META;
-
-    return 0;
-  }
-
-  int key2ascii (int key)
-  {
-    if (key < 256) return key;
-    if (key == FL_Tab) return '\t';
-    if (key == FL_Enter) return 0x0a;
-    if (key == FL_BackSpace) return 0x08;
-    if (key == FL_Escape) return 0x1b;
-
-    return 0;
-  }
-
-  Cell modifier2cell ()
-  {
-    string_vector mod;
-
-    if (shift & FL_SHIFT)
-      mod.append (std::string ("shift"));
-    if (shift & FL_CTRL)
-      mod.append (std::string ("control"));
-    if (shift & FL_ALT || shift & FL_META)
-      mod.append (std::string ("alt"));
-
-    return Cell (mod);
-  }
-
-  void resize (int xx,int yy,int ww,int hh)
-  {
-    Fl_Window::resize (xx, yy, ww, hh);
-
-    Matrix pos (1,4,0);
-    pos(0) = xx;
-    pos(1) = yy;
-    pos(2) = ww;
-    pos(3) = hh - status_h - menu_h;
-
-    fp.set_boundingbox (pos, true);
-  }
-
-  void draw (void)
-  {
-    Matrix pos = fp.get_boundingbox (true);
-    Fl_Window::resize (pos(0), pos(1), pos(2), pos(3) + status_h + menu_h);
-
-    return Fl_Window::draw ();
-  }
-
-  int handle (int event)
-  {
-    graphics_handle gh;
-
-    graphics_object fig = gh_manager::get_object (fp.get___myhandle__ ());
-    int retval = Fl_Window::handle (event);
-
-    // We only handle events which are in the canvas area.
-    if (!Fl::event_inside (canvas))
-      return retval;
-
-    if (!fp.is_beingdeleted ())
-      {
-        switch (event)
-          {
-          case FL_KEYDOWN:
-            {
-              int key = Fl::event_key ();
-
-              shift |= key2shift (key);
-              int key_a = key2ascii (key);
-              if (key_a && fp.get_keypressfcn ().is_defined ())
-                {
-                  Octave_map evt;
-                  evt.assign ("Character", octave_value (key_a));
-                  evt.assign ("Key", octave_value (std::tolower (key_a)));
-                  evt.assign ("Modifier", octave_value (modifier2cell ()));
-                  fp.execute_keypressfcn (evt);
-                }
-              switch (key)
-                {
-                case 'a':
-                case 'A':
-                  axis_auto ();
-                break;
-
-                case 'g':
-                case 'G':
-                  toggle_grid ();
-                break;
-
-                case 'p':
-                case 'P':
-                  gui_mode = pan_zoom;
-                break;
-
-                case 'r':
-                case 'R':
-                  gui_mode = rotate_zoom;
-                break;
-                }
-            }
-            break;
-
-          case FL_KEYUP:
-            {
-              int key = Fl::event_key ();
-
-              shift &= (~key2shift (key));
-              int key_a = key2ascii (key);
-              if (key_a && fp.get_keyreleasefcn ().is_defined ())
-                {
-                  Octave_map evt;
-                  evt.assign ("Character", octave_value (key_a));
-                  evt.assign ("Key", octave_value (std::tolower (key_a)));
-                  evt.assign ("Modifier", octave_value (modifier2cell ()));
-                  fp.execute_keyreleasefcn (evt);
-                }
-            }
-            break;
-
-          case FL_MOVE:
-            pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()),
-                          Fl::event_x (), Fl::event_y ());
-            break;
-
-          case FL_PUSH:
-            pos_x = Fl::event_x ();
-            pos_y = Fl::event_y ();
-
-            set_currentpoint (Fl::event_x (), Fl::event_y ());
-
-            gh = pixel2axes_or_ca (pos_x, pos_y);
-
-            if (gh.ok ())
-              {
-                ax_obj = gh_manager::get_object (gh);
-                set_axes_currentpoint (ax_obj, pos_x, pos_y);
-              }
-
-            fp.execute_windowbuttondownfcn ();
-
-            if (Fl::event_button () == 1 || Fl::event_button () == 3)
-              return 1;
-
-            break;
-
-          case FL_DRAG:
-            if (fp.get_windowbuttonmotionfcn ().is_defined ())
-              {
-                set_currentpoint (Fl::event_x (), Fl::event_y ());
-                fp.execute_windowbuttonmotionfcn ();
-              }
-
-            if (Fl::event_button () == 1)
-              {
-                if (ax_obj && ax_obj.isa ("axes"))
-                  {
-                    if (gui_mode == pan_zoom)
-                      pixel2status (ax_obj, pos_x, pos_y,
-                                    Fl::event_x (), Fl::event_y ());
-                    else
-                      view2status (ax_obj);
-                    axes::properties& ap =
-                      dynamic_cast<axes::properties&> (ax_obj.get_properties ());
-
-                    double x0, y0, x1, y1;
-                    Matrix pos = fp.get_boundingbox (true);
-                    pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
-                    pixel2pos (ax_obj, Fl::event_x (), Fl::event_y (), x1, y1);
-
-                    if (gui_mode == pan_zoom)
-                      ap.translate_view (x0, x1, y0, y1);
-                    else if (gui_mode == rotate_zoom)
-                      {
-                        double daz, del;
-                        daz = (Fl::event_x () - pos_x) / pos(2) * 360;
-                        del = (Fl::event_y () - pos_y) / pos(3) * 360;
-                        ap.rotate_view (del, daz);
-                      }
-
-                    pos_x = Fl::event_x ();
-                    pos_y = Fl::event_y ();
-                    mark_modified ();
-                  }
-                return 1;
-              }
-            else if (Fl::event_button () == 3)
-              {
-                pixel2status (ax_obj, pos_x, pos_y,
-                              Fl::event_x (), Fl::event_y ());
-                Matrix zoom_box (1,4,0);
-                zoom_box (0) = pos_x;
-                zoom_box (1) = pos_y;
-                zoom_box (2) =  Fl::event_x ();
-                zoom_box (3) =  Fl::event_y ();
-                canvas->set_zoom_box (zoom_box);
-                canvas->zoom (true);
-                canvas->redraw ();
-              }
-
-            break;
-
-          case FL_MOUSEWHEEL:
-            {
-              graphics_object ax =
-                gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (),
-                                                          Fl::event_y ()));
-              if (ax && ax.isa ("axes"))
-                {
-                  axes::properties& ap =
-                    dynamic_cast<axes::properties&> (ax.get_properties ());
-
-                  // Determine if we're zooming in or out.
-                  const double factor =
-                    (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed;
-
-                  // Get the point we're zooming about.
-                  double x1, y1;
-                  pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1);
-
-                  ap.zoom_about_point (x1, y1, factor, false);
-                  mark_modified ();
-                }
-            }
-          return 1;
-
-          case FL_RELEASE:
-            if (fp.get_windowbuttonupfcn ().is_defined ())
-              {
-                set_currentpoint (Fl::event_x (), Fl::event_y ());
-                fp.execute_windowbuttonupfcn ();
-              }
-
-            if (Fl::event_button () == 1)
-              {
-                if ( Fl::event_clicks () == 1)
-                  {
-                    if (ax_obj && ax_obj.isa ("axes"))
-                      {
-                        axes::properties& ap =
-                          dynamic_cast<axes::properties&> (ax_obj.get_properties ());
-                        ap.set_xlimmode ("auto");
-                        ap.set_ylimmode ("auto");
-                        ap.set_zlimmode ("auto");
-                        mark_modified ();
-                      }
-                  }
-              }
-            if (Fl::event_button () == 3)
-              {
-                // End of drag -- zoom.
-                if (canvas->zoom ())
-                  {
-                    canvas->zoom (false);
-                    double x0,y0,x1,y1;
-                    if (ax_obj && ax_obj.isa ("axes"))
-                      {
-                        axes::properties& ap =
-                          dynamic_cast<axes::properties&> (ax_obj.get_properties ());
-                        pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
-                        int pos_x1 = Fl::event_x ();
-                        int pos_y1 = Fl::event_y ();
-                        pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1);
-                        Matrix xl (1,2,0);
-                        Matrix yl (1,2,0);
-                        int dx = abs (pos_x - pos_x1);
-                        int dy = abs (pos_y - pos_y1);
-                        // Smallest zoom box must be 4 pixels square
-                        if ((dx > 4) && (dy > 4))
-                          {
-                            if (x0 < x1)
-                              {
-                                xl(0) = x0;
-                                xl(1) = x1;
-                              }
-                            else
-                              {
-                                xl(0) = x1;
-                                xl(1) = x0;
-                              }
-                            if (y0 < y1)
-                              {
-                                yl(0) = y0;
-                                yl(1) = y1;
-                              }
-                            else
-                              {
-                                yl(0) = y1;
-                                yl(1) = y0;
-                              }
-                            ap.zoom (xl, yl);
-                          }
-                        mark_modified ();
-                      }
-                  }
-              }
-            break;
-          }
-      }
-
-    return retval;
-  }
-};
-
-class figure_manager
-{
-public:
-
-  static bool instance_ok (void)
-  {
-    bool retval = true;
-
-    if (! instance)
-      instance = new figure_manager ();
-
-    if (! instance)
-      {
-        ::error ("unable to create figure_manager object!");
-
-        retval = false;
-      }
-
-    return retval;
-  }
-
-  ~figure_manager (void)
-  {
-    close_all ();
-  }
-
-  static void close_all (void)
-  {
-    if (instance_ok ())
-      instance->do_close_all ();
-  }
-
-  static void new_window (figure::properties& fp)
-  {
-    if (instance_ok ())
-      instance->do_new_window (fp);
-  }
-
-  static void delete_window (int idx)
-  {
-    if (instance_ok ())
-      instance->do_delete_window (idx);
-  }
-
-  static void delete_window (const std::string& idx_str)
-  {
-    delete_window (str2idx (idx_str));
-  }
-
-  static void renumber_figure (const std::string& idx_str, double new_number)
-  {
-    if (instance_ok ())
-      instance->do_renumber_figure (str2idx (idx_str), new_number);
-  }
-
-  static void toggle_window_visibility (int idx, bool is_visible)
-  {
-    if (instance_ok ())
-      instance->do_toggle_window_visibility (idx, is_visible);
-  }
-
-  static void toggle_window_visibility (const std::string& idx_str,
-                                        bool is_visible)
-  {
-    toggle_window_visibility (str2idx (idx_str), is_visible);
-  }
-
-  static void mark_modified (int idx)
-  {
-    if (instance_ok ())
-      instance->do_mark_modified (idx);
-  }
-
-  static void mark_modified (const graphics_handle& gh)
-  {
-    mark_modified (hnd2idx (gh));
-  }
-
-  static void set_name (int idx)
-  {
-    if (instance_ok ())
-      instance->do_set_name (idx);
-  }
-
-  static void set_name (const std::string& idx_str)
-  {
-    set_name (str2idx (idx_str));
-  }
-
-  static Matrix get_size (int idx)
-  {
-    return instance_ok () ? instance->do_get_size (idx) : Matrix ();
-  }
-
-  static Matrix get_size (const graphics_handle& gh)
-  {
-    return get_size (hnd2idx (gh));
-  }
-
-  static void print (const graphics_handle& gh, const std::string& cmd,
-                     const std::string& term)
-  {
-    if (instance_ok ())
-      instance->do_print (hnd2idx (gh), cmd, term);
-  }
-
-  static void uimenu_update (const graphics_handle& figh,
-                             const graphics_handle& uimenuh, int id)
-  {
-    if (instance_ok ())
-      instance->do_uimenu_update (hnd2idx (figh), uimenuh, id);
-  }
-
-  static void update_canvas (const graphics_handle& gh,
-                             const graphics_handle& ca)
-  {
-    if (instance_ok ())
-      instance->do_update_canvas (hnd2idx (gh), ca);
-  }
-
-  static void toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
-  {
-    if (instance_ok ())
-      instance->do_toggle_menubar_visibility (fig_idx, menubar_is_figure);
-  }
-
-  static void toggle_menubar_visibility (const std::string& fig_idx_str,
-                                         bool menubar_is_figure)
-  {
-    toggle_menubar_visibility (str2idx (fig_idx_str), menubar_is_figure);
-  }
-
-private:
-
-  static figure_manager *instance;
-
-  figure_manager (void) { }
-
-  // No copying!
-  figure_manager (const figure_manager&);
-  figure_manager& operator = (const figure_manager&);
-
-  // Singelton -- hide all of the above.
-
-  static int curr_index;
-  typedef std::map<int, plot_window*> window_map;
-  typedef window_map::iterator wm_iterator;;
-  window_map windows;
-
-  static std::string fltk_idx_header;
-
-  void do_close_all (void)
-  {
-    wm_iterator win;
-    for (win = windows.begin (); win != windows.end (); win++)
-      delete win->second;
-    windows.clear ();
-  }
-
-  void do_new_window (figure::properties& fp)
-  {
-    int idx = figprops2idx (fp);
-
-    if (idx >= 0 && windows.find (idx) == windows.end ())
-      {
-        Matrix pos = fp.get_boundingbox (true);
-
-        int x = pos(0);
-        int y = pos(1);
-        int w = pos(2);
-        int h = pos(3);
-
-        idx2figprops (curr_index, fp);
-
-        windows[curr_index++] = new plot_window (x, y, w, h, fp);
-      }
-  }
-
-  void do_delete_window (int idx)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      {
-        delete win->second;
-        windows.erase (win);
-      }
-  }
-
-  void do_renumber_figure (int idx, double new_number)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      win->second->renumber (new_number);
-  }
-
-  void do_toggle_window_visibility (int idx, bool is_visible)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      {
-        if (is_visible)
-          win->second->show ();
-        else
-          win->second->hide ();
-
-        win->second->redraw ();
-      }
-  }
-
-  void do_toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
-  {
-    wm_iterator win = windows.find (fig_idx);
-
-    if (win != windows.end ())
-      {
-        if (menubar_is_figure)
-          win->second->show_menubar ();
-        else
-          win->second->hide_menubar ();
-
-        win->second->redraw ();
-      }
-  }
-
-  void do_mark_modified (int idx)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      win->second->mark_modified ();
-  }
-
-  void do_set_name (int idx)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      win->second->set_name ();
-  }
-
-  Matrix do_get_size (int idx)
-  {
-    Matrix sz (1, 2, 0.0);
-
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      {
-        sz(0) = win->second->w ();
-        sz(1) = win->second->h ();
-      }
-
-    return sz;
-  }
-
-  void do_print (int idx, const std::string& cmd, const std::string& term)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      win->second->print (cmd, term);
-  }
-
-  void do_uimenu_update (int idx, const graphics_handle& gh, int id)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      win->second->uimenu_update (gh, id);
-  }
-
-  void do_update_canvas (int idx, const graphics_handle& ca)
-  {
-    wm_iterator win = windows.find (idx);
-
-    if (win != windows.end ())
-      {
-        if (ca.ok ())
-          win->second->show_canvas ();
-        else
-          win->second->hide_canvas ();
-      }
-  }
-
-  static int str2idx (const caseless_str& clstr)
-  {
-    int ind;
-    if (clstr.find (fltk_idx_header,0) == 0)
-      {
-        std::istringstream istr (clstr.substr (fltk_idx_header.size ()));
-        if (istr >> ind)
-          return ind;
-      }
-    error ("figure_manager: could not recognize fltk index");
-    return -1;
-  }
-
-  void idx2figprops (int idx, figure::properties& fp)
-  {
-    std::ostringstream ind_str;
-    ind_str << fltk_idx_header << idx;
-    fp.set___plot_stream__ (ind_str.str ());
-  }
-
-  static int figprops2idx (const figure::properties& fp)
-  {
-    if (fp.get___graphics_toolkit__ () == FLTK_GRAPHICS_TOOLKIT_NAME)
-      {
-        octave_value ps = fp.get___plot_stream__ ();
-        if (ps.is_string ())
-          return str2idx (ps.string_value ());
-        else
-          return 0;
-      }
-    error ("figure_manager: figure is not fltk");
-    return -1;
-  }
-
-  static int hnd2idx (double h)
-  {
-    graphics_object fobj = gh_manager::get_object (h);
-    if (fobj &&  fobj.isa ("figure"))
-      {
-        figure::properties& fp =
-          dynamic_cast<figure::properties&> (fobj.get_properties ());
-        return figprops2idx (fp);
-      }
-    error ("figure_manager: H (= %g) is not a figure", h);
-    return -1;
-  }
-
-  static int hnd2idx (const graphics_handle& fh)
-  {
-    return hnd2idx (fh.value ());
-  }
-};
-
-figure_manager *figure_manager::instance = 0;
-
-std::string figure_manager::fltk_idx_header="fltk index=";
-int figure_manager::curr_index = 1;
-
-static bool toolkit_loaded = false;
-
-static int
-__fltk_redraw__ (void)
-{
-  if (toolkit_loaded)
-    {
-      // We scan all figures and add those which use FLTK.
-      graphics_object obj = gh_manager::get_object (0);
-      if (obj && obj.isa ("root"))
-        {
-          base_properties& props = obj.get_properties ();
-          Matrix children = props.get_all_children ();
-
-          for (octave_idx_type n = 0; n < children.numel (); n++)
-            {
-              graphics_object fobj = gh_manager::get_object (children (n));
-              if (fobj && fobj.isa ("figure"))
-                {
-                  figure::properties& fp =
-                      dynamic_cast<figure::properties&> (fobj.get_properties ());
-                  if (fp.get___graphics_toolkit__ ()
-                      == FLTK_GRAPHICS_TOOLKIT_NAME)
-                    figure_manager::new_window (fp);
-                }
-            }
-        }
-
-      // it seems that we have to call Fl::check twice to get everything drawn
-      Fl::check ();
-      Fl::check ();
-    }
-
-  return 0;
-}
-
-class fltk_graphics_toolkit : public base_graphics_toolkit
-{
-public:
-  fltk_graphics_toolkit (void)
-    : base_graphics_toolkit (FLTK_GRAPHICS_TOOLKIT_NAME) { }
-
-  ~fltk_graphics_toolkit (void) { }
-
-  bool is_valid (void) const { return true; }
-
-  bool initialize (const graphics_object& go)
-    { return go.isa ("figure"); }
-
-  void finalize (const graphics_object& go)
-  {
-    if (go.isa ("figure"))
-      {
-        octave_value ov = go.get (caseless_str ("__plot_stream__"));
-
-        if (! ov.is_empty ())
-          figure_manager::delete_window (ov.string_value ());
-      }
-  }
-
-  void uimenu_set_fltk_label (graphics_object uimenu_obj)
-  {
-    if (uimenu_obj.valid_object ())
-      {
-        uimenu::properties& uimenup =
-          dynamic_cast<uimenu::properties&> (uimenu_obj.get_properties ());
-        std::string fltk_label = uimenup.get_label ();
-        graphics_object go = gh_manager::get_object (uimenu_obj.get_parent ());
-        if (go.isa ("uimenu"))
-          fltk_label = dynamic_cast<const uimenu::properties&> (go.get_properties ()).get_fltk_label ()
-            + "/"
-            + fltk_label;
-        else if (go.isa ("figure"))
-          ;
-        else
-          error ("unexpected parent object\n");
-
-        uimenup.set_fltk_label (fltk_label);
-      }
-  }
-
-  void update (const graphics_object& go, int id)
-  {
-    if (go.isa ("figure"))
-      {
-        octave_value ov = go.get (caseless_str ("__plot_stream__"));
-
-        if (! ov.is_empty ())
-          {
-            const figure::properties& fp =
-              dynamic_cast<const figure::properties&> (go.get_properties ());
-
-            switch (id)
-              {
-              case base_properties::ID_VISIBLE:
-                figure_manager::toggle_window_visibility
-                  (ov.string_value (), fp.is_visible ());
-                break;
-
-              case figure::properties::ID_MENUBAR:
-                figure_manager::toggle_menubar_visibility
-                  (ov.string_value (), fp.menubar_is ("figure"));
-                break;
-
-              case figure::properties::ID_CURRENTAXES:
-                figure_manager::update_canvas
-                  (go.get_handle (), fp.get_currentaxes ());
-                break;
-
-              case figure::properties::ID_NAME:
-              case figure::properties::ID_NUMBERTITLE:
-                figure_manager::set_name (ov.string_value ());
-                break;
-
-              case figure::properties::ID_INTEGERHANDLE:
-                {
-                  std::string tmp = ov.string_value ();
-                  graphics_handle gh = fp.get___myhandle__ ();
-                  figure_manager::renumber_figure (tmp, gh.value ());
-                  figure_manager::set_name (tmp);
-                }
-                break;
-              }
-          }
-      }
-    else if (go.isa ("uimenu"))
-      {
-        if (id == uimenu::properties::ID_LABEL)
-          uimenu_set_fltk_label (go);
-
-        graphics_object fig = go.get_ancestor ("figure");
-        figure_manager::uimenu_update (fig.get_handle (), go.get_handle (), id);
-      }
-  }
-
-  void redraw_figure (const graphics_object& go) const
-  {
-    figure_manager::mark_modified (go.get_handle ());
-
-    __fltk_redraw__ ();
-  }
-
-  void print_figure (const graphics_object& go,
-                     const std::string& term,
-                     const std::string& file_cmd, bool /*mono*/,
-                     const std::string& /*debug_file*/) const
-  {
-    figure_manager::print (go.get_handle (), file_cmd, term);
-    redraw_figure (go);
-  }
-
-  Matrix get_canvas_size (const graphics_handle& fh) const
-  {
-    return figure_manager::get_size (fh);
-  }
-
-  double get_screen_resolution (void) const
-  {
-    // FLTK doesn't give this info.
-    return 72.0;
-  }
-
-  Matrix get_screen_size (void) const
-  {
-    Matrix sz (1, 2, 0.0);
-    sz(0) = Fl::w ();
-    sz(1) = Fl::h ();
-    return sz;
-  }
-
-  void close (void)
-  {
-    if (toolkit_loaded)
-      {
-        munlock ("__init_fltk__");
-
-        figure_manager::close_all ();
-        gtk_manager::unload_toolkit (FLTK_GRAPHICS_TOOLKIT_NAME);
-        toolkit_loaded = false;
-
-        octave_value_list args;
-        args(0) = "__fltk_redraw__";
-        feval ("remove_input_event_hook", args, 0);
-
-        // FIXME ???
-        Fl::wait (fltk_maxtime);
-      }
-  }
-};
-
-// Initialize the fltk graphics toolkit.
-
-DEFUN_DLD (__init_fltk__, , , "")
-{
-  if (! toolkit_loaded)
-    {
-      mlock ();
-
-      graphics_toolkit tk (new fltk_graphics_toolkit ());
-      gtk_manager::load_toolkit (tk);
-      toolkit_loaded = true;
-
-      octave_value_list args;
-      args(0) = "__fltk_redraw__";
-      feval ("add_input_event_hook", args, 0);
-    }
-
-  octave_value retval;
-  return retval;
-}
-
-DEFUN_DLD (__fltk_redraw__, , , "")
-{
-  __fltk_redraw__ ();
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__fltk_maxtime__, args, ,"")
-{
-  octave_value retval = fltk_maxtime;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_real_scalar ())
-        fltk_maxtime = args(0).double_value ();
-      else
-        error ("argument must be a real scalar");
-    }
-
-  return retval;
-}
-
-#endif
-
-// FIXME -- This function should be abstracted and made potentially
-// available to all graphics toolkits.  This suggests putting it in
-// graphics.cc as is done for drawnow() and having the master
-// mouse_wheel_zoom function call fltk_mouse_wheel_zoom.  The same
-// should be done for gui_mode and fltk_gui_mode.  For now (2011.01.30),
-// just changing function names and docstrings.
-
-DEFUN_DLD (mouse_wheel_zoom, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{speed} =} mouse_wheel_zoom ()\n\
-@deftypefnx {Built-in Function} {} mouse_wheel_zoom (@var{speed})\n\
-Query or set the mouse wheel zoom factor.\n\
-\n\
-This function is currently implemented only for the FLTK graphics toolkit.\n\
-@seealso{gui_mode}\n\
-@end deftypefn")
-{
-#if defined (HAVE_FLTK)
-  octave_value retval = wheel_zoom_speed;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_real_scalar ())
-        wheel_zoom_speed = args(0).double_value ();
-      else
-        error ("mouse_wheel_zoom: SPEED must be a real scalar");
-    }
-
-  return retval;
-#else
-  error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
-  return octave_value ();
-#endif
-}
-
-DEFUN_DLD (gui_mode, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{mode} =} gui_mode ()\n\
-@deftypefnx {Built-in Function} {} gui_mode (@var{mode})\n\
-Query or set the GUI mode for the current graphics toolkit.\n\
-The @var{mode} argument can be one of the following strings:\n\
-\n\
-@table @asis\n\
-@item '2d'\n\
-Allows panning and zooming of current axes.\n\
-\n\
-@item '3d'\n\
-Allows rotating and zooming of current axes.\n\
-\n\
-@item 'none'\n\
-Mouse inputs have no effect.\n\
-@end table\n\
-\n\
-This function is currently implemented only for the FLTK graphics toolkit.\n\
-@seealso{mouse_wheel_zoom}\n\
-@end deftypefn")
-{
-#if defined (HAVE_FLTK)
-  caseless_str mode_str;
-
-  if (gui_mode == pan_zoom)
-    mode_str = "2d";
-  else if (gui_mode == rotate_zoom)
-    mode_str = "3d";
-  else
-    mode_str = "none";
-
-  bool failed = false;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_string ())
-        {
-          mode_str = args(0).string_value ();
-
-          if (mode_str.compare ("2d"))
-            gui_mode = pan_zoom;
-          else if (mode_str.compare ("3d"))
-            gui_mode = rotate_zoom;
-          else if (mode_str.compare ("none"))
-            gui_mode = none;
-          else
-            failed = true;
-        }
-      else
-        failed = true;
-    }
-
-  if (failed)
-    error ("MODE must be one of the strings: \"2D\", \"3D\", or \"none\"");
-
-  return octave_value (mode_str);
-#else
-  error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
-  return octave_value ();
-#endif
-}
-
--- a/src/DLD-FUNCTIONS/__init_gnuplot__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
-
-Copyright (C) 2007-2012 John W. Eaton
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-
-To initialize:
-
-  graphics_toolkit ("gnuplot");
-  plot (randn (1e3, 1));
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun-dld.h"
-#include "error.h"
-#include "graphics.h"
-#include "parse.h"
-#include "variables.h"
-
-// PKG_ADD: register_graphics_toolkit ("gnuplot");
-
-static bool toolkit_loaded = false;
-
-class gnuplot_graphics_toolkit : public base_graphics_toolkit
-{
-public:
-  gnuplot_graphics_toolkit (void)
-      : base_graphics_toolkit ("gnuplot") { }
-
-  ~gnuplot_graphics_toolkit (void) { }
-
-  bool is_valid (void) const { return true; }
-
-  bool initialize (const graphics_object& go)
-    {
-      return go.isa ("figure");
-    }
-
-  void finalize (const graphics_object& go)
-    {
-      if (go.isa ("figure"))
-        {
-          const figure::properties& props =
-              dynamic_cast<const figure::properties&> (go.get_properties ());
-
-          send_quit (props.get___plot_stream__ ());
-        }
-    }
-
-  void update (const graphics_object& go, int id)
-    {
-      if (go.isa ("figure"))
-        {
-          graphics_object obj (go);
-
-          figure::properties& props =
-              dynamic_cast<figure::properties&> (obj.get_properties ());
-
-          switch (id)
-            {
-            case base_properties::ID_VISIBLE:
-              if (! props.is_visible ())
-                {
-                  send_quit (props.get___plot_stream__ ());
-                  props.set___plot_stream__ (Matrix ());
-                  props.set___enhanced__ (false);
-                }
-              break;
-            }
-        }
-    }
-
-  void redraw_figure (const graphics_object& go) const
-    {
-      octave_value_list args;
-      args(0) = go.get_handle ().as_octave_value ();
-      feval ("__gnuplot_drawnow__", args);
-    }
-
-  void print_figure (const graphics_object& go, const std::string& term,
-                     const std::string& file, bool mono,
-                     const std::string& debug_file) const
-    {
-      octave_value_list args;
-      if (! debug_file.empty ())
-        args(4) = debug_file;
-      args(3) = mono;
-      args(2) = file;
-      args(1) = term;
-      args(0) = go.get_handle ().as_octave_value ();
-      feval ("__gnuplot_drawnow__", args);
-    }
-
-  Matrix get_canvas_size (const graphics_handle&) const
-    {
-      Matrix sz (1, 2, 0.0);
-      return sz;
-    }
-
-  double get_screen_resolution (void) const
-    { return 72.0; }
-
-  Matrix get_screen_size (void) const
-    { return Matrix (1, 2, 0.0); }
-
-  void close (void)
-  {
-    if (toolkit_loaded)
-      {
-        munlock ("__init_gnuplot__");
-
-        gtk_manager::unload_toolkit ("gnuplot");
-
-        toolkit_loaded = false;
-      }
-  }
-
-private:
-
-  void send_quit (const octave_value& pstream) const
-    {
-      if (! pstream.is_empty ())
-        {
-          octave_value_list args;
-          Matrix fids = pstream.matrix_value ();
-
-          if (! error_state)
-            {
-              args(1) = "\nquit;\n";
-              args(0) = fids(0);
-              feval ("fputs", args);
-
-              args.resize (1);
-              feval ("fflush", args);
-              feval ("pclose", args);
-
-              if (fids.numel () > 1)
-                {
-                  args(0) = fids(1);
-                  feval ("pclose", args);
-
-                  if (fids.numel () > 2)
-                    {
-                      args(0) = fids(2);
-                      feval ("waitpid", args);
-                    }
-                }
-            }
-        }
-    }
-};
-
-// Initialize the fltk graphics toolkit.
-
-DEFUN_DLD (__init_gnuplot__, , , "")
-{
-  octave_value retval;
-
-  if (! toolkit_loaded)
-    {
-      mlock ();
-
-      graphics_toolkit tk (new gnuplot_graphics_toolkit ());
-      gtk_manager::load_toolkit (tk);
-
-      toolkit_loaded = true;
-    }
-
-  return retval;
-}
-
--- a/src/DLD-FUNCTIONS/__magick_read__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1216 +0,0 @@
-/*
-
-Copyright (C) 2002-2012 Andy Adler
-Copyright (C) 2008 Thomas L. Scofield
-Copyright (C) 2010 David Grundberg
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cmath>
-
-#include "file-stat.h"
-#include "oct-env.h"
-#include "oct-time.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "ov-struct.h"
-
-#ifdef HAVE_MAGICK
-
-#include <Magick++.h>
-#include <clocale>
-
-octave_value_list
-read_indexed_images (std::vector<Magick::Image>& imvec,
-                     const Array<int>& frameidx, bool wantalpha)
-{
-  octave_value_list output;
-
-  int rows = imvec[0].baseRows ();
-  int columns = imvec[0].baseColumns ();
-  int nframes = frameidx.length ();
-
-  dim_vector idim = dim_vector ();
-  idim.resize (4);
-  idim(0) = rows;
-  idim(1) = columns;
-  idim(2) = 1;
-  idim(3) = nframes;
-
-  Array<int> idx (dim_vector (4, 1));
-
-  Magick::ImageType type = imvec[0].type ();
-
-  unsigned int mapsize = imvec[0].colorMapSize ();
-  unsigned int i = mapsize;
-  unsigned int depth = 0;
-  while (i >>= 1)
-    depth++;
-  i = 0;
-  depth--;
-  while (depth >>= 1)
-    i++;
-  depth = 1 << i;
-
-  switch (depth)
-    {
-    case 1:
-    case 2:
-    case 4:
-    case 8:
-      {
-        uint8NDArray im = uint8NDArray (idim);
-
-        idx(2) = 0;
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            const Magick::IndexPacket *pix
-              = imvec[frameidx(frame)].getConstIndexes ();
-
-            i = 0;
-            idx(3) = frame;
-
-            for (int y = 0; y < rows; y++)
-              {
-                idx(0) = y;
-                for (int x = 0; x < columns; x++)
-                  {
-                    idx(1) = x;
-                    im(idx) = static_cast<octave_uint8> (pix[i++]);
-                  }
-              }
-          }
-
-        output(0) = octave_value (im);
-      }
-      break;
-
-    case 16:
-      {
-        uint16NDArray im = uint16NDArray (idim);
-
-        idx(2) = 0;
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            const Magick::IndexPacket *pix
-              = imvec[frameidx(frame)].getConstIndexes ();
-
-            i = 0;
-            idx(3) = frame;
-
-            for (int y = 0; y < rows; y++)
-              {
-                idx(0) = y;
-                for (int x = 0; x < columns; x++)
-                  {
-                    idx(1) = x;
-                    im(idx) = static_cast<octave_uint16> (pix[i++]);
-                  }
-              }
-          }
-
-        output(0) = octave_value (im);
-      }
-      break;
-
-    default:
-      error ("__magic_read__: index depths greater than 16-bit are not supported");
-      return octave_value_list ();
-    }
-
-  Matrix map = Matrix (mapsize, 3);
-  Matrix alpha;
-
-  switch (type)
-    {
-    case Magick::PaletteMatteType:
-#if 0
-      warning ("palettematte");
-      Matrix map (mapsize, 3);
-      Matrix alpha (mapsize, 1);
-      for (i = 0; i < mapsize; i++)
-        {
-          warning ("%d", i);
-          Magick::ColorRGB c = imvec[0].colorMap (i);
-          map(i,0) = c.red ();
-          map(i,1) = c.green ();
-          map(i,2) = c.blue ();
-          alpha(i,1) = c.alpha ();
-        }
-      break;
-#endif
-
-    case Magick::PaletteType:
-      alpha = Matrix (0, 0);
-      for (i = 0; i < mapsize; i++)
-        {
-          Magick::ColorRGB c = imvec[0].colorMap (i);
-          map(i,0) = c.red ();
-          map(i,1) = c.green ();
-          map(i,2) = c.blue ();
-        }
-      break;
-
-    default:
-      error ("__magick_read__: unsupported indexed image type");
-      return octave_value_list ();
-    }
-
-  if (wantalpha)
-    output(2) = alpha;
-
-  output(1) = map;
-
-  return output;
-}
-
-template <class T>
-octave_value_list
-read_images (const std::vector<Magick::Image>& imvec,
-             const Array<int>& frameidx, unsigned int depth)
-{
-  typedef typename T::element_type P;
-
-  octave_value_list retval (3, Matrix ());
-
-  T im;
-
-  int rows = imvec[0].baseRows ();
-  int columns = imvec[0].baseColumns ();
-  int nframes = frameidx.length ();
-
-  dim_vector idim = dim_vector ();
-  idim.resize (4);
-  idim(0) = rows;
-  idim(1) = columns;
-  idim(2) = 1;
-  idim(3) = nframes;
-
-  Magick::ImageType type = imvec[0].type ();
-  const int divisor = ((uint64_t (1) << QuantumDepth) - 1) / 
-                      ((uint64_t (1) << depth) - 1);
-
-  switch (type)
-    {
-    case Magick::BilevelType:
-    case Magick::GrayscaleType:
-      {
-        im = T (idim);
-        P *vec = im.fortran_vec ();
-
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            const Magick::PixelPacket *pix
-              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            P *rbuf = vec;
-            for (int y = 0; y < rows; y++)
-              {
-                for (int x = 0; x < columns; x++)
-                  {
-                    *rbuf = pix->red / divisor;
-                    pix++;
-                    rbuf += rows;
-                  }
-                rbuf -= rows * columns - 1;
-              }
-
-            // Next frame.
-            vec += rows * columns * idim(2);
-          }
-        }
-      break;
-
-    case Magick::GrayscaleMatteType:
-      {
-        idim(2) = 2;
-        im = T (idim);
-        P *vec = im.fortran_vec ();
-
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            const Magick::PixelPacket *pix
-              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            P *rbuf = vec;
-            P *obuf = vec + rows * columns;
-            for (int y = 0; y < rows; y++)
-              {
-                for (int x = 0; x < columns; x++)
-                  {
-                    *rbuf = pix->red / divisor;
-                    *obuf = pix->opacity / divisor;
-                    pix++;
-                    rbuf += rows;
-                    obuf += rows;
-                  }
-                rbuf -= rows * columns - 1;
-                obuf -= rows * columns - 1;
-              }
-
-            // Next frame.
-            vec += rows * columns * idim(2);
-          }
-        }
-      break;
-
-    case Magick::PaletteType:
-    case Magick::TrueColorType:
-      {
-        idim(2) = 3;
-        im = T (idim);
-        P *vec = im.fortran_vec ();
-
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            const Magick::PixelPacket *pix
-              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            P *rbuf = vec;
-            P *gbuf = vec + rows * columns;
-            P *bbuf = vec + rows * columns * 2;
-            for (int y = 0; y < rows; y++)
-              {
-                for (int x = 0; x < columns; x++)
-                  {
-                    *rbuf = pix->red / divisor;
-                    *gbuf = pix->green / divisor;
-                    *bbuf = pix->blue / divisor;
-                    pix++;
-                    rbuf += rows;
-                    gbuf += rows;
-                    bbuf += rows;
-                  }
-                rbuf -= rows * columns - 1;
-                gbuf -= rows * columns - 1;
-                bbuf -= rows * columns - 1;
-              }
-
-            // Next frame.
-            vec += rows * columns * idim(2);
-          }
-        }
-      break;
-
-    case Magick::PaletteMatteType:
-    case Magick::TrueColorMatteType:
-    case Magick::ColorSeparationType:
-      {
-        idim(2) = 4;
-        im = T (idim);
-        P *vec = im.fortran_vec ();
-
-        for (int frame = 0; frame < nframes; frame++)
-          {
-            const Magick::PixelPacket *pix
-              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
-
-            P *rbuf = vec;
-            P *gbuf = vec + rows * columns;
-            P *bbuf = vec + rows * columns * 2;
-            P *obuf = vec + rows * columns * 3;
-            for (int y = 0; y < rows; y++)
-              {
-                for (int x = 0; x < columns; x++)
-                  {
-                    *rbuf = pix->red / divisor;
-                    *gbuf = pix->green / divisor;
-                    *bbuf = pix->blue / divisor;
-                    *obuf = pix->opacity / divisor;
-                    pix++;
-                    rbuf += rows;
-                    gbuf += rows;
-                    bbuf += rows;
-                    obuf += rows;
-                  }
-                rbuf -= rows * columns - 1;
-                gbuf -= rows * columns - 1;
-                bbuf -= rows * columns - 1;
-                obuf -= rows * columns - 1;
-              }
-
-            // Next frame.
-            vec += rows * columns * idim(2);
-          }
-        }
-      break;
-
-    default:
-      error ("__magick_read__: undefined ImageMagick image type");
-      return retval;
-    }
-
-  retval(0) = im;
-
-  return retval;
-}
-
-#endif
-
-static void
-maybe_initialize_magick (void)
-{
-#ifdef HAVE_MAGICK
-
-  static bool initialized = false;
-
-  if (! initialized)
-    {
-      // Save the locale as GraphicsMagick might change this (depending on version)
-      const char *static_locale = setlocale (LC_ALL, NULL);
-      const std::string locale (static_locale);
-
-      std::string program_name = octave_env::get_program_invocation_name ();
-
-      Magick::InitializeMagick (program_name.c_str ());
-
-      // Restore locale from before GraphicsMagick initialisation
-      setlocale (LC_ALL, locale.c_str ());
-
-      if (QuantumDepth < 32)
-        warning ("your version of %s limits images to %d bits per pixel",
-                 MagickPackageName, QuantumDepth);
-
-      initialized = true;
-    }
-#endif
-}
-
-DEFUN_DLD (__magick_read__, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Function File} {@var{m} =} __magick_read__ (@var{fname}, @var{index})\n\
-@deftypefnx {Function File} {[@var{m}, @var{colormap}] =} __magick_read__ (@var{fname}, @var{index})\n\
-@deftypefnx {Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__ (@var{fname}, @var{index})\n\
-Read images with ImageMagick++.  In general you should not be using this\n\
-function.  Instead use @code{imread}.\n\
-@seealso{imread}\n\
-@end deftypefn")
-{
-  octave_value_list output;
-
-#ifdef HAVE_MAGICK
-
-  maybe_initialize_magick ();
-
-  if (args.length () > 3 || args.length () < 1 || ! args(0).is_string ()
-      || nargout > 3)
-    {
-      print_usage ();
-      return output;
-    }
-
-  Array<int> frameidx;
-  bool all_frames = false;
-
-  if (args.length () == 2 && args(1).is_real_type ())
-    frameidx = args(1).int_vector_value ();
-  else if (args.length () == 3 && args(1).is_string ()
-           && args(1).string_value () == "frames")
-    {
-      if (args(2).is_string () && args(2).string_value () == "all")
-        all_frames = true;
-      else if (args(2).is_real_type ())
-        frameidx = args(2).int_vector_value ();
-    }
-  else
-    {
-      frameidx = Array<int> (dim_vector (1, 1));
-      frameidx(0) = 1;
-    }
-
-  std::vector<Magick::Image> imvec;
-
-  try
-    {
-      // Read a file into vector of image objects
-      Magick::readImages (&imvec, args(0).string_value ());
-    }
-  catch (Magick::Warning& w)
-    {
-      warning ("Magick++ warning: %s", w.what ());
-    }
-  catch (Magick::ErrorCoder& e)
-    {
-      warning ("Magick++ coder error: %s", e.what ());
-    }
-  catch (Magick::Exception& e)
-    {
-      error ("Magick++ exception: %s", e.what ());
-      return output;
-    }
-
-  int nframes = imvec.size ();
-  if (all_frames)
-    {
-      frameidx = Array<int> (dim_vector (1, nframes));
-      for (int i = 0; i < frameidx.length (); i++)
-        frameidx(i) = i;
-    }
-  else
-    {
-      for (int i = 0; i < frameidx.length (); i++)
-        {
-          frameidx(i) = frameidx(i) - 1;
-
-          if (frameidx(i) >= nframes || frameidx(i) < 0)
-            {
-              error ("__magick_read__: invalid INDEX vector");
-              return output;
-            }
-        }
-    }
-
-  Magick::ClassType klass = imvec[0].classType ();
-
-  if (klass == Magick::PseudoClass && nargout > 1)
-    output = read_indexed_images (imvec, frameidx, (nargout == 3));
-  else
-    {
-      unsigned int depth = imvec[0].modulusDepth ();
-      if (depth > 1)
-        {
-          --depth;
-          int i = 1;
-          while (depth >>= 1)
-            i++;
-          depth = 1 << i;
-        }
-
-      switch (depth)
-        {
-        case 1:
-          output = read_images<boolNDArray> (imvec, frameidx, depth);
-          break;
-
-        case 2:
-        case 4:
-        case 8:
-          output = read_images<uint8NDArray> (imvec, frameidx, depth) ;
-          break;
-
-        case 16:
-          output = read_images<uint16NDArray> (imvec, frameidx, depth);
-          break;
-
-        case 32:
-        case 64:
-        default:
-          error ("__magick_read__: image depths greater than 16-bit are not supported");
-        }
-    }
-#else
-
-  error ("imread: image reading capabilities were disabled when Octave was compiled");
-
-#endif
-
-  return output;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
-
-#ifdef HAVE_MAGICK
-
-static void
-jpg_settings (std::vector<Magick::Image>& imvec,
-              const Octave_map& options,
-              bool)
-{
-  bool something_set = false;
-
-  // Quality setting
-  octave_value result;
-  Octave_map::const_iterator p;
-  bool found_it = false;
-
-  for (p = options.begin (); p != options.end (); p++)
-    {
-      if (options.key (p) == "Quality")
-        {
-          found_it = true;
-          result = options.contents (p).elem (0);
-          break;
-        }
-    }
-
-  if (found_it && (! result.is_empty ()))
-    {
-      something_set = true;
-
-      if (result.is_real_type ())
-        {
-          int qlev = result.int_value ();
-
-          if (qlev < 0 || qlev > 100)
-            warning ("warning: Quality setting invalid--use default of 75");
-          else
-            {
-              for (size_t fnum = 0; fnum < imvec.size (); fnum++)
-                imvec[fnum].quality (static_cast<unsigned int>(qlev));
-            }
-        }
-      else
-        warning ("warning: Quality setting invalid--use default of 75");
-    }
-
-  // Other settings go here
-
-  if (! something_set)
-    warning ("__magick_write__ warning: all write parameters ignored");
-}
-
-static void
-encode_bool_image (std::vector<Magick::Image>& imvec, const octave_value& img)
-{
-  unsigned int nframes = 1;
-  boolNDArray m = img.bool_array_value ();
-
-  dim_vector dsizes = m.dims ();
-  if (dsizes.length () == 4)
-    nframes = dsizes(3);
-
-  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
-
-  octave_idx_type rows = m.rows ();
-  octave_idx_type columns = m.columns ();
-
-  for (unsigned int ii = 0; ii < nframes; ii++)
-    {
-      Magick::Image im (Magick::Geometry (columns, rows), "black");
-      im.classType (Magick::DirectClass);
-      im.depth (1);
-
-      for (int y = 0; y < columns; y++)
-        {
-          idx(1) = y;
-
-          for (int x = 0; x < rows; x++)
-            {
-              if (nframes > 1)
-                {
-                  idx(2) = 0;
-                  idx(3) = ii;
-                }
-
-              idx(0) = x;
-
-              if (m(idx))
-                im.pixelColor (y, x, "white");
-            }
-        }
-
-      im.quantizeColorSpace (Magick::GRAYColorspace);
-      im.quantizeColors (2);
-      im.quantize ();
-
-      imvec.push_back (im);
-    }
-}
-
-template <class T>
-static void
-encode_uint_image (std::vector<Magick::Image>& imvec,
-                   const octave_value& img,
-                   bool has_map)
-{
-  unsigned int bitdepth = 0;
-  T m;
-
-  if (img.is_uint8_type ())
-    {
-      bitdepth = 8;
-      m = img.uint8_array_value ();
-    }
-  else if (img.is_uint16_type ())
-    {
-      bitdepth = 16;
-      m = img.uint16_array_value ();
-    }
-  else
-    error ("__magick_write__: invalid image class");
-
-  dim_vector dsizes = m.dims ();
-  unsigned int nframes = 1;
-  if (dsizes.length () == 4)
-    nframes = dsizes(3);
-
-  bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2));
-  bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4));
-
-  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
-  octave_idx_type rows = m.rows ();
-  octave_idx_type columns = m.columns ();
-
-  unsigned int div_factor = (1 << bitdepth) - 1;
-
-  for (unsigned int ii = 0; ii < nframes; ii++)
-    {
-      Magick::Image im (Magick::Geometry (columns, rows), "black");
-
-      im.depth (bitdepth);
-
-      if (has_map)
-        im.classType (Magick::PseudoClass);
-      else
-        im.classType (Magick::DirectClass);
-
-      if (is_color)
-        {
-          if (has_alpha)
-            im.type (Magick::TrueColorMatteType);
-          else
-            im.type (Magick::TrueColorType);
-
-          Magick::ColorRGB c;
-
-          for (int y = 0; y < columns; y++)
-            {
-              idx(1) = y;
-
-              for (int x = 0; x < rows; x++)
-                {
-                  idx(0) = x;
-
-                  if (nframes > 1)
-                    idx(3) = ii;
-
-                  idx(2) = 0;
-                  c.red (static_cast<double>(m(idx)) / div_factor);
-
-                  idx(2) = 1;
-                  c.green (static_cast<double>(m(idx)) / div_factor);
-
-                  idx(2) = 2;
-                  c.blue (static_cast<double>(m(idx)) / div_factor);
-
-                  if (has_alpha)
-                    {
-                      idx(2) = 3;
-                      c.alpha (static_cast<double>(m(idx)) / div_factor);
-                    }
-
-                  im.pixelColor (y, x, c);
-                }
-            }
-        }
-      else
-        {
-          if (has_alpha)
-            im.type (Magick::GrayscaleMatteType);
-          else
-            im.type (Magick::GrayscaleType);
-
-          Magick::ColorGray c;
-
-          for (int y = 0; y < columns; y++)
-            {
-              idx(1) = y;
-
-              for (int x=0; x < rows; x++)
-                {
-                  idx(0) = x;
-
-                  if (nframes > 1)
-                    {
-                      idx(2) = 0;
-                      idx(3) = ii;
-                    }
-
-                  if (has_alpha)
-                    {
-                      idx(2) = 1;
-                      c.alpha (static_cast<double>(m(idx)) / div_factor);
-                      idx(2) = 0;
-                    }
-
-                  c.shade (static_cast<double>(m(idx)) / div_factor);
-
-                  im.pixelColor (y, x, c);
-                }
-            }
-
-          im.quantizeColorSpace (Magick::GRAYColorspace);
-          im.quantizeColors (1 << bitdepth);
-          im.quantize ();
-        }
-
-      imvec.push_back (im);
-    }
-}
-
-static void
-encode_map (std::vector<Magick::Image>& imvec, const NDArray& cmap)
-{
-  unsigned int mapsize = cmap.dim1 ();
-
-  for (size_t fnum = 0; fnum < imvec.size (); fnum++)
-    {
-      imvec[fnum].colorMapSize (mapsize);
-      imvec[fnum].type (Magick::PaletteType);
-    }
-
-  for (unsigned int ii = 0; ii < mapsize; ii++)
-    {
-      Magick::ColorRGB c (cmap(ii,0), cmap(ii,1), cmap(ii,2));
-
-      // FIXME -- is this case needed?
-      if (cmap.dim2 () == 4)
-        c.alpha (cmap(ii,3));
-
-      try
-        {
-          for_each (imvec.begin (), imvec.end (),
-                    Magick::colorMapImage (ii, c));
-        }
-      catch (Magick::Warning& w)
-        {
-          warning ("Magick++ warning: %s", w.what ());
-        }
-      catch (Magick::ErrorCoder& e)
-        {
-          warning ("Magick++ coder error: %s", e.what ());
-        }
-      catch (Magick::Exception& e)
-        {
-          error ("Magick++ exception: %s", e.what ());
-        }
-    }
-}
-
-static void
-write_image (const std::string& filename, const std::string& fmt,
-             const octave_value& img,
-             const octave_value& map = octave_value (),
-             const octave_value& params = octave_value ())
-{
-  std::vector<Magick::Image> imvec;
-
-  bool has_map = map.is_defined ();
-
-  if (has_map)
-    {
-      error ("__magick_write__: direct saving of indexed images not currently supported; use ind2rgb and save converted image");
-      return;
-    }
-
-  if (img.is_bool_type ())
-    encode_bool_image (imvec, img);
-  else if (img.is_uint8_type ())
-    encode_uint_image<uint8NDArray> (imvec, img, has_map);
-  else if (img.is_uint16_type ())
-    encode_uint_image<uint16NDArray> (imvec, img, has_map);
-  else
-    error ("__magick_write__: image type not supported");
-
-  if (! error_state && has_map)
-    {
-      NDArray cmap = map.array_value ();
-
-      if (! error_state)
-        encode_map (imvec, cmap);
-    }
-
-  if (! error_state && params.is_defined ())
-    {
-      Octave_map options = params.map_value ();
-
-      // Insert calls here to handle parameters for various image formats
-      if (fmt == "jpg" || fmt == "jpeg")
-        jpg_settings (imvec, options, has_map);
-      else
-        warning ("warning: your parameter(s) currently not supported");
-    }
-
-  try
-    {
-      Magick::writeImages (imvec.begin (), imvec.end (), fmt + ":" + filename);
-    }
-  catch (Magick::Warning& w)
-    {
-      warning ("Magick++ warning: %s", w.what ());
-    }
-  catch (Magick::ErrorCoder& e)
-    {
-      warning ("Magick++ coder error: %s", e.what ());
-    }
-  catch (Magick::Exception& e)
-    {
-      error ("Magick++ exception: %s", e.what ());
-    }
-}
-
-#endif
-
-DEFUN_DLD (__magick_write__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Function File} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img})\n\
-@deftypefnx {Function File} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img}, @var{map})\n\
-Write images with ImageMagick++.  In general you should not be using this\n\
-function.  Instead use @code{imwrite}.\n\
-@seealso{imread}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_MAGICK
-  maybe_initialize_magick ();
-
-  int nargin = args.length ();
-
-  if (nargin > 2)
-    {
-      std::string filename = args(0).string_value ();
-
-      if (! error_state)
-        {
-          std::string fmt = args(1).string_value ();
-
-          if (! error_state)
-            {
-              if (nargin > 4)
-                write_image (filename, fmt, args(2), args(3), args(4));
-              else if (nargin > 3)
-                if (args(3).is_real_type ())
-                  write_image (filename, fmt, args(2), args(3));
-                else
-                  write_image (filename, fmt, args(2), octave_value (), args(3));
-              else
-                write_image (filename, fmt, args(2));
-            }
-          else
-            error ("__magick_write__: FMT must be string");
-        }
-      else
-        error ("__magick_write__: FNAME must be a string");
-    }
-  else
-    print_usage ();
-#else
-
-  error ("__magick_write__: not available in this version of Octave");
-
-#endif
-
-return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
-
-#ifdef HAVE_MAGICK
-
-template<class T>
-static octave_value
-magick_to_octave_value (const T magick)
-{
-  return octave_value (magick);
-}
-
-static octave_value
-magick_to_octave_value (const Magick::EndianType magick)
-{
-  switch (magick)
-    {
-      case Magick::LSBEndian:
-        return octave_value ("little-endian");
-
-      case Magick::MSBEndian:
-        return octave_value ("big-endian");
-
-      default:
-        return octave_value ("undefined");
-    }
-}
-
-static octave_value
-magick_to_octave_value (const Magick::ResolutionType magick)
-{
-  switch (magick)
-    {
-      case Magick::PixelsPerInchResolution:
-        return octave_value ("pixels per inch");
-
-      case Magick::PixelsPerCentimeterResolution:
-        return octave_value ("pixels per centimeter");
-
-      default:
-        return octave_value ("undefined");
-    }
-}
-
-static octave_value
-magick_to_octave_value (const Magick::ImageType magick)
-{
-  switch (magick)
-    {
-      case Magick::BilevelType:
-      case Magick::GrayscaleType:
-      case Magick::GrayscaleMatteType:
-        return octave_value ("grayscale");
-
-      case Magick::PaletteType:
-      case Magick::PaletteMatteType:
-        return octave_value ("indexed");
-
-      case Magick::TrueColorType:
-      case Magick::TrueColorMatteType:
-      case Magick::ColorSeparationType:
-        return octave_value ("truecolor");
-
-      default:
-        return octave_value ("undefined");
-    }
-}
-
-// We put this in a try-block because GraphicsMagick will throw
-// exceptions if a parameter isn't present in the current image.
-#define GET_PARAM(NAME, OUTNAME) \
-  try \
-    { \
-      info.contents (OUTNAME)(frame,0) = magick_to_octave_value (im.NAME ()); \
-    } \
-  catch (Magick::Warning& w) \
-    { \
-    }
-
-#endif
-
-DEFUN_DLD (__magick_finfo__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __magick_finfo__ (@var{fname})\n\
-Read image information with GraphicsMagick++.  In general you should\n\
-not be using this function.  Instead use @code{imfinfo}.\n\
-@seealso{imfinfo, imread}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-#ifdef HAVE_MAGICK
-
-  maybe_initialize_magick ();
-
-  if (args.length () < 1 || ! args (0).is_string ())
-    {
-      print_usage ();
-      return retval;
-    }
-
-  const std::string filename = args (0).string_value ();
-
-  try
-    {
-      // Read the file.
-      std::vector<Magick::Image> imvec;
-      Magick::readImages (&imvec, args(0).string_value ());
-      int nframes = imvec.size ();
-
-      // Create the right size for the output.
-
-      static const char *fields[] =
-        {
-          "Filename",
-          "FileModDate",
-          "FileSize",
-          "Height",
-          "Width",
-          "BitDepth",
-          "Format",
-          "LongFormat",
-          "XResolution",
-          "YResolution",
-          "TotalColors",
-          "TileName",
-          "AnimationDelay",
-          "AnimationIterations",
-          "ByteOrder",
-          "Gamma",
-          "Matte",
-          "ModulusDepth",
-          "Quality",
-          "QuantizeColors",
-          "ResolutionUnits",
-          "ColorType",
-          "View",
-          0
-        };
-
-      Octave_map info (string_vector (fields), dim_vector (nframes, 1));
-
-      file_stat fs (filename);
-
-      std::string filetime;
-
-      if (fs)
-        {
-          octave_localtime mtime = fs.mtime ();
-
-          filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S");
-        }
-      else
-        {
-          std::string msg = fs.error ();
-
-          error ("imfinfo: error reading `%s': %s",
-                 filename.c_str (), msg.c_str ());
-
-          return retval;
-        }
-
-      // For each frame in the image (some images contain multiple
-      // layers, each to be treated like a separate image).
-      for (int frame = 0; frame < nframes; frame++)
-        {
-          Magick::Image im = imvec[frame];
-
-          // Add file name and timestamp.
-          info.contents ("Filename")(frame,0) = filename;
-          info.contents ("FileModDate")(frame,0) = filetime;
-
-          // Annoying CamelCase naming is for Matlab compatibility.
-          GET_PARAM (fileSize, "FileSize")
-          GET_PARAM (rows, "Height")
-          GET_PARAM (columns, "Width")
-          GET_PARAM (depth, "BitDepth")
-          GET_PARAM (magick, "Format")
-          GET_PARAM (format, "LongFormat")
-          GET_PARAM (xResolution, "XResolution")
-          GET_PARAM (yResolution, "YResolution")
-          GET_PARAM (totalColors, "TotalColors")
-          GET_PARAM (tileName, "TileName")
-          GET_PARAM (animationDelay, "AnimationDelay")
-          GET_PARAM (animationIterations, "AnimationIterations")
-          GET_PARAM (endian, "ByteOrder")
-          GET_PARAM (gamma, "Gamma")
-          GET_PARAM (matte, "Matte")
-          GET_PARAM (modulusDepth, "ModulusDepth")
-          GET_PARAM (quality, "Quality")
-          GET_PARAM (quantizeColors, "QuantizeColors")
-          GET_PARAM (resolutionUnits, "ResolutionUnits")
-          GET_PARAM (type, "ColorType")
-          GET_PARAM (view, "View")
-        }
-
-      retval = octave_value (info);
-    }
-  catch (Magick::Warning& w)
-    {
-      warning ("Magick++ warning: %s", w.what ());
-    }
-  catch (Magick::ErrorCoder& e)
-    {
-      warning ("Magick++ coder error: %s", e.what ());
-    }
-  catch (Magick::Exception& e)
-    {
-      error ("Magick++ exception: %s", e.what ());
-      return retval;
-    }
-
-#else
-
-  error ("imfinfo: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
-
-#undef GET_PARAM
-
-// Determine the file formats supported by GraphicsMagick.  This is
-// called once at the beginning of imread or imwrite to determine
-// exactly which file formats are supported, so error messages can be
-// displayed properly.
-
-DEFUN_DLD (__magick_format_list__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Function File} {} __magick_format_list__ (@var{formats})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-#ifdef HAVE_MAGICK
-  maybe_initialize_magick ();
-
-  std::list<std::string> accepted_formats;
-
-  if (args.length () == 1)
-    {
-      Cell c = args (0).cell_value ();
-
-      if (! error_state)
-        {
-          for (octave_idx_type i = 0; i < c.nelem (); i++)
-            {
-              try
-                {
-                  std::string fmt = c.elem (i).string_value ();
-
-                  Magick::CoderInfo info(fmt);
-
-                  if (info.isReadable () && info.isWritable ())
-                    accepted_formats.push_back (fmt);
-                }
-              catch (Magick::Exception& e)
-                {
-                  // Do nothing: exception here are simply missing formats.
-                }
-            }
-        }
-      else
-        error ("__magick_format_list__: expecting a cell array of image format names");
-    }
-  else
-    print_usage ();
-
-  retval = Cell (accepted_formats);
-
-#else
-
-  error ("__magick_format_list__: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/src/DLD-FUNCTIONS/__voronoi__.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/*
-
-Copyright (C) 2000-2012 Kai Habel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-20. Augiust 2000 - Kai Habel: first release
-*/
-
-/*
-2003-12-14 Rafael Laboissiere <rafael@laboissiere.net>
-Added optional second argument to pass options to the underlying
-qhull command
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cstdio>
-
-#include <list>
-
-#include "lo-ieee.h"
-
-#include "Cell.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-#include "unwind-prot.h"
-
-#if defined (HAVE_QHULL)
-# include "oct-qhull.h"
-# if defined (NEED_QHULL_VERSION)
-char qh_version[] = "__voronoi__.oct 2007-07-24";
-# endif
-#endif
-
-static void
-close_fcn (FILE *f)
-{
-  gnulib::fclose (f);
-}
-
-DEFUN_DLD (__voronoi__, args, ,
-        "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{C}, @var{F} =} __voronoi__ (@var{caller}, @var{pts})\n\
-@deftypefnx {Loadable Function} {@var{C}, @var{F} =} __voronoi__ (@var{caller}, @var{pts}, @var{options})\n\
-@deftypefnx {Loadable Function} {@var{C}, @var{F}, @var{Inf_Pts} =} __voronoi__ (@dots{})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  std::string caller = args(0).string_value ();
-
-#if defined (HAVE_QHULL)
-
-  retval(0) = 0.0;
-
-  int nargin = args.length ();
-  if (nargin < 2 || nargin > 3)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  Matrix points = args(1).matrix_value ();
-  const octave_idx_type dim = points.columns ();
-  const octave_idx_type num_points = points.rows ();
-
-  points = points.transpose ();
-
-  std::string options;
-
-  if (dim <= 4)
-    options = " Qbb";
-  else
-    options = " Qbb Qx";
-
-  if (nargin == 3)
-    {
-      octave_value opt_arg = args(2);
-
-      if (opt_arg.is_string ())
-        options = " " + opt_arg.string_value ();
-      else if (opt_arg.is_empty ())
-        ; // Use default options.
-      else if (opt_arg.is_cellstr ())
-        {
-          options = "";
-
-          Array<std::string> tmp = opt_arg.cellstr_value ();
-
-          for (octave_idx_type i = 0; i < tmp.numel (); i++)
-            options += " " + tmp(i);
-        }
-      else
-        {
-          error ("%s: OPTIONS must be a string, cell array of strings, or empty",
-                 caller.c_str ());
-          return retval;
-        }
-    }
-
-  boolT ismalloc = false;
-
-  unwind_protect frame;
-
-  // Replace the outfile pointer with stdout for debugging information.
-#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
-  FILE *outfile = gnulib::fopen ("NUL", "w");
-#else
-  FILE *outfile = gnulib::fopen ("/dev/null", "w");
-#endif
-  FILE *errfile = stderr;
-
-  if (outfile)
-    frame.add_fcn (close_fcn, outfile);
-  else
-    {
-      error ("__voronoi__: unable to create temporary file for output");
-      return retval;
-    }
-
-  // qh_new_qhull command and points arguments are not const...
-
-  std::string cmd = "qhull v" + options;
-
-  OCTAVE_LOCAL_BUFFER (char, cmd_str, cmd.length () + 1);
-
-  strcpy (cmd_str, cmd.c_str ());
-
-  int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
-                               ismalloc, cmd_str, outfile, errfile);
-  if (! exitcode) 
-    {
-      // Calling findgood_all provides the number of Voronoi vertices
-      // (sets qh num_good).
-
-      qh_findgood_all (qh facet_list);
-
-      octave_idx_type num_voronoi_regions
-        = qh num_vertices - qh_setsize (qh del_vertices);
-
-      octave_idx_type num_voronoi_vertices = qh num_good;
-
-      // Find the voronoi centers for all facets.
-
-      qh_setvoronoi_all ();
-
-      facetT *facet;
-      vertexT *vertex;
-      octave_idx_type k;
-
-      // Find the number of Voronoi vertices for each Voronoi cell and
-      // store them in NI so we can use them later to set the dimensions
-      // of the RowVector objects used to collect them.
-
-      FORALLfacets
-        {
-          facet->seen = false;
-        }
-      
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, ni, num_voronoi_regions);
-      for (octave_idx_type i = 0; i < num_voronoi_regions; i++)
-        ni[i] = 0;
-
-      k = 0;
-
-      FORALLvertices
-        {
-          if (qh hull_dim == 3)
-            qh_order_vertexneighbors (vertex);
-          
-          bool infinity_seen = false;
-
-          facetT *neighbor, **neighborp;
-
-          FOREACHneighbor_ (vertex)
-            {
-              if (neighbor->upperdelaunay)
-                {
-                  if (! infinity_seen)
-                    {
-                      infinity_seen = true;
-                      ni[k]++;
-                    }
-                }
-              else
-                {
-                  neighbor->seen = true;
-                  ni[k]++;
-                }
-            }
-
-          k++;
-        }
-
-      // If Qhull finds fewer regions than points, we will pad the end
-      // of the at_inf and C arrays so that they always contain at least
-      // as many elements as the given points array.
-
-      // FIXME -- is it possible (or does it make sense) for
-      // num_voronoi_regions to ever be larger than num_points?
-
-      octave_idx_type nr = (num_points > num_voronoi_regions
-                            ? num_points : num_voronoi_regions);
-
-      boolMatrix at_inf (nr, 1, false);
-
-      // The list of Voronoi vertices.  The first element is always
-      // Inf.
-      Matrix F (num_voronoi_vertices+1, dim);
-
-      for (octave_idx_type d = 0; d < dim; d++)
-        F(0,d) = octave_Inf;
-
-      // The cell array of vectors of indices into F that represent the
-      // vertices of the Voronoi regions (cells).
-
-      Cell C (nr, 1);
-
-      // Now loop through the list of vertices again and store the
-      // coordinates of the Voronoi vertices and the lists of indices
-      // for the cells.
-
-      FORALLfacets
-        {
-          facet->seen = false;
-        }
-
-      octave_idx_type i = 0;
-      k = 0;
-
-      FORALLvertices
-        {
-          if (qh hull_dim == 3)
-            qh_order_vertexneighbors (vertex);
-
-          bool infinity_seen = false;
-
-          octave_idx_type idx = qh_pointid (vertex->point);
-
-          octave_idx_type num_vertices = ni[k++];
-
-          // Qhull seems to sometimes produces regions with a single
-          // vertex.  Is that a bug?  How can a region have just one
-          // vertex?  Let's skip it.
-
-          if (num_vertices == 1)
-            continue;
-
-          RowVector facet_list (num_vertices);
-
-          octave_idx_type m = 0;
-
-          facetT *neighbor, **neighborp;
-
-          FOREACHneighbor_(vertex)
-            {
-              if (neighbor->upperdelaunay)
-                {
-                  if (! infinity_seen)
-                    {
-                      infinity_seen = true;
-                      facet_list(m++) = 1;
-                      at_inf(idx) = true;
-                    }
-                }
-              else
-                {
-                  if (! neighbor->seen)
-                    {
-                      i++;
-                      for (octave_idx_type d = 0; d < dim; d++)
-                        F(i,d) = neighbor->center[d];
-
-                      neighbor->seen = true;
-                      neighbor->visitid = i;
-                    }
-
-                  facet_list(m++) = neighbor->visitid + 1;
-                }
-            }
-
-          C(idx) = facet_list;
-        }
-
-      retval(2) = at_inf;
-      retval(1) = C;
-      retval(0) = F;
-    }
-  else
-    error ("%s: qhull failed", caller.c_str ());
-
-  // Free memory from Qhull
-  qh_freeqhull (! qh_ALL);
-
-  int curlong, totlong;
-  qh_memfreeshort (&curlong, &totlong);
-
-  if (curlong || totlong)
-    warning ("%s: qhull did not free %d bytes of long memory (%d pieces)",
-             caller.c_str (), totlong, curlong);
-
-#else
-  error ("%s: not available in this version of Octave", caller.c_str ());
-#endif
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/src/DLD-FUNCTIONS/amd.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/*
-
-Copyright (C) 2008-2012 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-// This is the octave interface to amd, which bore the copyright given
-// in the help of the functions.
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cstdlib>
-
-#include <string>
-#include <vector>
-
-#include "ov.h"
-#include "defun-dld.h"
-#include "pager.h"
-#include "ov-re-mat.h"
-
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "oct-map.h"
-
-#include "oct-sparse.h"
-#include "oct-locbuf.h"
-
-#ifdef IDX_TYPE_LONG
-#define AMD_NAME(name) amd_l ## name
-#else
-#define AMD_NAME(name) amd ## name
-#endif
-
-DEFUN_DLD (amd, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} amd (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} amd (@var{S}, @var{opts})\n\
-\n\
-Return the approximate minimum degree permutation of a matrix.  This\n\
-permutation such that the Cholesky@tie{}factorization of @code{@var{S}\n\
-(@var{p}, @var{p})} tends to be sparser than the Cholesky@tie{}factorization\n\
-of @var{S} itself.  @code{amd} is typically faster than @code{symamd} but\n\
-serves a similar purpose.\n\
-\n\
-The optional parameter @var{opts} is a structure that controls the\n\
-behavior of @code{amd}.  The fields of the structure are\n\
-\n\
-@table @asis\n\
-@item @var{opts}.dense\n\
-Determines what @code{amd} considers to be a dense row or column of the\n\
-input matrix.  Rows or columns with more than @code{max(16, (dense *\n\
-sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{S},\n\
-are ignored by @code{amd} during the calculation of the permutation\n\
-The value of dense must be a positive scalar and its default value is 10.0\n\
-\n\
-@item @var{opts}.aggressive\n\
-If this value is a non zero scalar, then @code{amd} performs aggressive\n\
-absorption.  The default is not to perform aggressive absorption.\n\
-@end table\n\
-\n\
-The author of the code itself is Timothy A. Davis\n\
-@email{davis@@cise.ufl.edu}, University of Florida (see\n\
-@url{http://www.cise.ufl.edu/research/sparse/amd}).\n\
-@seealso{symamd, colamd}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_AMD
-  int nargin = args.length ();
-
-  if (nargin < 1 || nargin > 2)
-    print_usage ();
-  else
-    {
-      octave_idx_type n_row, n_col;
-      const octave_idx_type *ridx, *cidx;
-      SparseMatrix sm;
-      SparseComplexMatrix scm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0).sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-        }
-      else
-        {
-          if (args(0).is_complex_type ())
-            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
-          else
-            sm = SparseMatrix (args(0).matrix_value ());
-
-          n_row = sm.rows ();
-          n_col = sm.cols ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
-        }
-
-      if (!error_state && n_row != n_col)
-        error ("amd: matrix S must be square");
-
-      if (!error_state)
-        {
-          OCTAVE_LOCAL_BUFFER (double, Control, AMD_CONTROL);
-          AMD_NAME (_defaults) (Control) ;
-          if (nargin > 1)
-            {
-              octave_scalar_map arg1 = args(1).scalar_map_value ();
-
-              if (!error_state)
-                {
-                  octave_value tmp;
-
-                  tmp = arg1.getfield ("dense");
-                  if (tmp.is_defined ())
-                    Control[AMD_DENSE] = tmp.double_value ();
-
-                  tmp = arg1.getfield ("aggressive");
-                  if (tmp.is_defined ())
-                    Control[AMD_AGGRESSIVE] = tmp.double_value ();
-                }
-              else
-                error ("amd: OPTS argument must be a scalar structure");
-            }
-
-          if (!error_state)
-            {
-              OCTAVE_LOCAL_BUFFER (octave_idx_type, P, n_col);
-              Matrix xinfo (AMD_INFO, 1);
-              double *Info = xinfo.fortran_vec ();
-
-              // FIXME -- how can we manage the memory allocation of
-              // amd in a cleaner manner?
-              amd_malloc = malloc;
-              amd_free = free;
-              amd_calloc = calloc;
-              amd_realloc = realloc;
-              amd_printf = printf;
-
-              octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P,
-                                                          Control, Info);
-
-              switch (result)
-                {
-                case AMD_OUT_OF_MEMORY:
-                  error ("amd: out of memory");
-                  break;
-                case AMD_INVALID:
-                  error ("amd: matrix S is corrupted");
-                  break;
-                default:
-                  {
-                    if (nargout > 1)
-                      retval(1) = xinfo;
-
-                    Matrix Pout (1, n_col);
-                    for (octave_idx_type i = 0; i < n_col; i++)
-                      Pout.xelem (i) = P[i] + 1;
-
-                    retval(0) = Pout;
-                  }
-                }
-            }
-        }
-    }
-#else
-
-  error ("amd: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
--- a/src/DLD-FUNCTIONS/ccolamd.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,583 +0,0 @@
-/*
-
-Copyright (C) 2005-2012 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-// This is the octave interface to ccolamd, which bore the copyright given
-// in the help of the functions.
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cstdlib>
-
-#include <string>
-#include <vector>
-
-#include "ov.h"
-#include "defun-dld.h"
-#include "pager.h"
-#include "ov-re-mat.h"
-
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-
-#include "oct-sparse.h"
-#include "oct-locbuf.h"
-
-#ifdef IDX_TYPE_LONG
-#define CCOLAMD_NAME(name) ccolamd_l ## name
-#define CSYMAMD_NAME(name) csymamd_l ## name
-#else
-#define CCOLAMD_NAME(name) ccolamd ## name
-#define CSYMAMD_NAME(name) csymamd ## name
-#endif
-
-DEFUN_DLD (ccolamd, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} ccolamd (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs})\n\
-@deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs}, @var{cmember})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})\n\
-\n\
-Constrained column approximate minimum degree permutation.\n\
-@code{@var{p} = ccolamd (@var{S})} returns the column approximate minimum\n\
-degree permutation vector for the sparse matrix @var{S}.  For a non-symmetric\n\
-matrix\n\
-@var{S},\n\
-@code{@var{S}(:, @var{p})} tends to have sparser LU@tie{}factors than\n\
-@var{S}.  @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))} also\n\
-tends to be sparser than @code{chol (@var{S}' * @var{S})}.  @code{@var{p} =\n\
-ccolamd (@var{S}, 1)} optimizes the ordering for @code{lu (@var{S}(:,\n\
-@var{p}))}.  The ordering is followed by a column elimination tree\n\
-post-ordering.\n\
-\n\
-@var{knobs} is an optional 1-element to 5-element input vector, with a\n\
-default value of @code{[0 10 10 1 0]} if not present or empty.  Entries not\n\
-present are set to their defaults.\n\
-\n\
-@table @code\n\
-@item @var{knobs}(1)\n\
-if nonzero, the ordering is optimized for @code{lu (S(:, p))}.  It will be a\n\
-poor ordering for @code{chol (@var{S}(:, @var{p})' * @var{S}(:,\n\
-@var{p}))}.  This is the most important knob for ccolamd.\n\
-\n\
-@item @var{knobs}(2)\n\
-if @var{S} is m-by-n, rows with more than @code{max (16, @var{knobs}(2) *\n\
-sqrt (n))} entries are ignored.\n\
-\n\
-@item @var{knobs}(3)\n\
-columns with more than @code{max (16, @var{knobs}(3) * sqrt (min (@var{m},\n\
-@var{n})))} entries are ignored and ordered last in the output permutation\n\
-(subject to the cmember constraints).\n\
-\n\
-@item @var{knobs}(4)\n\
-if nonzero, aggressive absorption is performed.\n\
-\n\
-@item @var{knobs}(5)\n\
-if nonzero, statistics and knobs are printed.\n\
-\n\
-@end table\n\
-\n\
-@var{cmember} is an optional vector of length @math{n}.  It defines the\n\
-constraints on the column ordering.  If @code{@var{cmember}(j) = @var{c}},\n\
-then column @var{j} is in constraint set @var{c} (@var{c} must be in the\n\
-range 1 to\n\
-n).  In the output permutation @var{p}, all columns in set 1 appear\n\
-first, followed by all columns in set 2, and so on.  @code{@var{cmember} =\n\
-ones (1,n)} if not present or empty.\n\
-@code{ccolamd (@var{S}, [], 1 : n)} returns @code{1 : n}\n\
-\n\
-@code{@var{p} = ccolamd (@var{S})} is about the same as\n\
-@code{@var{p} = colamd (@var{S})}.  @var{knobs} and its default values\n\
-differ.  @code{colamd} always does aggressive absorption, and it finds an\n\
-ordering suitable for both @code{lu (@var{S}(:, @var{p}))} and @code{chol\n\
-(@var{S}(:, @var{p})' * @var{S}(:, @var{p}))}; it cannot optimize its\n\
-ordering for @code{lu (@var{S}(:, @var{p}))} to the extent that\n\
-@code{ccolamd (@var{S}, 1)} can.\n\
-\n\
-@var{stats} is an optional 20-element output vector that provides data\n\
-about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
-statistics are in @code{@var{stats}(1 : 3)}.  @code{@var{stats}(1)} and\n\
-@code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
-ignored by @sc{ccolamd} and @code{@var{stats}(3)} is the number of garbage\n\
-collections performed on the internal data structure used by @sc{ccolamd}\n\
-(roughly of size @code{2.2 * nnz (@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
-integers).\n\
-\n\
-@code{@var{stats}(4 : 7)} provide information if CCOLAMD was able to\n\
-continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
-invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
-unsorted or contains duplicate entries, or zero if no such column exists.\n\
-@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
-index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
-such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
-or out-of-order row indices.  @code{@var{stats}(8 : 20)} is always zero in\n\
-the current version of @sc{ccolamd} (reserved for future use).\n\
-\n\
-The authors of the code itself are S. Larimore, T. Davis (Univ. of Florida)\n\
-and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
-by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
-and a grant from Sandia National Lab.  See\n\
-@url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
-colamd, symamd, and other related orderings.\n\
-@seealso{colamd, csymamd}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_CCOLAMD
-
-  int nargin = args.length ();
-  int spumoni = 0;
-
-  if (nargout > 2 || nargin < 1 || nargin > 3)
-    usage ("ccolamd: incorrect number of input and/or output arguments");
-  else
-    {
-      // Get knobs
-      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);
-      CCOLAMD_NAME (_set_defaults) (knobs);
-
-      // Check for user-passed knobs
-      if (nargin > 1)
-        {
-          NDArray User_knobs = args(1).array_value ();
-          int nel_User_knobs = User_knobs.length ();
-
-          if (nel_User_knobs > 0)
-            knobs[CCOLAMD_LU] = (User_knobs(0) != 0);
-          if (nel_User_knobs > 1)
-            knobs[CCOLAMD_DENSE_ROW] = User_knobs(1);
-          if (nel_User_knobs > 2)
-            knobs[CCOLAMD_DENSE_COL] = User_knobs(2);
-          if (nel_User_knobs > 3)
-            knobs[CCOLAMD_AGGRESSIVE] = (User_knobs(3) != 0);
-          if (nel_User_knobs > 4)
-            spumoni = (User_knobs(4) != 0);
-
-          // print knob settings if spumoni is set
-          if (spumoni)
-            {
-              octave_stdout << "\nccolamd version " << CCOLAMD_MAIN_VERSION << "."
-                            <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE
-                            << ":\nknobs(1): " << User_knobs(0) << ", order for ";
-              if (knobs[CCOLAMD_LU] != 0)
-                octave_stdout << "lu (A)\n";
-              else
-                octave_stdout << "chol (A'*A)\n";
-
-              if (knobs[CCOLAMD_DENSE_ROW] >= 0)
-                octave_stdout << "knobs(2): " << User_knobs(1)
-                              << ", rows with > max (16,"
-                              << knobs[CCOLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
-                              << " entries removed\n";
-              else
-                octave_stdout << "knobs(2): " << User_knobs(1)
-                              << ", no dense rows removed\n";
-
-              if (knobs[CCOLAMD_DENSE_COL] >= 0)
-                octave_stdout << "knobs(3): " << User_knobs(2)
-                              << ", cols with > max (16,"
-                              << knobs[CCOLAMD_DENSE_COL] << "*sqrt (size(A)))"
-                              << " entries removed\n";
-              else
-                octave_stdout << "knobs(3): " << User_knobs(2)
-                              << ", no dense columns removed\n";
-
-              if (knobs[CCOLAMD_AGGRESSIVE] != 0)
-                octave_stdout << "knobs(4): " << User_knobs(3)
-                              << ", aggressive absorption: yes";
-              else
-                octave_stdout << "knobs(4): " << User_knobs(3)
-                              << ", aggressive absorption: no";
-
-              octave_stdout << "knobs(5): " << User_knobs(4)
-                            << ", statistics and knobs printed\n";
-            }
-        }
-
-      octave_idx_type n_row, n_col, nnz;
-      octave_idx_type *ridx, *cidx;
-      SparseComplexMatrix scm;
-      SparseMatrix sm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0). sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              nnz = scm.nnz ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              nnz = sm.nnz ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-        }
-      else
-        {
-          if (args(0).is_complex_type ())
-            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
-          else
-            sm = SparseMatrix (args(0).matrix_value ());
-
-          n_row = sm.rows ();
-          n_col = sm.cols ();
-          nnz = sm.nnz ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
-        }
-
-      // Allocate workspace for ccolamd
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
-      for (octave_idx_type i = 0; i < n_col+1; i++)
-        p[i] = cidx[i];
-
-      octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
-      for (octave_idx_type i = 0; i < nnz; i++)
-        A[i] = ridx[i];
-
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
-
-      if (nargin > 2)
-        {
-          NDArray in_cmember = args(2).array_value ();
-          octave_idx_type cslen = in_cmember.length ();
-          OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
-          for (octave_idx_type i = 0; i < cslen; i++)
-            // convert cmember from 1-based to 0-based
-            cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
-
-          if (cslen != n_col)
-            error ("ccolamd: CMEMBER must be of length equal to #cols of A");
-          else
-            // Order the columns (destroys A)
-            if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, cmember))
-              {
-                CCOLAMD_NAME (_report) (stats) ;
-                error ("ccolamd: internal error!");
-                return retval;
-              }
-        }
-      else
-        {
-          // Order the columns (destroys A)
-          if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, 0))
-            {
-              CCOLAMD_NAME (_report) (stats) ;
-              error ("ccolamd: internal error!");
-              return retval;
-            }
-        }
-
-      // return the permutation vector
-      NDArray out_perm (dim_vector (1, n_col));
-      for (octave_idx_type i = 0; i < n_col; i++)
-        out_perm(i) = p[i] + 1;
-
-      retval(0) = out_perm;
-
-      // print stats if spumoni > 0
-      if (spumoni > 0)
-        CCOLAMD_NAME (_report) (stats) ;
-
-      // Return the stats vector
-      if (nargout == 2)
-        {
-          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
-          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
-            out_stats(i) = stats[i] ;
-          retval(1) = out_stats;
-
-          // 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 (CCOLAMD_INFO1) ++ ;
-          out_stats (CCOLAMD_INFO2) ++ ;
-        }
-    }
-
-#else
-
-  error ("ccolamd: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (csymamd, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} csymamd (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs})\n\
-@deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs}, @var{cmember})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\
-\n\
-For a symmetric positive definite matrix @var{S}, returns the permutation\n\
-vector @var{p} such that @code{@var{S}(@var{p},@var{p})} tends to have a\n\
-sparser Cholesky@tie{}factor than @var{S}.  Sometimes @code{csymamd} works\n\
-well for symmetric indefinite matrices too.  The matrix @var{S} is assumed\n\
-to be symmetric; only the strictly lower triangular part is referenced.\n\
-@var{S} must be square.  The ordering is followed by an elimination tree\n\
-post-ordering.\n\
-\n\
-@var{knobs} is an optional 1-element to 3-element input vector, with a\n\
-default value of @code{[10 1 0]} if present or empty.  Entries not\n\
-present are set to their defaults.\n\
-\n\
-@table @code\n\
-@item @var{knobs}(1)\n\
-If @var{S} is n-by-n, then rows and columns with more than\n\
-@code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\
-last in the output permutation (subject to the cmember constraints).\n\
-\n\
-@item @var{knobs}(2)\n\
-If nonzero, aggressive absorption is performed.\n\
-\n\
-@item @var{knobs}(3)\n\
-If nonzero, statistics and knobs are printed.\n\
-\n\
-@end table\n\
-\n\
-@var{cmember} is an optional vector of length n. It defines the constraints\n\
-on the ordering.  If @code{@var{cmember}(j) = @var{S}}, then row/column j is\n\
-in constraint set @var{c} (@var{c} must be in the range 1 to n).  In the\n\
-output permutation @var{p}, rows/columns in set 1 appear first, followed\n\
-by all rows/columns in set 2, and so on.  @code{@var{cmember} = ones (1,n)}\n\
-if not present or empty.  @code{csymamd (@var{S},[],1:n)} returns @code{1:n}.\n\
-\n\
-@code{@var{p} = csymamd (@var{S})} is about the same as @code{@var{p} =\n\
-symamd (@var{S})}.  @var{knobs} and its default values differ.\n\
-\n\
-@code{@var{stats}(4:7)} provide information if CCOLAMD was able to\n\
-continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
-invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
-unsorted or contains duplicate entries, or zero if no such column exists.\n\
-@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
-index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
-such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
-or out-of-order row indices.  @code{@var{stats}(8:20)} is always zero in\n\
-the current version of @sc{ccolamd} (reserved for future use).\n\
-\n\
-The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
-and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
-by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
-and a grant from Sandia National Lab.  See\n\
-@url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
-colamd, symamd, and other related orderings.\n\
-@seealso{symamd, ccolamd}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#if HAVE_CCOLAMD
-
-  int nargin = args.length ();
-  int spumoni = 0;
-
-  if (nargout > 2 || nargin < 1 || nargin > 3)
-    usage ("ccolamd: incorrect number of input and/or output arguments");
-  else
-    {
-      // Get knobs
-      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);
-      CCOLAMD_NAME (_set_defaults) (knobs);
-
-      // Check for user-passed knobs
-      if (nargin > 1)
-        {
-          NDArray User_knobs = args(1).array_value ();
-          int nel_User_knobs = User_knobs.length ();
-
-          if (nel_User_knobs > 0)
-            knobs[CCOLAMD_DENSE_ROW] = User_knobs(0);
-          if (nel_User_knobs > 0)
-            knobs[CCOLAMD_AGGRESSIVE] = User_knobs(1);
-          if (nel_User_knobs > 1)
-            spumoni = static_cast<int> (User_knobs(2));
-
-          // print knob settings if spumoni is set
-          if (spumoni)
-            {
-              octave_stdout << "\ncsymamd version " << CCOLAMD_MAIN_VERSION << "."
-                            <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE << "\n";
-
-              if (knobs[CCOLAMD_DENSE_ROW] >= 0)
-                octave_stdout << "knobs(1): " << User_knobs(0)
-                              << ", rows/cols with > max (16,"
-                              << knobs[CCOLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
-                              << " entries removed\n";
-              else
-                octave_stdout << "knobs(1): " << User_knobs(0)
-                              << ", no dense rows/cols removed\n";
-
-              if (knobs[CCOLAMD_AGGRESSIVE] != 0)
-                octave_stdout << "knobs(2): " << User_knobs(1)
-                              << ", aggressive absorption: yes";
-              else
-                octave_stdout << "knobs(2): " << User_knobs(1)
-                              << ", aggressive absorption: no";
-
-
-              octave_stdout << "knobs(3): " << User_knobs(2)
-                            << ", statistics and knobs printed\n";
-            }
-        }
-
-      octave_idx_type n_row, n_col;
-      octave_idx_type *ridx, *cidx;
-      SparseMatrix sm;
-      SparseComplexMatrix scm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0).sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-        }
-      else
-        {
-          if (args(0).is_complex_type ())
-            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
-          else
-            sm = SparseMatrix (args(0).matrix_value ());
-
-          n_row = sm.rows ();
-          n_col = sm.cols ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
-        }
-
-      if (n_row != n_col)
-        {
-          error ("csymamd: matrix S must be square");
-          return retval;
-        }
-
-      // Allocate workspace for symamd
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
-
-      if (nargin > 2)
-        {
-          NDArray in_cmember = args(2).array_value ();
-          octave_idx_type cslen = in_cmember.length ();
-          OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
-          for (octave_idx_type i = 0; i < cslen; i++)
-            // convert cmember from 1-based to 0-based
-            cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
-
-          if (cslen != n_col)
-            error ("csymamd: CMEMBER must be of length equal to #cols of A");
-          else
-            if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
-                                  &calloc, &free, cmember, -1))
-              {
-                CSYMAMD_NAME (_report) (stats) ;
-                error ("csymamd: internal error!") ;
-                return retval;
-              }
-        }
-      else
-        {
-          if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
-                                &calloc, &free, 0, -1))
-            {
-              CSYMAMD_NAME (_report) (stats) ;
-              error ("csymamd: internal error!") ;
-              return retval;
-            }
-        }
-
-      // return the permutation vector
-      NDArray out_perm (dim_vector (1, n_col));
-      for (octave_idx_type i = 0; i < n_col; i++)
-        out_perm(i) = perm[i] + 1;
-
-      retval(0) = out_perm;
-
-      // Return the stats vector
-      if (nargout == 2)
-        {
-          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
-          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
-            out_stats(i) = stats[i] ;
-          retval(1) = out_stats;
-
-          // 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 (CCOLAMD_INFO1) ++ ;
-          out_stats (CCOLAMD_INFO2) ++ ;
-        }
-
-      // print stats if spumoni > 0
-      if (spumoni > 0)
-        CSYMAMD_NAME (_report) (stats) ;
-
-      // Return the stats vector
-      if (nargout == 2)
-        {
-          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
-          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
-            out_stats(i) = stats[i] ;
-          retval(1) = out_stats;
-
-          // 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 (CCOLAMD_INFO1) ++ ;
-          out_stats (CCOLAMD_INFO2) ++ ;
-        }
-    }
-
-#else
-
-  error ("csymamd: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
--- a/src/DLD-FUNCTIONS/chol.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1385 +0,0 @@
-/*
-
-Copyright (C) 1996-2012 John W. Eaton
-Copyright (C) 2008-2009 Jaroslav Hajek
-Copyright (C) 2008-2009 VZLU Prague
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "CmplxCHOL.h"
-#include "dbleCHOL.h"
-#include "fCmplxCHOL.h"
-#include "floatCHOL.h"
-#include "SparseCmplxCHOL.h"
-#include "SparsedbleCHOL.h"
-#include "oct-spparms.h"
-#include "sparse-util.h"
-
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "utils.h"
-
-template <class CHOLT>
-static octave_value
-get_chol_r (const CHOLT& fact)
-{
-  return octave_value (fact.chol_matrix (),
-                       MatrixType (MatrixType::Upper));
-}
-
-template <class CHOLT>
-static octave_value
-get_chol_l (const CHOLT& fact)
-{
-  return octave_value (fact.chol_matrix ().transpose (),
-                       MatrixType (MatrixType::Lower));
-}
-
-DEFUN_DLD (chol, args, nargout,
-"-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{R} =} chol (@var{A})\n\
-@deftypefnx {Loadable Function} {[@var{R}, @var{p}] =} chol (@var{A})\n\
-@deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S})\n\
-@deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S}, \"vector\")\n\
-@deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"lower\")\n\
-@deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"upper\")\n\
-@cindex Cholesky factorization\n\
-Compute the Cholesky@tie{}factor, @var{R}, of the symmetric positive definite\n\
-matrix @var{A}, where\n\
-@tex\n\
-$ R^T R = A $.\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-@var{R}' * @var{R} = @var{A}.\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-\n\
-Called with one output argument @code{chol} fails if @var{A} or @var{S} is\n\
-not positive definite.  With two or more output arguments @var{p} flags\n\
-whether the matrix was positive definite and @code{chol} does not fail.  A\n\
-zero value indicated that the matrix was positive definite and the @var{R}\n\
-gives the factorization, and @var{p} will have a positive value otherwise.\n\
-\n\
-If called with 3 outputs then a sparsity preserving row/column permutation\n\
-is applied to @var{A} prior to the factorization.  That is @var{R}\n\
-is the factorization of @code{@var{A}(@var{Q},@var{Q})} such that\n\
-@tex\n\
-$ R^T R = Q^T A Q$.\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-@var{R}' * @var{R} = @var{Q}' * @var{A} * @var{Q}.\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-\n\
-The sparsity preserving permutation is generally returned as a matrix.\n\
-However, given the flag \"vector\", @var{Q} will be returned as a vector\n\
-such that\n\
-@tex\n\
-$ R^T R = A (Q, Q)$.\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-@var{R}' * @var{R} = @var{A}(@var{Q}, @var{Q}).\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-\n\
-Called with either a sparse or full matrix and using the \"lower\" flag,\n\
-@code{chol} returns the lower triangular factorization such that\n\
-@tex\n\
-$ L L^T = A $.\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-@var{L} * @var{L}' = @var{A}.\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-\n\
-For full matrices, if the \"lower\" flag is set only the lower triangular\n\
-part of the matrix is used for the factorization, otherwise the upper\n\
-triangular part is used.\n\
-\n\
-In general the lower triangular factorization is significantly faster for\n\
-sparse matrices.\n\
-@seealso{cholinv, chol2inv}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-  bool LLt = false;
-  bool vecout = false;
-
-  if (nargin < 1 || nargin > 3 || nargout > 3
-      || (! args(0).is_sparse_type () && nargout > 2))
-    {
-      print_usage ();
-      return retval;
-    }
-
-  int n = 1;
-  while (n < nargin && ! error_state)
-    {
-      std::string tmp = args(n++).string_value ();
-
-      if (! error_state )
-        {
-          if (tmp.compare ("vector") == 0)
-            vecout = true;
-          else if (tmp.compare ("lower") == 0)
-            // FIXME currently the option "lower" is handled by transposing the
-            //  matrix, factorizing it with the lapack function DPOTRF ('U', ...)
-            //  and finally transposing the factor. It would be more efficient to use
-            //  DPOTRF ('L', ...) in this case.
-            LLt = true;
-          else if (tmp.compare ("upper") == 0)
-            LLt = false;
-          else
-            error ("chol: unexpected second or third input");
-        }
-      else
-        error ("chol: expecting trailing string arguments");
-    }
-
-  if (! error_state)
-    {
-      octave_value arg = args(0);
-
-      octave_idx_type nr = arg.rows ();
-      octave_idx_type nc = arg.columns ();
-      bool natural = (nargout != 3);
-
-      int arg_is_empty = empty_arg ("chol", nr, nc);
-
-      if (arg_is_empty < 0)
-        return retval;
-      if (arg_is_empty > 0)
-        return octave_value (Matrix ());
-
-      if (arg.is_sparse_type ())
-        {
-          if (arg.is_real_type ())
-            {
-              SparseMatrix m = arg.sparse_matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-                  SparseCHOL fact (m, info, natural);
-                  if (nargout == 3)
-                    {
-                      if (vecout)
-                        retval(2) = fact.perm ();
-                      else
-                        retval(2) = fact.Q ();
-                    }
-
-                  if (nargout > 1 || info == 0)
-                    {
-                      retval(1) = fact.P ();
-                      if (LLt)
-                        retval(0) = fact.L ();
-                      else
-                        retval(0) = fact.R ();
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else if (arg.is_complex_type ())
-            {
-              SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-                  SparseComplexCHOL fact (m, info, natural);
-
-                  if (nargout == 3)
-                    {
-                      if (vecout)
-                        retval(2) = fact.perm ();
-                      else
-                        retval(2) = fact.Q ();
-                    }
-
-                  if (nargout > 1 || info == 0)
-                    {
-                      retval(1) = fact.P ();
-                      if (LLt)
-                        retval(0) = fact.L ();
-                      else
-                        retval(0) = fact.R ();
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else
-            gripe_wrong_type_arg ("chol", arg);
-        }
-      else if (arg.is_single_type ())
-        {
-          if (arg.is_real_type ())
-            {
-              FloatMatrix m = arg.float_matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-
-                  FloatCHOL fact;
-                  if (LLt)
-                    fact = FloatCHOL (m.transpose (), info);
-                  else
-                    fact = FloatCHOL (m, info);
-
-                  if (nargout == 2 || info == 0)
-                    {
-                      retval(1) = info;
-                      if (LLt)
-                        retval(0) = get_chol_l (fact);
-                      else
-                        retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else if (arg.is_complex_type ())
-            {
-              FloatComplexMatrix m = arg.float_complex_matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-
-                  FloatComplexCHOL fact;
-                  if (LLt)
-                    fact = FloatComplexCHOL (m.transpose (), info);
-                  else
-                    fact = FloatComplexCHOL (m, info);
-
-                  if (nargout == 2 || info == 0)
-                    {
-                      retval(1) = info;
-                      if (LLt)
-                        retval(0) = get_chol_l (fact);
-                      else
-                        retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else
-            gripe_wrong_type_arg ("chol", arg);
-        }
-      else
-        {
-          if (arg.is_real_type ())
-            {
-              Matrix m = arg.matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-                  
-                  CHOL fact;
-                  if (LLt)
-                     fact = CHOL (m.transpose (), info);
-                  else
-                    fact = CHOL (m, info);
-
-                  if (nargout == 2 || info == 0)
-                    {
-                      retval(1) = info;
-                      if (LLt)
-                        retval(0) = get_chol_l (fact);
-                      else
-                        retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else if (arg.is_complex_type ())
-            {
-              ComplexMatrix m = arg.complex_matrix_value ();
-
-              if (! error_state)
-                {
-                  octave_idx_type info;
-                  
-                  ComplexCHOL fact;
-                  if (LLt)
-                    fact = ComplexCHOL (m.transpose (), info);
-                  else
-                    fact = ComplexCHOL (m, info);
-
-                  if (nargout == 2 || info == 0)
-                    {
-                      retval(1) = info;
-                      if (LLt)
-                        retval(0) = get_chol_l (fact);
-                      else
-                        retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    error ("chol: input matrix must be positive definite");
-                }
-            }
-          else
-            gripe_wrong_type_arg ("chol", arg);
-        }
-    }
-
-  return retval;
-}
-
-/*
-%!assert (chol ([2, 1; 1, 1]), [sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)], sqrt (eps))
-%!assert (chol (single ([2, 1; 1, 1])), single ([sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)]), sqrt (eps ("single")))
-
-%!error chol ()
-%!error <matrix must be positive definite> chol ([1, 2; 3, 4])
-%!error <requires square matrix> chol ([1, 2; 3, 4; 5, 6])
-%!error <unexpected second or third input> chol (1, 2)
-*/
-
-DEFUN_DLD (cholinv, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} cholinv (@var{A})\n\
-Use the Cholesky@tie{}factorization to compute the inverse of the\n\
-symmetric positive definite matrix @var{A}.\n\
-@seealso{chol, chol2inv, inv}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1)
-    {
-      octave_value arg = args(0);
-
-      octave_idx_type nr = arg.rows ();
-      octave_idx_type nc = arg.columns ();
-
-      if (nr == 0 || nc == 0)
-        retval = Matrix ();
-      else
-        {
-          if (arg.is_sparse_type ())
-            {
-              if (arg.is_real_type ())
-                {
-                  SparseMatrix m = arg.sparse_matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      SparseCHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else if (arg.is_complex_type ())
-                {
-                  SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      SparseComplexCHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else
-                gripe_wrong_type_arg ("cholinv", arg);
-            }
-          else if (arg.is_single_type ())
-            {
-              if (arg.is_real_type ())
-                {
-                  FloatMatrix m = arg.float_matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      FloatCHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else if (arg.is_complex_type ())
-                {
-                  FloatComplexMatrix m = arg.float_complex_matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      FloatComplexCHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else
-                gripe_wrong_type_arg ("chol", arg);
-            }
-          else
-            {
-              if (arg.is_real_type ())
-                {
-                  Matrix m = arg.matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      CHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else if (arg.is_complex_type ())
-                {
-                  ComplexMatrix m = arg.complex_matrix_value ();
-
-                  if (! error_state)
-                    {
-                      octave_idx_type info;
-                      ComplexCHOL chol (m, info);
-                      if (info == 0)
-                        retval = chol.inverse ();
-                      else
-                        error ("cholinv: A must be positive definite");
-                    }
-                }
-              else
-                gripe_wrong_type_arg ("chol", arg);
-            }
-        }
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!shared A, Ainv
-%! A = [2,0.2;0.2,1];
-%! Ainv = inv (A);
-%!test
-%! Ainv1 = cholinv (A);
-%! assert (norm (Ainv-Ainv1), 0, 1e-10);
-%!testif HAVE_CHOLMOD
-%! Ainv2 = inv (sparse (A));
-%! assert (norm (Ainv-Ainv2), 0, 1e-10);
-%!testif HAVE_CHOLMOD
-%! Ainv3 = cholinv (sparse (A));
-%! assert (norm (Ainv-Ainv3), 0, 1e-10);
-*/
-
-DEFUN_DLD (chol2inv, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} chol2inv (@var{U})\n\
-Invert a symmetric, positive definite square matrix from its Cholesky\n\
-decomposition, @var{U}.  Note that @var{U} should be an upper-triangular\n\
-matrix with positive diagonal elements.  @code{chol2inv (@var{U})}\n\
-provides @code{inv (@var{U}'*@var{U})} but it is much faster than\n\
-using @code{inv}.\n\
-@seealso{chol, cholinv, inv}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1)
-    {
-      octave_value arg = args(0);
-
-      octave_idx_type nr = arg.rows ();
-      octave_idx_type nc = arg.columns ();
-
-      if (nr == 0 || nc == 0)
-        retval = Matrix ();
-      else
-        {
-          if (arg.is_sparse_type ())
-            {
-              if (arg.is_real_type ())
-                {
-                  SparseMatrix r = arg.sparse_matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else if (arg.is_complex_type ())
-                {
-                  SparseComplexMatrix r = arg.sparse_complex_matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else
-                gripe_wrong_type_arg ("chol2inv", arg);
-            }
-          else if (arg.is_single_type ())
-            {
-              if (arg.is_real_type ())
-                {
-                  FloatMatrix r = arg.float_matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else if (arg.is_complex_type ())
-                {
-                  FloatComplexMatrix r = arg.float_complex_matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else
-                gripe_wrong_type_arg ("chol2inv", arg);
-
-            }
-          else
-            {
-              if (arg.is_real_type ())
-                {
-                  Matrix r = arg.matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else if (arg.is_complex_type ())
-                {
-                  ComplexMatrix r = arg.complex_matrix_value ();
-
-                  if (! error_state)
-                    retval = chol2inv (r);
-                }
-              else
-                gripe_wrong_type_arg ("chol2inv", arg);
-            }
-        }
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN_DLD (cholupdate, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})\n\
-Update or downdate a Cholesky@tie{}factorization.  Given an upper triangular\n\
-matrix @var{R} and a column vector @var{u}, attempt to determine another\n\
-upper triangular matrix @var{R1} such that\n\
-\n\
-@itemize @bullet\n\
-@item\n\
-@var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
-if @var{op} is \"+\"\n\
-\n\
-@item\n\
-@var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\
-if @var{op} is \"-\"\n\
-@end itemize\n\
-\n\
-If @var{op} is \"-\", @var{info} is set to\n\
-\n\
-@itemize\n\
-@item 0 if the downdate was successful,\n\
-\n\
-@item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,\n\
-\n\
-@item 2 if @var{R} is singular.\n\
-@end itemize\n\
-\n\
-If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
-@seealso{chol, qrupdate}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-
-  octave_value_list retval;
-
-  if (nargin > 3 || nargin < 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argr = args(0);
-  octave_value argu = args(1);
-
-  if (argr.is_numeric_type () && argu.is_numeric_type ()
-      && (nargin < 3 || args(2).is_string ()))
-    {
-      octave_idx_type n = argr.rows ();
-
-      std::string op = (nargin < 3) ? "+" : args(2).string_value ();
-
-      bool down = op == "-";
-
-      if (down || op == "+")
-        if (argr.columns () == n && argu.rows () == n && argu.columns () == 1)
-          {
-            int err = 0;
-            if (argr.is_single_type () || argu.is_single_type ())
-              {
-                if (argr.is_real_type () && argu.is_real_type ())
-                  {
-                    // real case
-                    FloatMatrix R = argr.float_matrix_value ();
-                    FloatColumnVector u = argu.float_column_vector_value ();
-
-                    FloatCHOL fact;
-                    fact.set (R);
-
-                    if (down)
-                      err = fact.downdate (u);
-                    else
-                      fact.update (u);
-
-                    retval(0) = get_chol_r (fact);
-                  }
-                else
-                  {
-                    // complex case
-                    FloatComplexMatrix R = argr.float_complex_matrix_value ();
-                    FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
-
-                    FloatComplexCHOL fact;
-                    fact.set (R);
-
-                    if (down)
-                      err = fact.downdate (u);
-                    else
-                      fact.update (u);
-
-                    retval(0) = get_chol_r (fact);
-                  }
-              }
-            else
-              {
-                if (argr.is_real_type () && argu.is_real_type ())
-                  {
-                    // real case
-                    Matrix R = argr.matrix_value ();
-                    ColumnVector u = argu.column_vector_value ();
-
-                    CHOL fact;
-                    fact.set (R);
-
-                    if (down)
-                      err = fact.downdate (u);
-                    else
-                      fact.update (u);
-
-                    retval(0) = get_chol_r (fact);
-                  }
-                else
-                  {
-                    // complex case
-                    ComplexMatrix R = argr.complex_matrix_value ();
-                    ComplexColumnVector u = argu.complex_column_vector_value ();
-
-                    ComplexCHOL fact;
-                    fact.set (R);
-
-                    if (down)
-                      err = fact.downdate (u);
-                    else
-                      fact.update (u);
-
-                    retval(0) = get_chol_r (fact);
-                  }
-              }
-
-            if (nargout > 1)
-              retval(1) = err;
-            else if (err == 1)
-              error ("cholupdate: downdate violates positiveness");
-            else if (err == 2)
-              error ("cholupdate: singular matrix");
-          }
-        else
-          error ("cholupdate: dimension mismatch between R and U");
-      else
-        error ("cholupdate: OP must be \"+\" or \"-\"");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!shared A, u, Ac, uc
-%! A = [  0.436997  -0.131721   0.124120  -0.061673 ;
-%!       -0.131721   0.738529   0.019851  -0.140295 ;
-%!        0.124120   0.019851   0.354879  -0.059472 ;
-%!       -0.061673  -0.140295  -0.059472   0.600939 ];
-%!
-%! u = [  0.98950 ;
-%!        0.39844 ;
-%!        0.63484 ;
-%!        0.13351 ];
-%! Ac = [  0.5585528 + 0.0000000i  -0.1662088 - 0.0315341i   0.0107873 + 0.0236411i  -0.0276775 - 0.0186073i ;
-%!        -0.1662088 + 0.0315341i   0.6760061 + 0.0000000i   0.0011452 - 0.0475528i   0.0145967 + 0.0247641i ;
-%!         0.0107873 - 0.0236411i   0.0011452 + 0.0475528i   0.6263149 - 0.0000000i  -0.1585837 - 0.0719763i ;
-%!        -0.0276775 + 0.0186073i   0.0145967 - 0.0247641i  -0.1585837 + 0.0719763i   0.6034234 - 0.0000000i ];
-%!
-%! uc = [ 0.54267 + 0.91519i ;
-%!        0.99647 + 0.43141i ;
-%!        0.83760 + 0.68977i ;
-%!        0.39160 + 0.90378i ];
-
-%!test
-%! R = chol (A);
-%! R1 = cholupdate (R, u);
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - R'*R - u*u', Inf) < 1e1*eps);
-%!
-%! R1 = cholupdate (R1, u, "-");
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1 - R, Inf) < 1e1*eps);
-
-%!test
-%! R = chol (Ac);
-%! R1 = cholupdate (R, uc);
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - R'*R - uc*uc', Inf) < 1e1*eps);
-%!
-%! R1 = cholupdate (R1, uc, "-");
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1 - R, Inf) < 1e1*eps);
-
-%!test
-%! R = chol (single (A));
-%! R1 = cholupdate (R, single (u));
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1'*R1 - R'*R - single (u*u'), Inf) < 1e1*eps ("single"));
-%!
-%! R1 = cholupdate (R1, single (u), "-");
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1 - R, Inf) < 2e1*eps ("single"));
-
-%!test
-%! R = chol (single (Ac));
-%! R1 = cholupdate (R, single (uc));
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1'*R1 - R'*R - single (uc*uc'), Inf) < 1e1*eps ("single"));
-%!
-%! R1 = cholupdate (R1, single (uc), "-");
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1 - R, Inf) < 2e1*eps ("single"));
-*/
-
-DEFUN_DLD (cholinsert, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{R1} =} cholinsert (@var{R}, @var{j}, @var{u})\n\
-@deftypefnx {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})\n\
-Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
-positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
-triangular, return the Cholesky@tie{}factorization of\n\
-@var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and\n\
-@w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.\n\
-On return, @var{info} is set to\n\
-\n\
-@itemize\n\
-@item 0 if the insertion was successful,\n\
-\n\
-@item 1 if @var{A1} is not positive definite,\n\
-\n\
-@item 2 if @var{R} is singular.\n\
-@end itemize\n\
-\n\
-If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
-@seealso{chol, cholupdate, choldelete}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-
-  octave_value_list retval;
-
-  if (nargin != 3)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argr = args(0);
-  octave_value argj = args(1);
-  octave_value argu = args(2);
-
-  if (argr.is_numeric_type () && argu.is_numeric_type ()
-      && argj.is_real_scalar ())
-    {
-      octave_idx_type n = argr.rows ();
-      octave_idx_type j = argj.scalar_value ();
-
-      if (argr.columns () == n && argu.rows () == n+1 && argu.columns () == 1)
-        {
-          if (j > 0 && j <= n+1)
-            {
-              int err = 0;
-              if (argr.is_single_type () || argu.is_single_type ())
-                {
-                  if (argr.is_real_type () && argu.is_real_type ())
-                    {
-                      // real case
-                      FloatMatrix R = argr.float_matrix_value ();
-                      FloatColumnVector u = argu.float_column_vector_value ();
-
-                      FloatCHOL fact;
-                      fact.set (R);
-                      err = fact.insert_sym (u, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
-                      FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
-
-                      FloatComplexCHOL fact;
-                      fact.set (R);
-                      err = fact.insert_sym (u, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-              else
-                {
-                  if (argr.is_real_type () && argu.is_real_type ())
-                    {
-                      // real case
-                      Matrix R = argr.matrix_value ();
-                      ColumnVector u = argu.column_vector_value ();
-
-                      CHOL fact;
-                      fact.set (R);
-                      err = fact.insert_sym (u, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      ComplexMatrix R = argr.complex_matrix_value ();
-                      ComplexColumnVector u = argu.complex_column_vector_value ();
-
-                      ComplexCHOL fact;
-                      fact.set (R);
-                      err = fact.insert_sym (u, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-
-              if (nargout > 1)
-                retval(1) = err;
-              else if (err == 1)
-                error ("cholinsert: insertion violates positiveness");
-              else if (err == 2)
-                error ("cholinsert: singular matrix");
-              else if (err == 3)
-                error ("cholinsert: diagonal element must be real");
-            }
-          else
-            error ("cholinsert: index J out of range");
-        }
-      else
-        error ("cholinsert: dimension mismatch between R and U");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!test
-%! u2 = [  0.35080 ;
-%!         0.63930 ;
-%!         3.31057 ;
-%!        -0.13825 ;
-%!         0.45266 ];
-%!
-%! R = chol (A);
-%!
-%! j = 3;  p = [1:j-1, j+1:5];
-%! R1 = cholinsert (R, j, u2);
-%! A1 = R1'*R1;
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (A1(p,p) - A, Inf) < 1e1*eps);
-
-%!test
-%! u2 = [  0.35080  + 0.04298i;
-%!         0.63930  + 0.23778i;
-%!         3.31057  + 0.00000i;
-%!        -0.13825  + 0.19879i;
-%!         0.45266  + 0.50020i];
-%!
-%! R = chol (Ac);
-%!
-%! j = 3;  p = [1:j-1, j+1:5];
-%! R1 = cholinsert (R, j, u2);
-%! A1 = R1'*R1;
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (A1(p,p) - Ac, Inf) < 1e1*eps);
-
-%!test
-%! u2 = single ([  0.35080 ;
-%!                 0.63930 ;
-%!                 3.31057 ;
-%!                -0.13825 ;
-%!                 0.45266 ]);
-%!
-%! R = chol (single (A));
-%!
-%! j = 3;  p = [1:j-1, j+1:5];
-%! R1 = cholinsert (R, j, u2);
-%! A1 = R1'*R1;
-%!
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (A1(p,p) - A, Inf) < 1e1*eps ("single"));
-
-%!test
-%! u2 = single ([  0.35080  + 0.04298i;
-%!                 0.63930  + 0.23778i;
-%!                 3.31057  + 0.00000i;
-%!                -0.13825  + 0.19879i;
-%!                 0.45266  + 0.50020i]);
-%!
-%! R = chol (single (Ac));
-%!
-%! j = 3;  p = [1:j-1, j+1:5];
-%! R1 = cholinsert (R, j, u2);
-%! A1 = R1'*R1;
-%!
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (A1(p,p) - single (Ac), Inf) < 2e1*eps ("single"));
-
-%!test
-%! cu = chol (triu (A), "upper");
-%! cl = chol (tril (A), "lower");
-%! assert (cu, cl', eps);
-
-%!test
-%! cca  = chol (Ac);
-%!
-%! ccal  = chol (Ac, "lower");
-%! ccal2 = chol (tril (Ac), "lower");
-%!
-%! ccau  = chol (Ac, "upper");
-%! ccau2 = chol (triu (Ac), "upper");
-%!
-%! assert (cca'*cca,     Ac, eps);
-%! assert (ccau'*ccau,   Ac, eps);
-%! assert (ccau2'*ccau2, Ac, eps);
-%!
-%! assert (cca, ccal',  eps);
-%! assert (cca, ccau,   eps);
-%! assert (cca, ccal2', eps);
-%! assert (cca, ccau2,  eps);
-
-%!test
-%! cca  = chol (single (Ac));
-%!
-%! ccal  = chol (single (Ac), "lower");
-%! ccal2 = chol (tril (single (Ac)), "lower");
-%!
-%! ccau  = chol (single (Ac), "upper");
-%! ccau2 = chol (triu (single (Ac)), "upper");
-%!
-%! assert (cca'*cca,     single (Ac), eps ("single"));
-%! assert (ccau'*ccau,   single (Ac), eps ("single"));
-%! assert (ccau2'*ccau2, single (Ac), eps ("single"));
-%!
-%! assert (cca, ccal',  eps ("single"));
-%! assert (cca, ccau,   eps ("single"));
-%! assert (cca, ccal2', eps ("single"));
-%! assert (cca, ccau2,  eps ("single"));
-
-%!test
-%! a = [12,  2,  3,  4;
-%!       2, 14,  5,  3;
-%!       3,  5, 16,  6;
-%!       4,  3,  6, 16];
-%!
-%! b = [0,  1,  2,  3;
-%!     -1,  0,  1,  2;
-%!     -2, -1,  0,  1;
-%!     -3, -2, -1,  0];
-%!
-%! ca = a + i*b;
-%!   
-%! cca  = chol (ca);
-%!
-%! ccal  = chol (ca, "lower");
-%! ccal2 = chol (tril (ca), "lower");
-%!
-%! ccau  = chol (ca, "upper");
-%! ccau2 = chol (triu (ca), "upper");
-%!
-%! assert (cca'*cca,     ca, 16*eps);
-%! assert (ccau'*ccau,   ca, 16*eps);
-%! assert (ccau2'*ccau2, ca, 16*eps);
-%!
-%! assert (cca, ccal',  16*eps);
-%! assert (cca, ccau,   16*eps);
-%! assert (cca, ccal2', 16*eps);
-%! assert (cca, ccau2,  16*eps);
-*/
-
-DEFUN_DLD (choldelete, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\
-Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
-positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
-triangular, return the Cholesky@tie{}factorization of @w{A(p,p)}, where\n\
-@w{p = [1:j-1,j+1:n+1]}.\n\
-@seealso{chol, cholupdate, cholinsert}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-
-  octave_value_list retval;
-
-  if (nargin != 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argr = args(0);
-  octave_value argj = args(1);
-
-  if (argr.is_numeric_type () && argj.is_real_scalar ())
-    {
-      octave_idx_type n = argr.rows ();
-      octave_idx_type j = argj.scalar_value ();
-
-      if (argr.columns () == n)
-        {
-          if (j > 0 && j <= n)
-            {
-              if (argr.is_single_type ())
-                {
-                  if (argr.is_real_type ())
-                    {
-                      // real case
-                      FloatMatrix R = argr.float_matrix_value ();
-
-                      FloatCHOL fact;
-                      fact.set (R);
-                      fact.delete_sym (j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
-
-                      FloatComplexCHOL fact;
-                      fact.set (R);
-                      fact.delete_sym (j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-              else
-                {
-                  if (argr.is_real_type ())
-                    {
-                      // real case
-                      Matrix R = argr.matrix_value ();
-
-                      CHOL fact;
-                      fact.set (R);
-                      fact.delete_sym (j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      ComplexMatrix R = argr.complex_matrix_value ();
-
-                      ComplexCHOL fact;
-                      fact.set (R);
-                      fact.delete_sym (j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-            }
-          else
-            error ("choldelete: index J out of range");
-        }
-      else
-        error ("choldelete: matrix R must be square");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!test
-%! R = chol (A);
-%!
-%! j = 3;  p = [1:j-1,j+1:4];
-%! R1 = choldelete (R, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
-
-%!test
-%! R = chol (Ac);
-%!
-%! j = 3;  p = [1:j-1,j+1:4];
-%! R1 = choldelete (R, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
-
-%!test
-%! R = chol (single (A));
-%!
-%! j = 3;  p = [1:j-1,j+1:4];
-%! R1 = choldelete (R, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
-
-%!test
-%! R = chol (single (Ac));
-%!
-%! j = 3;  p = [1:j-1,j+1:4];
-%! R1 = choldelete (R,j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), single (0));
-%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
-*/
-
-DEFUN_DLD (cholshift, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})\n\
-Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
-positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
-triangular, return the Cholesky@tie{}factorization of\n\
-@w{@var{A}(p,p)}, where @w{p} is the permutation @*\n\
-@code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
- or @*\n\
-@code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
-\n\
-@seealso{chol, cholinsert, choldelete}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-
-  octave_value_list retval;
-
-  if (nargin != 3)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argr = args(0);
-  octave_value argi = args(1);
-  octave_value argj = args(2);
-
-  if (argr.is_numeric_type () && argi.is_real_scalar () && argj.is_real_scalar ())
-    {
-      octave_idx_type n = argr.rows ();
-      octave_idx_type i = argi.scalar_value ();
-      octave_idx_type j = argj.scalar_value ();
-
-      if (argr.columns () == n)
-        {
-          if (j > 0 && j <= n+1 && i > 0 && i <= n+1)
-            {
-
-              if (argr.is_single_type () && argi.is_single_type () &&
-                  argj.is_single_type ())
-                {
-                  if (argr.is_real_type ())
-                    {
-                      // real case
-                      FloatMatrix R = argr.float_matrix_value ();
-
-                      FloatCHOL fact;
-                      fact.set (R);
-                      fact.shift_sym (i-1, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
-
-                      FloatComplexCHOL fact;
-                      fact.set (R);
-                      fact.shift_sym (i-1, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-              else
-                {
-                  if (argr.is_real_type ())
-                    {
-                      // real case
-                      Matrix R = argr.matrix_value ();
-
-                      CHOL fact;
-                      fact.set (R);
-                      fact.shift_sym (i-1, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                  else
-                    {
-                      // complex case
-                      ComplexMatrix R = argr.complex_matrix_value ();
-
-                      ComplexCHOL fact;
-                      fact.set (R);
-                      fact.shift_sym (i-1, j-1);
-
-                      retval(0) = get_chol_r (fact);
-                    }
-                }
-            }
-          else
-            error ("cholshift: index I or J is out of range");
-        }
-      else
-        error ("cholshift: R must be a square matrix");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!test
-%! R = chol (A);
-%!
-%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
-%!
-%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1) - R1, Inf), 0);
-%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
-
-%!test
-%! R = chol (Ac);
-%!
-%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
-%!
-%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
-
-%!test
-%! R = chol (single (A));
-%! 
-%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
-%!
-%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
-
-%!test
-%! R = chol (single (Ac));
-%!
-%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
-%!
-%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
-%! R1 = cholshift (R, i, j);
-%!
-%! assert (norm (triu (R1)-R1, Inf), 0);
-%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
-*/
--- a/src/DLD-FUNCTIONS/colamd.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,768 +0,0 @@
-/*
-
-Copyright (C) 2004-2012 David Bateman
-Copyright (C) 1998-2004 Andy Adler
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-// This is the octave interface to colamd, which bore the copyright given
-// in the help of the functions.
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cstdlib>
-
-#include <string>
-#include <vector>
-
-#include "ov.h"
-#include "defun-dld.h"
-#include "pager.h"
-#include "ov-re-mat.h"
-
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-
-#include "oct-sparse.h"
-#include "oct-locbuf.h"
-
-#ifdef IDX_TYPE_LONG
-#define COLAMD_NAME(name) colamd_l ## name
-#define SYMAMD_NAME(name) symamd_l ## name
-#else
-#define COLAMD_NAME(name) colamd ## name
-#define SYMAMD_NAME(name) symamd ## name
-#endif
-
-// The symmetric column elimination tree code take from the Davis LDL code.
-// Copyright given elsewhere in this file.
-static void
-symetree (const octave_idx_type *ridx, const octave_idx_type *cidx,
-          octave_idx_type *Parent, octave_idx_type *P, octave_idx_type n)
-{
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, Flag, n);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, Pinv, (P ? n : 0));
-  if (P)
-    // If P is present then compute Pinv, the inverse of P
-    for (octave_idx_type k = 0 ; k < n ; k++)
-      Pinv[P[k]] = k ;
-
-  for (octave_idx_type k = 0 ; k < n ; k++)
-    {
-      // L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k)
-      Parent[k] = n ;                // parent of k is not yet known
-      Flag[k] = k ;                  // mark node k as visited
-      octave_idx_type kk = (P) ? (P[k]) : (k) ;  // kth original, or permuted, column
-      octave_idx_type p2 = cidx[kk+1] ;
-      for (octave_idx_type p = cidx[kk] ; p < p2 ; p++)
-        {
-          // A (i,k) is nonzero (original or permuted A)
-          octave_idx_type i = (Pinv) ? (Pinv[ridx[p]]) : (ridx[p]) ;
-          if (i < k)
-            {
-              // follow path from i to root of etree, stop at flagged node
-              for ( ; Flag[i] != k ; i = Parent[i])
-                {
-                  // find parent of i if not yet determined
-                  if (Parent[i] == n)
-                    Parent[i] = k ;
-                  Flag[i] = k ;        // mark i as visited
-                }
-            }
-        }
-    }
-}
-
-// The elimination tree post-ordering code below is taken from SuperLU
-static inline octave_idx_type
-make_set (octave_idx_type i, octave_idx_type *pp)
-{
-  pp[i] = i;
-  return i;
-}
-
-static inline octave_idx_type
-link (octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
-{
-  pp[s] = t;
-  return t;
-}
-
-static inline octave_idx_type
-find (octave_idx_type i, octave_idx_type *pp)
-{
-  register octave_idx_type p, gp;
-
-  p = pp[i];
-  gp = pp[p];
-
-  while (gp != p)
-    {
-      pp[i] = gp;
-      i = gp;
-      p = pp[i];
-      gp = pp[p];
-    }
-
-  return p;
-}
-
-static octave_idx_type
-etdfs (octave_idx_type v, octave_idx_type *first_kid,
-       octave_idx_type *next_kid, octave_idx_type *post,
-       octave_idx_type postnum)
-{
-  for (octave_idx_type w = first_kid[v]; w != -1; w = next_kid[w])
-    postnum = etdfs (w, first_kid, next_kid, post, postnum);
-
-  post[postnum++] = v;
-
-  return postnum;
-}
-
-static void
-tree_postorder (octave_idx_type n, octave_idx_type *parent,
-                octave_idx_type *post)
-{
-  // Allocate storage for working arrays and results
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, first_kid, n+1);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, next_kid, n+1);
-
-  // Set up structure describing children
-  for (octave_idx_type v = 0; v <= n; first_kid[v++] = -1)
-    /* do nothing */;
-
-  for (octave_idx_type v = n-1; v >= 0; v--)
-    {
-      octave_idx_type dad = parent[v];
-      next_kid[v] = first_kid[dad];
-      first_kid[dad] = v;
-    }
-
-  // Depth-first search from dummy root vertex #n
-  etdfs (n, first_kid, next_kid, post, 0);
-}
-
-static void
-coletree (const octave_idx_type *ridx, const octave_idx_type *colbeg,
-          octave_idx_type *colend, octave_idx_type *parent,
-          octave_idx_type nr, octave_idx_type nc)
-{
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, root, nc);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, pp, nc);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, firstcol, nr);
-
-  // Compute firstcol[row] = first nonzero column in row
-  for (octave_idx_type row = 0; row < nr; firstcol[row++] = nc)
-    /* do nothing */;
-
-  for (octave_idx_type col = 0; col < nc; col++)
-    for (octave_idx_type p = colbeg[col]; p < colend[col]; p++)
-      {
-        octave_idx_type row = ridx[p];
-        if (firstcol[row] > col)
-          firstcol[row] = col;
-      }
-
-  // Compute etree by Liu's algorithm for symmetric matrices,
-  // except use (firstcol[r],c) in place of an edge (r,c) of A.
-  // Thus each row clique in A'*A is replaced by a star
-  // centered at its first vertex, which has the same fill.
-  for (octave_idx_type col = 0; col < nc; col++)
-    {
-      octave_idx_type cset = make_set (col, pp);
-      root[cset] = col;
-      parent[col] = nc;
-      for (octave_idx_type p = colbeg[col]; p < colend[col]; p++)
-        {
-          octave_idx_type row = firstcol[ridx[p]];
-          if (row >= col)
-            continue;
-          octave_idx_type rset = find (row, pp);
-          octave_idx_type rroot = root[rset];
-          if (rroot != col)
-            {
-              parent[rroot] = col;
-              cset = link (cset, rset, pp);
-              root[cset] = col;
-            }
-        }
-    }
-}
-
-DEFUN_DLD (colamd, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} colamd (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} colamd (@var{S}, @var{knobs})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S}, @var{knobs})\n\
-\n\
-Column approximate minimum degree permutation.\n\
-@code{@var{p} = colamd (@var{S})} returns the column approximate minimum\n\
-degree permutation vector for the sparse matrix @var{S}.  For a\n\
-non-symmetric matrix @var{S}, @code{@var{S}(:,@var{p})} tends to have\n\
-sparser LU@tie{}factors than @var{S}.  The Cholesky@tie{}factorization of\n\
-@code{@var{S}(:,@var{p})' * @var{S}(:,@var{p})} also tends to be sparser\n\
-than that of @code{@var{S}' * @var{S}}.\n\
-\n\
-@var{knobs} is an optional one- to three-element input vector.  If @var{S} is\n\
-m-by-n, then rows with more than @code{max(16,@var{knobs}(1)*sqrt(n))}\n\
-entries are ignored.  Columns with more than\n\
-@code{max (16,@var{knobs}(2)*sqrt(min(m,n)))} entries are removed prior to\n\
-ordering, and ordered last in the output permutation @var{p}.  Only\n\
-completely dense rows or columns are removed if @code{@var{knobs}(1)} and\n\
-@code{@var{knobs}(2)} are < 0, respectively.  If @code{@var{knobs}(3)} is\n\
-nonzero, @var{stats} and @var{knobs} are printed.  The default is\n\
-@code{@var{knobs} = [10 10 0]}.  Note that @var{knobs} differs from earlier\n\
-versions of colamd.\n\
-\n\
-@var{stats} is an optional 20-element output vector that provides data\n\
-about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
-statistics are in @code{@var{stats}(1:3)}.  @code{@var{stats}(1)} and\n\
-@code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
-ignored by @sc{colamd} and @code{@var{stats}(3)} is the number of garbage\n\
-collections performed on the internal data structure used by @sc{colamd}\n\
-(roughly of size @code{2.2 * nnz(@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
-integers).\n\
-\n\
-Octave built-in functions are intended to generate valid sparse matrices,\n\
-with no duplicate entries, with ascending row indices of the nonzeros\n\
-in each column, with a non-negative number of entries in each column (!)\n\
-and so on.  If a matrix is invalid, then @sc{colamd} may or may not be able\n\
-to continue.  If there are duplicate entries (a row index appears two or\n\
-more times in the same column) or if the row indices in a column are out\n\
-of order, then @sc{colamd} can correct these errors by ignoring the duplicate\n\
-entries and sorting each column of its internal copy of the matrix\n\
-@var{S} (the input matrix @var{S} is not repaired, however).  If a matrix\n\
-is invalid in other ways then @sc{colamd} cannot continue, an error message\n\
-is printed, and no output arguments (@var{p} or @var{stats}) are returned.\n\
-@sc{colamd} is thus a simple way to check a sparse matrix to see if it's\n\
-valid.\n\
-\n\
-@code{@var{stats}(4:7)} provide information if COLAMD was able to\n\
-continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
-invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
-unsorted or contains duplicate entries, or zero if no such column exists.\n\
-@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
-index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
-such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
-or out-of-order row indices.  @code{@var{stats}(8:20)} is always zero in\n\
-the current version of @sc{colamd} (reserved for future use).\n\
-\n\
-The ordering is followed by a column elimination tree post-ordering.\n\
-\n\
-The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
-Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
-developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
-Ng, Oak Ridge National Laboratory.  (see\n\
-@url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
-@seealso{colperm, symamd, ccolamd}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_COLAMD
-
-  int nargin = args.length ();
-  int spumoni = 0;
-
-  if (nargout > 2 || nargin < 1 || nargin > 2)
-    print_usage ();
-  else
-    {
-      // Get knobs
-      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);
-      COLAMD_NAME (_set_defaults) (knobs);
-
-      // Check for user-passed knobs
-      if (nargin == 2)
-        {
-          NDArray User_knobs = args(1).array_value ();
-          int nel_User_knobs = User_knobs.length ();
-
-          if (nel_User_knobs > 0)
-            knobs[COLAMD_DENSE_ROW] = User_knobs(0);
-          if (nel_User_knobs > 1)
-            knobs[COLAMD_DENSE_COL] = User_knobs(1) ;
-          if (nel_User_knobs > 2)
-            spumoni = static_cast<int> (User_knobs(2));
-
-          // print knob settings if spumoni is set
-          if (spumoni)
-            {
-
-              octave_stdout << "\ncolamd version " << COLAMD_MAIN_VERSION << "."
-                            <<  COLAMD_SUB_VERSION << ", " << COLAMD_DATE << ":\n";
-
-              if (knobs[COLAMD_DENSE_ROW] >= 0)
-                octave_stdout << "knobs(1): " << User_knobs (0)
-                              << ", rows with > max (16,"
-                              << knobs[COLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
-                              << " entries removed\n";
-              else
-                octave_stdout << "knobs(1): " << User_knobs (0)
-                              << ", only completely dense rows removed\n";
-
-              if (knobs[COLAMD_DENSE_COL] >= 0)
-                octave_stdout << "knobs(2): " << User_knobs (1)
-                              << ", cols with > max (16,"
-                              << knobs[COLAMD_DENSE_COL] << "*sqrt (size(A)))"
-                              << " entries removed\n";
-              else
-                octave_stdout << "knobs(2): " << User_knobs (1)
-                              << ", only completely dense columns removed\n";
-
-              octave_stdout << "knobs(3): " << User_knobs (2)
-                            << ", statistics and knobs printed\n";
-
-            }
-        }
-
-      octave_idx_type n_row, n_col, nnz;
-      octave_idx_type *ridx, *cidx;
-      SparseComplexMatrix scm;
-      SparseMatrix sm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0). sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              nnz = scm.nnz ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              nnz = sm.nnz ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-        }
-      else
-        {
-          if (args(0).is_complex_type ())
-            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
-          else
-            sm = SparseMatrix (args(0).matrix_value ());
-
-          n_row = sm.rows ();
-          n_col = sm.cols ();
-          nnz = sm.nnz ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
-        }
-
-      // Allocate workspace for colamd
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
-      for (octave_idx_type i = 0; i < n_col+1; i++)
-        p[i] = cidx[i];
-
-      octave_idx_type Alen = COLAMD_NAME (_recommended) (nnz, n_row, n_col);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
-      for (octave_idx_type i = 0; i < nnz; i++)
-        A[i] = ridx[i];
-
-      // Order the columns (destroys A)
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
-      if (! COLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats))
-        {
-          COLAMD_NAME (_report) (stats) ;
-          error ("colamd: internal error!");
-          return retval;
-        }
-
-      // column elimination tree post-ordering (reuse variables)
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col + 1);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col + 1);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
-
-      for (octave_idx_type i = 0; i < n_col; i++)
-        {
-          colbeg[i] = cidx[p[i]];
-          colend[i] = cidx[p[i]+1];
-        }
-
-      coletree (ridx, colbeg, colend, etree, n_row, n_col);
-
-      // Calculate the tree post-ordering
-      tree_postorder (n_col, etree, colbeg);
-
-      // return the permutation vector
-      NDArray out_perm (dim_vector (1, n_col));
-      for (octave_idx_type i = 0; i < n_col; i++)
-        out_perm(i) = p[colbeg[i]] + 1;
-
-      retval(0) = out_perm;
-
-      // print stats if spumoni > 0
-      if (spumoni > 0)
-        COLAMD_NAME (_report) (stats) ;
-
-      // Return the stats vector
-      if (nargout == 2)
-        {
-          NDArray out_stats (dim_vector (1, COLAMD_STATS));
-          for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
-            out_stats(i) = stats[i] ;
-          retval(1) = out_stats;
-
-          // 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) ++ ;
-        }
-    }
-
-#else
-
-  error ("colamd: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (symamd, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} symamd (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} symamd (@var{S}, @var{knobs})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S}, @var{knobs})\n\
-\n\
-For a symmetric positive definite matrix @var{S}, returns the permutation\n\
-vector p such that @code{@var{S}(@var{p}, @var{p})} tends to have a\n\
-sparser Cholesky@tie{}factor than @var{S}.  Sometimes @code{symamd} works\n\
-well for symmetric indefinite matrices too.  The matrix @var{S} is assumed\n\
-to be symmetric; only the strictly lower triangular part is referenced.\n\
-@var{S} must be square.\n\
-\n\
-@var{knobs} is an optional one- to two-element input vector.  If @var{S} is\n\
-n-by-n, then rows and columns with more than\n\
-@code{max (16,@var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,\n\
-and ordered last in the output permutation @var{p}.  No rows/columns are\n\
-removed if @code{@var{knobs}(1) < 0}.  If @code{@var{knobs} (2)} is nonzero,\n\
-@code{stats} and @var{knobs} are printed.  The default is @code{@var{knobs}\n\
-= [10 0]}.  Note that @var{knobs} differs from earlier versions of symamd.\n\
-\n\
-@var{stats} is an optional 20-element output vector that provides data\n\
-about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
-statistics are in @code{@var{stats}(1:3)}.  @code{@var{stats}(1) =\n\
-@var{stats}(2)} is the number of dense or empty rows and columns\n\
-ignored by SYMAMD and @code{@var{stats}(3)} is the number of garbage\n\
-collections performed on the internal data structure used by SYMAMD\n\
-(roughly of size @code{8.4 * nnz (tril (@var{S}, -1)) + 9 * @var{n}}\n\
-integers).\n\
-\n\
-Octave built-in functions are intended to generate valid sparse matrices,\n\
-with no duplicate entries, with ascending row indices of the nonzeros\n\
-in each column, with a non-negative number of entries in each column (!)\n\
-and so on.  If a matrix is invalid, then SYMAMD may or may not be able\n\
-to continue.  If there are duplicate entries (a row index appears two or\n\
-more times in the same column) or if the row indices in a column are out\n\
-of order, then SYMAMD can correct these errors by ignoring the duplicate\n\
-entries and sorting each column of its internal copy of the matrix S (the\n\
-input matrix S is not repaired, however).  If a matrix is invalid in\n\
-other ways then SYMAMD cannot continue, an error message is printed, and\n\
-no output arguments (@var{p} or @var{stats}) are returned.  SYMAMD is\n\
-thus a simple way to check a sparse matrix to see if it's valid.\n\
-\n\
-@code{@var{stats}(4:7)} provide information if SYMAMD was able to\n\
-continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1\n\
-if invalid.  @code{@var{stats}(5)} is the rightmost column index that\n\
-is unsorted or contains duplicate entries, or zero if no such column\n\
-exists.  @code{@var{stats}(6)} is the last seen duplicate or out-of-order\n\
-row index in the column index given by @code{@var{stats}(5)}, or zero\n\
-if no such row index exists.  @code{@var{stats}(7)} is the number of\n\
-duplicate or out-of-order row indices.  @code{@var{stats}(8:20)} is\n\
-always zero in the current version of SYMAMD (reserved for future use).\n\
-\n\
-The ordering is followed by a column elimination tree post-ordering.\n\
-\n\
-The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
-Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
-developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
-Ng, Oak Ridge National Laboratory.  (see\n\
-@url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
-@seealso{colperm, colamd}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_COLAMD
-
-  int nargin = args.length ();
-  int spumoni = 0;
-
-  if (nargout > 2 || nargin < 1 || nargin > 2)
-    print_usage ();
-  else
-    {
-      // Get knobs
-      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);
-      COLAMD_NAME (_set_defaults) (knobs);
-
-      // Check for user-passed knobs
-      if (nargin == 2)
-        {
-          NDArray User_knobs = args(1).array_value ();
-          int nel_User_knobs = User_knobs.length ();
-
-          if (nel_User_knobs > 0)
-            knobs[COLAMD_DENSE_ROW] = User_knobs(COLAMD_DENSE_ROW);
-          if (nel_User_knobs > 1)
-            spumoni = static_cast<int> (User_knobs (1));
-        }
-
-      // print knob settings if spumoni is set
-      if (spumoni > 0)
-        octave_stdout << "symamd: dense row/col fraction: "
-                      << knobs[COLAMD_DENSE_ROW] << std::endl;
-
-      octave_idx_type n_row, n_col;
-      octave_idx_type *ridx, *cidx;
-      SparseMatrix sm;
-      SparseComplexMatrix scm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0).sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-        }
-      else
-        {
-          if (args(0).is_complex_type ())
-            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
-          else
-            sm = SparseMatrix (args(0).matrix_value ());
-
-          n_row = sm.rows ();
-          n_col = sm.cols ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
-        }
-
-      if (n_row != n_col)
-        {
-          error ("symamd: matrix S must be square");
-          return retval;
-        }
-
-      // Allocate workspace for symamd
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
-      if (!SYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, &calloc, &free))
-        {
-          SYMAMD_NAME (_report) (stats) ;
-          error ("symamd: internal error!") ;
-          return retval;
-        }
-
-      // column elimination tree post-ordering
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
-      symetree (ridx, cidx, etree, perm, n_col);
-
-      // Calculate the tree post-ordering
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
-      tree_postorder (n_col, etree, post);
-
-      // return the permutation vector
-      NDArray out_perm (dim_vector (1, n_col));
-      for (octave_idx_type i = 0; i < n_col; i++)
-        out_perm(i) = perm[post[i]] + 1;
-
-      retval(0) = out_perm;
-
-      // print stats if spumoni > 0
-      if (spumoni > 0)
-        SYMAMD_NAME (_report) (stats) ;
-
-      // Return the stats vector
-      if (nargout == 2)
-        {
-          NDArray out_stats (dim_vector (1, COLAMD_STATS));
-          for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
-            out_stats(i) = stats[i] ;
-          retval(1) = out_stats;
-
-          // 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) ++ ;
-        }
-    }
-
-#else
-
-  error ("symamd: not available in this version of Octave");
-
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (etree, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} etree (@var{S})\n\
-@deftypefnx {Loadable Function} {@var{p} =} etree (@var{S}, @var{typ})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{S}, @var{typ})\n\
-\n\
-Return the elimination tree for the matrix @var{S}.  By default @var{S}\n\
-is assumed to be symmetric and the symmetric elimination tree is\n\
-returned.  The argument @var{typ} controls whether a symmetric or\n\
-column elimination tree is returned.  Valid values of @var{typ} are\n\
-\"sym\" or \"col\", for symmetric or column elimination tree respectively\n\
-\n\
-Called with a second argument, @code{etree} also returns the postorder\n\
-permutations on the tree.\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargout > 2 || nargin < 1 || nargin > 2)
-    print_usage ();
-  else
-    {
-      octave_idx_type n_row, n_col;
-      octave_idx_type *ridx, *cidx;
-      bool is_sym = true;
-      SparseMatrix sm;
-      SparseComplexMatrix scm;
-
-      if (args(0).is_sparse_type ())
-        {
-          if (args(0).is_complex_type ())
-            {
-              scm = args(0).sparse_complex_matrix_value ();
-              n_row = scm.rows ();
-              n_col = scm.cols ();
-              ridx = scm.xridx ();
-              cidx = scm.xcidx ();
-            }
-          else
-            {
-              sm = args(0).sparse_matrix_value ();
-              n_row = sm.rows ();
-              n_col = sm.cols ();
-              ridx = sm.xridx ();
-              cidx = sm.xcidx ();
-            }
-
-        }
-      else
-        {
-          error ("etree: S must be a sparse matrix");
-          return retval;
-        }
-
-      if (nargin == 2)
-        {
-          if (args(1).is_string ())
-            {
-              std::string str = args(1).string_value ();
-              if (str.find ("C") == 0 || str.find ("c") == 0)
-                is_sym = false;
-            }
-          else
-            {
-              error ("etree: TYP must be a string");
-              return retval;
-            }
-        }
-
-      // column elimination tree post-ordering (reuse variables)
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
-
-      if (is_sym)
-        {
-          if (n_row != n_col)
-            {
-              error ("etree: S is marked as symmetric, but is not square");
-              return retval;
-            }
-
-          symetree (ridx, cidx, etree, 0, n_col);
-        }
-      else
-        {
-          OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col);
-          OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col);
-
-          for (octave_idx_type i = 0; i < n_col; i++)
-            {
-              colbeg[i] = cidx[i];
-              colend[i] = cidx[i+1];
-            }
-
-          coletree (ridx, colbeg, colend, etree, n_row, n_col);
-        }
-
-      NDArray tree (dim_vector (1, n_col));
-      for (octave_idx_type i = 0; i < n_col; i++)
-        // We flag a root with n_col while Matlab does it with zero
-        // Convert for matlab compatiable output
-        if (etree[i] == n_col)
-          tree(i) = 0;
-        else
-          tree(i) = etree[i] + 1;
-
-      retval(0) = tree;
-
-      if (nargout == 2)
-        {
-          // Calculate the tree post-ordering
-          OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
-          tree_postorder (n_col, etree, post);
-
-          NDArray postorder (dim_vector (1, n_col));
-          for (octave_idx_type i = 0; i < n_col; i++)
-            postorder(i) = post[i] + 1;
-
-          retval(1) = postorder;
-        }
-    }
-
-  return retval;
-}
--- a/src/DLD-FUNCTIONS/config-module.awk	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-BEGIN {
-  FS = "|";
-  nfiles = 0;
-
-  print "## DO NOT EDIT -- generated from module-files by config-module.awk";
-  print ""
-  print "EXTRA_DIST += \\"
-  print "  DLD-FUNCTIONS/config-module.sh \\"
-  print "  DLD-FUNCTIONS/config-module.awk \\"
-  print "  DLD-FUNCTIONS/module-files \\"
-  print "  DLD-FUNCTIONS/oct-qhull.h"
-  print ""
-}
-/^#.*/ { next; }
-{
-  nfiles++;
-  files[nfiles] = $1;
-  cppflags[nfiles] = $2;
-  ldflags[nfiles] = $3;
-  libraries[nfiles] = $4;
-} END {
-  sep = " \\\n";
-  print "DLD_FUNCTIONS_SRC = \\";
-  for (i = 1; i <= nfiles; i++) {
-    if (i == nfiles)
-      sep = "\n";
-    printf ("  DLD-FUNCTIONS/%s%s", files[i], sep);
-  }
-  print "";
-
-  sep = " \\\n";
-  print "DLD_FUNCTIONS_LIBS = $(DLD_FUNCTIONS_SRC:.cc=.la)";
-  print "";
-  print "if AMCOND_ENABLE_DYNAMIC_LINKING";
-  print "";
-  print "octlib_LTLIBRARIES += $(DLD_FUNCTIONS_LIBS)";
-  print "";
-  print "## Use stamp files to avoid problems with checking timestamps";
-  print "## of symbolic links";
-  print "";
-  for (i = 1; i <= nfiles; i++) {
-    basename = files[i];
-    sub (/\.cc$/, "", basename);
-    printf ("DLD-FUNCTIONS/$(am__leading_dot)%s.oct-stamp: DLD-FUNCTIONS/%s.la\n", basename, basename);
-    print "\trm -f $(<:.la=.oct)";
-    print "\tla=$(<F) && \\";
-    print "\t  of=$(<F:.la=.oct) && \\";
-    print "\t  cd DLD-FUNCTIONS && \\";
-    print "\t  $(LN_S) .libs/`$(SED) -n -e \"s/dlname='\\([^']*\\)'/\\1/p\" < $$la` $$of && \\";
-    print "\t  touch $(@F)";
-    print "";
-  }
-  print "else";
-  print "";
-  print "noinst_LTLIBRARIES += $(DLD_FUNCTIONS_LIBS)";
-  print "";
-  print "endif";
-
-  for (i = 1; i <= nfiles; i++) {
-    basename = files[i];
-    sub (/\.cc$/, "", basename);
-    print "";
-    printf ("DLD_FUNCTIONS_%s_la_SOURCES = DLD-FUNCTIONS/%s\n",
-	    basename, files[i]);
-    if (cppflags[i])
-      {
-        printf ("DLD-FUNCTIONS/%s.df: CPPFLAGS += %s\n",
-                basename, cppflags[i]);
-        printf ("DLD_FUNCTIONS_%s_la_CPPFLAGS = $(AM_CPPFLAGS) %s\n",
-                basename, cppflags[i]);
-      }
-    printf ("DLD_FUNCTIONS_%s_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED_LDFLAG) %s $(OCT_LINK_OPTS)\n",
-            basename, ldflags[i]);
-    printf ("DLD_FUNCTIONS_%s_la_LIBADD = $(DLD_LIBOCTINTERP_LIBADD) ../liboctave/liboctave.la ../libcruft/libcruft.la %s $(OCT_LINK_DEPS)\n",
-            basename, libraries[i]);
-  }
-}
--- a/src/DLD-FUNCTIONS/config-module.sh	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#! /bin/sh
-
-set -e
-
-: ${AWK=awk}
-
-if [ $# -eq 1 ]; then
-  top_srcdir="$1";
-else
-  top_srcdir="../.."
-fi
-
-move_if_change="$top_srcdir/build-aux/move-if-change"
-
-dld_dir=$top_srcdir/src/DLD-FUNCTIONS
-
-$AWK -f $dld_dir/config-module.awk < $dld_dir/module-files > $dld_dir/module.mk-t
-
-$move_if_change $dld_dir/module.mk-t $dld_dir/module.mk
--- a/src/DLD-FUNCTIONS/convhulln.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-/*
-
-Copyright (C) 2000-2012 Kai Habel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-29. July 2000 - Kai Habel: first release
-2002-04-22 Paul Kienzle
-* Use warning(...) function rather than writing to cerr
-2006-05-01 Tom Holroyd
-* add support for consistent winding in all dimensions; output is
-* guaranteed to be simplicial.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sstream>
-
-#include "Cell.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-#include "parse.h"
-#include "unwind-prot.h"
-
-#if defined (HAVE_QHULL)
-# include "oct-qhull.h"
-# if defined (NEED_QHULL_VERSION)
-char qh_version[] = "convhulln.oct 2007-07-24";
-# endif
-#endif
-
-static void
-close_fcn (FILE *f)
-{
-  gnulib::fclose (f);
-}
-
-DEFUN_DLD (convhulln, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{h} =} convhulln (@var{pts})\n\
-@deftypefnx {Loadable Function} {@var{h} =} convhulln (@var{pts}, @var{options})\n\
-@deftypefnx {Loadable Function} {[@var{h}, @var{v}] =} convhulln (@dots{})\n\
-Compute the convex hull of the set of points @var{pts} which is a matrix\n\
-of size [n, dim] containing n points in a space of dimension dim.\n\
-The hull @var{h} is an index vector into the set of points and specifies\n\
-which points form the enclosing hull.\n\
-\n\
-An optional second argument, which must be a string or cell array of strings,\n\
-contains options passed to the underlying qhull command.\n\
-See the documentation for the Qhull library for details\n\
-@url{http://www.qhull.org/html/qh-quick.htm#options}.\n\
-The default options depend on the dimension of the input:\n\
-\n\
-@itemize\n\
-@item 2D, 3D, 4D: @var{options} = @code{@{\"Qt\"@}}\n\
-\n\
-@item 5D and higher: @var{options} = @code{@{\"Qt\", \"Qx\"@}}\n\
-@end itemize\n\
-\n\
-If @var{options} is not present or @code{[]} then the default arguments are\n\
-used.  Otherwise, @var{options} replaces the default argument list.\n\
-To append user options to the defaults it is necessary to repeat the\n\
-default arguments in @var{options}.  Use a null string to pass no arguments.\n\
-\n\
-If the second output @var{v} is requested the volume of the enclosing\n\
-convex hull is calculated.\n\n\
-@seealso{convhull, delaunayn, voronoin}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#if defined (HAVE_QHULL)
-
-  int nargin = args.length ();
-  if (nargin < 1 || nargin > 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  Matrix points (args(0).matrix_value ());
-  const octave_idx_type dim = points.columns ();
-  const octave_idx_type num_points = points.rows ();
-
-  points = points.transpose ();
-
-  std::string options;
-
-  if (dim <= 4)
-    options = " Qt";
-  else
-    options = " Qt Qx";
-
-  if (nargin == 2)
-    {
-      if (args(1).is_string ())
-        options = " " + args(1).string_value ();
-      else if (args(1).is_empty ())
-        ; // Use default options.
-      else if (args(1).is_cellstr ())
-        {
-          options = "";
-
-          Array<std::string> tmp = args(1).cellstr_value ();
-
-          for (octave_idx_type i = 0; i < tmp.numel (); i++)
-            options += " " + tmp(i);
-        }
-      else
-        {
-          error ("convhulln: OPTIONS must be a string, cell array of strings, or empty");
-          return retval;
-        }
-     }
-
-  boolT ismalloc = false;
-
-  unwind_protect frame;
-
-  // Replace the outfile pointer with stdout for debugging information.
-#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
-  FILE *outfile = gnulib::fopen ("NUL", "w");
-#else
-  FILE *outfile = gnulib::fopen ("/dev/null", "w");
-#endif
-  FILE *errfile = stderr;
-
-  if (outfile)
-    frame.add_fcn (close_fcn, outfile);
-  else
-    {
-      error ("convhulln: unable to create temporary file for output");
-      return retval;
-    }
-
-  // qh_new_qhull command and points arguments are not const...
-
-  std::string cmd = "qhull" + options;
-
-  OCTAVE_LOCAL_BUFFER (char, cmd_str, cmd.length () + 1);
-
-  strcpy (cmd_str, cmd.c_str ());
-
-  int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
-                               ismalloc, cmd_str, outfile, errfile);
-  if (! exitcode)
-    {
-      bool nonsimp_seen = false;
-
-      octave_idx_type nf = qh num_facets;
-
-      Matrix idx (nf, dim + 1);
-
-      facetT *facet;
-
-      octave_idx_type i = 0;
-
-      FORALLfacets
-        {
-          octave_idx_type j = 0;
-
-          if (! nonsimp_seen && ! facet->simplicial)
-            {
-              nonsimp_seen = true;
-
-              if (cmd.find ("QJ") != std::string::npos)
-                {
-                  // Should never happen with QJ.
-                  error ("convhulln: qhull failed: option 'QJ' returned non-simplicial facet");
-                  return retval;
-                }
-            }
-
-          if (dim == 3)
-            {
-              setT *vertices = qh_facet3vertex (facet);
-
-              vertexT *vertex, **vertexp;
-
-              FOREACHvertex_ (vertices)
-                idx(i, j++) = 1 + qh_pointid(vertex->point);
-
-              qh_settempfree (&vertices);
-            }
-          else
-            {
-              if (facet->toporient ^ qh_ORIENTclock)
-                {
-                  vertexT *vertex, **vertexp;
-
-                  FOREACHvertex_ (facet->vertices)
-                    idx(i, j++) = 1 + qh_pointid(vertex->point);
-                }
-              else
-                {
-                  vertexT *vertex, **vertexp;
-
-                  FOREACHvertexreverse12_ (facet->vertices)
-                    idx(i, j++) = 1 + qh_pointid(vertex->point);
-                }
-            }
-          if (j < dim)
-            warning ("convhulln: facet %d only has %d vertices", i, j);
-
-          i++;
-        }
-
-      // Remove extra dimension if all facets were simplicial.
-
-      if (! nonsimp_seen)
-        idx.resize (nf, dim, 0.0);
-
-      if (nargout == 2)
-        {
-          // Calculate volume of convex hull, taken from qhull src/geom2.c.
-
-          realT area;
-          realT dist;
-
-          FORALLfacets
-            {
-              if (! facet->normal)
-                continue;
-
-              if (facet->upperdelaunay && qh ATinfinity)
-                continue;
-
-              facet->f.area = area = qh_facetarea (facet);
-              facet->isarea = True;
-
-              if (qh DELAUNAY)
-                {
-                  if (facet->upperdelaunay == qh UPPERdelaunay)
-                    qh totarea += area;
-                }
-              else
-                {
-                  qh totarea += area;
-                  qh_distplane (qh interior_point, facet, &dist);
-                  qh totvol += -dist * area/ qh hull_dim;
-                }
-            }
-
-          retval(1) = octave_value (qh totvol);
-        }
-
-      retval(0) = idx;
-    }
-  else
-    error ("convhulln: qhull failed");
-
-  // Free memory from Qhull
-  qh_freeqhull (! qh_ALL);
-
-  int curlong, totlong;
-  qh_memfreeshort (&curlong, &totlong);
-
-  if (curlong || totlong)
-    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
-             totlong, curlong);
-
-#else
-  error ("convhulln: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-/*
-%!testif HAVE_QHULL
-%! cube = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1];
-%! [h, v] = convhulln (cube, "Qt");
-%! assert (size (h), [12 3]); 
-%! h = sortrows (sort (h, 2), [1:3]);
-%! assert (h, [1 2 4; 1 2 6; 1 4 8; 1 5 6; 1 5 8; 2 3 4; 2 3 7; 2 6 7; 3 4 7; 4 7 8; 5 6 7; 5 7 8]);
-%! assert (v, 1, 10*eps);
-%! [h2, v2] = convhulln (cube); % Test defaut option = "Qt"
-%! assert (size (h2), size (h));
-%! h2 = sortrows (sort (h2, 2), [1:3]);
-%! assert (h2, h);
-%! assert (v2, v, 10*eps);
-
-%!testif HAVE_QHULL
-%! cube = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1];
-%! [h, v] = convhulln (cube, "QJ");
-%! assert (size (h), [12 3]); 
-%! assert (sortrows (sort (h, 2), [1:3]), [1 2 4; 1 2 5; 1 4 5; 2 3 4; 2 3 6; 2 5 6; 3 4 8; 3 6 7; 3 7 8; 4 5 8; 5 6 8; 6 7 8]);
-%! assert (v, 1.0, 1e6*eps);
-
-%!testif HAVE_QHULL
-%! tetrahedron = [1 1 1;-1 -1 1;-1 1 -1;1 -1 -1];
-%! [h, v] = convhulln (tetrahedron);
-%! h = sortrows (sort (h, 2), [1 2 3]);
-%! assert (h, [1 2 3;1 2 4; 1 3 4; 2 3 4]);
-%! assert (v, 8/3, 10*eps);
-*/
--- a/src/DLD-FUNCTIONS/dmperm.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
-
-Copyright (C) 2005-2012 David Bateman
-Copyright (C) 1998-2005 Andy Adler
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "utils.h"
-
-#include "oct-sparse.h"
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "SparseQR.h"
-#include "SparseCmplxQR.h"
-
-#ifdef IDX_TYPE_LONG
-#define CXSPARSE_NAME(name) cs_dl ## name
-#else
-#define CXSPARSE_NAME(name) cs_di ## name
-#endif
-
-static RowVector
-put_int (octave_idx_type *p, octave_idx_type n)
-{
-  RowVector ret (n);
-  for (octave_idx_type i = 0; i < n; i++)
-    ret.xelem (i) = p[i] + 1;
-  return ret;
-}
-
-#if HAVE_CXSPARSE
-static octave_value_list
-dmperm_internal (bool rank, const octave_value arg, int nargout)
-{
-  octave_value_list retval;
-  octave_idx_type nr = arg.rows ();
-  octave_idx_type nc = arg.columns ();
-  SparseMatrix m;
-  SparseComplexMatrix cm;
-  CXSPARSE_NAME () csm;
-  csm.m = nr;
-  csm.n = nc;
-  csm.x = 0;
-  csm.nz = -1;
-
-  if (arg.is_real_type ())
-    {
-      m = arg.sparse_matrix_value ();
-      csm.nzmax = m.nnz ();
-      csm.p = m.xcidx ();
-      csm.i = m.xridx ();
-    }
-  else
-    {
-      cm = arg.sparse_complex_matrix_value ();
-      csm.nzmax = cm.nnz ();
-      csm.p = cm.xcidx ();
-      csm.i = cm.xridx ();
-    }
-
-  if (!error_state)
-    {
-      if (nargout <= 1 || rank)
-        {
-#if defined(CS_VER) && (CS_VER >= 2)
-          octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
-#else
-          octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm);
-#endif
-          if (rank)
-            {
-              octave_idx_type r = 0;
-              for (octave_idx_type i = 0; i < nc; i++)
-                if (jmatch[nr+i] >= 0)
-                  r++;
-              retval(0) = static_cast<double>(r);
-            }
-          else
-            retval(0) = put_int (jmatch + nr, nc);
-          CXSPARSE_NAME (_free) (jmatch);
-        }
-      else
-        {
-#if defined(CS_VER) && (CS_VER >= 2)
-          CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm, 0);
-#else
-          CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm);
-#endif
-
-          //retval(5) = put_int (dm->rr, 5);
-          //retval(4) = put_int (dm->cc, 5);
-#if defined(CS_VER) && (CS_VER >= 2)
-          retval(3) = put_int (dm->s, dm->nb+1);
-          retval(2) = put_int (dm->r, dm->nb+1);
-          retval(1) = put_int (dm->q, nc);
-          retval(0) = put_int (dm->p, nr);
-#else
-          retval(3) = put_int (dm->S, dm->nb+1);
-          retval(2) = put_int (dm->R, dm->nb+1);
-          retval(1) = put_int (dm->Q, nc);
-          retval(0) = put_int (dm->P, nr);
-#endif
-          CXSPARSE_NAME (_dfree) (dm);
-        }
-    }
-  return retval;
-}
-#endif
-
-DEFUN_DLD (dmperm, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{p} =} dmperm (@var{S})\n\
-@deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{S}] =} dmperm (@var{S})\n\
-\n\
-@cindex Dulmage-Mendelsohn decomposition\n\
-Perform a Dulmage-Mendelsohn permutation of the sparse matrix @var{S}.\n\
-With a single output argument @code{dmperm} performs the row permutations\n\
-@var{p} such that @code{@var{S}(@var{p},:)} has no zero elements on the\n\
-diagonal.\n\
-\n\
-Called with two or more output arguments, returns the row and column\n\
-permutations, such that @code{@var{S}(@var{p}, @var{q})} is in block\n\
-triangular form.  The values of @var{r} and @var{S} define the boundaries\n\
-of the blocks.  If @var{S} is square then @code{@var{r} == @var{S}}.\n\
-\n\
-The method used is described in: A. Pothen & C.-J. Fan. @cite{Computing the\n\
-Block Triangular Form of a Sparse Matrix}. ACM Trans. Math. Software,\n\
-16(4):303-324, 1990.\n\
-@seealso{colamd, ccolamd}\n\
-@end deftypefn")
-{
-  int nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin != 1)
-    {
-      print_usage ();
-      return retval;
-    }
-
-#if HAVE_CXSPARSE
-  retval = dmperm_internal (false, args(0), nargout);
-#else
-  error ("dmperm: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-/*
-%!testif HAVE_CXSPARSE
-%! n = 20;
-%! a = speye (n,n);
-%! a = a(randperm (n),:);
-%! assert (a(dmperm (a),:), speye (n));
-
-%!testif HAVE_CXSPARSE
-%! n = 20;
-%! d = 0.2;
-%! a = tril (sprandn (n,n,d), -1) + speye (n,n);
-%! a = a(randperm (n), randperm (n));
-%! [p,q,r,s] = dmperm (a);
-%! assert (tril (a(p,q), -1), sparse (n, n));
-*/
-
-DEFUN_DLD (sprank, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{p} =} sprank (@var{S})\n\
-@cindex structural rank\n\
-\n\
-Calculate the structural rank of the sparse matrix @var{S}.  Note that\n\
-only the structure of the matrix is used in this calculation based on\n\
-a Dulmage-Mendelsohn permutation to block triangular form.  As such the\n\
-numerical rank of the matrix @var{S} is bounded by\n\
-@code{sprank (@var{S}) >= rank (@var{S})}.  Ignoring floating point errors\n\
-@code{sprank (@var{S}) == rank (@var{S})}.\n\
-@seealso{dmperm}\n\
-@end deftypefn")
-{
-  int nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin != 1)
-    {
-      print_usage ();
-      return retval;
-    }
-
-#if HAVE_CXSPARSE
-  retval = dmperm_internal (true, args(0), nargout);
-#else
-  error ("sprank: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-/*
-%!testif HAVE_CXSPARSE
-%! assert (sprank (speye (20)), 20)
-%!testif HAVE_CXSPARSE
-%! assert (sprank ([1,0,2,0;2,0,4,0]), 2)
-
-%!error sprank (1,2)
-*/
--- a/src/DLD-FUNCTIONS/eigs.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1521 +0,0 @@
-/*
-
-Copyright (C) 2005-2012 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ov.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "quit.h"
-#include "variables.h"
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "oct-map.h"
-#include "pager.h"
-#include "unwind-prot.h"
-
-#include "eigs-base.cc"
-
-// Global pointer for user defined function.
-static octave_function *eigs_fcn = 0;
-
-// Have we warned about imaginary values returned from user function?
-static bool warned_imaginary = false;
-
-// Is this a recursive call?
-static int call_depth = 0;
-
-ColumnVector
-eigs_func (const ColumnVector &x, int &eigs_error)
-{
-  ColumnVector retval;
-  octave_value_list args;
-  args(0) = x;
-
-  if (eigs_fcn)
-    {
-      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
-
-      if (error_state)
-        {
-          eigs_error = 1;
-          gripe_user_supplied_eval ("eigs");
-          return retval;
-        }
-
-      if (tmp.length () && tmp(0).is_defined ())
-        {
-          if (! warned_imaginary && tmp(0).is_complex_type ())
-            {
-              warning ("eigs: ignoring imaginary part returned from user-supplied function");
-              warned_imaginary = true;
-            }
-
-          retval = ColumnVector (tmp(0).vector_value ());
-
-          if (error_state)
-            {
-              eigs_error = 1;
-              gripe_user_supplied_eval ("eigs");
-            }
-        }
-      else
-        {
-          eigs_error = 1;
-          gripe_user_supplied_eval ("eigs");
-        }
-    }
-
-  return retval;
-}
-
-ComplexColumnVector
-eigs_complex_func (const ComplexColumnVector &x, int &eigs_error)
-{
-  ComplexColumnVector retval;
-  octave_value_list args;
-  args(0) = x;
-
-  if (eigs_fcn)
-    {
-      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
-
-      if (error_state)
-        {
-          eigs_error = 1;
-          gripe_user_supplied_eval ("eigs");
-          return retval;
-        }
-
-      if (tmp.length () && tmp(0).is_defined ())
-        {
-          retval = ComplexColumnVector (tmp(0).complex_vector_value ());
-
-          if (error_state)
-            {
-              eigs_error = 1;
-              gripe_user_supplied_eval ("eigs");
-            }
-        }
-      else
-        {
-          eigs_error = 1;
-          gripe_user_supplied_eval ("eigs");
-        }
-    }
-
-  return retval;
-}
-
-DEFUN_DLD (eigs, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{d} =} eigs (@var{A})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})\n\
-Calculate a limited number of eigenvalues and eigenvectors of @var{A},\n\
-based on a selection criteria.  The number of eigenvalues and eigenvectors to\n\
-calculate is given by @var{k} and defaults to 6.\n\
-\n\
-By default, @code{eigs} solve the equation\n\
-@tex\n\
-$A \\nu = \\lambda \\nu$,\n\
-@end tex\n\
-@ifinfo\n\
-@code{A * v = lambda * v},\n\
-@end ifinfo\n\
-where\n\
-@tex\n\
-$\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\
-@end tex\n\
-@ifinfo\n\
-@code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\
-@end ifinfo\n\
-is the corresponding eigenvector.  If given the positive definite matrix\n\
-@var{B} then @code{eigs} solves the general eigenvalue equation\n\
-@tex\n\
-$A \\nu = \\lambda B \\nu$.\n\
-@end tex\n\
-@ifinfo\n\
-@code{A * v = lambda * B * v}.\n\
-@end ifinfo\n\
-\n\
-The argument @var{sigma} determines which eigenvalues are returned.\n\
-@var{sigma} can be either a scalar or a string.  When @var{sigma} is a\n\
-scalar, the @var{k} eigenvalues closest to @var{sigma} are returned.  If\n\
-@var{sigma} is a string, it must have one of the following values.\n\
-\n\
-@table @asis\n\
-@item \"lm\"\n\
-Largest Magnitude (default).\n\
-\n\
-@item \"sm\"\n\
-Smallest Magnitude.\n\
-\n\
-@item \"la\"\n\
-Largest Algebraic (valid only for real symmetric problems).\n\
-\n\
-@item \"sa\"\n\
-Smallest Algebraic (valid only for real symmetric problems).\n\
-\n\
-@item \"be\"\n\
-Both Ends, with one more from the high-end if @var{k} is odd (valid only for\n\
-real symmetric problems).\n\
-\n\
-@item \"lr\"\n\
-Largest Real part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"sr\"\n\
-Smallest Real part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"li\"\n\
-Largest Imaginary part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"si\"\n\
-Smallest Imaginary part (valid only for complex or unsymmetric problems).\n\
-@end table\n\
-\n\
-If @var{opts} is given, it is a structure defining possible options that\n\
-@code{eigs} should use.  The fields of the @var{opts} structure are:\n\
-\n\
-@table @code\n\
-@item issym\n\
-If @var{af} is given, then flags whether the function @var{af} defines a\n\
-symmetric problem.  It is ignored if @var{A} is given.  The default is false.\n\
-\n\
-@item isreal\n\
-If @var{af} is given, then flags whether the function @var{af} defines a\n\
-real problem.  It is ignored if @var{A} is given.  The default is true.\n\
-\n\
-@item tol\n\
-Defines the required convergence tolerance, calculated as\n\
-@code{tol * norm (A)}.  The default is @code{eps}.\n\
-\n\
-@item maxit\n\
-The maximum number of iterations.  The default is 300.\n\
-\n\
-@item p\n\
-The number of Lanzcos basis vectors to use.  More vectors will result in\n\
-faster convergence, but a greater use of memory.  The optimal value of\n\
-@code{p} is problem dependent and should be in the range @var{k} to @var{n}.\n\
-The default value is @code{2 * @var{k}}.\n\
-\n\
-@item v0\n\
-The starting vector for the algorithm.  An initial vector close to the\n\
-final vector will speed up convergence.  The default is for @sc{arpack}\n\
-to randomly generate a starting vector.  If specified, @code{v0} must be\n\
-an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}\n\
-\n\
-@item disp\n\
-The level of diagnostic printout (0|1|2).  If @code{disp} is 0 then\n\
-diagnostics are disabled.  The default value is 0.\n\
-\n\
-@item cholB\n\
-Flag if @code{chol (@var{B})} is passed rather than @var{B}.  The default is\n\
-false.\n\
-\n\
-@item permB\n\
-The permutation vector of the Cholesky@tie{}factorization of @var{B} if\n\
-@code{cholB} is true.  That is @code{chol (@var{B}(permB, permB))}.  The\n\
-default is @code{1:@var{n}}.\n\
-\n\
-@end table\n\
-\n\
-It is also possible to represent @var{A} by a function denoted @var{af}.\n\
-@var{af} must be followed by a scalar argument @var{n} defining the length\n\
-of the vector argument accepted by @var{af}.  @var{af} can be\n\
-a function handle, an inline function, or a string.  When @var{af} is a\n\
-string it holds the name of the function to use.\n\
-\n\
-@var{af} is a function of the form @code{y = af (x)}\n\
-where the required return value of @var{af} is determined by\n\
-the value of @var{sigma}.  The four possible forms are\n\
-\n\
-@table @code\n\
-@item A * x\n\
-if @var{sigma} is not given or is a string other than \"sm\".\n\
-\n\
-@item A \\ x\n\
-if @var{sigma} is 0 or \"sm\".\n\
-\n\
-@item (A - sigma * I) \\ x\n\
-for the standard eigenvalue problem, where @code{I} is the identity matrix of\n\
-the same size as @var{A}.\n\
-\n\
-@item (A - sigma * B) \\ x\n\
-for the general eigenvalue problem.\n\
-@end table\n\
-\n\
-The return arguments of @code{eigs} depend on the number of return arguments\n\
-requested.  With a single return argument, a vector @var{d} of length @var{k}\n\
-is returned containing the @var{k} eigenvalues that have been found.  With\n\
-two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns\n\
-are the @var{k} eigenvectors corresponding to the returned eigenvalues.  The\n\
-eigenvalues themselves are returned in @var{d} in the form of a\n\
-@var{n}-by-@var{k} matrix, where the elements on the diagonal are the\n\
-eigenvalues.\n\
-\n\
-Given a third return argument @var{flag}, @code{eigs} returns the status\n\
-of the convergence.  If @var{flag} is 0 then all eigenvalues have converged.\n\
-Any other value indicates a failure to converge.\n\
-\n\
-This function is based on the @sc{arpack} package, written by R. Lehoucq,\n\
-K. Maschhoff, D. Sorensen, and C. Yang.  For more information see\n\
-@url{http://www.caam.rice.edu/software/ARPACK/}.\n\
-\n\
-@seealso{eig, svds}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-#ifdef HAVE_ARPACK
-  int nargin = args.length ();
-  std::string fcn_name;
-  octave_idx_type n = 0;
-  octave_idx_type k = 6;
-  Complex sigma = 0.;
-  double sigmar, sigmai;
-  bool have_sigma = false;
-  std::string typ = "LM";
-  Matrix amm, bmm, bmt;
-  ComplexMatrix acm, bcm, bct;
-  SparseMatrix asmm, bsmm, bsmt;
-  SparseComplexMatrix ascm, bscm, bsct;
-  int b_arg = 0;
-  bool have_b = false;
-  bool have_a_fun = false;
-  bool a_is_complex = false;
-  bool b_is_complex = false;
-  bool symmetric = false;
-  bool sym_tested = false;
-  bool cholB = false;
-  bool a_is_sparse = false;
-  ColumnVector permB;
-  int arg_offset = 0;
-  double tol = DBL_EPSILON;
-  int maxit = 300;
-  int disp = 0;
-  octave_idx_type p = -1;
-  ColumnVector resid;
-  ComplexColumnVector cresid;
-  octave_idx_type info = 1;
-
-  warned_imaginary = false;
-
-  unwind_protect frame;
-
-  frame.protect_var (call_depth);
-  call_depth++;
-
-  if (call_depth > 1)
-    {
-      error ("eigs: invalid recursive call");
-      if (fcn_name.length ())
-        clear_function (fcn_name);
-      return retval;
-    }
-
-  if (nargin == 0)
-    print_usage ();
-  else if (args(0).is_function_handle () || args(0).is_inline_function ()
-           || args(0).is_string ())
-    {
-      if (args(0).is_string ())
-        {
-          std::string name = args(0).string_value ();
-          std::string fname = "function y = ";
-          fcn_name = unique_symbol_name ("__eigs_fcn_");
-          fname.append (fcn_name);
-          fname.append ("(x) y = ");
-          eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname,
-                                       "; endfunction");
-        }
-      else
-        eigs_fcn = args(0).function_value ();
-
-      if (!eigs_fcn)
-        {
-          error ("eigs: unknown function");
-          return retval;
-        }
-
-      if (nargin < 2)
-        {
-          error ("eigs: incorrect number of arguments");
-          return retval;
-        }
-      else
-        {
-          n = args(1).nint_value ();
-          arg_offset = 1;
-          have_a_fun = true;
-        }
-    }
-  else
-    {
-      if (args(0).is_complex_type ())
-        {
-          if (args(0).is_sparse_type ())
-            {
-              ascm = (args(0).sparse_complex_matrix_value ());
-              a_is_sparse = true;
-            }
-          else
-            acm = (args(0).complex_matrix_value ());
-          a_is_complex = true;
-          symmetric = false; // ARPACK doesn't special case complex symmetric
-          sym_tested = true;
-        }
-      else
-        {
-          if (args(0).is_sparse_type ())
-            {
-              asmm = (args(0).sparse_matrix_value ());
-              a_is_sparse = true;
-            }
-          else
-            {
-              amm = (args(0).matrix_value ());
-            }
-        }
-
-    }
-
-  // Note hold off reading B till later to avoid issues of double
-  // copies of the matrix if B is full/real while A is complex.
-  if (!error_state && nargin > 1 + arg_offset &&
-      !(args(1 + arg_offset).is_real_scalar ()))
-    {
-      if (args(1+arg_offset).is_complex_type ())
-        {
-          b_arg = 1+arg_offset;
-          have_b = true;
-          b_is_complex = true;
-          arg_offset++;
-        }
-      else
-        {
-          b_arg = 1+arg_offset;
-          have_b = true;
-          arg_offset++;
-        }
-    }
-
-  if (!error_state && nargin > (1+arg_offset))
-    k = args(1+arg_offset).nint_value ();
-
-  if (!error_state && nargin > (2+arg_offset))
-    {
-      if (args(2+arg_offset).is_string ())
-        {
-          typ = args(2+arg_offset).string_value ();
-
-          // Use STL function to convert to upper case
-          transform (typ.begin (), typ.end (), typ.begin (), toupper);
-
-          sigma = 0.;
-        }
-      else
-        {
-          sigma = args(2+arg_offset).complex_value ();
-
-          if (! error_state)
-            have_sigma = true;
-          else
-            {
-              error ("eigs: SIGMA must be a scalar or a string");
-              return retval;
-            }
-        }
-    }
-
-  sigmar = std::real (sigma);
-  sigmai = std::imag (sigma);
-
-  if (!error_state && nargin > (3+arg_offset))
-    {
-      if (args(3+arg_offset).is_map ())
-        {
-          octave_scalar_map map = args(3+arg_offset).scalar_map_value ();
-
-          if (! error_state)
-            {
-              octave_value tmp;
-
-              // issym is ignored for complex matrix inputs
-              tmp = map.getfield ("issym");
-              if (tmp.is_defined () && !sym_tested)
-                {
-                  symmetric = tmp.double_value () != 0.;
-                  sym_tested = true;
-                }
-
-              // isreal is ignored if A is not a function
-              tmp = map.getfield ("isreal");
-              if (tmp.is_defined () && have_a_fun)
-                a_is_complex = ! (tmp.double_value () != 0.);
-
-              tmp = map.getfield ("tol");
-              if (tmp.is_defined ())
-                tol = tmp.double_value ();
-
-              tmp = map.getfield ("maxit");
-              if (tmp.is_defined ())
-                maxit = tmp.nint_value ();
-
-              tmp = map.getfield ("p");
-              if (tmp.is_defined ())
-                p = tmp.nint_value ();
-
-              tmp = map.getfield ("v0");
-              if (tmp.is_defined ())
-                {
-                  if (a_is_complex || b_is_complex)
-                    cresid = ComplexColumnVector (tmp.complex_vector_value ());
-                  else
-                    resid = ColumnVector (tmp.vector_value ());
-                }
-
-              tmp = map.getfield ("disp");
-              if (tmp.is_defined ())
-                disp = tmp.nint_value ();
-
-              tmp = map.getfield ("cholB");
-              if (tmp.is_defined ())
-                cholB = tmp.double_value () != 0.;
-
-              tmp = map.getfield ("permB");
-              if (tmp.is_defined ())
-                permB = ColumnVector (tmp.vector_value ()) - 1.0;
-            }
-          else
-            {
-              error ("eigs: OPTS argument must be a scalar structure");
-              return retval;
-            }
-        }
-      else
-        {
-          error ("eigs: OPTS argument must be a structure");
-          return retval;
-        }
-    }
-
-  if (nargin > (4+arg_offset))
-    {
-      error ("eigs: incorrect number of arguments");
-      return retval;
-    }
-
-  // Test undeclared (no issym) matrix inputs for symmetry
-  if (!sym_tested && !have_a_fun)
-    {
-      if (a_is_sparse)
-        symmetric = asmm.is_symmetric ();
-      else
-        symmetric = amm.is_symmetric ();
-    }
-
-  if (have_b)
-    {
-      if (a_is_complex || b_is_complex)
-        {
-          if (a_is_sparse)
-            bscm = args(b_arg).sparse_complex_matrix_value ();
-          else
-            bcm = args(b_arg).complex_matrix_value ();
-        }
-      else
-        {
-          if (a_is_sparse)
-            bsmm = args(b_arg).sparse_matrix_value ();
-          else
-            bmm = args(b_arg).matrix_value ();
-        }
-    }
-
-  // Mode 1 for SM mode seems unstable for some reason.
-  // Use Mode 3 instead, with sigma = 0.
-  if (!error_state && !have_sigma && typ == "SM")
-    have_sigma = true;
-
-  if (!error_state)
-    {
-      octave_idx_type nconv;
-      if (a_is_complex || b_is_complex)
-        {
-          ComplexMatrix eig_vec;
-          ComplexColumnVector eig_val;
-
-
-          if (have_a_fun)
-            nconv = EigsComplexNonSymmetricFunc
-              (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val,
-               cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-          else if (have_sigma)
-            {
-              if (a_is_sparse)
-                nconv = EigsComplexNonSymmetricMatrixShift
-                  (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB,
-                   cresid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                   maxit);
-              else
-                nconv = EigsComplexNonSymmetricMatrixShift
-                  (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
-                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-            }
-          else
-            {
-              if (a_is_sparse)
-                nconv = EigsComplexNonSymmetricMatrix
-                  (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid,
-                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-              else
-                nconv = EigsComplexNonSymmetricMatrix
-                  (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
-                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-            }
-
-          if (nargout < 2)
-            retval(0) = eig_val;
-          else
-            {
-              retval(2) = double (info);
-              retval(1) = ComplexDiagMatrix (eig_val);
-              retval(0) = eig_vec;
-            }
-        }
-      else if (sigmai != 0.)
-        {
-          // Promote real problem to a complex one.
-          ComplexMatrix eig_vec;
-          ComplexColumnVector eig_val;
-
-          if (have_a_fun)
-            nconv = EigsComplexNonSymmetricFunc
-              (eigs_complex_func, n, typ,  sigma, k, p, info, eig_vec, eig_val,
-               cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-          else
-            {
-              if (a_is_sparse)
-                nconv = EigsComplexNonSymmetricMatrixShift
-                  (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec,
-                   eig_val, SparseComplexMatrix (bsmm), permB, cresid,
-                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-              else
-                nconv = EigsComplexNonSymmetricMatrixShift
-                  (ComplexMatrix (amm), sigma, k, p, info, eig_vec,
-                   eig_val, ComplexMatrix (bmm), permB, cresid,
-                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
-            }
-
-          if (nargout < 2)
-            retval(0) = eig_val;
-          else
-            {
-              retval(2) = double (info);
-              retval(1) = ComplexDiagMatrix (eig_val);
-              retval(0) = eig_vec;
-            }
-        }
-      else
-        {
-          if (symmetric)
-            {
-              Matrix eig_vec;
-              ColumnVector eig_val;
-
-              if (have_a_fun)
-                nconv = EigsRealSymmetricFunc
-                  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
-                   resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                   maxit);
-              else if (have_sigma)
-                {
-                  if (a_is_sparse)
-                    nconv = EigsRealSymmetricMatrixShift
-                      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                  else
-                    nconv = EigsRealSymmetricMatrixShift
-                      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                }
-              else
-                {
-                  if (a_is_sparse)
-                    nconv = EigsRealSymmetricMatrix
-                      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                  else
-                    nconv = EigsRealSymmetricMatrix
-                      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                }
-
-              if (nargout < 2)
-                retval(0) = eig_val;
-              else
-                {
-                  retval(2) = double (info);
-                  retval(1) = DiagMatrix (eig_val);
-                  retval(0) = eig_vec;
-                }
-            }
-          else
-            {
-              ComplexMatrix eig_vec;
-              ComplexColumnVector eig_val;
-
-              if (have_a_fun)
-                nconv = EigsRealNonSymmetricFunc
-                  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
-                   resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                   maxit);
-              else if (have_sigma)
-                {
-                  if (a_is_sparse)
-                    nconv = EigsRealNonSymmetricMatrixShift
-                      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                  else
-                    nconv = EigsRealNonSymmetricMatrixShift
-                      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                }
-              else
-                {
-                  if (a_is_sparse)
-                    nconv = EigsRealNonSymmetricMatrix
-                      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                  else
-                    nconv = EigsRealNonSymmetricMatrix
-                      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
-                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
-                       maxit);
-                }
-
-              if (nargout < 2)
-                retval(0) = eig_val;
-              else
-                {
-                  retval(2) = double (info);
-                  retval(1) = ComplexDiagMatrix (eig_val);
-                  retval(0) = eig_vec;
-                }
-            }
-        }
-
-      if (nconv <= 0)
-        warning ("eigs: None of the %d requested eigenvalues converged", k);
-      else if (nconv < k)
-        warning ("eigs: Only %d of the %d requested eigenvalues converged",
-                 nconv, k);
-    }
-
-  if (! fcn_name.empty ())
-    clear_function (fcn_name);
-#else
-  error ("eigs: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-/* #### SPARSE MATRIX VERSIONS #### */
-
-/*
-## Real positive definite tests, n must be even
-%!shared n, k, A, d0, d2
-%! n = 20;
-%! k = 4;
-%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]);
-%! d0 = eig (A);
-%! d2 = sort (d0);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); # initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (d1, d0(end:-1:(end-k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "la");
-%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sa");
-%! assert (d1, d2(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "be");
-%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1, "be");
-%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (d1, eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! AA = speye (10);
-%! fn = @(x) AA * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! assert (eigs (fn, 10, AA, 3, "lm", opts), [1; 1; 1], 10*eps);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "la");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sa");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "be");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Real unsymmetric tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A =  sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (d0));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Complex hermitian tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]);
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/* #### FULL MATRIX VERSIONS #### */
-
-/*
-## Real positive definite tests, n must be even
-%!shared n, k, A, d0, d2
-%! n = 20;
-%! k = 4;
-%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]));
-%! d0 = eig (A);
-%! d2 = sort (d0);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (d1, d0(end:-1:(end-k)),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "la");
-%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sa");
-%! assert (d1, d2(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "be");
-%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1, "be");
-%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (d1, eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "la");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sa");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "be");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Real unsymmetric tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A =  full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]));
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (d0));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Complex hermitian tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]));
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
--- a/src/DLD-FUNCTIONS/fftw.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-/*
-
-Copyright (C) 2006-2012 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <algorithm>
-
-#include "oct-fftw.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "ov.h"
-
-DEFUN_DLD (fftw, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{method} =} fftw (\"planner\")\n\
-@deftypefnx {Loadable Function} {} fftw (\"planner\", @var{method})\n\
-@deftypefnx {Loadable Function} {@var{wisdom} =} fftw (\"dwisdom\")\n\
-@deftypefnx {Loadable Function} {} fftw (\"dwisdom\", @var{wisdom})\n\
-\n\
-Manage @sc{fftw} wisdom data.  Wisdom data can be used to significantly\n\
-accelerate the calculation of the FFTs, but implies an initial cost\n\
-in its calculation.  When the @sc{fftw} libraries are initialized, they read\n\
-a system wide wisdom file (typically in @file{/etc/fftw/wisdom}), allowing\n\
-wisdom to be shared between applications other than Octave.  Alternatively,\n\
-the @code{fftw} function can be used to import wisdom.  For example,\n\
-\n\
-@example\n\
-@var{wisdom} = fftw (\"dwisdom\")\n\
-@end example\n\
-\n\
-@noindent\n\
-will save the existing wisdom used by Octave to the string @var{wisdom}.\n\
-This string can then be saved to a file and restored using the @code{save}\n\
-and @code{load} commands respectively.  This existing wisdom can be\n\
-reimported as follows\n\
-\n\
-@example\n\
-fftw (\"dwisdom\", @var{wisdom})\n\
-@end example\n\
-\n\
-If @var{wisdom} is an empty matrix, then the wisdom used is cleared.\n\
-\n\
-During the calculation of Fourier transforms further wisdom is generated.\n\
-The fashion in which this wisdom is generated is also controlled by\n\
-the @code{fftw} function.  There are five different manners in which the\n\
-wisdom can be treated:\n\
-\n\
-@table @asis\n\
-@item \"estimate\"\n\
-Specifies that no run-time measurement of the optimal means of\n\
-calculating a particular is performed, and a simple heuristic is used\n\
-to pick a (probably sub-optimal) plan.  The advantage of this method is\n\
-that there is little or no overhead in the generation of the plan, which\n\
-is appropriate for a Fourier transform that will be calculated once.\n\
-\n\
-@item \"measure\"\n\
-In this case a range of algorithms to perform the transform is considered\n\
-and the best is selected based on their execution time.\n\
-\n\
-@item \"patient\"\n\
-Similar to \"measure\", but a wider range of algorithms is considered.\n\
-\n\
-@item \"exhaustive\"\n\
-Like \"measure\", but all possible algorithms that may be used to\n\
-treat the transform are considered.\n\
-\n\
-@item \"hybrid\"\n\
-As run-time measurement of the algorithm can be expensive, this is a\n\
-compromise where \"measure\" is used for transforms up to the size of 8192\n\
-and beyond that the \"estimate\" method is used.\n\
-@end table\n\
-\n\
-The default method is \"estimate\".  The current method can\n\
-be queried with\n\
-\n\
-@example\n\
-@var{method} = fftw (\"planner\")\n\
-@end example\n\
-\n\
-@noindent\n\
-or set by using\n\
-\n\
-@example\n\
-fftw (\"planner\", @var{method})\n\
-@end example\n\
-\n\
-Note that calculated wisdom will be lost when restarting Octave.  However,\n\
-the wisdom data can be reloaded if it is saved to a file as described\n\
-above.  Saved wisdom files should not be used on different platforms since\n\
-they will not be efficient and the point of calculating the wisdom is lost.\n\
-@seealso{fft, ifft, fft2, ifft2, fftn, ifftn}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin < 1 || nargin > 2)
-    {
-      print_usage ();
-      return retval;
-    }
-
-#if defined (HAVE_FFTW)
-  if (args(0).is_string ())
-    {
-      std::string arg0 = args(0).string_value ();
-
-      if (!error_state)
-        {
-          // Use STL function to convert to lower case
-          std::transform (arg0.begin (), arg0.end (), arg0.begin (), tolower);
-
-          if (nargin == 2)
-            {
-              std::string arg1 = args(1).string_value ();
-              if (!error_state)
-                {
-                  if (arg0 == "planner")
-                    {
-                      std::transform (arg1.begin (), arg1.end (),
-                                      arg1.begin (), tolower);
-                      octave_fftw_planner::FftwMethod meth
-                        = octave_fftw_planner::UNKNOWN;
-                      octave_float_fftw_planner::FftwMethod methf
-                        = octave_float_fftw_planner::UNKNOWN;
-
-                      if (arg1 == "estimate")
-                        {
-                          meth = octave_fftw_planner::ESTIMATE;
-                          methf = octave_float_fftw_planner::ESTIMATE;
-                        }
-                      else if (arg1 == "measure")
-                        {
-                          meth = octave_fftw_planner::MEASURE;
-                          methf = octave_float_fftw_planner::MEASURE;
-                        }
-                      else if (arg1 == "patient")
-                        {
-                          meth = octave_fftw_planner::PATIENT;
-                          methf = octave_float_fftw_planner::PATIENT;
-                        }
-                      else if (arg1 == "exhaustive")
-                        {
-                          meth = octave_fftw_planner::EXHAUSTIVE;
-                          methf = octave_float_fftw_planner::EXHAUSTIVE;
-                        }
-                      else if (arg1 == "hybrid")
-                        {
-                          meth = octave_fftw_planner::HYBRID;
-                          methf = octave_float_fftw_planner::HYBRID;
-                        }
-                      else
-                        error ("unrecognized planner METHOD");
-
-                      if (!error_state)
-                        {
-                          meth = octave_fftw_planner::method (meth);
-                          octave_float_fftw_planner::method (methf);
-
-                          if (meth == octave_fftw_planner::MEASURE)
-                            retval = octave_value ("measure");
-                          else if (meth == octave_fftw_planner::PATIENT)
-                            retval = octave_value ("patient");
-                          else if (meth == octave_fftw_planner::EXHAUSTIVE)
-                            retval = octave_value ("exhaustive");
-                          else if (meth == octave_fftw_planner::HYBRID)
-                            retval = octave_value ("hybrid");
-                          else
-                            retval = octave_value ("estimate");
-                        }
-                    }
-                  else if (arg0 == "dwisdom")
-                    {
-                      char *str = fftw_export_wisdom_to_string ();
-
-                      if (arg1.length () < 1)
-                        fftw_forget_wisdom ();
-                      else if (! fftw_import_wisdom_from_string (arg1.c_str ()))
-                        error ("could not import supplied WISDOM");
-
-                      if (!error_state)
-                        retval = octave_value (std::string (str));
-
-                      free (str);
-                    }
-                  else if (arg0 == "swisdom")
-                    {
-                      char *str = fftwf_export_wisdom_to_string ();
-
-                      if (arg1.length () < 1)
-                        fftwf_forget_wisdom ();
-                      else if (! fftwf_import_wisdom_from_string (arg1.c_str ()))
-                        error ("could not import supplied WISDOM");
-
-                      if (!error_state)
-                        retval = octave_value (std::string (str));
-
-                      free (str);
-                    }
-                  else
-                    error ("unrecognized argument");
-                }
-            }
-          else
-            {
-              if (arg0 == "planner")
-                {
-                  octave_fftw_planner::FftwMethod meth =
-                    octave_fftw_planner::method ();
-
-                  if (meth == octave_fftw_planner::MEASURE)
-                    retval = octave_value ("measure");
-                  else if (meth == octave_fftw_planner::PATIENT)
-                    retval = octave_value ("patient");
-                  else if (meth == octave_fftw_planner::EXHAUSTIVE)
-                    retval = octave_value ("exhaustive");
-                  else if (meth == octave_fftw_planner::HYBRID)
-                    retval = octave_value ("hybrid");
-                  else
-                    retval = octave_value ("estimate");
-                }
-              else if (arg0 == "dwisdom")
-                {
-                  char *str = fftw_export_wisdom_to_string ();
-                  retval = octave_value (std::string (str));
-                  free (str);
-                }
-              else if (arg0 == "swisdom")
-                {
-                  char *str = fftwf_export_wisdom_to_string ();
-                  retval = octave_value (std::string (str));
-                  free (str);
-                }
-              else
-                error ("unrecognized argument");
-            }
-        }
-    }
-#else
-
-  warning ("fftw: this copy of Octave was not configured to use the FFTW3 planner");
-
-#endif
-
-  return retval;
-}
--- a/src/DLD-FUNCTIONS/module-files	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-# FILE|CPPFLAGS|LDFLAGS|LIBRARIES
-__delaunayn__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
-__dsearchn__.cc
-__fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
-__glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS)
-__init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
-__init_gnuplot__.cc
-__magick_read__.cc|$(MAGICK_CPPFLAGS)|$(MAGICK_LDFLAGS)|$(MAGICK_LIBS)
-__voronoi__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
-amd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-ccolamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-chol.cc
-colamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-convhulln.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
-dmperm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-eigs.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)
-fftw.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS)
-qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS)
-symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-tsearch.cc
-urlwrite.cc|$(CURL_CPPFLAGS)|$(CURL_LDFLAGS)|$(CURL_LIBS)
--- a/src/DLD-FUNCTIONS/oct-qhull.h	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
-
-Copyright (C) 2012 John W. Eaton
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#if !defined (octave_oct_qhull_h)
-#define octave_oct_qhull_h 1
-
-#include <cstdio>
-
-extern "C" {
-
-#if defined (HAVE_LIBQHULL_LIBQHULL_H)
-# include <libqhull/libqhull.h>
-# include <libqhull/qset.h>
-# include <libqhull/geom.h>
-# include <libqhull/poly.h>
-# include <libqhull/io.h>
-#elif defined (HAVE_QHULL_LIBQHULL_H) || defined (HAVE_QHULL_QHULL_H)
-# if defined (HAVE_QHULL_LIBQHULL_H)
-#  include <qhull/libqhull.h>
-# else
-#  include <qhull/qhull.h>
-# endif
-# include <qhull/qset.h>
-# include <qhull/geom.h>
-# include <qhull/poly.h>
-# include <qhull/io.h>
-#elif defined (HAVE_LIBQHULL_H) || defined (HAVE_QHULL_H)
-# if defined (HAVE_LIBQHULL_H)
-#  include <libqhull.h>
-# else
-#  include <qhull.h>
-# endif
-# include <qset.h>
-# include <geom.h>
-# include <poly.h>
-# include <io.h>
-#endif
-
-}
-
-#endif
--- a/src/DLD-FUNCTIONS/qr.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1598 +0,0 @@
-/*
-
-Copyright (C) 1996-2012 John W. Eaton
-Copyright (C) 2008-2009 Jaroslav Hajek
-Copyright (C) 2008-2009 VZLU Prague
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "CmplxQR.h"
-#include "CmplxQRP.h"
-#include "dbleQR.h"
-#include "dbleQRP.h"
-#include "fCmplxQR.h"
-#include "fCmplxQRP.h"
-#include "floatQR.h"
-#include "floatQRP.h"
-#include "SparseQR.h"
-#include "SparseCmplxQR.h"
-
-
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "utils.h"
-
-template <class MT>
-static octave_value
-get_qr_r (const base_qr<MT>& fact)
-{
-  MT R = fact.R ();
-  if (R.is_square () && fact.regular ())
-    return octave_value (R, MatrixType (MatrixType::Upper));
-  else
-    return R;
-}
-
-// [Q, R] = qr (X):      form Q unitary and R upper triangular such
-//                        that Q * R = X
-//
-// [Q, R] = qr (X, 0):    form the economy decomposition such that if X is
-//                        m by n then only the first n columns of Q are
-//                        computed.
-//
-// [Q, R, P] = qr (X):    form QRP factorization of X where
-//                        P is a permutation matrix such that
-//                        A * P = Q * R
-//
-// [Q, R, P] = qr (X, 0): form the economy decomposition with
-//                        permutation vector P such that Q * R = X (:, P)
-//
-// qr (X) alone returns the output of the LAPACK routine dgeqrf, such
-// that R = triu (qr (X))
-
-DEFUN_DLD (qr, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A})\n\
-@deftypefnx {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A}, '0')\n\
-@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B})\n\
-@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B}, '0')\n\
-@cindex QR factorization\n\
-Compute the QR@tie{}factorization of @var{A}, using standard @sc{lapack}\n\
-subroutines.  For example, given the matrix @code{@var{A} = [1, 2; 3, 4]},\n\
-\n\
-@example\n\
-[@var{Q}, @var{R}] = qr (@var{A})\n\
-@end example\n\
-\n\
-@noindent\n\
-returns\n\
-\n\
-@example\n\
-@group\n\
-@var{Q} =\n\
-\n\
-  -0.31623  -0.94868\n\
-  -0.94868   0.31623\n\
-\n\
-@var{R} =\n\
-\n\
-  -3.16228  -4.42719\n\
-   0.00000  -0.63246\n\
-@end group\n\
-@end example\n\
-\n\
-The @code{qr} factorization has applications in the solution of least\n\
-squares problems\n\
-@tex\n\
-$$\n\
-\\min_x \\left\\Vert A x - b \\right\\Vert_2\n\
-$$\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-min norm(A x - b)\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-for overdetermined systems of equations (i.e.,\n\
-@tex\n\
-$A$\n\
-@end tex\n\
-@ifnottex\n\
-@var{A}\n\
-@end ifnottex\n\
- is a tall, thin matrix).  The QR@tie{}factorization is\n\
-@tex\n\
-$QR = A$ where $Q$ is an orthogonal matrix and $R$ is upper triangular.\n\
-@end tex\n\
-@ifnottex\n\
-@code{@var{Q} * @var{Q} = @var{A}} where @var{Q} is an orthogonal matrix and\n\
-@var{R} is upper triangular.\n\
-@end ifnottex\n\
-\n\
-If given a second argument of '0', @code{qr} returns an economy-sized\n\
-QR@tie{}factorization, omitting zero rows of @var{R} and the corresponding\n\
-columns of @var{Q}.\n\
-\n\
-If the matrix @var{A} is full, the permuted QR@tie{}factorization\n\
-@code{[@var{Q}, @var{R}, @var{P}] = qr (@var{A})} forms the\n\
-QR@tie{}factorization such that the diagonal entries of @var{R} are\n\
-decreasing in magnitude order.  For example, given the matrix @code{a = [1,\n\
-2; 3, 4]},\n\
-\n\
-@example\n\
-[@var{Q}, @var{R}, @var{P}] = qr (@var{A})\n\
-@end example\n\
-\n\
-@noindent\n\
-returns\n\
-\n\
-@example\n\
-@group\n\
-@var{Q} =\n\
-\n\
-  -0.44721  -0.89443\n\
-  -0.89443   0.44721\n\
-\n\
-@var{R} =\n\
-\n\
-  -4.47214  -3.13050\n\
-   0.00000   0.44721\n\
-\n\
-@var{P} =\n\
-\n\
-   0  1\n\
-   1  0\n\
-@end group\n\
-@end example\n\
-\n\
-The permuted @code{qr} factorization @code{[@var{Q}, @var{R}, @var{P}] = qr\n\
-(@var{A})} factorization allows the construction of an orthogonal basis of\n\
-@code{span (A)}.\n\
-\n\
-If the matrix @var{A} is sparse, then compute the sparse\n\
-QR@tie{}factorization of @var{A}, using @sc{CSparse}.  As the matrix @var{Q}\n\
-is in general a full matrix, this function returns the @var{Q}-less\n\
-factorization @var{R} of @var{A}, such that @code{@var{R} = chol (@var{A}' *\n\
-@var{A})}.\n\
-\n\
-If the final argument is the scalar @code{0} and the number of rows is\n\
-larger than the number of columns, then an economy factorization is\n\
-returned.  That is @var{R} will have only @code{size (@var{A},1)} rows.\n\
-\n\
-If an additional matrix @var{B} is supplied, then @code{qr} returns\n\
-@var{C}, where @code{@var{C} = @var{Q}' * @var{B}}.  This allows the\n\
-least squares approximation of @code{@var{A} \\ @var{B}} to be calculated\n\
-as\n\
-\n\
-@example\n\
-@group\n\
-[@var{C}, @var{R}] = qr (@var{A}, @var{B})\n\
-x = @var{R} \\ @var{C}\n\
-@end group\n\
-@end example\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin < 1 || nargin > (args(0).is_sparse_type () ? 3 : 2))
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value arg = args(0);
-
-  int arg_is_empty = empty_arg ("qr", arg.rows (), arg.columns ());
-
-  if (arg_is_empty < 0)
-    return retval;
-
-  if (arg.is_sparse_type ())
-    {
-      bool economy = false;
-      bool is_cmplx = false;
-      int have_b = 0;
-
-      if (arg.is_complex_type ())
-        is_cmplx = true;
-      if (nargin > 1)
-        {
-          have_b = 1;
-          if (args(nargin-1).is_scalar_type ())
-            {
-              int val = args(nargin-1).int_value ();
-              if (val == 0)
-                {
-                  economy = true;
-                  have_b = (nargin > 2 ? 2 : 0);
-                }
-            }
-          if (have_b > 0 && args(have_b).is_complex_type ())
-            is_cmplx = true;
-        }
-
-      if (!error_state)
-        {
-          if (have_b && nargout < 2)
-            error ("qr: incorrect number of output arguments");
-          else if (is_cmplx)
-            {
-              SparseComplexQR q (arg.sparse_complex_matrix_value ());
-              if (!error_state)
-                {
-                  if (have_b > 0)
-                    {
-                      retval(1) = q.R (economy);
-                      retval(0) = q.C (args(have_b).complex_matrix_value ());
-                      if (arg.rows () < arg.columns ())
-                        warning ("qr: non minimum norm solution for under-determined problem");
-                    }
-                  else if (nargout > 1)
-                    {
-                      retval(1) = q.R (economy);
-                      retval(0) = q.Q ();
-                    }
-                  else
-                    retval(0) = q.R (economy);
-                }
-            }
-          else
-            {
-              SparseQR q (arg.sparse_matrix_value ());
-              if (!error_state)
-                {
-                  if (have_b > 0)
-                    {
-                      retval(1) = q.R (economy);
-                      retval(0) = q.C (args(have_b).matrix_value ());
-                      if (args(0).rows () < args(0).columns ())
-                        warning ("qr: non minimum norm solution for under-determined problem");
-                    }
-                  else if (nargout > 1)
-                    {
-                      retval(1) = q.R (economy);
-                      retval(0) = q.Q ();
-                    }
-                  else
-                    retval(0) = q.R (economy);
-                }
-            }
-        }
-    }
-  else
-    {
-      QR::type type = (nargout == 0 || nargout == 1) ? QR::raw
-        : (nargin == 2 ? QR::economy : QR::std);
-
-      if (arg.is_single_type ())
-        {
-          if (arg.is_real_type ())
-            {
-              FloatMatrix m = arg.float_matrix_value ();
-
-              if (! error_state)
-                {
-                  switch (nargout)
-                    {
-                    case 0:
-                    case 1:
-                      {
-                        FloatQR fact (m, type);
-                        retval(0) = fact.R ();
-                      }
-                      break;
-
-                    case 2:
-                      {
-                        FloatQR fact (m, type);
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-
-                    default:
-                      {
-                        FloatQRP fact (m, type);
-                        if (type == QR::economy)
-                          retval(2) = fact.Pvec ();
-                        else
-                          retval(2) = fact.P ();
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-                    }
-                }
-            }
-          else if (arg.is_complex_type ())
-            {
-              FloatComplexMatrix m = arg.float_complex_matrix_value ();
-
-              if (! error_state)
-                {
-                  switch (nargout)
-                    {
-                    case 0:
-                    case 1:
-                      {
-                        FloatComplexQR fact (m, type);
-                        retval(0) = fact.R ();
-                      }
-                      break;
-
-                    case 2:
-                      {
-                        FloatComplexQR fact (m, type);
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-
-                    default:
-                      {
-                        FloatComplexQRP fact (m, type);
-                        if (type == QR::economy)
-                          retval(2) = fact.Pvec ();
-                        else
-                          retval(2) = fact.P ();
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-                    }
-                }
-            }
-        }
-      else
-        {
-          if (arg.is_real_type ())
-            {
-              Matrix m = arg.matrix_value ();
-
-              if (! error_state)
-                {
-                  switch (nargout)
-                    {
-                    case 0:
-                    case 1:
-                      {
-                        QR fact (m, type);
-                        retval(0) = fact.R ();
-                      }
-                      break;
-
-                    case 2:
-                      {
-                        QR fact (m, type);
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-
-                    default:
-                      {
-                        QRP fact (m, type);
-                        if (type == QR::economy)
-                          retval(2) = fact.Pvec ();
-                        else
-                          retval(2) = fact.P ();
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-                    }
-                }
-            }
-          else if (arg.is_complex_type ())
-            {
-              ComplexMatrix m = arg.complex_matrix_value ();
-
-              if (! error_state)
-                {
-                  switch (nargout)
-                    {
-                    case 0:
-                    case 1:
-                      {
-                        ComplexQR fact (m, type);
-                        retval(0) = fact.R ();
-                      }
-                      break;
-
-                    case 2:
-                      {
-                        ComplexQR fact (m, type);
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-
-                    default:
-                      {
-                        ComplexQRP fact (m, type);
-                        if (type == QR::economy)
-                          retval(2) = fact.Pvec ();
-                        else
-                          retval(2) = fact.P ();
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                      break;
-                    }
-                }
-            }
-          else
-            gripe_wrong_type_arg ("qr", arg);
-        }
-    }
-
-  return retval;
-}
-
-/*
-%!test
-%! a = [0, 2, 1; 2, 1, 2];
-%!
-%! [q, r] = qr (a);
-%! [qe, re] = qr (a, 0);
-%!
-%! assert (q * r, a, sqrt (eps));
-%! assert (qe * re, a, sqrt (eps));
-
-%!test
-%! a = [0, 2, 1; 2, 1, 2];
-%!
-%! [q, r, p] = qr (a);  # FIXME: not giving right dimensions. 
-%! [qe, re, pe] = qr (a, 0);
-%!
-%! assert (q * r, a * p, sqrt (eps));
-%! assert (qe * re, a(:, pe), sqrt (eps));
-
-%!test
-%! a = [0, 2; 2, 1; 1, 2];
-%!
-%! [q, r] = qr (a);
-%! [qe, re] = qr (a, 0);
-%!
-%! assert (q * r, a, sqrt (eps));
-%! assert (qe * re, a, sqrt (eps));
-
-%!test
-%! a = [0, 2; 2, 1; 1, 2];
-%!
-%! [q, r, p] = qr (a);
-%! [qe, re, pe] = qr (a, 0);
-%!
-%! assert (q * r, a * p, sqrt (eps));
-%! assert (qe * re, a(:, pe), sqrt (eps));
-
-%!error qr ()
-%!error qr ([1, 2; 3, 4], 0, 2)
-
-%!function retval = __testqr (q, r, a, p)
-%!  tol = 100*eps (class (q));
-%!  retval = 0;
-%!  if (nargin == 3)
-%!    n1 = norm (q*r - a);
-%!    n2 = norm (q'*q - eye (columns (q)));
-%!    retval = (n1 < tol && n2 < tol);
-%!  else
-%!    n1 = norm (q'*q - eye (columns (q)));
-%!    retval = (n1 < tol);
-%!    if (isvector (p))
-%!      n2 = norm (q*r - a(:,p));
-%!      retval = (retval && n2 < tol);
-%!    else
-%!      n2 = norm (q*r - a*p);
-%!      retval = (retval && n2 < tol);
-%!    endif
-%!  endif
-%!endfunction
-
-%!test
-%! t = ones (24, 1);
-%! j = 1;
-%!
-%! if (false)  # eliminate big matrix tests
-%!   a = rand (5000, 20);
-%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%!
-%!   a = a+1i*eps;
-%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%! endif
-%!
-%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
-%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = a+1i*eps;
-%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
-%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = a+1i*eps;
-%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = [ 611   196  -192   407    -8   -52   -49    29
-%!       196   899   113  -192   -71   -43    -8   -44
-%!      -192   113   899   196    61    49     8    52
-%!       407  -192   196   611     8    44    59   -23
-%!        -8   -71    61     8   411  -599   208   208
-%!       -52   -43    49    44  -599   411   208   208
-%!       -49    -8     8    59   208   208    99  -911
-%!        29   -44    52   -23   208   208  -911    99 ];
-%! [q,r] = qr (a);
-%!
-%! assert (all (t) && norm (q*r - a) < 5000*eps);
-
-%!test
-%! a = single ([0, 2, 1; 2, 1, 2]);
-%!
-%! [q, r] = qr (a);
-%! [qe, re] = qr (a, 0);
-%!
-%! assert (q * r, a, sqrt (eps ("single")));
-%! assert (qe * re, a, sqrt (eps ("single")));
-
-%!test
-%! a = single ([0, 2, 1; 2, 1, 2]);
-%!
-%! [q, r, p] = qr (a);  # FIXME: not giving right dimensions.
-%! [qe, re, pe] = qr (a, 0);
-%!
-%! assert (q * r, a * p, sqrt (eps ("single")));
-%! assert (qe * re, a(:, pe), sqrt (eps ("single")));
-
-%!test
-%! a = single ([0, 2; 2, 1; 1, 2]);
-%!
-%! [q, r] = qr (a);
-%! [qe, re] = qr (a, 0);
-%!
-%! assert (q * r, a, sqrt (eps ("single")));
-%! assert (qe * re, a, sqrt (eps ("single")));
-
-%!test
-%! a = single ([0, 2; 2, 1; 1, 2]);
-%!
-%! [q, r, p] = qr (a);
-%! [qe, re, pe] = qr (a, 0);
-%!
-%! assert (q * r, a * p, sqrt (eps ("single")));
-%! assert (qe * re, a(:, pe), sqrt (eps ("single")));
-
-%!error qr ()
-%!error qr ([1, 2; 3, 4], 0, 2)
-
-%!test
-%! t = ones (24, 1);
-%! j = 1;
-%!
-%! if (false)  # eliminate big matrix tests
-%!   a = rand (5000,20);
-%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%!
-%!   a = a+1i*eps ("single");
-%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%! endif
-%!
-%! a = [ ones(1,15); sqrt(eps("single"))*eye(15) ];
-%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = a+1i*eps ("single");
-%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = [ ones(1,15); sqrt(eps("single"))*eye(15) ];
-%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
-%!
-%! a = a+1i*eps ("single");
-%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
-%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
-%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
-%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a',p);
-%!
-%! a = [ 611   196  -192   407    -8   -52   -49    29
-%!       196   899   113  -192   -71   -43    -8   -44
-%!      -192   113   899   196    61    49     8    52
-%!       407  -192   196   611     8    44    59   -23
-%!        -8   -71    61     8   411  -599   208   208
-%!       -52   -43    49    44  -599   411   208   208
-%!       -49    -8     8    59   208   208    99  -911
-%!        29   -44    52   -23   208   208  -911    99 ];
-%! [q,r] = qr (a);
-%!
-%! assert (all (t) && norm (q*r-a) < 5000*eps ("single"));
-
-## The deactivated tests below can't be tested till rectangular back-subs is
-## implemented for sparse matrices.
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = sprandn (n,n,d) + speye (n,n);
-%! r = qr (a);
-%! assert (r'*r, a'*a, 1e-10)
-
-%!testif HAVE_COLAMD
-%! n = 20;  d = 0.2;
-%! a = sprandn (n,n,d) + speye (n,n);
-%! q = symamd (a);
-%! a = a(q,q);
-%! r = qr (a);
-%! assert (r'*r, a'*a, 1e-10)
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = sprandn (n,n,d) + speye (n,n);
-%! [c,r] = qr (a, ones (n,1));
-%! assert (r\c, full (a)\ones (n,1), 10e-10)
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = sprandn (n,n,d) + speye (n,n);
-%! b = randn (n,2);
-%! [c,r] = qr (a, b);
-%! assert (r\c, full (a)\b, 10e-10)
-
-%% Test under-determined systems!!
-%!#testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = sprandn (n,n+1,d) + speye (n,n+1);
-%! b = randn (n,2);
-%! [c,r] = qr (a, b);
-%! assert (r\c, full (a)\b, 10e-10)
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = 1i*sprandn (n,n,d) + speye (n,n);
-%! r = qr (a);
-%! assert (r'*r,a'*a,1e-10)
-
-%!testif HAVE_COLAMD
-%! n = 20;  d = 0.2;
-%! a = 1i*sprandn (n,n,d) + speye (n,n);
-%! q = symamd (a);
-%! a = a(q,q);
-%! r = qr (a);
-%! assert (r'*r, a'*a, 1e-10)
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = 1i*sprandn (n,n,d) + speye (n,n);
-%! [c,r] = qr (a, ones (n,1));
-%! assert (r\c, full (a)\ones (n,1), 10e-10)
-
-%!testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = 1i*sprandn (n,n,d) + speye (n,n);
-%! b = randn (n,2);
-%! [c,r] = qr (a, b);
-%! assert (r\c, full (a)\b, 10e-10)
-
-%% Test under-determined systems!!
-%!#testif HAVE_CXSPARSE
-%! n = 20;  d = 0.2;
-%! a = 1i*sprandn (n,n+1,d) + speye (n,n+1);
-%! b = randn (n,2);
-%! [c,r] = qr (a, b);
-%! assert (r\c, full (a)\b, 10e-10)
-
-%!error qr (sprandn (10,10,0.2), ones (10,1))
-*/
-
-static
-bool check_qr_dims (const octave_value& q, const octave_value& r,
-                    bool allow_ecf = false)
-{
-  octave_idx_type m = q.rows (), k = r.rows (), n = r.columns ();
-  return ((q.ndims () == 2 && r.ndims () == 2 && k == q.columns ())
-            && (m == k || (allow_ecf && k == n && k < m)));
-}
-
-static
-bool check_index (const octave_value& i, bool vector_allowed = false)
-{
-  return ((i.is_real_type () || i.is_integer_type ())
-          && (i.is_scalar_type () || vector_allowed));
-}
-
-DEFUN_DLD (qrupdate, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrupdate (@var{Q}, @var{R}, @var{u}, @var{v})\n\
-Given a QR@tie{}factorization of a real or complex matrix\n\
-@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
-@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization\n\
-of @w{@var{A} + @var{u}*@var{v}'}, where @var{u} and @var{v} are\n\
-column vectors (rank-1 update) or matrices with equal number of columns\n\
-(rank-k update).  Notice that the latter case is done as a sequence of rank-1\n\
-updates; thus, for k large enough, it will be both faster and more accurate\n\
-to recompute the factorization from scratch.\n\
-\n\
-The QR@tie{}factorization supplied may be either full\n\
-(Q is square) or economized (R is square).\n\
-\n\
-@seealso{qr, qrinsert, qrdelete}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin != 4)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argq = args(0);
-  octave_value argr = args(1);
-  octave_value argu = args(2);
-  octave_value argv = args(3);
-
-  if (argq.is_numeric_type () && argr.is_numeric_type ()
-      && argu.is_numeric_type () && argv.is_numeric_type ())
-    {
-      if (check_qr_dims (argq, argr, true))
-        {
-          if (argq.is_real_type ()
-              && argr.is_real_type ()
-              && argu.is_real_type ()
-              && argv.is_real_type ())
-            {
-              // all real case
-              if (argq.is_single_type ()
-                  || argr.is_single_type ()
-                  || argu.is_single_type ()
-                  || argv.is_single_type ())
-                {
-                  FloatMatrix Q = argq.float_matrix_value ();
-                  FloatMatrix R = argr.float_matrix_value ();
-                  FloatMatrix u = argu.float_matrix_value ();
-                  FloatMatrix v = argv.float_matrix_value ();
-
-                  FloatQR fact (Q, R);
-                  fact.update (u, v);
-
-                  retval(1) = get_qr_r (fact);
-                  retval(0) = fact.Q ();
-                }
-              else
-                {
-                  Matrix Q = argq.matrix_value ();
-                  Matrix R = argr.matrix_value ();
-                  Matrix u = argu.matrix_value ();
-                  Matrix v = argv.matrix_value ();
-
-                  QR fact (Q, R);
-                  fact.update (u, v);
-
-                  retval(1) = get_qr_r (fact);
-                  retval(0) = fact.Q ();
-                }
-            }
-          else
-            {
-              // complex case
-              if (argq.is_single_type ()
-                  || argr.is_single_type ()
-                  || argu.is_single_type ()
-                  || argv.is_single_type ())
-                {
-                  FloatComplexMatrix Q = argq.float_complex_matrix_value ();
-                  FloatComplexMatrix R = argr.float_complex_matrix_value ();
-                  FloatComplexMatrix u = argu.float_complex_matrix_value ();
-                  FloatComplexMatrix v = argv.float_complex_matrix_value ();
-
-                  FloatComplexQR fact (Q, R);
-                  fact.update (u, v);
-
-                  retval(1) = get_qr_r (fact);
-                  retval(0) = fact.Q ();
-                }
-              else
-                {
-                  ComplexMatrix Q = argq.complex_matrix_value ();
-                  ComplexMatrix R = argr.complex_matrix_value ();
-                  ComplexMatrix u = argu.complex_matrix_value ();
-                  ComplexMatrix v = argv.complex_matrix_value ();
-
-                  ComplexQR fact (Q, R);
-                  fact.update (u, v);
-
-                  retval(1) = get_qr_r (fact);
-                  retval(0) = fact.Q ();
-                }
-            }
-        }
-      else
-        error ("qrupdate: Q and R dimensions don't match");
-    }
-  else
-    error ("qrupdate: Q, R, U, and V must be numeric");
-
-  return retval;
-}
-
-/*
-%!shared A, u, v, Ac, uc, vc
-%! A = [0.091364  0.613038  0.999083;
-%!      0.594638  0.425302  0.603537;
-%!      0.383594  0.291238  0.085574;
-%!      0.265712  0.268003  0.238409;
-%!      0.669966  0.743851  0.445057 ];
-%!
-%! u = [0.85082;
-%!      0.76426;
-%!      0.42883;
-%!      0.53010;
-%!      0.80683 ];
-%!
-%! v = [0.98810;
-%!      0.24295;
-%!      0.43167 ];
-%!
-%! Ac = [0.620405 + 0.956953i  0.480013 + 0.048806i  0.402627 + 0.338171i;
-%!      0.589077 + 0.658457i  0.013205 + 0.279323i  0.229284 + 0.721929i;
-%!      0.092758 + 0.345687i  0.928679 + 0.241052i  0.764536 + 0.832406i;
-%!      0.912098 + 0.721024i  0.049018 + 0.269452i  0.730029 + 0.796517i;
-%!      0.112849 + 0.603871i  0.486352 + 0.142337i  0.355646 + 0.151496i ];
-%!
-%! uc = [0.20351 + 0.05401i;
-%!      0.13141 + 0.43708i;
-%!      0.29808 + 0.08789i;
-%!      0.69821 + 0.38844i;
-%!      0.74871 + 0.25821i ];
-%!
-%! vc = [0.85839 + 0.29468i;
-%!      0.20820 + 0.93090i;
-%!      0.86184 + 0.34689i ];
-%!
-
-%!test
-%! [Q,R] = qr (A);
-%! [Q,R] = qrupdate (Q, R, u, v);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R)-R), Inf) == 0);
-%! assert (norm (vec (Q*R - A - u*v'), Inf) < norm (A)*1e1*eps);
-%!
-%!test
-%! [Q,R] = qr (Ac);
-%! [Q,R] = qrupdate (Q, R, uc, vc);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R)-R), Inf) == 0);
-%! assert (norm (vec (Q*R - Ac - uc*vc'), Inf) < norm (Ac)*1e1*eps);
-
-%!test
-%! [Q,R] = qr (single (A));
-%! [Q,R] = qrupdate (Q, R, single (u), single (v));
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R)-R), Inf) == 0);
-%! assert (norm (vec (Q*R - single (A) - single (u)*single (v)'), Inf) < norm (single (A))*1e1*eps ("single"));
-%!
-%!test
-%! [Q,R] = qr (single (Ac));
-%! [Q,R] = qrupdate (Q, R, single (uc), single (vc));
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R)-R), Inf) == 0);
-%! assert (norm (vec (Q*R - single (Ac) - single (uc)*single (vc)'), Inf) < norm (single (Ac))*1e1*eps ("single"));
-*/
-
-DEFUN_DLD (qrinsert, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrinsert (@var{Q}, @var{R}, @var{j}, @var{x}, @var{orient})\n\
-Given a QR@tie{}factorization of a real or complex matrix\n\
-@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
-@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
-@w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be\n\
-inserted into @var{A} (if @var{orient} is @code{\"col\"}), or the\n\
-QR@tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}\n\
-is a row vector to be inserted into @var{A} (if @var{orient} is\n\
-@code{\"row\"}).\n\
-\n\
-The default value of @var{orient} is @code{\"col\"}.\n\
-If @var{orient} is @code{\"col\"},\n\
-@var{u} may be a matrix and @var{j} an index vector\n\
-resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
-@w{B(:,@var{j})} gives @var{u} and @w{B(:,@var{j}) = []} gives @var{A}.\n\
-Notice that the latter case is done as a sequence of k insertions;\n\
-thus, for k large enough, it will be both faster and more accurate to\n\
-recompute the factorization from scratch.\n\
-\n\
-If @var{orient} is @code{\"col\"},\n\
-the QR@tie{}factorization supplied may be either full\n\
-(Q is square) or economized (R is square).\n\
-\n\
-If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
-@seealso{qr, qrupdate, qrdelete}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin < 4 || nargin > 5)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argq = args(0);
-  octave_value argr = args(1);
-  octave_value argj = args(2);
-  octave_value argx = args(3);
-
-  if (argq.is_numeric_type () && argr.is_numeric_type ()
-      && argx.is_numeric_type ()
-      && (nargin < 5 || args(4).is_string ()))
-    {
-      std::string orient = (nargin < 5) ? "col" : args(4).string_value ();
-
-      bool col = orient == "col";
-
-      if (col || orient == "row")
-        if (check_qr_dims (argq, argr, col)
-            && (col || argx.rows () == 1))
-          {
-            if (check_index (argj, col))
-              {
-                MArray<octave_idx_type> j
-                  = argj.octave_idx_type_vector_value ();
-
-                octave_idx_type one = 1;
-
-                if (argq.is_real_type ()
-                    && argr.is_real_type ()
-                    && argx.is_real_type ())
-                  {
-                    // real case
-                    if (argq.is_single_type ()
-                        || argr.is_single_type ()
-                        || argx.is_single_type ())
-                      {
-                        FloatMatrix Q = argq.float_matrix_value ();
-                        FloatMatrix R = argr.float_matrix_value ();
-                        FloatMatrix x = argx.float_matrix_value ();
-
-                        FloatQR fact (Q, R);
-
-                        if (col)
-                          fact.insert_col (x, j-one);
-                        else
-                          fact.insert_row (x.row (0), j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-
-                      }
-                    else
-                      {
-                        Matrix Q = argq.matrix_value ();
-                        Matrix R = argr.matrix_value ();
-                        Matrix x = argx.matrix_value ();
-
-                        QR fact (Q, R);
-
-                        if (col)
-                          fact.insert_col (x, j-one);
-                        else
-                          fact.insert_row (x.row (0), j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-
-                      }
-                  }
-                else
-                  {
-                    // complex case
-                    if (argq.is_single_type ()
-                        || argr.is_single_type ()
-                        || argx.is_single_type ())
-                      {
-                        FloatComplexMatrix Q = argq.float_complex_matrix_value ();
-                        FloatComplexMatrix R = argr.float_complex_matrix_value ();
-                        FloatComplexMatrix x = argx.float_complex_matrix_value ();
-
-                        FloatComplexQR fact (Q, R);
-
-                        if (col)
-                          fact.insert_col (x, j-one);
-                        else
-                          fact.insert_row (x.row (0), j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                    else
-                      {
-                        ComplexMatrix Q = argq.complex_matrix_value ();
-                        ComplexMatrix R = argr.complex_matrix_value ();
-                        ComplexMatrix x = argx.complex_matrix_value ();
-
-                        ComplexQR fact (Q, R);
-
-                        if (col)
-                          fact.insert_col (x, j-one);
-                        else
-                          fact.insert_row (x.row (0), j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                  }
-
-              }
-            else
-              error ("qrinsert: invalid index J");
-          }
-        else
-          error ("qrinsert: dimension mismatch");
-
-      else
-        error ("qrinsert: ORIENT must be \"col\" or \"row\"");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!test
-%! [Q,R] = qr (A);
-%! [Q,R] = qrinsert (Q, R, 3, u);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [A(:,1:2) u A(:,3)]), Inf) < norm (A)*1e1*eps);
-%!test
-%! [Q,R] = qr (Ac);
-%! [Q,R] = qrinsert (Q, R, 3, uc);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [Ac(:,1:2) uc Ac(:,3)]), Inf) < norm (Ac)*1e1*eps);
-%!test
-%! x = [0.85082  0.76426  0.42883 ];
-%!
-%! [Q,R] = qr (A);
-%! [Q,R] = qrinsert (Q, R, 3, x, "row");
-%! assert (norm (vec (Q'*Q - eye (6)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [A(1:2,:);x;A(3:5,:)]), Inf) < norm (A)*1e1*eps);
-%!test
-%! x = [0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ];
-%!
-%! [Q,R] = qr (Ac);
-%! [Q,R] = qrinsert (Q, R, 3, x, "row");
-%! assert (norm (vec (Q'*Q - eye (6)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [Ac(1:2,:);x;Ac(3:5,:)]), Inf) < norm (Ac)*1e1*eps);
-
-%!test
-%! [Q,R] = qr (single (A));
-%! [Q,R] = qrinsert (Q, R, 3, single (u));
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - single ([A(:,1:2) u A(:,3)])), Inf) < norm (single (A))*1e1*eps ("single"));
-%!test
-%! [Q,R] = qr (single (Ac));
-%! [Q,R] = qrinsert (Q, R, 3, single (uc));
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - single ([Ac(:,1:2) uc Ac(:,3)])), Inf) < norm (single (Ac))*1e1*eps ("single"));
-%!test
-%! x = single ([0.85082  0.76426  0.42883 ]);
-%!
-%! [Q,R] = qr (single (A));
-%! [Q,R] = qrinsert (Q, R, 3, x, "row");
-%! assert (norm (vec (Q'*Q - eye (6,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - single ([A(1:2,:);x;A(3:5,:)])), Inf) < norm (single (A))*1e1*eps ("single"));
-%!test
-%! x = single ([0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ]);
-%!
-%! [Q,R] = qr (single (Ac));
-%! [Q,R] = qrinsert (Q, R, 3, x, "row");
-%! assert (norm (vec (Q'*Q - eye (6,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - single ([Ac(1:2,:);x;Ac(3:5,:)])), Inf) < norm (single (Ac))*1e1*eps ("single"));
-*/
-
-DEFUN_DLD (qrdelete, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrdelete (@var{Q}, @var{R}, @var{j}, @var{orient})\n\
-Given a QR@tie{}factorization of a real or complex matrix\n\
-@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
-@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
-@w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted\n\
-(if @var{orient} is \"col\"), or the QR@tie{}factorization of\n\
-@w{[A(1:j-1,:);A(j+1:n,:)]}, i.e., @var{A} with one row deleted (if\n\
-@var{orient} is \"row\").\n\
-\n\
-The default value of @var{orient} is \"col\".\n\
-\n\
-If @var{orient} is @code{\"col\"},\n\
-@var{j} may be an index vector\n\
-resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
-@w{A(:,@var{j}) = []} gives @var{B}.\n\
-Notice that the latter case is done as a sequence of k deletions;\n\
-thus, for k large enough, it will be both faster and more accurate to\n\
-recompute the factorization from scratch.\n\
-\n\
-If @var{orient} is @code{\"col\"},\n\
-the QR@tie{}factorization supplied may be either full\n\
-(Q is square) or economized (R is square).\n\
-\n\
-If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
-@seealso{qr, qrinsert, qrupdate}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin < 3 || nargin > 4)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argq = args(0);
-  octave_value argr = args(1);
-  octave_value argj = args(2);
-
-  if (argq.is_numeric_type () && argr.is_numeric_type ()
-      && (nargin < 4 || args(3).is_string ()))
-    {
-      std::string orient = (nargin < 4) ? "col" : args(3).string_value ();
-
-      bool col = orient == "col";
-
-      if (col || orient == "row")
-        if (check_qr_dims (argq, argr, col))
-          {
-            if (check_index (argj, col))
-              {
-                MArray<octave_idx_type> j
-                  = argj.octave_idx_type_vector_value ();
-
-                octave_idx_type one = 1;
-
-                if (argq.is_real_type ()
-                    && argr.is_real_type ())
-                  {
-                    // real case
-                    if (argq.is_single_type ()
-                        || argr.is_single_type ())
-                      {
-                        FloatMatrix Q = argq.float_matrix_value ();
-                        FloatMatrix R = argr.float_matrix_value ();
-
-                        FloatQR fact (Q, R);
-
-                        if (col)
-                          fact.delete_col (j-one);
-                        else
-                          fact.delete_row (j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                    else
-                      {
-                        Matrix Q = argq.matrix_value ();
-                        Matrix R = argr.matrix_value ();
-
-                        QR fact (Q, R);
-
-                        if (col)
-                          fact.delete_col (j-one);
-                        else
-                          fact.delete_row (j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                  }
-                else
-                  {
-                    // complex case
-                    if (argq.is_single_type ()
-                        || argr.is_single_type ())
-                      {
-                        FloatComplexMatrix Q = argq.float_complex_matrix_value ();
-                        FloatComplexMatrix R = argr.float_complex_matrix_value ();
-
-                        FloatComplexQR fact (Q, R);
-
-                        if (col)
-                          fact.delete_col (j-one);
-                        else
-                          fact.delete_row (j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                    else
-                      {
-                        ComplexMatrix Q = argq.complex_matrix_value ();
-                        ComplexMatrix R = argr.complex_matrix_value ();
-
-                        ComplexQR fact (Q, R);
-
-                        if (col)
-                          fact.delete_col (j-one);
-                        else
-                          fact.delete_row (j(0)-one);
-
-                        retval(1) = get_qr_r (fact);
-                        retval(0) = fact.Q ();
-                      }
-                  }
-              }
-            else
-              error ("qrdelete: invalid index J");
-          }
-        else
-          error ("qrdelete: dimension mismatch");
-
-      else
-        error ("qrdelete: ORIENT must be \"col\" or \"row\"");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-/*
-%!test
-%! AA = [0.091364  0.613038  0.027504  0.999083;
-%!       0.594638  0.425302  0.562834  0.603537;
-%!       0.383594  0.291238  0.742073  0.085574;
-%!       0.265712  0.268003  0.783553  0.238409;
-%!       0.669966  0.743851  0.457255  0.445057 ];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 16*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps);
-%!
-%!test
-%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
-%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
-%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
-%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
-%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3);
-%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 16*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps);
-%!
-%!test
-%! AA = [0.091364  0.613038  0.027504  0.999083;
-%!       0.594638  0.425302  0.562834  0.603537;
-%!       0.383594  0.291238  0.742073  0.085574;
-%!       0.265712  0.268003  0.783553  0.238409;
-%!       0.669966  0.743851  0.457255  0.445057 ];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3, "row");
-%! assert (norm (vec (Q'*Q - eye (4)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps);
-%!
-%!test
-%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
-%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
-%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
-%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
-%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3, "row");
-%! assert (norm (vec (Q'*Q - eye (4)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps);
-
-%!test
-%! AA = single ([0.091364  0.613038  0.027504  0.999083;
-%!               0.594638  0.425302  0.562834  0.603537;
-%!               0.383594  0.291238  0.742073  0.085574;
-%!               0.265712  0.268003  0.783553  0.238409;
-%!               0.669966  0.743851  0.457255  0.445057 ]);
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3);
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%!test
-%! AA = single ([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
-%!               0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
-%!               0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
-%!               0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
-%!               0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3);
-%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%!test
-%! AA = single ([0.091364  0.613038  0.027504  0.999083;
-%!               0.594638  0.425302  0.562834  0.603537;
-%!               0.383594  0.291238  0.742073  0.085574;
-%!               0.265712  0.268003  0.783553  0.238409;
-%!               0.669966  0.743851  0.457255  0.445057 ]);
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3, "row");
-%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1.5e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
-%!testif HAVE_QRUPDATE
-%! # Same test as above but with more precicision
-%! AA = single ([0.091364  0.613038  0.027504  0.999083;
-%!               0.594638  0.425302  0.562834  0.603537;
-%!               0.383594  0.291238  0.742073  0.085574;
-%!               0.265712  0.268003  0.783553  0.238409;
-%!               0.669966  0.743851  0.457255  0.445057 ]);
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3, "row");
-%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%!test
-%! AA = single ([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
-%!              0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
-%!              0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
-%!              0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
-%!              0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrdelete (Q, R, 3, "row");
-%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
-*/
-
-DEFUN_DLD (qrshift, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrshift (@var{Q}, @var{R}, @var{i}, @var{j})\n\
-Given a QR@tie{}factorization of a real or complex matrix\n\
-@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
-@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization\n\
-of @w{@var{A}(:,p)}, where @w{p} is the permutation @*\n\
-@code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
- or @*\n\
-@code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
-\n\
-@seealso{qr, qrinsert, qrdelete}\n\
-@end deftypefn")
-{
-  octave_idx_type nargin = args.length ();
-  octave_value_list retval;
-
-  if (nargin != 4)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value argq = args(0);
-  octave_value argr = args(1);
-  octave_value argi = args(2);
-  octave_value argj = args(3);
-
-  if (argq.is_numeric_type () && argr.is_numeric_type ())
-    {
-      if (check_qr_dims (argq, argr, true))
-        {
-          if (check_index (argi) && check_index (argj))
-            {
-              octave_idx_type i = argi.int_value ();
-              octave_idx_type j = argj.int_value ();
-
-              if (argq.is_real_type ()
-                  && argr.is_real_type ())
-                {
-                  // all real case
-                  if (argq.is_single_type ()
-                      && argr.is_single_type ())
-                    {
-                      FloatMatrix Q = argq.float_matrix_value ();
-                      FloatMatrix R = argr.float_matrix_value ();
-
-                      FloatQR fact (Q, R);
-                      fact.shift_cols (i-1, j-1);
-
-                      retval(1) = get_qr_r (fact);
-                      retval(0) = fact.Q ();
-                    }
-                  else
-                    {
-                      Matrix Q = argq.matrix_value ();
-                      Matrix R = argr.matrix_value ();
-
-                      QR fact (Q, R);
-                      fact.shift_cols (i-1, j-1);
-
-                      retval(1) = get_qr_r (fact);
-                      retval(0) = fact.Q ();
-                    }
-                }
-              else
-                {
-                  // complex case
-                  if (argq.is_single_type ()
-                      && argr.is_single_type ())
-                    {
-                      FloatComplexMatrix Q = argq.float_complex_matrix_value ();
-                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
-
-                      FloatComplexQR fact (Q, R);
-                      fact.shift_cols (i-1, j-1);
-
-                      retval(1) = get_qr_r (fact);
-                      retval(0) = fact.Q ();
-                    }
-                  else
-                    {
-                      ComplexMatrix Q = argq.complex_matrix_value ();
-                      ComplexMatrix R = argr.complex_matrix_value ();
-
-                      ComplexQR fact (Q, R);
-                      fact.shift_cols (i-1, j-1);
-
-                      retval(1) = get_qr_r (fact);
-                      retval(0) = fact.Q ();
-                    }
-                }
-            }
-          else
-            error ("qrshift: invalid index I or J");
-        }
-      else
-        error ("qrshift: dimensions mismatch");
-    }
-  else
-    error ("qrshift: Q and R must be numeric");
-
-  return retval;
-}
-
-/*
-%!test
-%! AA = A.';
-%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
-%!
-%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
-%!
-%!test
-%! AA = Ac.';
-%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
-%!
-%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
-
-%!test
-%! AA = single (A).';
-%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%!test
-%! AA = single (Ac).';
-%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
-%!
-%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
-%!
-%! [Q,R] = qr (AA);
-%! [Q,R] = qrshift (Q, R, i, j);
-%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
-%! assert (norm (vec (triu (R) - R), Inf) == 0);
-%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
-*/
--- a/src/DLD-FUNCTIONS/symbfact.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,363 +0,0 @@
-/*
-
-Copyright (C) 2005-2012 David Bateman
-Copyright (C) 1998-2005 Andy Adler
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "SparseCmplxCHOL.h"
-#include "SparsedbleCHOL.h"
-#include "oct-spparms.h"
-#include "sparse-util.h"
-#include "oct-locbuf.h"
-
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "utils.h"
-
-DEFUN_DLD (symbfact, args, nargout,
-    "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {[@var{count}, @var{h}, @var{parent}, @var{post}, @var{r}] =} symbfact (@var{S})\n\
-@deftypefnx {Loadable Function} {[@dots{}] =} symbfact (@var{S}, @var{typ})\n\
-@deftypefnx {Loadable Function} {[@dots{}] =} symbfact (@var{S}, @var{typ}, @var{mode})\n\
-\n\
-Perform a symbolic factorization analysis on the sparse matrix @var{S}.\n\
-Where\n\
-\n\
-@table @var\n\
-@item S\n\
-@var{S} is a complex or real sparse matrix.\n\
-\n\
-@item typ\n\
-Is the type of the factorization and can be one of\n\
-\n\
-@table @samp\n\
-@item sym\n\
-Factorize @var{S}.  This is the default.\n\
-\n\
-@item col\n\
-Factorize @code{@var{S}' * @var{S}}.\n\
-\n\
-@item row\n\
-Factorize @xcode{@var{S} * @var{S}'}.\n\
-\n\
-@item lo\n\
-Factorize @xcode{@var{S}'}\n\
-@end table\n\
-\n\
-@item mode\n\
-The default is to return the Cholesky@tie{}factorization for @var{r}, and if\n\
-@var{mode} is 'L', the conjugate transpose of the Cholesky@tie{}factorization\n\
-is returned.  The conjugate transpose version is faster and uses less\n\
-memory, but returns the same values for @var{count}, @var{h}, @var{parent}\n\
-and @var{post} outputs.\n\
-@end table\n\
-\n\
-The output variables are\n\
-\n\
-@table @var\n\
-@item count\n\
-The row counts of the Cholesky@tie{}factorization as determined by @var{typ}.\n\
-\n\
-@item h\n\
-The height of the elimination tree.\n\
-\n\
-@item parent\n\
-The elimination tree itself.\n\
-\n\
-@item post\n\
-A sparse boolean matrix whose structure is that of the Cholesky\n\
-factorization as determined by @var{typ}.\n\
-@end table\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-
-  if (nargin < 1  || nargin > 3 || nargout > 5)
-    {
-      print_usage ();
-      return retval;
-    }
-
-#ifdef HAVE_CHOLMOD
-
-  cholmod_common Common;
-  cholmod_common *cm = &Common;
-  CHOLMOD_NAME(start) (cm);
-
-  double spu = octave_sparse_params::get_key ("spumoni");
-  if (spu == 0.)
-    {
-      cm->print = -1;
-      cm->print_function = 0;
-    }
-  else
-    {
-      cm->print = static_cast<int> (spu) + 2;
-      cm->print_function =&SparseCholPrint;
-    }
-
-  cm->error_handler = &SparseCholError;
-  cm->complex_divide = CHOLMOD_NAME(divcomplex);
-  cm->hypotenuse = CHOLMOD_NAME(hypot);
-
-  double dummy;
-  cholmod_sparse Astore;
-  cholmod_sparse *A = &Astore;
-  A->packed = true;
-  A->sorted = true;
-  A->nz = 0;
-#ifdef IDX_TYPE_LONG
-  A->itype = CHOLMOD_LONG;
-#else
-  A->itype = CHOLMOD_INT;
-#endif
-  A->dtype = CHOLMOD_DOUBLE;
-  A->stype = 1;
-  A->x = &dummy;
-
-  if (args(0).is_real_type ())
-    {
-      const SparseMatrix a = args(0).sparse_matrix_value ();
-      A->nrow = a.rows ();
-      A->ncol = a.cols ();
-      A->p = a.cidx ();
-      A->i = a.ridx ();
-      A->nzmax = a.nnz ();
-      A->xtype = CHOLMOD_REAL;
-
-      if (a.rows () > 0 && a.cols () > 0)
-        A->x = a.data ();
-    }
-  else if (args(0).is_complex_type ())
-    {
-      const SparseComplexMatrix a = args(0).sparse_complex_matrix_value ();
-      A->nrow = a.rows ();
-      A->ncol = a.cols ();
-      A->p = a.cidx ();
-      A->i = a.ridx ();
-      A->nzmax = a.nnz ();
-      A->xtype = CHOLMOD_COMPLEX;
-
-      if (a.rows () > 0 && a.cols () > 0)
-        A->x = a.data ();
-    }
-  else
-    gripe_wrong_type_arg ("symbfact", args(0));
-
-  octave_idx_type coletree = false;
-  octave_idx_type n = A->nrow;
-
-  if (nargin > 1)
-    {
-      char ch;
-      std::string str = args(1).string_value ();
-      ch = tolower (str.c_str ()[0]);
-      if (ch == 'r')
-        A->stype = 0;
-      else if (ch == 'c')
-        {
-          n = A->ncol;
-          coletree = true;
-          A->stype = 0;
-        }
-      else if (ch == 's')
-        A->stype = 1;
-      else if (ch == 's')
-        A->stype = -1;
-      else
-        error ("symbfact: unrecognized TYP in symbolic factorization");
-    }
-
-  if (A->stype && A->nrow != A->ncol)
-    error ("symbfact: S must be a square matrix");
-
-  if (!error_state)
-    {
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, Parent, n);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, Post, n);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, ColCount, n);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, First, n);
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, Level, n);
-
-      cholmod_sparse *F = CHOLMOD_NAME(transpose) (A, 0, cm);
-      cholmod_sparse *Aup, *Alo;
-
-      if (A->stype == 1 || coletree)
-        {
-          Aup = A ;
-          Alo = F ;
-        }
-      else
-        {
-          Aup = F ;
-          Alo = A ;
-        }
-
-      CHOLMOD_NAME(etree) (Aup, Parent, cm);
-
-      if (cm->status < CHOLMOD_OK)
-        {
-          error ("matrix corrupted");
-          goto symbfact_error;
-        }
-
-      if (CHOLMOD_NAME(postorder) (Parent, n, 0, Post, cm) != n)
-        {
-          error ("postorder failed");
-          goto symbfact_error;
-        }
-
-      CHOLMOD_NAME(rowcolcounts) (Alo, 0, 0, Parent, Post, 0,
-                                  ColCount, First, Level, cm);
-
-      if (cm->status < CHOLMOD_OK)
-        {
-          error ("matrix corrupted");
-          goto symbfact_error;
-        }
-
-      if (nargout > 4)
-        {
-          cholmod_sparse *A1, *A2;
-
-          if (A->stype == 1)
-            {
-              A1 = A;
-              A2 = 0;
-            }
-          else if (A->stype == -1)
-            {
-              A1 = F;
-              A2 = 0;
-            }
-          else if (coletree)
-            {
-              A1 = F;
-              A2 = A;
-            }
-          else
-            {
-              A1 = A;
-              A2 = F;
-            }
-
-          // count the total number of entries in L
-          octave_idx_type lnz = 0 ;
-          for (octave_idx_type j = 0 ; j < n ; j++)
-            lnz += ColCount[j];
-
-
-          // allocate the output matrix L (pattern-only)
-          SparseBoolMatrix L (n, n, lnz);
-
-          // initialize column pointers
-          lnz = 0;
-          for (octave_idx_type j = 0 ; j < n ; j++)
-            {
-              L.xcidx(j) = lnz;
-              lnz += ColCount[j];
-            }
-          L.xcidx(n) = lnz;
-
-
-          /* create a copy of the column pointers */
-          octave_idx_type *W = First;
-          for (octave_idx_type j = 0 ; j < n ; j++)
-            W[j] = L.xcidx (j);
-
-          // get workspace for computing one row of L
-          cholmod_sparse *R = cholmod_allocate_sparse (n, 1, n, false, true,
-                                                       0, CHOLMOD_PATTERN, cm);
-          octave_idx_type *Rp = static_cast<octave_idx_type *>(R->p);
-          octave_idx_type *Ri = static_cast<octave_idx_type *>(R->i);
-
-          // compute L one row at a time
-          for (octave_idx_type k = 0 ; k < n ; k++)
-            {
-              // get the kth row of L and store in the columns of L
-              CHOLMOD_NAME (row_subtree) (A1, A2, k, Parent, R, cm) ;
-              for (octave_idx_type p = 0 ; p < Rp[1] ; p++)
-                L.xridx (W[Ri[p]]++) = k ;
-
-              // add the diagonal entry
-              L.xridx (W[k]++) = k ;
-            }
-
-          // free workspace
-          cholmod_free_sparse (&R, cm) ;
-
-
-          // transpose L to get R, or leave as is
-          if (nargin < 3)
-            L = L.transpose ();
-
-          // fill numerical values of L with one's
-          for (octave_idx_type p = 0 ; p < lnz ; p++)
-            L.xdata(p) = true;
-
-          retval(4) = L;
-        }
-
-      ColumnVector tmp (n);
-      if (nargout > 3)
-        {
-          for (octave_idx_type i = 0; i < n; i++)
-            tmp(i) = Post[i] + 1;
-          retval(3) = tmp;
-        }
-
-      if (nargout > 2)
-        {
-          for (octave_idx_type i = 0; i < n; i++)
-            tmp(i) = Parent[i] + 1;
-          retval(2) = tmp;
-        }
-
-      if (nargout > 1)
-        {
-          /* compute the elimination tree height */
-          octave_idx_type height = 0 ;
-          for (int i = 0 ; i < n ; i++)
-            height = (height > Level[i] ? height : Level[i]);
-          height++ ;
-          retval(1) = static_cast<double> (height);
-        }
-
-      for (octave_idx_type i = 0; i < n; i++)
-        tmp(i) = ColCount[i];
-      retval(0) = tmp;
-    }
-
- symbfact_error:
-#else
-  error ("symbfact: not available in this version of Octave");
-#endif
-
-  return retval;
-}
--- a/src/DLD-FUNCTIONS/symrcm.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,702 +0,0 @@
-/*
-
-Copyright (C) 2007-2012 Michael Weitzel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-/*
-An implementation of the Reverse Cuthill-McKee algorithm (symrcm)
-
-The implementation of this algorithm is based in the descriptions found in
-
-@INPROCEEDINGS{,
-        author = {E. Cuthill and J. McKee},
-        title = {Reducing the Bandwidth of Sparse Symmetric Matrices},
-        booktitle = {Proceedings of the 24th ACM National Conference},
-        publisher = {Brandon Press},
-        pages = {157 -- 172},
-        location = {New Jersey},
-        year = {1969}
-}
-
-@BOOK{,
-        author = {Alan George and Joseph W. H. Liu},
-        title = {Computer Solution of Large Sparse Positive Definite Systems},
-        publisher = {Prentice Hall Series in Computational Mathematics},
-        ISBN = {0-13-165274-5},
-        year = {1981}
-}
-
-The algorithm represents a heuristic approach to the NP-complete minimum
-bandwidth problem.
-
-Written by Michael Weitzel <michael.weitzel@@uni-siegen.de>
-                           <weitzel@@ldknet.org>
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ov.h"
-#include "defun-dld.h"
-#include "error.h"
-#include "gripes.h"
-#include "utils.h"
-#include "oct-locbuf.h"
-
-#include "ov-re-mat.h"
-#include "ov-re-sparse.h"
-#include "ov-cx-sparse.h"
-#include "oct-sparse.h"
-
-// A node struct for the Cuthill-McKee algorithm
-struct CMK_Node
-{
-  // the node's id (matrix row index)
-  octave_idx_type id;
-  // the node's degree
-  octave_idx_type deg;
-  // minimal distance to the root of the spanning tree
-  octave_idx_type dist;
-};
-
-// A simple queue.
-// Queues Q have a fixed maximum size N (rows,cols of the matrix) and are
-// stored in an array. qh and qt point to queue head and tail.
-
-// Enqueue operation (adds a node "o" at the tail)
-
-inline static void
-Q_enq (CMK_Node *Q, octave_idx_type N, octave_idx_type& qt, const CMK_Node& o)
-{
-  Q[qt] = o;
-  qt = (qt + 1) % (N + 1);
-}
-
-// Dequeue operation (removes a node from the head)
-
-inline static CMK_Node
-Q_deq (CMK_Node * Q, octave_idx_type N, octave_idx_type& qh)
-{
-  CMK_Node r = Q[qh];
-  qh = (qh + 1) % (N + 1);
-  return r;
-}
-
-// Predicate (queue empty)
-#define Q_empty(Q, N, qh, qt)   ((qh) == (qt))
-
-// A simple, array-based binary heap (used as a priority queue for nodes)
-
-// the left descendant of entry i
-#define LEFT(i)         (((i) << 1) + 1)        // = (2*(i)+1)
-// the right descendant of entry i
-#define RIGHT(i)        (((i) << 1) + 2)        // = (2*(i)+2)
-// the parent of entry i
-#define PARENT(i)       (((i) - 1) >> 1)        // = floor(((i)-1)/2)
-
-// Builds a min-heap (the root contains the smallest element). A is an array
-// with the graph's nodes, i is a starting position, size is the length of A.
-
-static void
-H_heapify_min (CMK_Node *A, octave_idx_type i, octave_idx_type size)
-{
-  octave_idx_type j = i;
-  for (;;)
-    {
-      octave_idx_type l = LEFT(j);
-      octave_idx_type r = RIGHT(j);
-
-      octave_idx_type smallest;
-      if (l < size && A[l].deg < A[j].deg)
-        smallest = l;
-      else
-        smallest = j;
-
-      if (r < size && A[r].deg < A[smallest].deg)
-        smallest = r;
-
-      if (smallest != j)
-        {
-          std::swap (A[j], A[smallest]);
-          j = smallest;
-        }
-      else
-        break;
-    }
-}
-
-// Heap operation insert. Running time is O(log(n))
-
-static void
-H_insert (CMK_Node *H, octave_idx_type& h, const CMK_Node& o)
-{
-  octave_idx_type i = h++;
-
-  H[i] = o;
-
-  if (i == 0)
-    return;
-  do
-    {
-      octave_idx_type p = PARENT(i);
-      if (H[i].deg < H[p].deg)
-        {
-          std::swap (H[i], H[p]);
-
-          i = p;
-        }
-      else
-        break;
-    }
-  while (i > 0);
-}
-
-// Heap operation remove-min. Removes the smalles element in O(1) and
-// reorganizes the heap optionally in O(log(n))
-
-inline static CMK_Node
-H_remove_min (CMK_Node *H, octave_idx_type& h, int reorg/*=1*/)
-{
-  CMK_Node r = H[0];
-  H[0] = H[--h];
-  if (reorg)
-    H_heapify_min (H, 0, h);
-  return r;
-}
-
-// Predicate (heap empty)
-#define H_empty(H, h)   ((h) == 0)
-
-// Helper function for the Cuthill-McKee algorithm. Tries to determine a
-// pseudo-peripheral node of the graph as starting node.
-
-static octave_idx_type
-find_starting_node (octave_idx_type N, const octave_idx_type *ridx,
-                    const octave_idx_type *cidx, const octave_idx_type *ridx2,
-                    const octave_idx_type *cidx2, octave_idx_type *D,
-                    octave_idx_type start)
-{
-  CMK_Node w;
-
-  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
-  boolNDArray btmp (dim_vector (1, N), false);
-  bool *visit = btmp.fortran_vec ();
-
-  octave_idx_type qh = 0;
-  octave_idx_type qt = 0;
-  CMK_Node x;
-  x.id = start;
-  x.deg = D[start];
-  x.dist = 0;
-  Q_enq (Q, N, qt, x);
-  visit[start] = true;
-
-  // distance level
-  octave_idx_type level = 0;
-  // current largest "eccentricity"
-  octave_idx_type max_dist = 0;
-
-  for (;;)
-    {
-      while (! Q_empty (Q, N, qh, qt))
-        {
-          CMK_Node v = Q_deq (Q, N, qh);
-
-          if (v.dist > x.dist || (v.id != x.id && v.deg > x.deg))
-            x = v;
-
-          octave_idx_type i = v.id;
-
-          // add all unvisited neighbors to the queue
-          octave_idx_type j1 = cidx[i];
-          octave_idx_type j2 = cidx2[i];
-          while (j1 < cidx[i+1] || j2 < cidx2[i+1])
-            {
-              OCTAVE_QUIT;
-
-              if (j1 == cidx[i+1])
-                {
-                  octave_idx_type r2 = ridx2[j2++];
-                  if (! visit[r2])
-                    {
-                      // the distance of node j is dist(i)+1
-                      w.id = r2;
-                      w.deg = D[r2];
-                      w.dist = v.dist+1;
-                      Q_enq (Q, N, qt, w);
-                      visit[r2] = true;
-
-                      if (w.dist > level)
-                        level = w.dist;
-                    }
-                }
-              else if (j2 == cidx2[i+1])
-                {
-                  octave_idx_type r1 = ridx[j1++];
-                  if (! visit[r1])
-                    {
-                      // the distance of node j is dist(i)+1
-                      w.id = r1;
-                      w.deg = D[r1];
-                      w.dist = v.dist+1;
-                      Q_enq (Q, N, qt, w);
-                      visit[r1] = true;
-
-                      if (w.dist > level)
-                        level = w.dist;
-                    }
-                }
-              else
-                {
-                  octave_idx_type r1 = ridx[j1];
-                  octave_idx_type r2 = ridx2[j2];
-                  if (r1 <= r2)
-                    {
-                      if (! visit[r1])
-                        {
-                          w.id = r1;
-                          w.deg = D[r1];
-                          w.dist = v.dist+1;
-                          Q_enq (Q, N, qt, w);
-                          visit[r1] = true;
-
-                          if (w.dist > level)
-                            level = w.dist;
-                        }
-                      j1++;
-                      if (r1 == r2)
-                        j2++;
-                    }
-                  else
-                    {
-                      if (! visit[r2])
-                        {
-                          w.id = r2;
-                          w.deg = D[r2];
-                          w.dist = v.dist+1;
-                          Q_enq (Q, N, qt, w);
-                          visit[r2] = true;
-
-                          if (w.dist > level)
-                            level = w.dist;
-                        }
-                      j2++;
-                    }
-                }
-            }
-        } // finish of BFS
-
-      if (max_dist < x.dist)
-        {
-          max_dist = x.dist;
-
-          for (octave_idx_type i = 0; i < N; i++)
-            visit[i] = false;
-
-          visit[x.id] = true;
-          x.dist = 0;
-          qt = qh = 0;
-          Q_enq (Q, N, qt, x);
-        }
-      else
-        break;
-    }
-  return x.id;
-}
-
-// Calculates the node's degrees. This means counting the non-zero elements
-// in the symmetric matrix' rows. This works for non-symmetric matrices
-// as well.
-
-static octave_idx_type
-calc_degrees (octave_idx_type N, const octave_idx_type *ridx,
-              const octave_idx_type *cidx, octave_idx_type *D)
-{
-  octave_idx_type max_deg = 0;
-
-  for (octave_idx_type i = 0; i < N; i++)
-    D[i] = 0;
-
-  for (octave_idx_type j = 0; j < N; j++)
-    {
-      for (octave_idx_type i = cidx[j]; i < cidx[j+1]; i++)
-        {
-          OCTAVE_QUIT;
-          octave_idx_type k = ridx[i];
-          // there is a non-zero element (k,j)
-          D[k]++;
-          if (D[k] > max_deg)
-            max_deg = D[k];
-          // if there is no element (j,k) there is one in
-          // the symmetric matrix:
-          if (k != j)
-            {
-              bool found = false;
-              for (octave_idx_type l = cidx[k]; l < cidx[k + 1]; l++)
-                {
-                  OCTAVE_QUIT;
-
-                  if (ridx[l] == j)
-                    {
-                      found = true;
-                      break;
-                    }
-                  else if (ridx[l] > j)
-                    break;
-                }
-
-              if (! found)
-                {
-                  // A(j,k) == 0
-                  D[j]++;
-                  if (D[j] > max_deg)
-                    max_deg = D[j];
-                }
-            }
-        }
-    }
-  return max_deg;
-}
-
-// Transpose of the structure of a square sparse matrix
-
-static void
-transpose (octave_idx_type N, const octave_idx_type *ridx,
-           const octave_idx_type *cidx, octave_idx_type *ridx2,
-           octave_idx_type *cidx2)
-{
-  octave_idx_type nz = cidx[N];
-
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, w, N + 1);
-  for (octave_idx_type i = 0; i < N; i++)
-    w[i] = 0;
-  for (octave_idx_type i = 0; i < nz; i++)
-    w[ridx[i]]++;
-  nz = 0;
-  for (octave_idx_type i = 0; i < N; i++)
-    {
-      OCTAVE_QUIT;
-      cidx2[i] = nz;
-      nz += w[i];
-      w[i] = cidx2[i];
-    }
-  cidx2[N] = nz;
-  w[N] = nz;
-
-  for (octave_idx_type j = 0; j < N; j++)
-    for (octave_idx_type k = cidx[j]; k < cidx[j + 1]; k++)
-      {
-        OCTAVE_QUIT;
-        octave_idx_type q = w[ridx[k]]++;
-        ridx2[q] = j;
-      }
-}
-
-// An implementation of the Cuthill-McKee algorithm.
-DEFUN_DLD (symrcm, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})\n\
-Return the symmetric reverse Cuthill-McKee permutation of @var{S}.\n\
-@var{p} is a permutation vector such that\n\
-@code{@var{S}(@var{p}, @var{p})} tends to have its diagonal elements\n\
-closer to the diagonal than @var{S}.  This is a good preordering for LU\n\
-or Cholesky@tie{}factorization of matrices that come from ``long, skinny''\n\
-problems.  It works for both symmetric and asymmetric @var{S}.\n\
-\n\
-The algorithm represents a heuristic approach to the NP-complete\n\
-bandwidth minimization problem.  The implementation is based in the\n\
-descriptions found in\n\
-\n\
-E. Cuthill, J. McKee. @cite{Reducing the Bandwidth of Sparse Symmetric\n\
-Matrices}. Proceedings of the 24th ACM National Conference, 157--172\n\
-1969, Brandon Press, New Jersey.\n\
-\n\
-A. George, J.W.H. Liu. @cite{Computer Solution of Large Sparse\n\
-Positive Definite Systems}, Prentice Hall Series in Computational\n\
-Mathematics, ISBN 0-13-165274-5, 1981.\n\
-\n\
-@seealso{colperm, colamd, symamd}\n\
-@end deftypefn")
-{
-  octave_value retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value arg = args(0);
-
-  // the parameter of the matrix is converted into a sparse matrix
-  //(if necessary)
-  octave_idx_type *cidx;
-  octave_idx_type *ridx;
-  SparseMatrix Ar;
-  SparseComplexMatrix Ac;
-
-  if (arg.is_real_type ())
-    {
-      Ar = arg.sparse_matrix_value ();
-      // Note cidx/ridx are const, so use xridx and xcidx...
-      cidx = Ar.xcidx ();
-      ridx = Ar.xridx ();
-    }
-  else
-    {
-      Ac = arg.sparse_complex_matrix_value ();
-      cidx = Ac.xcidx ();
-      ridx = Ac.xridx ();
-    }
-
-  if (error_state)
-    return retval;
-
-  octave_idx_type nr = arg.rows ();
-  octave_idx_type nc = arg.columns ();
-
-  if (nr != nc)
-    {
-      gripe_square_matrix_required ("symrcm");
-      return retval;
-    }
-
-  if (nr == 0 && nc == 0)
-    return octave_value (NDArray (dim_vector (1, 0)));
-
-  // sizes of the heaps
-  octave_idx_type s = 0;
-
-  // head- and tail-indices for the queue
-  octave_idx_type qt = 0, qh = 0;
-  CMK_Node v, w;
-  // dimension of the matrix
-  octave_idx_type N = nr;
-
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, cidx2, N + 1);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, ridx2, cidx[N]);
-  transpose (N, ridx, cidx, ridx2, cidx2);
-
-  // the permutation vector
-  NDArray P (dim_vector (1, N));
-
-  // compute the node degrees
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, D, N);
-  octave_idx_type max_deg = calc_degrees (N, ridx, cidx, D);
-
-  // if none of the nodes has a degree > 0 (a matrix of zeros)
-  // the return value corresponds to the identity permutation
-  if (max_deg == 0)
-    {
-      for (octave_idx_type i = 0; i < N; i++)
-        P(i) = i;
-      return octave_value (P);
-    }
-
-  // a heap for the a node's neighbors. The number of neighbors is
-  // limited by the maximum degree max_deg:
-  OCTAVE_LOCAL_BUFFER (CMK_Node, S, max_deg);
-
-  // a queue for the BFS. The array is always one element larger than
-  // the number of entries that are stored.
-  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
-
-  // a counter (for building the permutation)
-  octave_idx_type c = -1;
-
-  // upper bound for the bandwidth (=quality of solution)
-  // initialize the bandwidth of the graph with 0. B contains the
-  // the maximum of the theoretical lower limits of the subgraphs
-  // bandwidths.
-  octave_idx_type B = 0;
-
-  // mark all nodes as unvisited; with the exception of the nodes
-  // that have degree==0 and build a CC of the graph.
-
-  boolNDArray btmp (dim_vector (1, N), false);
-  bool *visit = btmp.fortran_vec ();
-
-  do
-    {
-      // locate an unvisited starting node of the graph
-      octave_idx_type i;
-      for (i = 0; i < N; i++)
-        if (! visit[i])
-          break;
-
-      // locate a probably better starting node
-      v.id = find_starting_node (N, ridx, cidx, ridx2, cidx2, D, i);
-
-      // mark the node as visited and enqueue it (a starting node
-      // for the BFS). Since the node will be a root of a spanning
-      // tree, its dist is 0.
-      v.deg = D[v.id];
-      v.dist = 0;
-      visit[v.id] = true;
-      Q_enq (Q, N, qt, v);
-
-      // lower bound for the bandwidth of a subgraph
-      // keep a "level" in the spanning tree (= min. distance to the
-      // root) for determining the bandwidth of the computed
-      // permutation P
-      octave_idx_type Bsub = 0;
-      // min. dist. to the root is 0
-      octave_idx_type level = 0;
-      // the root is the first/only node on level 0
-      octave_idx_type level_N = 1;
-
-      while (! Q_empty (Q, N, qh, qt))
-        {
-          v = Q_deq (Q, N, qh);
-          i = v.id;
-
-          c++;
-
-          // for computing the inverse permutation P where
-          // A(inv(P),inv(P)) or P'*A*P is banded
-          //         P(i) = c;
-
-          // for computing permutation P where
-          // A(P(i),P(j)) or P*A*P' is banded
-          P(c) = i;
-
-          // put all unvisited neighbors j of node i on the heap
-          s = 0;
-          octave_idx_type j1 = cidx[i];
-          octave_idx_type j2 = cidx2[i];
-
-          OCTAVE_QUIT;
-          while (j1 < cidx[i+1] || j2 < cidx2[i+1])
-            {
-              OCTAVE_QUIT;
-              if (j1 == cidx[i+1])
-                {
-                  octave_idx_type r2 = ridx2[j2++];
-                  if (! visit[r2])
-                    {
-                      // the distance of node j is dist(i)+1
-                      w.id = r2;
-                      w.deg = D[r2];
-                      w.dist = v.dist+1;
-                      H_insert (S, s, w);
-                      visit[r2] = true;
-                    }
-                }
-              else if (j2 == cidx2[i+1])
-                {
-                  octave_idx_type r1 = ridx[j1++];
-                  if (! visit[r1])
-                    {
-                      w.id = r1;
-                      w.deg = D[r1];
-                      w.dist = v.dist+1;
-                      H_insert (S, s, w);
-                      visit[r1] = true;
-                    }
-                }
-              else
-                {
-                  octave_idx_type r1 = ridx[j1];
-                  octave_idx_type r2 = ridx2[j2];
-                  if (r1 <= r2)
-                    {
-                      if (! visit[r1])
-                        {
-                          w.id = r1;
-                          w.deg = D[r1];
-                          w.dist = v.dist+1;
-                          H_insert (S, s, w);
-                          visit[r1] = true;
-                        }
-                      j1++;
-                      if (r1 == r2)
-                        j2++;
-                    }
-                  else
-                    {
-                      if (! visit[r2])
-                        {
-                          w.id = r2;
-                          w.deg = D[r2];
-                          w.dist = v.dist+1;
-                          H_insert (S, s, w);
-                          visit[r2] = true;
-                        }
-                      j2++;
-                    }
-                }
-            }
-
-          // add the neighbors to the queue (sorted by node degree)
-          while (! H_empty (S, s))
-            {
-              OCTAVE_QUIT;
-
-              // locate a neighbor of i with minimal degree in O(log(N))
-              v = H_remove_min (S, s, 1);
-
-              // entered the BFS a new level?
-              if (v.dist > level)
-                {
-                  // adjustment of bandwith:
-                  // "[...] the minimum bandwidth that
-                  // can be obtained [...] is the
-                  //  maximum number of nodes per level"
-                  if (Bsub < level_N)
-                    Bsub = level_N;
-
-                  level = v.dist;
-                  // v is the first node on the new level
-                  level_N = 1;
-                }
-              else
-                {
-                  // there is no new level but another node on
-                  // this level:
-                  level_N++;
-                }
-
-              // enqueue v in O(1)
-              Q_enq (Q, N, qt, v);
-            }
-
-          // synchronize the bandwidth with level_N once again:
-          if (Bsub < level_N)
-            Bsub = level_N;
-        }
-      // finish of BFS. If there are still unvisited nodes in the graph
-      // then it is split into CCs. The computed bandwidth is the maximum
-      // of all subgraphs. Update:
-      if (Bsub > B)
-        B = Bsub;
-    }
-  // are there any nodes left?
-  while (c+1 < N);
-
-  // compute the reverse-ordering
-  s = N / 2 - 1;
-  for (octave_idx_type i = 0, j = N - 1; i <= s; i++, j--)
-    std::swap (P.elem (i), P.elem (j));
-
-  // increment all indices, since Octave is not C
-  return octave_value (P+1);
-}
--- a/src/DLD-FUNCTIONS/tsearch.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*
-
-Copyright (C) 2002-2012 Andreas Stahel
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-// Author: Andreas Stahel <Andreas.Stahel@hta-bi.bfh.ch>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <iostream>
-#include <fstream>
-#include <string>
-
-#include "lo-ieee.h"
-#include "lo-math.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-#include "parse.h"
-
-inline double max (double a, double b, double c)
-{
-  if (a < b)
-    return (b < c ? c : b);
-  else
-    return (a < c ? c : a);
-}
-
-inline double min (double a, double b, double c)
-{
-  if (a > b)
-    return (b > c ? c : b);
-  else
-    return (a > c ? c : a);
-}
-
-#define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
-
-// for large data set the algorithm is very slow
-// one should presort (how?) either the elements of the points of evaluation
-// to cut down the time needed to decide which triangle contains the
-// given point
-
-// e.g., build up a neighbouring triangle structure and use a simplex-like
-// method to traverse it
-
-DEFUN_DLD (tsearch, args, ,
-        "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})\n\
-Search for the enclosing Delaunay convex hull.  For @code{@var{t} =\n\
-delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the\n\
-points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,\n\
-@var{idx} is NaN.\n\
-@seealso{delaunay, delaunayn}\n\
-@end deftypefn")
-{
-  const double eps=1.0e-12;
-
-  octave_value_list retval;
-  const int nargin = args.length ();
-  if (nargin != 5)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  const ColumnVector x (args(0).vector_value ());
-  const ColumnVector y (args(1).vector_value ());
-  const Matrix elem (args(2).matrix_value ());
-  const ColumnVector xi (args(3).vector_value ());
-  const ColumnVector yi (args(4).vector_value ());
-
-  if (error_state)
-    return retval;
-
-  const octave_idx_type nelem = elem.rows ();
-
-  ColumnVector minx (nelem);
-  ColumnVector maxx (nelem);
-  ColumnVector miny (nelem);
-  ColumnVector maxy (nelem);
-  for (octave_idx_type k = 0; k < nelem; k++)
-    {
-      minx(k) = min (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) - eps;
-      maxx(k) = max (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) + eps;
-      miny(k) = min (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) - eps;
-      maxy(k) = max (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) + eps;
-    }
-
-  const octave_idx_type np = xi.length ();
-  ColumnVector values (np);
-
-  double x0 = 0.0, y0 = 0.0;
-  double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
-
-  octave_idx_type k = nelem; // k is a counter of elements
-  for (octave_idx_type kp = 0; kp < np; kp++)
-    {
-      const double xt = xi(kp);
-      const double yt = yi(kp);
-
-      // check if last triangle contains the next point
-      if (k < nelem)
-        {
-          const double dx1 = xt - x0;
-          const double dx2 = yt - y0;
-          const double c1 = (a22 * dx1 - a21 * dx2) / det;
-          const double c2 = (-a12 * dx1 + a11 * dx2) / det;
-          if (c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
-            {
-              values(kp) = double(k+1);
-              continue;
-            }
-        }
-
-      // it doesn't, so go through all elements
-      for (k = 0; k < nelem; k++)
-        {
-          OCTAVE_QUIT;
-          if (xt >= minx(k) && xt <= maxx(k) && yt >= miny(k) && yt <= maxy(k))
-            {
-              // element inside the minimum rectangle: examine it closely
-              x0  = REF (x, k, 0);
-              y0  = REF (y, k, 0);
-              a11 = REF (x, k, 1) - x0;
-              a12 = REF (y, k, 1) - y0;
-              a21 = REF (x, k, 2) - x0;
-              a22 = REF (y, k, 2) - y0;
-              det = a11 * a22 - a21 * a12;
-
-              // solve the system
-              const double dx1 = xt - x0;
-              const double dx2 = yt - y0;
-              const double c1 = (a22 * dx1 - a21 * dx2) / det;
-              const double c2 = (-a12 * dx1 + a11 * dx2) / det;
-              if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
-                {
-                  values(kp) = double(k+1);
-                  break;
-                }
-            } //endif # examine this element closely
-        } //endfor # each element
-
-      if (k == nelem)
-        values(kp) = lo_ieee_nan_value ();
-
-    } //endfor # kp
-
-  retval(0) = values;
-
-  return retval;
-}
-
-/*
-%!shared x, y, tri
-%! x = [-1;-1;1];
-%! y = [-1;1;-1];
-%! tri = [1, 2, 3];
-%!assert (tsearch (x,y,tri,-1,-1), 1)
-%!assert (tsearch (x,y,tri, 1,-1), 1)
-%!assert (tsearch (x,y,tri,-1, 1), 1)
-%!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
-%!assert (tsearch (x,y,tri, 1, 1), NaN)
-
-%!error tsearch ()
-*/
--- a/src/DLD-FUNCTIONS/urlwrite.cc	Tue Jul 31 20:46:47 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1740 +0,0 @@
-// urlwrite and urlread, a curl front-end for octave
-/*
-
-Copyright (C) 2006-2012 Alexander Barth
-Copyright (C) 2009 David Bateman
-
-This file is part of Octave.
-
-Octave 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.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-// Author: Alexander Barth <abarth@marine.usf.edu>
-// Adapted-By: jwe
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-
-#include "dir-ops.h"
-#include "file-ops.h"
-#include "file-stat.h"
-#include "oct-env.h"
-#include "glob-match.h"
-
-#include "defun-dld.h"
-#include "error.h"
-#include "oct-obj.h"
-#include "ov-cell.h"
-#include "pager.h"
-#include "oct-map.h"
-#include "oct-refcount.h"
-#include "unwind-prot.h"
-
-#ifdef HAVE_CURL
-
-#include <curl/curl.h>
-#include <curl/curlver.h>
-#include <curl/easy.h>
-
-// Backwards compatibility for curl < 7.17.0
-#if LIBCURL_VERSION_NUM < 0x071100
-#define CURLOPT_DIRLISTONLY CURLOPT_FTPLISTONLY
-#endif
-
-static int
-write_data (void *buffer, size_t size, size_t nmemb, void *streamp)
-{
-  std::ostream& stream = *(static_cast<std::ostream*> (streamp));
-  stream.write (static_cast<const char*> (buffer), size*nmemb);
-  return (stream.fail () ? 0 : size * nmemb);
-}
-
-static int
-read_data (void *buffer, size_t size, size_t nmemb, void *streamp)
-{
-  std::istream& stream = *(static_cast<std::istream*> (streamp));
-  stream.read (static_cast<char*> (buffer), size*nmemb);
-  if (stream.eof ())
-    return stream.gcount ();
-  else
-    return (stream.fail () ? 0 : size * nmemb);
-}
-
-static size_t
-throw_away (void *, size_t size, size_t nmemb, void *)
-{
-  return static_cast<size_t>(size * nmemb);
-}
-
-class
-curl_handle
-{
-private:
-  class
-  curl_handle_rep
-  {
-  public:
-    curl_handle_rep (void) : count (1), valid (true), ascii (false)
-      {
-        curl = curl_easy_init ();
-        if (!curl)
-          error ("can not create curl handle");
-      }
-
-    ~curl_handle_rep (void)
-      {
-        if (curl)
-          curl_easy_cleanup (curl);
-      }
-
-    bool is_valid (void) const
-      {
-        return valid;
-      }
-
-    bool perform (bool curlerror) const
-      {
-        bool retval = false;
-        if (!error_state)
-          {
-            BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
-
-            errnum = curl_easy_perform (curl);
-            if (errnum != CURLE_OK)
-              {
-                if (curlerror)
-                  error ("%s", curl_easy_strerror (errnum));
-              }
-            else
-              retval = true;
-
-            END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
-          }
-        return retval;
-      }
-
-    CURL* handle (void) const
-      {
-        return curl;
-      }
-
-    bool is_ascii (void) const
-      {
-        return ascii;
-      }
-
-    bool is_binary (void) const
-      {
-        return !ascii;
-      }
-
-    octave_refcount<size_t> count;
-    std::string host;
-    bool valid;
-    bool ascii;
-    mutable CURLcode errnum;
-
-  private:
-    CURL *curl;
-
-    // No copying!
-
-    curl_handle_rep (const curl_handle_rep& ov);
-
-    curl_handle_rep& operator = (const curl_handle_rep&);
-  };
-
-public:
-
-// I'd love to rewrite this as a private method of the curl_handle
-// class, but you can't pass the va_list from the wrapper setopt to
-// the curl_easy_setopt function.
-#define setopt(option, parameter) \
-  { \
-    CURLcode res = curl_easy_setopt (rep->handle (), option, parameter); \
-    if (res != CURLE_OK) \
-      error ("%s", curl_easy_strerror (res)); \
-  }
-
-  curl_handle (void) : rep (new curl_handle_rep ())
-    {
-      rep->valid = false;
-    }
-
-  curl_handle (const std::string& _host, const std::string& user,
-               const std::string& passwd) :
-    rep (new curl_handle_rep ())
-    {
-      rep->host = _host;
-      init (user, passwd, std::cin, octave_stdout);
-
-      std::string url = "ftp://" + _host;
-      setopt (CURLOPT_URL, url.c_str ());
-
-      // Setup the link, with no transfer
-      if (!error_state)
-        perform ();
-    }
-
-  curl_handle (const std::string& url, const std::string& method,
-               const Cell& param, std::ostream& os, bool& retval) :
-    rep (new curl_handle_rep ())
-    {
-      retval = false;
-
-      init ("", "", std::cin, os);
-
-      setopt (CURLOPT_NOBODY, 0);
-
-      // Don't need to store the parameters here as we can't change
-      // the URL after the handle is created
-      std::string query_string = form_query_string (param);
-
-      if (method == "get")
-        {
-          query_string = url + "?" + query_string;
-          setopt (CURLOPT_URL, query_string.c_str ());
-        }
-      else if (method == "post")
-        {
-          setopt (CURLOPT_URL, url.c_str ());
-          setopt (CURLOPT_POSTFIELDS, query_string.c_str ());
-        }
-      else
-        setopt (CURLOPT_URL, url.c_str ());
-
-      if (!error_state)
-        retval = perform (false);
-    }
-
-  curl_handle (const curl_handle& h) : rep (h.rep)
-    {
-      rep->count++;
-    }
-
-  ~curl_handle (void)
-    {
-      if (--rep->count == 0)
-        delete rep;
-    }
-
-  curl_handle& operator = (const curl_handle& h)
-    {
-      if (this != &h)
-        {
-          if (--rep->count == 0)
-            delete rep;
-
-          rep = h.rep;
-          rep->count++;
-        }
-      return *this;
-    }
-
-  bool is_valid (void) const
-    {
-      return rep->is_valid ();
-    }
-
-  std::string lasterror (void) const
-    {
-      return std::string (curl_easy_strerror (rep->errnum));
-    }
-
-  void set_ostream (std::ostream& os) const
-    {
-      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&os));
-    }
-
-  void set_istream (std::istream& is) const
-    {
-      setopt (CURLOPT_READDATA, static_cast<void*> (&is));
-    }
-
-  void ascii (void) const
-    {
-      setopt (CURLOPT_TRANSFERTEXT, 1);
-      rep->ascii = true;
-    }
-
-  void binary (void) const
-    {
-      setopt (CURLOPT_TRANSFERTEXT, 0);
-      rep->ascii = false;
-    }
-
-  bool is_ascii (void) const
-    {
-      return rep->is_ascii ();
-    }
-
-  bool is_binary (void) const
-    {
-      return rep->is_binary ();
-    }
-
-  void cwd (const std::string& path) const
-    {
-      struct curl_slist *slist = 0;
-      std::string cmd = "cwd " + path;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      setopt (CURLOPT_POSTQUOTE, slist);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-    }
-
-  void del (const std::string& file) const
-    {
-      struct curl_slist *slist = 0;
-      std::string cmd = "dele " + file;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      setopt (CURLOPT_POSTQUOTE, slist);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-    }
-
-  void rmdir (const std::string& path) const
-    {
-      struct curl_slist *slist = 0;
-      std::string cmd = "rmd " + path;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      setopt (CURLOPT_POSTQUOTE, slist);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-    }
-
-  bool mkdir (const std::string& path, bool curlerror = true) const
-    {
-      bool retval = false;
-      struct curl_slist *slist = 0;
-      std::string cmd = "mkd " + path;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      setopt (CURLOPT_POSTQUOTE, slist);
-      if (! error_state)
-        retval = perform (curlerror);
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-      return retval;
-    }
-
-  void rename (const std::string& oldname, const std::string& newname) const
-    {
-      struct curl_slist *slist = 0;
-      std::string cmd = "rnfr " + oldname;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      cmd = "rnto " + newname;
-      slist = curl_slist_append (slist, cmd.c_str ());
-      setopt (CURLOPT_POSTQUOTE, slist);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-    }
-
-  void put (const std::string& file, std::istream& is) const
-    {
-      std::string url = "ftp://" + rep->host + "/" + file;
-      setopt (CURLOPT_URL, url.c_str ());
-      setopt (CURLOPT_UPLOAD, 1);
-      setopt (CURLOPT_NOBODY, 0);
-      set_istream (is);
-      if (! error_state)
-        perform ();
-      set_istream (std::cin);
-      setopt (CURLOPT_NOBODY, 1);
-      setopt (CURLOPT_UPLOAD, 0);
-      url = "ftp://" + rep->host;
-      setopt (CURLOPT_URL, url.c_str ());
-    }
-
-  void get (const std::string& file, std::ostream& os) const
-    {
-      std::string url = "ftp://" + rep->host + "/" + file;
-      setopt (CURLOPT_URL, url.c_str ());
-      setopt (CURLOPT_NOBODY, 0);
-      set_ostream (os);
-      if (! error_state)
-        perform ();
-      set_ostream (octave_stdout);
-      setopt (CURLOPT_NOBODY, 1);
-      url = "ftp://" + rep->host;
-      setopt (CURLOPT_URL, url.c_str ());
-    }
-
-  void dir (void) const
-    {
-      std::string url = "ftp://" + rep->host + "/";
-      setopt (CURLOPT_URL, url.c_str ());
-      setopt (CURLOPT_NOBODY, 0);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_NOBODY, 1);
-      url = "ftp://" + rep->host;
-      setopt (CURLOPT_URL, url.c_str ());
-    }
-
-  string_vector list (void) const
-    {
-      std::ostringstream buf;
-      std::string url = "ftp://" + rep->host + "/";
-      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&buf));
-      setopt (CURLOPT_URL, url.c_str ());
-      setopt (CURLOPT_DIRLISTONLY, 1);
-      setopt (CURLOPT_NOBODY, 0);
-      if (! error_state)
-        perform ();
-      setopt (CURLOPT_NOBODY, 1);
-      url = "ftp://" + rep->host;
-      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&octave_stdout));
-      setopt (CURLOPT_DIRLISTONLY, 0);
-      setopt (CURLOPT_URL, url.c_str ());
-
-      // Count number of directory entries
-      std::string str = buf.str ();
-      octave_idx_type n = 0;
-      size_t pos = 0;
-      while (true)
-        {
-          pos = str.find_first_of ('\n', pos);
-          if (pos == std::string::npos)
-            break;
-          pos++;
-          n++;
-        }
-      string_vector retval (n);
-      pos = 0;
-      for (octave_idx_type i = 0; i < n; i++)
-        {
-          size_t newpos = str.find_first_of ('\n', pos);
-          if (newpos == std::string::npos)
-            break;
-
-          retval(i) = str.substr(pos, newpos - pos);
-          pos = newpos + 1;
-        }
-      return retval;
-    }
-
-  void get_fileinfo (const std::string& filename, double& filesize,
-                     time_t& filetime, bool& fileisdir) const
-    {
-      std::string path = pwd ();
-
-      std::string url = "ftp://" + rep->host + "/" + path + "/" + filename;
-      setopt (CURLOPT_URL, url.c_str ());
-      setopt (CURLOPT_FILETIME, 1);
-      setopt (CURLOPT_HEADERFUNCTION, throw_away);
-      setopt (CURLOPT_WRITEFUNCTION, throw_away);
-
-      // FIXME
-      // The MDTM command fails for a directory on the servers I tested
-      // so this is a means of testing for directories. It also means
-      // I can't get the date of directories!
-      if (! error_state)
-        {
-          if (! perform (false))
-            {
-              fileisdir = true;
-              filetime = -1;
-              filesize = 0;
-            }
-          else
-            {
-              fileisdir = false;
-              time_t ft;
-              curl_easy_getinfo (rep->handle (), CURLINFO_FILETIME, &ft);
-              filetime = ft;
-              double fs;
-              curl_easy_getinfo (rep->handle (),
-                                 CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs);
-              filesize = fs;
-            }
-        }
-
-      setopt (CURLOPT_WRITEFUNCTION, write_data);
-      setopt (CURLOPT_HEADERFUNCTION, 0);
-      setopt (CURLOPT_FILETIME, 0);
-      url = "ftp://" + rep->host;
-      setopt (CURLOPT_URL, url.c_str ());
-
-      // The MDTM command seems to reset the path to the root with the
-      // servers I tested with, so cd again into the correct path. Make
-      // the path absolute so that this will work even with servers that
-      // don't end up in the root after an MDTM command.
-      cwd ("/" + path);
-    }
-
-  std::string pwd (void) const
-    {
-      struct curl_slist *slist = 0;
-      std::string retval;
-      std::ostringstream buf;
-
-      slist = curl_slist_append (slist, "pwd");
-      setopt (CURLOPT_POSTQUOTE, slist);
-      setopt (CURLOPT_HEADERFUNCTION, write_data);
-      setopt (CURLOPT_WRITEHEADER, static_cast<void *>(&buf));
-
-      if (! error_state)
-        {
-          perform ();
-          retval = buf.str ();
-
-          // Can I assume that the path is alway in "" on the last line
-          size_t pos2 = retval.rfind ('"');
-          size_t pos1 = retval.rfind ('"', pos2 - 1);
-          retval = retval.substr (pos1 + 1, pos2 - pos1 - 1);
-        }
-      setopt (CURLOPT_HEADERFUNCTION, 0);
-      setopt (CURLOPT_WRITEHEADER, 0);
-      setopt (CURLOPT_POSTQUOTE, 0);
-      curl_slist_free_all (slist);
-
-      return retval;
-    }
-
-  bool perform (bool curlerror = true) const
-    {
-      return rep->perform (curlerror);
-    }
-
-private:
-  curl_handle_rep *rep;
-
-  std::string form_query_string (const Cell& param)
-    {
-      std::ostringstream query;
-
-      for (int i = 0; i < param.numel (); i += 2)
-        {
-          std::string name = param(i).string_value ();
-          std::string text = param(i+1).string_value ();
-
-          // Encode strings.
-          char *enc_name = curl_easy_escape (rep->handle (), name.c_str (),
-                                             name.length ());
-          char *enc_text = curl_easy_escape (rep->handle (), text.c_str (),
-                                             text.length ());
-
-          query << enc_name << "=" << enc_text;
-
-          curl_free (enc_name);
-          curl_free (enc_text);
-
-          if (i < param.numel ()-1)
-            query << "&";
-        }
-
-      query.flush ();
-
-      return query.str ();
-    }
-
-  void init (const std::string& user, const std::string& passwd,
-             std::istream& is, std::ostream& os)
-    {
-      // No data transfer by default
-      setopt (CURLOPT_NOBODY, 1);
-
-      // Set the username and password
-      std::string userpwd = user;
-      if (! passwd.empty ())
-        userpwd += ":" + passwd;
-      if (! userpwd.empty ())
-        setopt (CURLOPT_USERPWD, userpwd.c_str ());
-
-      // Define our callback to get called when there's data to be written.
-      setopt (CURLOPT_WRITEFUNCTION, write_data);
-
-      // Set a pointer to our struct to pass to the callback.
-      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&os));
-
-      // Define our callback to get called when there's data to be read
-      setopt (CURLOPT_READFUNCTION, read_data);
-
-      // Set a pointer to our struct to pass to the callback.
-      setopt (CURLOPT_READDATA, static_cast<void*> (&is));
-
-      // Follow redirects.
-      setopt (CURLOPT_FOLLOWLOCATION, true);
-
-      // Don't use EPSV since connecting to sites that don't support it
-      // will hang for some time (3 minutes?) before moving on to try PASV
-      // instead.
-      setopt (CURLOPT_FTP_USE_EPSV, false);
-
-      setopt (CURLOPT_NOPROGRESS, true);
-      setopt (CURLOPT_FAILONERROR, true);
-
-      setopt (CURLOPT_POSTQUOTE, 0);
-      setopt (CURLOPT_QUOTE, 0);
-    }
-
-#undef setopt
-};
-
-class
-curl_handles
-{
-public:
-
-  typedef std::map<std::string, curl_handle>::iterator iterator;
-  typedef std::map<std::string, curl_handle>::const_iterator const_iterator;
-
-  curl_handles (void) : map ()
-   {
-     curl_global_init (CURL_GLOBAL_DEFAULT);
-   }
-
-  ~curl_handles (void)
-    {
-      // Remove the elements of the map explicitly as they should
-      // be deleted before the call to curl_global_cleanup
-      map.erase (begin (), end ());
-
-      curl_global_cleanup ();
-    }
-
-  iterator begin (void) { return iterator (map.begin ()); }
-  const_iterator begin (void) const { return const_iterator (map.begin ()); }
-
-  iterator end (void) { return iterator (map.end ()); }
-  const_iterator end (void) const { return const_iterator (map.end ()); }
-
-  iterator seek (const std::string& k) { return map.find (k); }
-  const_iterator seek (const std::string& k) const { return map.find (k); }
-
-  std::string key (const_iterator p) const { return p->first; }
-
-  curl_handle& contents (const std::string& k)
-    {
-      return map[k];
-    }
-
-  curl_handle contents (const std::string& k) const
-    {
-      const_iterator p = seek (k);
-      return p != end () ? p->second : curl_handle ();
-    }
-
-  curl_handle& contents (iterator p)
-    { return p->second; }
-
-  curl_handle contents (const_iterator p) const
-    { return p->second; }
-
-  void del (const std::string& k)
-    {
-      iterator p = map.find (k);
-
-      if (p != map.end ())
-        map.erase (p);
-    }
-
-private:
-  std::map<std::string, curl_handle> map;
-};
-
-static curl_handles handles;
-
-static void
-cleanup_urlwrite (std::string filename)
-{
-  octave_unlink (filename);
-}
-
-static void
-reset_path (const curl_handle curl)
-{
-  curl.cwd ("..");
-}
-
-static void
-delete_file (std::string file)
-{
-  octave_unlink (file);
-}
-#endif
-
-DEFUN_DLD (urlwrite, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {} urlwrite (@var{url}, @var{localfile})\n\
-@deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})\n\
-@deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})\n\
-@deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})\n\
-Download a remote file specified by its @var{url} and save it as\n\
-@var{localfile}.  For example:\n\
-\n\
-@example\n\
-@group\n\
-urlwrite (\"ftp://ftp.octave.org/pub/octave/README\",\n\
-          \"README.txt\");\n\
-@end group\n\
-@end example\n\
-\n\
-The full path of the downloaded file is returned in @var{f}.  The\n\
-variable @var{success} is 1 if the download was successful,\n\
-otherwise it is 0 in which case @var{message} contains an error\n\
-message.  If no output argument is specified and an error occurs,\n\
-then the error is signaled through Octave's error handling mechanism.\n\
-\n\
-This function uses libcurl.  Curl supports, among others, the HTTP,\n\
-FTP and FILE protocols.  Username and password may be specified in\n\
-the URL, for example:\n\
-\n\
-@example\n\
-@group\n\
-urlwrite (\"http://username:password@@example.com/file.txt\",\n\
-          \"file.txt\");\n\
-@end group\n\
-@end example\n\
-\n\
-GET and POST requests can be specified by @var{method} and @var{param}.\n\
-The parameter @var{method} is either @samp{get} or @samp{post}\n\
-and @var{param} is a cell array of parameter and value pairs.\n\
-For example:\n\
-\n\
-@example\n\
-@group\n\
-urlwrite (\"http://www.google.com/search\", \"search.html\",\n\
-          \"get\", @{\"query\", \"octave\"@});\n\
-@end group\n\
-@end example\n\
-@seealso{urlread}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-#ifdef HAVE_CURL
-
-  int nargin = args.length ();
-
-  // verify arguments
-  if (nargin != 2 && nargin != 4)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  std::string url = args(0).string_value ();
-
-  if (error_state)
-    {
-      error ("urlwrite: URL must be a character string");
-      return retval;
-    }
-
-  // name to store the file if download is succesful
-  std::string filename = args(1).string_value ();
-
-  if (error_state)
-    {
-      error ("urlwrite: LOCALFILE must be a character string");
-      return retval;
-    }
-
-  std::string method;
-  Cell param; // empty cell array
-
-  if (nargin == 4)
-    {
-      method = args(2).string_value ();
-
-      if (error_state)
-        {
-          error ("urlwrite: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      if (method != "get" && method != "post")
-        {
-          error ("urlwrite: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      param = args(3).cell_value ();
-
-      if (error_state)
-        {
-          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell");
-          return retval;
-        }
-
-
-      if (param.numel () % 2 == 1 )
-        {
-          error ("urlwrite: number of elements in PARAM must be even");
-          return retval;
-        }
-    }
-
-  // The file should only be deleted if it doesn't initially exist, we
-  // create it, and the download fails.  We use unwind_protect to do
-  // it so that the deletion happens no matter how we exit the function.
-
-  file_stat fs (filename);
-
-  std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary);
-
-  if (! ofile.is_open ())
-    {
-      error ("urlwrite: unable to open file");
-      return retval;
-    }
-
-  unwind_protect_safe frame;
-
-  frame.add_fcn (cleanup_urlwrite, filename);
-
-  bool ok;
-  curl_handle curl = curl_handle (url, method, param, ofile, ok);
-
-  ofile.close ();
-
-  if (!error_state)
-    frame.discard ();
-  else
-    frame.run ();
-
-  if (nargout > 0)
-    {
-      if (ok)
-        {
-          retval(2) = std::string ();
-          retval(1) = true;
-          retval(0) = octave_env::make_absolute (filename);
-        }
-      else
-        {
-          retval(2) = curl.lasterror ();
-          retval(1) = false;
-          retval(0) = std::string ();
-        }
-    }
-
-  if (nargout < 2 && ! ok)
-    error ("urlwrite: curl: %s", curl.lasterror ().c_str ());
-
-#else
-  error ("urlwrite: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (urlread, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{s} =} urlread (@var{url})\n\
-@deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})\n\
-@deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})\n\
-@deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})\n\
-Download a remote file specified by its @var{url} and return its content\n\
-in string @var{s}.  For example:\n\
-\n\
-@example\n\
-s = urlread (\"ftp://ftp.octave.org/pub/octave/README\");\n\
-@end example\n\
-\n\
-The variable @var{success} is 1 if the download was successful,\n\
-otherwise it is 0 in which case @var{message} contains an error\n\
-message.  If no output argument is specified and an error occurs,\n\
-then the error is signaled through Octave's error handling mechanism.\n\
-\n\
-This function uses libcurl.  Curl supports, among others, the HTTP,\n\
-FTP and FILE protocols.  Username and password may be specified in the\n\
-URL@.  For example:\n\
-\n\
-@example\n\
-s = urlread (\"http://user:password@@example.com/file.txt\");\n\
-@end example\n\
-\n\
-GET and POST requests can be specified by @var{method} and @var{param}.\n\
-The parameter @var{method} is either @samp{get} or @samp{post}\n\
-and @var{param} is a cell array of parameter and value pairs.\n\
-For example:\n\
-\n\
-@example\n\
-@group\n\
-s = urlread (\"http://www.google.com/search\", \"get\",\n\
-            @{\"query\", \"octave\"@});\n\
-@end group\n\
-@end example\n\
-@seealso{urlwrite}\n\
-@end deftypefn")
-{
-  // Octave's return value
-  octave_value_list retval;
-
-#ifdef HAVE_CURL
-
-  int nargin = args.length ();
-
-  // verify arguments
-  if (nargin != 1  && nargin != 3)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  std::string url = args(0).string_value ();
-
-  if (error_state)
-    {
-      error ("urlread: URL must be a character string");
-      return retval;
-    }
-
-  std::string method;
-  Cell param; // empty cell array
-
-  if (nargin == 3)
-    {
-      method = args(1).string_value ();
-
-      if (error_state)
-        {
-          error ("urlread: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      if (method != "get" && method != "post")
-        {
-          error ("urlread: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      param = args(2).cell_value ();
-
-      if (error_state)
-        {
-          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell");
-          return retval;
-        }
-
-      if (param.numel () % 2 == 1 )
-        {
-          error ("urlread: number of elements in PARAM must be even");
-          return retval;
-        }
-    }
-
-  std::ostringstream buf;
-
-  bool ok;
-  curl_handle curl = curl_handle (url, method, param, buf, ok);
-
-  if (nargout > 0)
-    {
-      // Return empty string if no error occured.
-      retval(2) = ok ? "" : curl.lasterror ();
-      retval(1) = ok;
-      retval(0) = buf.str ();
-    }
-
-  if (nargout < 2 && ! ok)
-    error ("urlread: curl: %s", curl.lasterror().c_str());
-
-#else
-  error ("urlread: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (__ftp__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {} __ftp__ (@var{handle}, @var{host})\n\
-@deftypefnx {Loadable Function} {} __ftp__ (@var{handle}, @var{host}, @var{username}, @var{password})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-  std::string handle;
-  std::string host;
-  std::string user = "anonymous";
-  std::string passwd = "";
-
-  if (nargin < 2 || nargin > 4)
-    error ("incorrect number of arguments");
-  else
-    {
-      handle = args(0).string_value ();
-      host = args(1).string_value ();
-
-      if (nargin > 1)
-        user = args(2).string_value ();
-
-      if (nargin > 2)
-        passwd = args(3).string_value ();
-
-      if (!error_state)
-        {
-          handles.contents (handle) = curl_handle (host, user, passwd);
-
-          if (error_state)
-            handles.del (handle);
-        }
-    }
-#else
-  error ("__ftp__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_pwd__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_pwd__ (@var{handle})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-  octave_value retval;
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    error ("__ftp_pwd__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            retval = curl.pwd ();
-          else
-            error ("__ftp_pwd__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_pwd__: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (__ftp_cwd__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_cwd__ (@var{handle}, @var{path})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 1 && nargin != 2)
-    error ("__ftp_cwd__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string path = "";
-
-      if (nargin > 1)
-        path  = args(1).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.cwd (path);
-          else
-            error ("__ftp_cwd__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_cwd__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_dir__, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_dir__ (@var{handle})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-  octave_value retval;
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    error ("__ftp_dir__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            {
-              if (nargout == 0)
-                curl.dir ();
-              else
-                {
-                  string_vector sv = curl.list ();
-                  octave_idx_type n = sv.length ();
-                  if (n == 0)
-                    {
-                      string_vector flds (5);
-                      flds(0) = "name";
-                      flds(1) = "date";
-                      flds(2) = "bytes";
-                      flds(3) = "isdir";
-                      flds(4) = "datenum";
-                      retval = octave_map (flds);
-                    }
-                  else
-                    {
-                      octave_map st;
-                      Cell filectime (dim_vector (n, 1));
-                      Cell filesize (dim_vector (n, 1));
-                      Cell fileisdir (dim_vector (n, 1));
-                      Cell filedatenum (dim_vector (n, 1));
-
-                      st.assign ("name", Cell (sv));
-
-                      for (octave_idx_type i = 0; i < n; i++)
-                        {
-                          time_t ftime;
-                          bool fisdir;
-                          double fsize;
-
-                          curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
-
-                          fileisdir (i) = fisdir;
-                          filectime (i) = ctime (&ftime);
-                          filesize (i) = fsize;
-                          filedatenum (i) = double (ftime);
-                        }
-                      st.assign ("date", filectime);
-                      st.assign ("bytes", filesize);
-                      st.assign ("isdir", fileisdir);
-                      st.assign ("datenum", filedatenum);
-                      retval = st;
-                    }
-                }
-            }
-          else
-            error ("__ftp_dir__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_dir__: not available in this version of Octave");
-#endif
-
-  return retval;
-}
-
-DEFUN_DLD (__ftp_ascii__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_ascii__ (@var{handle})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    error ("__ftp_ascii__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.ascii ();
-          else
-            error ("__ftp_ascii__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_ascii__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_binary__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_binary__ (@var{handle})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    error ("__ftp_binary__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.binary ();
-          else
-            error ("__ftp_binary__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_binary__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_close__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_close__ (@var{handle})\n\
- Undocumented internal function\n\
- @end deftypefn")
- {
- #ifdef HAVE_CURL
-   int nargin = args.length ();
-
-   if (nargin != 1)
-     error ("__ftp_close__: incorrect number of arguments");
-   else
-     {
-       std::string handle = args(0).string_value ();
-
-       if (!error_state)
-         handles.del (handle);
-     }
- #else
-   error ("__ftp_close__: not available in this version of Octave");
- #endif
-
-   return octave_value ();
- }
-
-DEFUN_DLD (__ftp_mode__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_mode__ (@var{handle})\n\
- Undocumented internal function\n\
- @end deftypefn")
- {
-   octave_value retval;
- #ifdef HAVE_CURL
-   int nargin = args.length ();
-
-   if (nargin != 1)
-     error ("__ftp_mode__: incorrect number of arguments");
-   else
-     {
-       std::string handle = args(0).string_value ();
-
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            retval = (curl.is_ascii () ? "ascii" : "binary");
-          else
-            error ("__ftp_binary__: invalid ftp handle");
-        }
-     }
- #else
-   error ("__ftp_mode__: not available in this version of Octave");
- #endif
-
-   return retval;
- }
-
-DEFUN_DLD (__ftp_delete__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_delete__ (@var{handle}, @var{path})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 2)
-    error ("__ftp_delete__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string file = args(1).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.del (file);
-          else
-            error ("__ftp_delete__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_delete__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_rmdir__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_rmdir__ (@var{handle}, @var{path})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 2)
-    error ("__ftp_rmdir__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string dir = args(1).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.rmdir (dir);
-          else
-            error ("__ftp_rmdir__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_rmdir__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_mkdir__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_mkdir__ (@var{handle}, @var{path})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 2)
-    error ("__ftp_mkdir__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string dir = args(1).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.mkdir (dir);
-          else
-            error ("__ftp_mkdir__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_mkdir__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-DEFUN_DLD (__ftp_rename__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_rename__ (@var{handle}, @var{path})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 3)
-    error ("__ftp_rename__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string oldname = args(1).string_value ();
-      std::string newname = args(2).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            curl.rename (oldname, newname);
-          else
-            error ("__ftp_rename__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_rename__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
-
-#ifdef HAVE_CURL
-static string_vector
-mput_directory (const curl_handle& curl, const std::string& base,
-                const std::string& dir)
-{
-  string_vector retval;
-
-  if (! curl.mkdir (dir, false))
-    warning ("__ftp_mput__: can not create the remote directory ""%s""",
-             (base.length () == 0 ? dir : base +
-              file_ops::dir_sep_str () + dir).c_str ());
-
-  curl.cwd (dir);
-
-  if (! error_state)
-    {
-      unwind_protect_safe frame;
-
-      frame.add_fcn (reset_path, curl);
-
-      std::string realdir = base.length () == 0 ? dir : base +
-                         file_ops::dir_sep_str () + dir;
-
-      dir_entry dirlist (realdir);
-
-      if (dirlist)
-        {
-          string_vector files = dirlist.read ();
-
-          for (octave_idx_type i = 0; i < files.length (); i++)
-            {
-              std::string file = files (i);
-
-              if (file == "." || file == "..")
-                continue;
-
-              std::string realfile = realdir + file_ops::dir_sep_str () + file;
-              file_stat fs (realfile);
-
-              if (! fs.exists ())
-                {
-                  error ("__ftp__mput: file ""%s"" does not exist",
-                         realfile.c_str ());
-                  break;
-                }
-
-              if (fs.is_dir ())
-                {
-                  retval.append (mput_directory (curl, realdir, file));
-
-                  if (error_state)
-                    break;
-                }
-              else
-                {
-                  // FIXME Does ascii mode need to be flagged here?
-                  std::ifstream ifile (realfile.c_str (), std::ios::in |
-                                       std::ios::binary);
-
-                  if (! ifile.is_open ())
-                    {
-                      error ("__ftp_mput__: unable to open file ""%s""",
-                             realfile.c_str ());
-                      break;
-                    }
-
-                  curl.put (file, ifile);
-
-                  ifile.close ();
-
-                  if (error_state)
-                    break;
-
-                  retval.append (realfile);
-                }
-            }
-        }
-      else
-        error ("__ftp_mput__: can not read the directory ""%s""",
-               realdir.c_str ());
-    }
-
-  return retval;
-}
-#endif
-
-DEFUN_DLD (__ftp_mput__, args, nargout,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_mput__ (@var{handle}, @var{files})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-  string_vector retval;
-
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 2)
-    error ("__ftp_mput__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string pat = args(1).string_value ();
-
-      if (!error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            {
-              glob_match pattern (file_ops::tilde_expand (pat));
-              string_vector files = pattern.glob ();
-
-              for (octave_idx_type i = 0; i < files.length (); i++)
-                {
-                  std::string file = files (i);
-
-                  file_stat fs (file);
-
-                  if (! fs.exists ())
-                    {
-                      error ("__ftp__mput: file does not exist");
-                      break;
-                    }
-
-                  if (fs.is_dir ())
-                    {
-                      retval.append (mput_directory (curl, "", file));
-                      if (error_state)
-                        break;
-                    }
-                  else
-                    {
-                      // FIXME Does ascii mode need to be flagged here?
-                      std::ifstream ifile (file.c_str (), std::ios::in |
-                                           std::ios::binary);
-
-                      if (! ifile.is_open ())
-                        {
-                          error ("__ftp_mput__: unable to open file");
-                          break;
-                        }
-
-                      curl.put (file, ifile);
-
-                      ifile.close ();
-
-                      if (error_state)
-                        break;
-
-                      retval.append (file);
-                    }
-                }
-            }
-          else
-            error ("__ftp_mput__: invalid ftp handle");
-        }
-    }
-#else
-  error ("__ftp_mput__: not available in this version of Octave");
-#endif
-
-  return (nargout > 0 ? octave_value (retval) : octave_value ());
-}
-
-#ifdef HAVE_CURL
-static void
-getallfiles (const curl_handle& curl, const std::string& dir,
-             const std::string& target)
-{
-  std::string sep = file_ops::dir_sep_str ();
-  file_stat fs (dir);
-
-  if (!fs || !fs.is_dir ())
-    {
-      std::string msg;
-      int status = octave_mkdir (dir, 0777, msg);
-
-      if (status < 0)
-        error ("__ftp_mget__: can't create directory %s%s%s. %s",
-               target.c_str (), sep.c_str (), dir.c_str (), msg.c_str ());
-    }
-
-  if (! error_state)
-    {
-      curl.cwd (dir);
-
-      if (! error_state)
-        {
-          unwind_protect_safe frame;
-
-          frame.add_fcn (reset_path, curl);
-
-          string_vector sv = curl.list ();
-
-          for (octave_idx_type i = 0; i < sv.length (); i++)
-            {
-              time_t ftime;
-              bool fisdir;
-              double fsize;
-
-              curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
-
-              if (fisdir)
-                getallfiles (curl, sv(i), target + dir + sep);
-              else
-                {
-                  std::string realfile = target + dir + sep + sv(i);
-                  std::ofstream ofile (realfile.c_str (),
-                                       std::ios::out |
-                                       std::ios::binary);
-
-                  if (! ofile.is_open ())
-                    {
-                      error ("__ftp_mget__: unable to open file");
-                      break;
-                    }
-
-                  unwind_protect_safe frame2;
-
-                  frame2.add_fcn (delete_file, realfile);
-
-                  curl.get (sv(i), ofile);
-
-                  ofile.close ();
-
-                  if (!error_state)
-                    frame2.discard ();
-                  else
-                    frame2.run ();
-                }
-
-              if (error_state)
-                break;
-            }
-        }
-    }
-}
-#endif
-
-DEFUN_DLD (__ftp_mget__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __ftp_mget__ (@var{handle}, @var{files})\n\
-Undocumented internal function\n\
-@end deftypefn")
-{
-#ifdef HAVE_CURL
-  int nargin = args.length ();
-
-  if (nargin != 2 && nargin != 3)
-    error ("__ftp_mget__: incorrect number of arguments");
-  else
-    {
-      std::string handle = args(0).string_value ();
-      std::string file = args(1).string_value ();
-      std::string target;
-
-      if (nargin == 3)
-        target = args(2).string_value () + file_ops::dir_sep_str ();
-
-      if (! error_state)
-        {
-          const curl_handle curl = handles.contents (handle);
-
-          if (curl.is_valid ())
-            {
-              string_vector sv = curl.list ();
-              octave_idx_type n = 0;
-              glob_match pattern (file);
-
-              for (octave_idx_type i = 0; i < sv.length (); i++)
-                {
-                  if (pattern.match (sv(i)))
-                    {
-                      n++;
-
-                      time_t ftime;
-                      bool fisdir;
-                      double fsize;
-
-                      curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
-
-                      if (fisdir)
-                        getallfiles (curl, sv(i), target);
-                      else
-                        {
-                          std::ofstream ofile ((target + sv(i)).c_str (),
-                                               std::ios::out |
-                                               std::ios::binary);
-
-                          if (! ofile.is_open ())
-                            {
-                              error ("__ftp_mget__: unable to open file");
-                              break;
-                            }
-
-                          unwind_protect_safe frame;
-
-                          frame.add_fcn (delete_file, target + sv(i));
-
-                          curl.get (sv(i), ofile);
-
-                          ofile.close ();
-
-                          if (!error_state)
-                            frame.discard ();
-                          else
-                            frame.run ();
-                        }
-
-                      if (error_state)
-                        break;
-                    }
-                }
-              if (n == 0)
-                error ("__ftp_mget__: file not found");
-            }
-        }
-    }
-#else
-  error ("__ftp_mget__: not available in this version of Octave");
-#endif
-
-  return octave_value ();
-}
--- a/src/Makefile.am	Tue Jul 31 20:46:47 2012 -0400
+++ b/src/Makefile.am	Tue Jul 31 21:57:58 2012 -0400
@@ -314,14 +314,14 @@
 include operators/module.mk
 include template-inst/module.mk
 include corefcn/module.mk
-include DLD-FUNCTIONS/module.mk
+include dldfcn/module.mk
 
-$(srcdir)/DLD-FUNCTIONS/module.mk: $(srcdir)/DLD-FUNCTIONS/config-module.sh $(srcdir)/DLD-FUNCTIONS/config-module.awk $(srcdir)/DLD-FUNCTIONS/module-files
-	$(srcdir)/DLD-FUNCTIONS/config-module.sh $(top_srcdir)
+$(srcdir)/dldfcn/module.mk: $(srcdir)/dldfcn/config-module.sh $(srcdir)/dldfcn/config-module.awk $(srcdir)/dldfcn/module-files
+	$(srcdir)/dldfcn/config-module.sh $(top_srcdir)
 
 if AMCOND_ENABLE_DYNAMIC_LINKING
-  OCT_FILES = $(DLD_FUNCTIONS_LIBS:.la=.oct)
-  OCT_STAMP_FILES = $(subst DLD-FUNCTIONS/,DLD-FUNCTIONS/$(am__leading_dot),$(DLD_FUNCTIONS_LIBS:.la=.oct-stamp))
+  OCT_FILES = $(DLDFCN_LIBS:.la=.oct)
+  OCT_STAMP_FILES = $(subst dldfcn/,dldfcn/$(am__leading_dot),$(DLDFCN_LIBS:.la=.oct-stamp))
   DLD_LIBOCTINTERP_LIBADD = liboctinterp.la
 else
   OCT_FILES =
@@ -387,17 +387,17 @@
 ## Section for defining and creating DEF_FILES
 SRC_DEF_FILES := $(shell $(srcdir)/find-defun-files.sh "$(srcdir)" $(DIST_SRC))
 
-DLD_FUNCTIONS_DEF_FILES = $(DLD_FUNCTIONS_SRC:.cc=.df)
+DLDFCN_DEF_FILES = $(DLDFCN_SRC:.cc=.df)
 
 ## builtins.cc depends on $(DEF_FILES), so DEF_FILES should only include
 ## .df files that correspond to sources included in liboctave.
 if AMCOND_ENABLE_DYNAMIC_LINKING
   DEF_FILES = $(SRC_DEF_FILES)
 else
-  DEF_FILES = $(SRC_DEF_FILES) $(DLD_FUNCTIONS_DEF_FILES)
+  DEF_FILES = $(SRC_DEF_FILES) $(DLDFCN_DEF_FILES)
 endif
 
-ALL_DEF_FILES = $(SRC_DEF_FILES) $(DLD_FUNCTIONS_DEF_FILES)
+ALL_DEF_FILES = $(SRC_DEF_FILES) $(DLDFCN_DEF_FILES)
 
 $(SRC_DEF_FILES): mkdefs Makefile
 
@@ -483,10 +483,10 @@
 	$(MAKE) -C $(@D) $(@F)
 
 if AMCOND_ENABLE_DYNAMIC_LINKING
-DLD_FUNCTIONS_PKG_ADD_FILE = DLD-FUNCTIONS/PKG_ADD
+DLDFCN_PKG_ADD_FILE = dldfcn/PKG_ADD
 
-DLD-FUNCTIONS/PKG_ADD: $(DLD_FUNCTIONS_DEF_FILES) mk-pkg-add
-	$(srcdir)/mk-pkg-add $(DLD_FUNCTIONS_DEF_FILES) > $@-t
+dldfcn/PKG_ADD: $(DLDFCN_DEF_FILES) mk-pkg-add
+	$(srcdir)/mk-pkg-add $(DLDFCN_DEF_FILES) > $@-t
 	mv $@-t $@
 endif
 
@@ -510,9 +510,9 @@
 	$(top_srcdir)/build-aux/move-if-change $@ DOCSTRINGS
 	touch $@
 
-all-local: $(OCT_STAMP_FILES) $(DLD_FUNCTIONS_PKG_ADD_FILE) .DOCSTRINGS
+all-local: $(OCT_STAMP_FILES) $(DLDFCN_PKG_ADD_FILE) .DOCSTRINGS
 else
-all-local: $(OCT_STAMP_FILES) $(DLD_FUNCTIONS_PKG_ADD_FILE)
+all-local: $(OCT_STAMP_FILES) $(DLDFCN_PKG_ADD_FILE)
 endif
 
 if AMCOND_BUILD_COMPILED_AUX_PROGRAMS
@@ -566,11 +566,11 @@
 if AMCOND_ENABLE_DYNAMIC_LINKING
 install-oct:
 	$(top_srcdir)/build-aux/mkinstalldirs $(DESTDIR)$(octfiledir)
-	if [ -n "`cat $(DLD_FUNCTIONS_PKG_ADD_FILE)`" ]; then \
-	  $(INSTALL_DATA) $(DLD_FUNCTIONS_PKG_ADD_FILE) $(DESTDIR)$(octfiledir)/PKG_ADD; \
+	if [ -n "`cat $(DLDFCN_PKG_ADD_FILE)`" ]; then \
+	  $(INSTALL_DATA) $(DLDFCN_PKG_ADD_FILE) $(DESTDIR)$(octfiledir)/PKG_ADD; \
 	fi
 	cd $(DESTDIR)$(octlibdir) && \
-	for ltlib in $(DLD_FUNCTIONS_LIBS); do \
+	for ltlib in $(DLDFCN_LIBS); do \
 	  f=`echo $$ltlib | $(SED) 's,.*/,,'`; \
 	  dl=`$(SED) -n -e "s/dlname='\([^']*\)'/\1/p" < $$f`; \
 	  if [ -n "$$dl" ]; then \
@@ -595,7 +595,7 @@
 
 CLEANFILES = \
   $(bin_SCRIPTS) \
-  $(DLD_FUNCTIONS_PKG_ADD_FILE) \
+  $(DLDFCN_PKG_ADD_FILE) \
   graphics-props.cc \
   oct-parse.output
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__delaunayn__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,229 @@
+/*
+
+Copyright (C) 2000-2012 Kai Habel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+  16. July 2000 - Kai Habel: first release
+
+  25. September 2002 - Changes by Rafael Laboissiere <rafael@laboissiere.net>
+
+  * Added Qbb option to normalize the input and avoid crashes in Octave.
+  * delaunayn accepts now a second (optional) argument that must be a string
+  containing extra options to the qhull command.
+  * Fixed doc string.  The dimension of the result matrix is [m, dim+1], and
+  not [n, dim-1].
+
+  6. June 2006: Changes by Alexander Barth <abarth@marine.usf.edu>
+
+  * triangulate non-simplicial facets
+  * allow options to be specified as cell array of strings
+  * change the default options (for compatibility with matlab)
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "Cell.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "unwind-prot.h"
+
+#if defined (HAVE_QHULL)
+# include "oct-qhull.h"
+# if defined (NEED_QHULL_VERSION)
+char qh_version[] = "__delaunayn__.oct 2007-08-21";
+# endif
+#endif
+
+static void
+close_fcn (FILE *f)
+{
+  gnulib::fclose (f);
+}
+
+DEFUN_DLD (__delaunayn__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts})\n\
+@deftypefnx {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts}, @var{options})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+
+{
+  octave_value_list retval;
+
+#if defined (HAVE_QHULL)
+
+  retval(0) = 0.0;
+
+  int nargin = args.length ();
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix p (args(0).matrix_value ());
+  const octave_idx_type dim = p.columns ();
+  const octave_idx_type n = p.rows ();
+
+  // Default options
+  std::string options;
+  if (dim <= 3)
+    options = "Qt Qbb Qc Qz";
+  else
+    options = "Qt Qbb Qc Qx";
+
+  if (nargin == 2)
+    {
+      if (args(1).is_string ())
+        options = args(1).string_value ();
+      else if (args(1).is_empty ())
+        ;  // Use default options
+      else if (args(1).is_cellstr ())
+        {
+          options = "";
+          Array<std::string> tmp = args(1).cellstr_value ();
+
+          for (octave_idx_type i = 0; i < tmp.numel (); i++)
+            options += tmp(i) + " ";
+        }
+      else
+        {
+          error ("__delaunayn__: OPTIONS argument must be a string, cell array of strings, or empty");
+          return retval;
+        }
+    }
+
+  if (n > dim + 1)
+    {
+      p = p.transpose ();
+      double *pt_array = p.fortran_vec ();
+      boolT ismalloc = false;
+
+      // Qhull flags argument is not const char*
+      OCTAVE_LOCAL_BUFFER (char, flags, 9 + options.length ());
+
+      sprintf (flags, "qhull d %s", options.c_str ());
+
+      unwind_protect frame;
+
+      // Replace the outfile pointer with stdout for debugging information.
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
+      FILE *outfile = gnulib::fopen ("NUL", "w");
+#else
+      FILE *outfile = gnulib::fopen ("/dev/null", "w");
+#endif
+      FILE *errfile = stderr;
+
+      if (outfile)
+        frame.add_fcn (close_fcn, outfile);
+      else
+        {
+          error ("__delaunayn__: unable to create temporary file for output");
+          return retval;
+        }
+
+      int exitcode = qh_new_qhull (dim, n, pt_array, 
+                                   ismalloc, flags, outfile, errfile);
+      if (! exitcode)
+        {
+          // triangulate non-simplicial facets
+          qh_triangulate ();
+
+          facetT *facet;
+          vertexT *vertex, **vertexp;
+          octave_idx_type nf = 0, i = 0;
+
+          FORALLfacets
+            {
+              if (! facet->upperdelaunay)
+                nf++;
+
+              // Double check.  Non-simplicial facets will cause segfault below
+              if (! facet->simplicial)
+                {
+                  error ("__delaunayn__: Qhull returned non-simplicial facets -- try delaunayn with different options");
+                  exitcode = 1;
+                  break;
+                }
+            }
+
+          if (! exitcode)
+            {
+              Matrix simpl (nf, dim+1);
+
+              FORALLfacets
+                {
+                  if (! facet->upperdelaunay)
+                    {
+                      octave_idx_type j = 0;
+
+                      FOREACHvertex_ (facet->vertices)
+                        {
+                          simpl(i, j++) = 1 + qh_pointid(vertex->point);
+                        }
+                      i++;
+                    }
+                }
+
+              retval(0) = simpl;
+            }
+        }
+      else
+        error ("__delaunayn__: qhull failed");
+
+      // Free memory from Qhull
+      qh_freeqhull (! qh_ALL);
+
+      int curlong, totlong;
+      qh_memfreeshort (&curlong, &totlong);
+
+      if (curlong || totlong)
+        warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
+                 totlong, curlong);
+    }
+  else if (n == dim + 1)
+    {
+      // one should check if nx points span a simplex
+      // I will look at this later.
+      RowVector vec (n);
+      for (octave_idx_type i = 0; i < n; i++)
+        vec(i) = i + 1.0;
+
+      retval(0) = vec;
+    }
+
+#else
+  error ("__delaunayn__: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__dsearchn__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,115 @@
+/*
+
+Copyright (C) 2007-2012 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "lo-math.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+
+DEFUN_DLD (__dsearchn__, args, ,
+        "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{idx}, @var{d}] =} dsearch (@var{x}, @var{xi})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix x = args(0).matrix_value ().transpose ();
+  Matrix xi = args(1).matrix_value ().transpose ();
+
+  if (! error_state)
+    {
+      if (x.rows () != xi.rows () || x.columns () < 1)
+        error ("__dsearch__: number of rows of X and XI must match");
+      else
+        {
+          octave_idx_type n = x.rows ();
+          octave_idx_type nx = x.columns ();
+          octave_idx_type nxi = xi.columns ();
+
+          ColumnVector idx (nxi);
+          double *pidx = idx.fortran_vec ();
+          ColumnVector dist (nxi);
+          double *pdist = dist.fortran_vec ();
+
+#define DIST(dd, y, yi, m) \
+  dd = 0.; \
+  for (octave_idx_type k = 0; k < m; k++) \
+   { \
+     double yd = y[k] - yi[k]; \
+     dd += yd * yd; \
+   } \
+  dd = sqrt (dd);
+
+          const double *pxi = xi.fortran_vec ();
+          for (octave_idx_type i = 0; i < nxi; i++)
+            {
+              double d0;
+              const double *px = x.fortran_vec ();
+              DIST(d0, px, pxi, n);
+              *pidx = 1.;
+              for (octave_idx_type j = 1; j < nx; j++)
+                {
+                  px += n;
+                  double d;
+                  DIST (d, px, pxi, n);
+                  if (d < d0)
+                    {
+                      d0 = d;
+                      *pidx = static_cast<double>(j + 1);
+                    }
+                  OCTAVE_QUIT;
+                }
+
+              *pdist++ = d0;
+              pidx++;
+              pxi += n;
+            }
+
+          retval(1) = dist;
+          retval(0) = idx;
+        }
+    }
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__fltk_uigetfile__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,142 @@
+/*
+
+Copyright (C) 2010-2012 Kai Habel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined (HAVE_FLTK)
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <FL/Fl.H>
+#include <FL/Fl_File_Chooser.H>
+
+// FLTK headers may include X11/X.h which defines Complex, and that
+// conflicts with Octave's Complex typedef.  We don't need the X11
+// Complex definition in this file, so remove it before including Octave
+// headers which may require Octave's Complex typedef.
+#undef Complex
+
+#include "defun-dld.h"
+#include "file-ops.h"
+
+DEFUN_DLD (__fltk_uigetfile__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __fltk_uigetfile__ (@dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  // Expected argument list:
+  //
+  //   args(0) ... FileFilter in fltk format
+  //   args(1) ... Title
+  //   args(2) ... Default Filename
+  //   args(3) ... PostionValue [x,y]
+  //   args(4) ... SelectValue "on"/"off"/"dir"/"create"
+
+  octave_value_list retval (3, octave_value (0));
+
+  std::string file_filter = args(0).string_value ();
+  std::string title = args(1).string_value ();
+  std::string default_name = args(2).string_value ();
+  Matrix pos = args(3).matrix_value ();
+
+  int multi_type = Fl_File_Chooser::SINGLE;
+  std::string flabel = "Filename:";
+
+  std::string multi = args(4).string_value ();
+  if (multi == "on")
+    multi_type = Fl_File_Chooser::MULTI;
+  else if (multi == "dir")
+    {
+      multi_type = Fl_File_Chooser::DIRECTORY;
+      flabel = "Directory:";
+    }
+  else if (multi == "create")
+    multi_type = Fl_File_Chooser::CREATE;
+
+  Fl_File_Chooser::filename_label = flabel.c_str ();
+
+  Fl_File_Chooser fc (default_name.c_str (), file_filter.c_str (),
+                      multi_type, title.c_str ());
+
+  fc.preview (0);
+
+  if (multi_type == Fl_File_Chooser::CREATE)
+    fc.ok_label ("Save");
+
+  fc.show ();
+
+  while (fc.shown ())
+    Fl::wait ();
+
+  if (fc.value ())
+    {
+      int file_count = fc.count ();
+      std::string fname;
+
+      //fltk uses forward slash even for windows
+      std::string sep = "/";
+      std::size_t idx;
+
+      if (file_count == 1 && multi_type != Fl_File_Chooser::DIRECTORY)
+        {
+          fname = fc.value ();
+          idx = fname.find_last_of (sep);
+          retval(0) = fname.substr (idx + 1);
+        }
+      else
+        {
+          Cell file_cell = Cell (file_count, 1);
+          for (octave_idx_type n = 1; n <= file_count; n++)
+            {
+              fname = fc.value (n);
+              idx = fname.find_last_of (sep);
+              file_cell(n - 1) = fname.substr (idx + 1);
+            }
+          retval(0) = file_cell;
+        }
+
+      if (multi_type == Fl_File_Chooser::DIRECTORY)
+        retval(0) = std::string (fc.value ());
+      else
+        {
+          retval(1) = std::string (fc.directory ()) + sep;
+          retval(2) = fc.filter_value () + 1;
+        }
+    }
+
+  fc.hide ();
+  Fl::flush ();
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__glpk__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,861 @@
+/*
+
+Copyright (C) 2005-2012 Nicolo' Giorgetti
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cfloat>
+#include <csetjmp>
+#include <ctime>
+
+#include "lo-ieee.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-obj.h"
+#include "pager.h"
+
+#if defined (HAVE_GLPK)
+
+extern "C"
+{
+#if defined (HAVE_GLPK_GLPK_H)
+#include <glpk/glpk.h>
+#else
+#include <glpk.h>
+#endif
+
+#if 0
+#ifdef GLPK_PRE_4_14
+
+#ifndef _GLPLIB_H
+#include <glplib.h>
+#endif
+#ifndef lib_set_fault_hook
+#define lib_set_fault_hook lib_fault_hook
+#endif
+#ifndef lib_set_print_hook
+#define lib_set_print_hook lib_print_hook
+#endif
+
+#else
+
+void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info);
+void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info);
+
+#endif
+#endif
+}
+
+#define NIntP 17
+#define NRealP 10
+
+int lpxIntParam[NIntP] = {
+  0,
+  1,
+  0,
+  1,
+  0,
+  -1,
+  0,
+  200,
+  1,
+  2,
+  0,
+  1,
+  0,
+  0,
+  2,
+  2,
+  1
+};
+
+int IParam[NIntP] = {
+  LPX_K_MSGLEV,
+  LPX_K_SCALE,
+  LPX_K_DUAL,
+  LPX_K_PRICE,
+  LPX_K_ROUND,
+  LPX_K_ITLIM,
+  LPX_K_ITCNT,
+  LPX_K_OUTFRQ,
+  LPX_K_MPSINFO,
+  LPX_K_MPSOBJ,
+  LPX_K_MPSORIG,
+  LPX_K_MPSWIDE,
+  LPX_K_MPSFREE,
+  LPX_K_MPSSKIP,
+  LPX_K_BRANCH,
+  LPX_K_BTRACK,
+  LPX_K_PRESOL
+};
+
+
+double lpxRealParam[NRealP] = {
+  0.07,
+  1e-7,
+  1e-7,
+  1e-9,
+  -DBL_MAX,
+  DBL_MAX,
+  -1.0,
+  0.0,
+  1e-6,
+  1e-7
+};
+
+int RParam[NRealP] = {
+  LPX_K_RELAX,
+  LPX_K_TOLBND,
+  LPX_K_TOLDJ,
+  LPX_K_TOLPIV,
+  LPX_K_OBJLL,
+  LPX_K_OBJUL,
+  LPX_K_TMLIM,
+  LPX_K_OUTDLY,
+  LPX_K_TOLINT,
+  LPX_K_TOLOBJ
+};
+
+static jmp_buf mark;  //-- Address for long jump to jump to
+
+#if 0
+int
+glpk_fault_hook (void * /* info */, char *msg)
+{
+  error ("CRITICAL ERROR in GLPK: %s", msg);
+  longjmp (mark, -1);
+}
+
+int
+glpk_print_hook (void * /* info */, char *msg)
+{
+  message (0, "%s", msg);
+  return 1;
+}
+#endif
+
+int
+glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
+      double *a, double *b, char *ctype, int *freeLB, double *lb,
+      int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
+      int save_pb, double *xmin, double *fmin, double *status,
+      double *lambda, double *redcosts, double *time, double *mem)
+{
+  int errnum;
+  int typx = 0;
+  int method;
+
+  clock_t t_start = clock ();
+
+#if 0
+#ifdef GLPK_PRE_4_14
+  lib_set_fault_hook (0, glpk_fault_hook);
+#else
+  _glp_lib_fault_hook (glpk_fault_hook, 0);
+#endif
+
+  if (lpxIntParam[0] > 1)
+#ifdef GLPK_PRE_4_14
+    lib_set_print_hook (0, glpk_print_hook);
+#else
+    _glp_lib_print_hook (glpk_print_hook, 0);
+#endif
+#endif
+
+  LPX *lp = lpx_create_prob ();
+
+
+  //-- Set the sense of optimization
+  if (sense == 1)
+    lpx_set_obj_dir (lp, LPX_MIN);
+  else
+    lpx_set_obj_dir (lp, LPX_MAX);
+
+  //-- If the problem has integer structural variables switch to MIP
+  if (isMIP)
+    lpx_set_class (lp, LPX_MIP);
+
+  lpx_add_cols (lp, n);
+  for (int i = 0; i < n; i++)
+    {
+      //-- Define type of the structural variables
+      if (! freeLB[i] && ! freeUB[i])
+        {
+          if (lb[i] != ub[i])
+            lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]);
+          else
+            lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]);
+        }
+      else
+        {
+          if (! freeLB[i] && freeUB[i])
+            lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]);
+          else
+            {
+              if (freeLB[i] && ! freeUB[i])
+                lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]);
+              else
+                lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]);
+            }
+        }
+
+      // -- Set the objective coefficient of the corresponding
+      // -- structural variable. No constant term is assumed.
+      lpx_set_obj_coef(lp,i+1,c[i]);
+
+      if (isMIP)
+        lpx_set_col_kind (lp, i+1, vartype[i]);
+    }
+
+  lpx_add_rows (lp, m);
+
+  for (int i = 0; i < m; i++)
+    {
+      /* If the i-th row has no lower bound (types F,U), the
+         corrispondent parameter will be ignored.
+         If the i-th row has no upper bound (types F,L), the corrispondent
+         parameter will be ignored.
+         If the i-th row is of S type, the i-th LB is used, but
+         the i-th UB is ignored.
+      */
+
+      switch (ctype[i])
+        {
+        case 'F':
+          typx = LPX_FR;
+          break;
+
+        case 'U':
+          typx = LPX_UP;
+          break;
+
+        case 'L':
+          typx = LPX_LO;
+          break;
+
+        case 'S':
+          typx = LPX_FX;
+          break;
+
+        case 'D':
+          typx = LPX_DB;
+          break;
+        }
+
+      lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]);
+
+    }
+
+  lpx_load_matrix (lp, nz, rn, cn, a);
+
+  if (save_pb)
+    {
+      static char tmp[] = "outpb.lp";
+      if (lpx_write_cpxlp (lp, tmp) != 0)
+        {
+          error ("__glpk__: unable to write problem");
+          longjmp (mark, -1);
+        }
+    }
+
+  //-- scale the problem data (if required)
+  //-- if (scale && (!presol || method == 1)) lpx_scale_prob (lp);
+  //-- LPX_K_SCALE=IParam[1]  LPX_K_PRESOL=IParam[16]
+  if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1))
+    lpx_scale_prob (lp);
+
+  //-- build advanced initial basis (if required)
+  if (lpsolver == 1 && ! lpxIntParam[16])
+    lpx_adv_basis (lp);
+
+  for (int i = 0; i < NIntP; i++)
+    lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]);
+
+  for (int i = 0; i < NRealP; i++)
+    lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]);
+
+  if (lpsolver == 1)
+    method = 'S';
+  else
+    method = 'T';
+
+  switch (method)
+    {
+    case 'S':
+      {
+        if (isMIP)
+          {
+            method = 'I';
+            errnum = lpx_simplex (lp);
+            errnum = lpx_integer (lp);
+          }
+        else
+          errnum = lpx_simplex (lp);
+      }
+     break;
+
+    case 'T':
+      errnum = lpx_interior (lp);
+      break;
+
+    default:
+      break;
+#if 0
+#ifdef GLPK_PRE_4_14
+      insist (method != method);
+#else
+      static char tmp[] = "method != method";
+      glpk_fault_hook (0, tmp);
+#endif
+#endif
+    }
+
+  /*  errnum assumes the following results:
+      errnum = 0 <=> No errors
+      errnum = 1 <=> Iteration limit exceeded.
+      errnum = 2 <=> Numerical problems with basis matrix.
+  */
+  if (errnum == LPX_E_OK)
+    {
+      if (isMIP)
+        {
+          *status = lpx_mip_status (lp);
+          *fmin = lpx_mip_obj_val (lp);
+        }
+      else
+        {
+          if (lpsolver == 1)
+            {
+              *status = lpx_get_status (lp);
+              *fmin = lpx_get_obj_val (lp);
+            }
+          else
+            {
+              *status = lpx_ipt_status (lp);
+              *fmin = lpx_ipt_obj_val (lp);
+            }
+        }
+
+      if (isMIP)
+        {
+          for (int i = 0; i < n; i++)
+            xmin[i] = lpx_mip_col_val (lp, i+1);
+        }
+      else
+        {
+          /* Primal values */
+          for (int i = 0; i < n; i++)
+            {
+              if (lpsolver == 1)
+                xmin[i] = lpx_get_col_prim (lp, i+1);
+              else
+                xmin[i] = lpx_ipt_col_prim (lp, i+1);
+            }
+
+          /* Dual values */
+          for (int i = 0; i < m; i++)
+            {
+              if (lpsolver == 1)
+                lambda[i] = lpx_get_row_dual (lp, i+1);
+              else
+                lambda[i] = lpx_ipt_row_dual (lp, i+1);
+            }
+
+          /* Reduced costs */
+          for (int i = 0; i < lpx_get_num_cols (lp); i++)
+            {
+              if (lpsolver == 1)
+                redcosts[i] = lpx_get_col_dual (lp, i+1);
+              else
+                redcosts[i] = lpx_ipt_col_dual (lp, i+1);
+            }
+        }
+
+      *time = (clock () - t_start) / CLOCKS_PER_SEC;
+
+#ifdef GLPK_PRE_4_14
+      *mem = (lib_env_ptr () -> mem_tpeak);
+#else
+      *mem = 0;
+#endif
+
+      lpx_delete_prob (lp);
+      return 0;
+    }
+
+   lpx_delete_prob (lp);
+
+   *status = errnum;
+
+   return errnum;
+}
+
+#endif
+
+#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \
+  do \
+    { \
+      octave_value tmp = PARAM.getfield (NAME); \
+ \
+      if (tmp.is_defined ()) \
+        { \
+          if (! tmp.is_empty ()) \
+            { \
+              lpxRealParam[IDX] = tmp.scalar_value (); \
+ \
+              if (error_state) \
+                { \
+                  error ("glpk: invalid value in PARAM." NAME); \
+                  return retval; \
+                } \
+            } \
+          else \
+            { \
+              error ("glpk: invalid value in PARAM." NAME); \
+              return retval; \
+            } \
+        } \
+    } \
+  while (0)
+
+#define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \
+  do \
+    { \
+      octave_value tmp = PARAM.getfield (NAME); \
+ \
+      if (tmp.is_defined ()) \
+        { \
+          if (! tmp.is_empty ()) \
+            { \
+              VAL = tmp.int_value (); \
+ \
+              if (error_state) \
+                { \
+                  error ("glpk: invalid value in PARAM." NAME); \
+                  return retval; \
+                } \
+            } \
+          else \
+            { \
+              error ("glpk: invalid value in PARAM." NAME); \
+              return retval; \
+            } \
+        } \
+    } \
+  while (0)
+
+DEFUN_DLD (__glpk__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  // The list of values to return.  See the declaration in oct-obj.h
+  octave_value_list retval;
+
+#if defined (HAVE_GLPK)
+
+  int nrhs = args.length ();
+
+  if (nrhs != 9)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  //-- 1nd Input. A column array containing the objective function
+  //--            coefficients.
+  volatile int mrowsc = args(0).rows ();
+
+  Matrix C (args(0).matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of C");
+      return retval;
+    }
+
+  double *c = C.fortran_vec ();
+  Array<int> rn;
+  Array<int> cn;
+  ColumnVector a;
+  volatile int mrowsA;
+  volatile int nz = 0;
+
+  //-- 2nd Input. A matrix containing the constraints coefficients.
+  // If matrix A is NOT a sparse matrix
+  if (args(1).is_sparse_type ())
+    {
+      SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix
+
+      if (error_state)
+        {
+          error ("__glpk__: invalid value of A");
+          return retval;
+        }
+
+      mrowsA = A.rows ();
+      octave_idx_type Anc = A.cols ();
+      octave_idx_type Anz = A.nnz ();
+      rn.resize (dim_vector (Anz+1, 1));
+      cn.resize (dim_vector (Anz+1, 1));
+      a.resize (Anz+1, 0.0);
+
+      if (Anc != mrowsc)
+        {
+          error ("__glpk__: invalid value of A");
+          return retval;
+        }
+
+      for (octave_idx_type j = 0; j < Anc; j++)
+        for (octave_idx_type i = A.cidx (j); i < A.cidx (j+1); i++)
+          {
+            nz++;
+            rn(nz) = A.ridx (i) + 1;
+            cn(nz) = j + 1;
+            a(nz) = A.data(i);
+          }
+    }
+  else
+    {
+      Matrix A (args(1).matrix_value ()); // get the matrix
+
+      if (error_state)
+        {
+          error ("__glpk__: invalid value of A");
+          return retval;
+        }
+
+      mrowsA = A.rows ();
+      rn.resize (dim_vector (mrowsA*mrowsc+1, 1));
+      cn.resize (dim_vector (mrowsA*mrowsc+1, 1));
+      a.resize (mrowsA*mrowsc+1, 0.0);
+
+      for (int i = 0; i < mrowsA; i++)
+        {
+          for (int j = 0; j < mrowsc; j++)
+            {
+              if (A(i,j) != 0)
+                {
+                  nz++;
+                  rn(nz) = i + 1;
+                  cn(nz) = j + 1;
+                  a(nz) = A(i,j);
+                }
+            }
+        }
+
+    }
+
+  //-- 3rd Input. A column array containing the right-hand side value
+  //               for each constraint in the constraint matrix.
+  Matrix B (args(2).matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of B");
+      return retval;
+    }
+
+  double *b = B.fortran_vec ();
+
+  //-- 4th Input. An array of length mrowsc containing the lower
+  //--            bound on each of the variables.
+  Matrix LB (args(3).matrix_value ());
+
+  if (error_state || LB.length () < mrowsc)
+    {
+      error ("__glpk__: invalid value of LB");
+      return retval;
+    }
+
+  double *lb = LB.fortran_vec ();
+
+  //-- LB argument, default: Free
+  Array<int> freeLB (dim_vector (mrowsc, 1));
+  for (int i = 0; i < mrowsc; i++)
+     {
+       if (xisinf (lb[i]))
+         {
+           freeLB(i) = 1;
+           lb[i] = -octave_Inf;
+         }
+       else
+         freeLB(i) = 0;
+     }
+
+  //-- 5th Input. An array of at least length numcols containing the upper
+  //--            bound on each of the variables.
+  Matrix UB (args(4).matrix_value ());
+
+  if (error_state || UB.length () < mrowsc)
+    {
+      error ("__glpk__: invalid value of UB");
+      return retval;
+    }
+
+  double *ub = UB.fortran_vec ();
+
+  Array<int> freeUB (dim_vector (mrowsc, 1));
+  for (int i = 0; i < mrowsc; i++)
+    {
+      if (xisinf (ub[i]))
+        {
+          freeUB(i) = 1;
+          ub[i] = octave_Inf;
+        }
+      else
+        freeUB(i) = 0;
+    }
+
+  //-- 6th Input. A column array containing the sense of each constraint
+  //--            in the constraint matrix.
+  charMatrix CTYPE (args(5).char_matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of CTYPE");
+      return retval;
+    }
+
+  char *ctype = CTYPE.fortran_vec ();
+
+  //-- 7th Input. A column array containing the types of the variables.
+  charMatrix VTYPE (args(6).char_matrix_value ());
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of VARTYPE");
+      return retval;
+    }
+
+  Array<int> vartype (dim_vector (mrowsc, 1));
+  volatile int isMIP = 0;
+  for (int i = 0; i < mrowsc ; i++)
+    {
+      if (VTYPE(i,0) == 'I')
+        {
+          isMIP = 1;
+          vartype(i) = LPX_IV;
+        }
+      else
+        vartype(i) = LPX_CV;
+    }
+
+  //-- 8th Input. Sense of optimization.
+  volatile int sense;
+  double SENSE = args(7).scalar_value ();
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of SENSE");
+      return retval;
+    }
+
+  if (SENSE >= 0)
+    sense = 1;
+  else
+    sense = -1;
+
+  //-- 9th Input. A structure containing the control parameters.
+  octave_scalar_map PARAM = args(8).scalar_map_value ();
+
+  if (error_state)
+    {
+      error ("__glpk__: invalid value of PARAM");
+      return retval;
+    }
+
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  //-- Integer parameters
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  //-- Level of messages output by the solver
+  OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]);
+  if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3)
+    {
+      error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)");
+      return retval;
+    }
+
+  //-- scaling option
+  OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]);
+  if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2)
+    {
+      error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)");
+      return retval;
+    }
+
+  //-- Dual dimplex option
+  OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]);
+  if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1)
+    {
+      error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)");
+      return retval;
+    }
+
+  //-- Pricing option
+  OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]);
+  if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1)
+    {
+      error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])");
+      return retval;
+    }
+
+  //-- Solution rounding option
+  OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]);
+  if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1)
+    {
+      error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)");
+      return retval;
+    }
+
+  //-- Simplex iterations limit
+  OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]);
+
+  //-- Simplex iterations count
+  OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]);
+
+  //-- Output frequency, in iterations
+  OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]);
+
+  //-- Branching heuristic option
+  OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]);
+  if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2)
+    {
+      error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]");
+      return retval;
+    }
+
+  //-- Backtracking heuristic option
+  OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]);
+  if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2)
+    {
+      error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]");
+      return retval;
+    }
+
+  //-- Presolver option
+  OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]);
+  if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1)
+    {
+      error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
+      return retval;
+    }
+
+  //-- LPsolver option
+  volatile int lpsolver = 1;
+  OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver);
+  if (lpsolver < 1 || lpsolver > 2)
+    {
+      error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)");
+      return retval;
+    }
+
+  //-- Save option
+  volatile int save_pb = 0;
+  OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
+  save_pb = save_pb != 0;
+
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  //-- Real parameters
+  //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  //-- Ratio test option
+  OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0);
+
+  //-- Relative tolerance used to check if the current basic solution
+  //-- is primal feasible
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1);
+
+  //-- Absolute tolerance used to check if the current basic solution
+  //-- is dual feasible
+  OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2);
+
+  //-- Relative tolerance used to choose eligible pivotal elements of
+  //--  the simplex table in the ratio test
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8);
+
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9);
+
+  //-- Assign pointers to the output parameters
+  ColumnVector xmin (mrowsc, octave_NA);
+  double fmin = octave_NA;
+  double status;
+  ColumnVector lambda (mrowsA, octave_NA);
+  ColumnVector redcosts (mrowsc, octave_NA);
+  double time;
+  double mem;
+
+  int jmpret = setjmp (mark);
+
+  if (jmpret == 0)
+    glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
+          cn.fortran_vec (), a.fortran_vec (), b, ctype,
+          freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
+          vartype.fortran_vec (), isMIP, lpsolver, save_pb,
+          xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (),
+          redcosts.fortran_vec (), &time, &mem);
+
+  octave_scalar_map extra;
+
+  if (! isMIP)
+    {
+      extra.assign ("lambda", lambda);
+      extra.assign ("redcosts", redcosts);
+    }
+
+  extra.assign ("time", time);
+  extra.assign ("mem", mem);
+
+  retval(3) = extra;
+  retval(2) = status;
+  retval(1) = fmin;
+  retval(0) = xmin;
+
+#else
+
+  gripe_not_supported ("glpk");
+
+#endif
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__init_fltk__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,2129 @@
+/*
+
+Copyright (C) 2007-2012 Shai Ayal
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+To initialize:
+
+  graphics_toolkit ("fltk");
+  plot (randn (1e3, 1));
+
+*/
+
+// PKG_ADD: register_graphics_toolkit ("fltk");
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+
+#if defined (HAVE_FLTK)
+
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_File_Chooser.H>
+#include <FL/Fl_Gl_Window.H>
+#include <FL/Fl_Menu_Bar.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+#include <FL/gl.h>
+
+// FLTK headers may include X11/X.h which defines Complex, and that
+// conflicts with Octave's Complex typedef.  We don't need the X11
+// Complex definition in this file, so remove it before including Octave
+// headers which may require Octave's Complex typedef.
+#undef Complex
+
+#include "cmd-edit.h"
+#include "lo-ieee.h"
+
+#include "file-ops.h"
+#include "gl-render.h"
+#include "gl2ps-renderer.h"
+#include "graphics.h"
+#include "parse.h"
+#include "sysdep.h"
+#include "toplev.h"
+#include "variables.h"
+
+#define FLTK_GRAPHICS_TOOLKIT_NAME "fltk"
+
+// Give FLTK no more than 0.01 sec to do its stuff.
+static double fltk_maxtime = 1e-2;
+
+const char* help_text = "\
+Keyboard Shortcuts\n\
+a - autoscale\n\
+p - pan/zoom\n\
+r - rotate\n\
+g - toggle grid\n\
+\n\
+Mouse\n\
+left drag - pan\n\
+mouse wheel - zoom\n\
+right drag - rectangle zoom\n\
+left double click - autoscale\n\
+";
+
+class OpenGL_fltk : public Fl_Gl_Window
+{
+public:
+  OpenGL_fltk (int xx, int yy, int ww, int hh, double num)
+    : Fl_Gl_Window (xx, yy, ww, hh, 0), number (num), renderer (),
+      in_zoom (false), zoom_box (),  print_mode (false)
+  {
+    // Ask for double buffering and a depth buffer.
+    mode (FL_DEPTH | FL_DOUBLE);
+  }
+
+  ~OpenGL_fltk (void) { }
+
+  void zoom (bool z)
+  {
+    in_zoom = z;
+    if (! in_zoom)
+      hide_overlay ();
+  }
+
+  bool zoom (void) { return in_zoom; }
+  void set_zoom_box (const Matrix& zb) { zoom_box = zb; }
+
+  void print (const std::string& cmd, const std::string& term)
+  {
+    print_mode  = true;
+    print_cmd = cmd;
+    print_term  = term;
+  }
+
+  void resize (int xx, int yy, int ww, int hh)
+  {
+    Fl_Gl_Window::resize (xx, yy, ww, hh);
+    setup_viewport (ww, hh);
+    redraw ();
+  }
+
+  bool renumber (double new_number)
+  {
+    bool retval = false;
+
+    if (number != new_number)
+      {
+        number = new_number;
+        retval = true;
+      }
+
+    return retval;
+  }
+
+private:
+  double number;
+  opengl_renderer renderer;
+  bool in_zoom;
+  // (x1,y1,x2,y2)
+  Matrix zoom_box;
+
+  bool print_mode;
+  std::string print_cmd;
+  std::string print_term;
+
+  void setup_viewport (int ww, int hh)
+  {
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    glViewport (0, 0, ww, hh);
+  }
+
+  void draw (void)
+  {
+    if (! valid ())
+      {
+        valid (1);
+        setup_viewport (w (), h ());
+      }
+
+    if (print_mode)
+      {
+        FILE *fp = octave_popen (print_cmd.c_str (), "w");
+        glps_renderer rend (fp, print_term);
+
+        rend.draw (gh_manager::get_object (number));
+
+        octave_pclose (fp);
+        print_mode = false;
+      }
+    else
+      {
+        renderer.draw (gh_manager::get_object (number));
+
+        if (zoom ())
+          overlay ();
+      }
+  }
+
+  void zoom_box_vertex (void)
+  {
+    glVertex2d (zoom_box(0), h () - zoom_box(1));
+    glVertex2d (zoom_box(0), h () - zoom_box(3));
+    glVertex2d (zoom_box(2), h () - zoom_box(3));
+    glVertex2d (zoom_box(2), h () - zoom_box(1));
+    glVertex2d (zoom_box(0), h () - zoom_box(1));
+  }
+
+  void overlay (void)
+  {
+    glPushMatrix ();
+
+    glMatrixMode (GL_MODELVIEW);
+    glLoadIdentity ();
+
+    glMatrixMode (GL_PROJECTION);
+    glLoadIdentity ();
+    gluOrtho2D (0.0, w (), 0.0, h ());
+
+    glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
+    glDisable (GL_DEPTH_TEST);
+
+    glBegin (GL_POLYGON);
+    glColor4f (0.45, 0.62, 0.81, 0.1);
+    zoom_box_vertex ();
+    glEnd ();
+
+    glBegin (GL_LINE_STRIP);
+    glLineWidth (1.5);
+    glColor4f (0.45, 0.62, 0.81, 0.9);
+    zoom_box_vertex ();
+    glEnd ();
+
+    glPopAttrib ();
+    glPopMatrix ();
+  }
+
+  int handle (int event)
+  {
+    int retval = Fl_Gl_Window::handle (event);
+
+    switch (event)
+      {
+      case FL_ENTER:
+        window ()->cursor (FL_CURSOR_CROSS);
+        return 1;
+
+      case FL_LEAVE:
+        window ()->cursor (FL_CURSOR_DEFAULT);
+        return 1;
+      }
+
+    return retval;
+  }
+};
+
+// Parameter controlling how fast we zoom when using the scrool wheel.
+static double wheel_zoom_speed = 0.05;
+// Parameter controlling the GUI mode.
+static enum { pan_zoom, rotate_zoom, none } gui_mode;
+
+void script_cb (Fl_Widget*, void* data)
+  {
+    static_cast<uimenu::properties*> (data)->execute_callback ();
+  }
+
+
+class fltk_uimenu
+{
+public:
+  fltk_uimenu (int xx, int yy, int ww, int hh)
+    {
+      menubar = new
+        Fl_Menu_Bar (xx, yy, ww, hh);
+    }
+
+  int items_to_show (void)
+    {
+      //returns the number of visible menu items
+      int len = menubar->size ();
+      int n = 0;
+      for (int t = 0; t < len; t++ )
+        {
+          const Fl_Menu_Item *m = static_cast<const Fl_Menu_Item*> (&(menubar->menu ()[t]));
+          if ((m->label () != NULL) && m->visible ())
+            n++;
+        }
+
+      return n;
+    }
+
+  void show (void)
+    {
+      menubar->show ();
+    }
+
+  void hide (void)
+    {
+      menubar->hide ();
+    }
+
+   bool is_visible (void)
+    {
+      return menubar->visible ();
+    }
+
+  int find_index_by_name (const std::string& findname)
+    {
+      // This function is derived from Greg Ercolano's function
+      // int GetIndexByName(...), see:
+      // http://seriss.com/people/erco/fltk/#Menu_ChangeLabel
+      // He agreed via PM that it can be included in octave using GPLv3
+      // Kai Habel (14.10.2010)
+
+      std::string menupath;
+      for (int t = 0; t < menubar->size (); t++ )
+        {
+          Fl_Menu_Item *m = const_cast<Fl_Menu_Item*> (&(menubar->menu ()[t]));
+          if (m->submenu ())
+            {
+              // item has submenu
+              if (!menupath.empty ())
+                menupath += "/";
+              menupath += m->label ();
+
+              if (menupath.compare (findname) == 0 )
+                return (t);
+            }
+          else
+            {
+              // End of submenu? Pop back one level.
+              if (m->label () == NULL)
+                {
+                  std::size_t idx = menupath.find_last_of ("/");
+                  if (idx != std::string::npos)
+                    menupath.erase (idx);
+                  else
+                    menupath.clear ();
+                  continue;
+                }
+              // Menu item?
+              std::string itempath = menupath;
+              if (!itempath.empty ())
+                itempath += "/";
+              itempath += m->label ();
+
+              if (itempath.compare (findname) == 0)
+                return (t);
+            }
+        }
+      return (-1);
+    }
+
+  Matrix find_uimenu_children (uimenu::properties& uimenup) const
+    {
+      Matrix uimenu_childs = uimenup.get_all_children ();
+      Matrix retval = do_find_uimenu_children (uimenu_childs);
+      return retval;
+    }
+
+  Matrix find_uimenu_children (figure::properties& figp) const
+    {
+      Matrix uimenu_childs = figp.get_all_children ();
+      Matrix retval = do_find_uimenu_children (uimenu_childs);
+      return retval;
+    }
+
+  Matrix do_find_uimenu_children (Matrix uimenu_childs) const
+    {
+      octave_idx_type k = 0;
+
+
+      Matrix pos = Matrix (uimenu_childs.numel (), 1);
+
+      for (octave_idx_type ii = 0; ii < uimenu_childs.numel (); ii++)
+      {
+        graphics_object kidgo = gh_manager::get_object (uimenu_childs (ii));
+
+        if (kidgo.valid_object () && kidgo.isa ("uimenu"))
+          {
+            uimenu_childs(k) = uimenu_childs(ii);
+            pos(k++) =
+              dynamic_cast<uimenu::properties&> (kidgo.get_properties ()).get_position ();
+          }
+      }
+
+      uimenu_childs.resize (k, 1);
+      pos.resize (k, 1);
+      Matrix retval = Matrix (k, 1);
+      // Don't know if this is the best method to sort.
+      // Can we avoid the for loop?
+      Array<octave_idx_type> sidx = pos.sort_rows_idx (DESCENDING);
+      for (octave_idx_type ii = 0; ii < k; ii++)
+        retval(ii) = uimenu_childs (sidx(ii));
+
+      return retval;
+    }
+
+  void delete_entry (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      int idx = find_index_by_name (fltk_label.c_str ());
+
+      if (idx >= 0)
+        menubar->remove (idx);
+    }
+
+  void update_accelerator (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
+          if (item != NULL)
+            {
+              std::string acc = uimenup.get_accelerator ();
+              if (acc.length () > 0)
+                {
+                  int key = FL_CTRL + acc[0];
+                  item->shortcut (key);
+                }
+            }
+        }
+    }
+
+  void update_callback (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
+          if (item != NULL)
+            {
+              if (!uimenup.get_callback ().is_empty ())
+                item->callback (static_cast<Fl_Callback*> (script_cb),
+                                static_cast<void*> (&uimenup));
+              else
+                item->callback (NULL, static_cast<void*> (0));
+            }
+        }
+    }
+
+  void update_enable (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
+          if (item != NULL)
+            {
+              if (uimenup.is_enable ())
+                item->activate ();
+              else
+                item->deactivate ();
+            }
+        }
+    }
+
+  void update_foregroundcolor (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
+          if (item != NULL)
+            {
+              Matrix rgb = uimenup.get_foregroundcolor_rgb ();
+
+              uchar r = static_cast<uchar> (gnulib::floor (rgb (0) * 255));
+              uchar g = static_cast<uchar> (gnulib::floor (rgb (1) * 255));
+              uchar b = static_cast<uchar> (gnulib::floor (rgb (2) * 255));
+
+              item->labelcolor (fl_rgb_color (r, g, b));
+            }
+        }
+    }
+
+  void update_seperator (const uimenu::properties& uimenup)
+    {
+      // Matlab places the separator before the current
+      // menu entry, while fltk places it after. So we need to find
+      // the previous item in this menu/submenu. (Kai)
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          int itemflags = 0, idx;
+          int curr_idx = find_index_by_name (fltk_label.c_str ());
+
+          for (idx = curr_idx - 1; idx >= 0; idx--)
+            {
+              Fl_Menu_Item* item = const_cast<Fl_Menu_Item*> (&menubar->menu () [idx]);
+              itemflags = item->flags;
+              if (item->label () != NULL)
+                break;
+            }
+
+          if (idx >= 0 && idx < menubar->size ())
+            {
+              if (uimenup.is_separator ())
+                {
+                  if (idx >= 0 && !(itemflags & FL_SUBMENU))
+                    menubar->mode (idx, itemflags | FL_MENU_DIVIDER);
+                }
+              else
+                menubar->mode (idx, itemflags & (~FL_MENU_DIVIDER));
+            }
+        }
+    }
+
+  void update_visible (uimenu::properties& uimenup)
+    {
+      std::string fltk_label = uimenup.get_fltk_label ();
+      if (!fltk_label.empty ())
+        {
+          Fl_Menu_Item* item
+            = const_cast<Fl_Menu_Item*> (menubar->find_item (fltk_label.c_str ()));
+          if (item != NULL)
+            {
+              if (uimenup.is_visible ())
+                item->show ();
+              else
+                item->hide ();
+            }
+        }
+    }
+
+  void add_entry (uimenu::properties& uimenup)
+    {
+
+      std::string fltk_label = uimenup.get_fltk_label ();
+
+      if (!fltk_label.empty ())
+        {
+          bool item_added = false;
+          do
+            {
+              const Fl_Menu_Item* item
+                = menubar->find_item (fltk_label.c_str ());
+
+              if (item == NULL)
+                {
+                  Matrix uimenu_ch = find_uimenu_children (uimenup);
+                  int len = uimenu_ch.numel ();
+                  int flags = 0;
+                  if (len > 0)
+                    flags = FL_SUBMENU;
+                  if (len == 0 && uimenup.is_checked ())
+                    flags += FL_MENU_TOGGLE + FL_MENU_VALUE;
+                  menubar->add (fltk_label.c_str (), 0, 0, 0, flags);
+                  item_added = true;
+                }
+              else
+                {
+                  //avoid duplicate menulabels
+                  std::size_t idx1 = fltk_label.find_last_of ("(");
+                  std::size_t idx2 = fltk_label.find_last_of (")");
+                  int len = idx2 - idx1;
+                  int val = 1;
+                  if (len > 0)
+                    {
+                      std::string valstr = fltk_label.substr (idx1 + 1, len - 1);
+                      fltk_label.erase (idx1, len + 1);
+                      val = atoi (valstr.c_str ());
+                      if (val > 0 && val < 99)
+                        val++;
+                    }
+                  std::ostringstream valstream;
+                  valstream << val;
+                  fltk_label += "(" + valstream.str () + ")";
+                }
+            }
+          while (!item_added);
+          uimenup.set_fltk_label (fltk_label);
+        }
+    }
+
+  void add_to_menu (uimenu::properties& uimenup)
+    {
+      Matrix kids = find_uimenu_children (uimenup);
+      int len = kids.length ();
+      std::string fltk_label = uimenup.get_fltk_label ();
+
+      add_entry (uimenup);
+      update_foregroundcolor (uimenup);
+      update_callback (uimenup);
+      update_accelerator (uimenup);
+      update_enable (uimenup);
+      update_visible (uimenup);
+      update_seperator (uimenup);
+
+      for (octave_idx_type ii = 0; ii < len; ii++)
+        {
+          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
+          if (kgo.valid_object ())
+            {
+              uimenu::properties& kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
+              add_to_menu (kprop);
+            }
+        }
+    }
+
+  void add_to_menu (figure::properties& figp)
+    {
+      Matrix kids = find_uimenu_children (figp);
+      int len = kids.length ();
+      menubar->clear ();
+      for (octave_idx_type ii = 0; ii < len; ii++)
+        {
+          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
+
+          if (kgo.valid_object ())
+            {
+              uimenu::properties& kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
+              add_to_menu (kprop);
+            }
+        }
+    }
+
+  template <class T_prop>
+  void remove_from_menu (T_prop& prop)
+    {
+      Matrix kids;
+      std::string type = prop.get_type ();
+      kids = find_uimenu_children (prop);
+      int len = kids.length ();
+
+      for (octave_idx_type ii = 0; ii < len; ii++)
+        {
+          graphics_object kgo = gh_manager::get_object (kids (len - (ii + 1)));
+
+          if (kgo.valid_object ())
+            {
+              uimenu::properties kprop = dynamic_cast<uimenu::properties&> (kgo.get_properties ());
+              remove_from_menu (kprop);
+            }
+        }
+
+      if (type.compare ("uimenu") == 0)
+        delete_entry (dynamic_cast<uimenu::properties&> (prop));
+      else if (type.compare ("figure") == 0)
+        menubar->clear ();
+    }
+
+  ~fltk_uimenu (void)
+    {
+      delete menubar;
+    }
+
+private:
+
+  // No copying!
+
+  fltk_uimenu (const fltk_uimenu&);
+
+  fltk_uimenu operator = (const fltk_uimenu&);
+
+  Fl_Menu_Bar* menubar;
+};
+
+class plot_window : public Fl_Window
+{
+  friend class fltk_uimenu;
+public:
+  plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp)
+    : Fl_Window (xx, yy, ww, hh, "octave"), window_label (), shift (0),
+      ndim (2), fp (xfp), canvas (0), autoscale (0), togglegrid (0),
+      panzoom (0), rotate (0), help (0), status (0),
+      ax_obj (), pos_x (0), pos_y (0)
+  {
+    callback (window_close, static_cast<void*> (this));
+    size_range (4*status_h, 2*status_h);
+
+    // FIXME: The function below is only available in FLTK >= 1.3
+    // At some point support for FLTK 1.1 will be dropped in Octave.
+    // At that point this function should be uncommented.
+    // The current solution is to call xclass() before show() for each window.
+    // Set WM_CLASS which allows window managers to properly group related
+    // windows.  Otherwise, the class is just "FLTK"
+    //default_xclass ("Octave");
+
+    begin ();
+    {
+
+      canvas = new OpenGL_fltk (0, 0, ww, hh - status_h, number ());
+
+      uimenu = new fltk_uimenu (0, 0, ww, menu_h);
+      uimenu->hide ();
+
+      bottom = new Fl_Box (0, hh - status_h, ww, status_h);
+      bottom->box (FL_FLAT_BOX);
+
+      ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
+
+      autoscale = new Fl_Button (0, hh - status_h, status_h, status_h, "A");
+      autoscale->callback (button_callback, static_cast<void*> (this));
+      autoscale->tooltip ("Autoscale");
+
+      togglegrid = new Fl_Button (status_h, hh - status_h, status_h,
+                                  status_h, "G");
+      togglegrid->callback (button_callback, static_cast<void*> (this));
+      togglegrid->tooltip ("Toggle Grid");
+
+      panzoom = new Fl_Button (2 * status_h, hh - status_h, status_h,
+                               status_h, "P");
+      panzoom->callback (button_callback, static_cast<void*> (this));
+      panzoom->tooltip ("Mouse Pan/Zoom");
+
+      rotate = new Fl_Button (3 * status_h, hh - status_h, status_h,
+                              status_h, "R");
+      rotate->callback (button_callback, static_cast<void*> (this));
+      rotate->tooltip ("Mouse Rotate");
+
+      if (ndim == 2)
+        rotate->deactivate ();
+
+      help = new Fl_Button (4 * status_h, hh - status_h, status_h,
+                            status_h, "?");
+      help->callback (button_callback, static_cast<void*> (this));
+      help->tooltip ("Help");
+
+      status = new Fl_Output (5 * status_h, hh - status_h,
+                              ww > 2*status_h ? ww - status_h : 0,
+                              status_h, "");
+
+      status->textcolor (FL_BLACK);
+      status->color (FL_GRAY);
+      status->textfont (FL_COURIER);
+      status->textsize (10);
+      status->box (FL_ENGRAVED_BOX);
+
+      // This allows us to have a valid OpenGL context right away.
+      canvas->mode (FL_DEPTH | FL_DOUBLE );
+      if (fp.is_visible ())
+        {
+          // FIXME: This code should be removed when Octave drops support
+          // for FLTK 1.1.  Search for default_xclass in this file to find
+          // code that should be uncommented to take its place.
+          //
+          // Set WM_CLASS which allows window managers to properly group
+          // related windows.  Otherwise, the class is just "FLTK"
+          xclass ("Octave");
+          show ();
+          if (fp.get_currentaxes ().ok ())
+            show_canvas ();
+          else
+            hide_canvas ();
+        }
+    }
+    end ();
+
+    status->show ();
+    autoscale->show ();
+    togglegrid->show ();
+    panzoom->show ();
+    rotate->show ();
+
+    set_name ();
+    resizable (canvas);
+    gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom);
+    uimenu->add_to_menu (fp);
+    if (uimenu->items_to_show ())
+      show_menubar ();
+    else
+      hide_menubar ();
+  }
+
+  ~plot_window (void)
+  {
+    canvas->hide ();
+    status->hide ();
+    uimenu->hide ();
+    this->hide ();
+  }
+
+  double number (void) { return fp.get___myhandle__ ().value (); }
+
+  void renumber (double new_number)
+  {
+    if (canvas)
+      {
+        if (canvas->renumber (new_number))
+          mark_modified ();
+      }
+    else
+      error ("unable to renumber figure");
+  }
+
+  void print (const std::string& cmd, const std::string& term)
+  {
+    canvas->print (cmd, term);
+
+    // Print immediately so the output file will exist when the drawnow
+    // command is done.
+    mark_modified ();
+    Fl::wait (fltk_maxtime);
+  }
+
+  void show_menubar (void)
+  {
+    if (!uimenu->is_visible ())
+      {
+        canvas->resize (canvas->x (),
+                        canvas->y () + menu_h,
+                        canvas->w (),
+                        canvas->h () - menu_h);
+        uimenu->show ();
+        mark_modified ();
+      }
+  }
+
+  void hide_menubar (void)
+  {
+    if (uimenu->is_visible ())
+      {
+        canvas->resize (canvas->x (),
+                        canvas->y () - menu_h,
+                        canvas->w (),
+                        canvas->h () + menu_h);
+        uimenu->hide ();
+        mark_modified ();
+      }
+  }
+
+  void uimenu_update (const graphics_handle& gh, int id)
+  {
+    graphics_object uimenu_obj = gh_manager::get_object (gh);
+
+    if (uimenu_obj.valid_object () && uimenu_obj.isa ("uimenu"))
+      {
+        uimenu::properties& uimenup =
+          dynamic_cast<uimenu::properties&> (uimenu_obj.get_properties ());
+        std::string fltk_label = uimenup.get_fltk_label ();
+        graphics_object fig = uimenu_obj.get_ancestor ("figure");
+        figure::properties& figp =
+          dynamic_cast<figure::properties&> (fig.get_properties ());
+
+        switch (id)
+          {
+          case base_properties::ID_BEINGDELETED:
+            uimenu->remove_from_menu (uimenup);
+            break;
+
+          case base_properties::ID_VISIBLE:
+            uimenu->update_visible (uimenup);
+            break;
+
+          case uimenu::properties::ID_ACCELERATOR:
+            uimenu->update_accelerator (uimenup);
+            break;
+
+          case uimenu::properties::ID_CALLBACK:
+            uimenu->update_callback (uimenup);
+            break;
+
+          case uimenu::properties::ID_CHECKED:
+            uimenu->add_to_menu (figp);//rebuilding entire menu
+            break;
+
+          case uimenu::properties::ID_ENABLE:
+            uimenu->update_enable (uimenup);
+            break;
+
+          case uimenu::properties::ID_FOREGROUNDCOLOR:
+            uimenu->update_foregroundcolor (uimenup);
+            break;
+
+          case uimenu::properties::ID_LABEL:
+            uimenu->add_to_menu (figp);//rebuilding entire menu
+            break;
+
+          case uimenu::properties::ID_POSITION:
+            uimenu->add_to_menu (figp);//rebuilding entire menu
+            break;
+
+          case uimenu::properties::ID_SEPARATOR:
+            uimenu->update_seperator (uimenup);
+            break;
+          }
+
+        if (uimenu->items_to_show ())
+          show_menubar ();
+        else
+          hide_menubar ();
+
+        mark_modified ();
+      }
+  }
+
+  void show_canvas (void)
+  {
+    if (fp.is_visible ())
+      {
+        canvas->show ();
+        canvas->make_current ();
+      }
+  }
+
+  void hide_canvas (void)
+  {
+    canvas->hide ();
+  }
+
+  void mark_modified (void)
+  {
+    damage (FL_DAMAGE_ALL);
+    canvas->damage (FL_DAMAGE_ALL);
+    ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
+
+    if (ndim == 3)
+      rotate->activate ();
+    else if (ndim == 2 && gui_mode == rotate_zoom)
+      {
+        rotate->deactivate ();
+        gui_mode = pan_zoom;
+      }
+  }
+
+  void set_name (void)
+  {
+    window_label = fp.get_title ();
+    label (window_label.c_str ());
+  }
+
+private:
+
+  // No copying!
+
+  plot_window (const plot_window&);
+
+  plot_window& operator = (const plot_window&);
+
+  // window name -- this must exists for the duration of the window's
+  // life
+  std::string window_label;
+
+  // Mod keys status
+  int shift;
+
+  // Number of dimensions, 2 or 3.
+  int ndim;
+
+  // Figure properties.
+  figure::properties& fp;
+
+  // Status area height.
+  static const int status_h = 20;
+
+  // Menu height
+  static const int menu_h = 20;
+
+  // Window callback.
+  static void window_close (Fl_Widget*, void* data)
+  {
+    octave_value_list args;
+    args(0) = static_cast<plot_window*> (data)->number ();
+    feval ("close", args);
+  }
+
+  // Button callbacks.
+  static void button_callback (Fl_Widget* ww, void* data)
+  {
+    static_cast<plot_window*> (data)->button_press (ww, data);
+  }
+
+  void button_press (Fl_Widget* widg, void*)
+  {
+    if (widg == autoscale)
+      axis_auto ();
+
+    if (widg == togglegrid)
+      toggle_grid ();
+
+    if (widg == panzoom)
+      gui_mode = pan_zoom;
+
+    if (widg == rotate && ndim == 3)
+      gui_mode = rotate_zoom;
+
+    if (widg == help)
+      fl_message ("%s", help_text);
+  }
+
+  fltk_uimenu* uimenu;
+  OpenGL_fltk* canvas;
+  Fl_Box*    bottom;
+  Fl_Button* autoscale;
+  Fl_Button* togglegrid;
+  Fl_Button* panzoom;
+  Fl_Button* rotate;
+  Fl_Button* help;
+  Fl_Output* status;
+  graphics_object ax_obj;
+  int pos_x;
+  int pos_y;
+
+  void axis_auto (void)
+  {
+    octave_value_list args;
+    args(0) = fp.get_currentaxes ().as_octave_value ();
+    args(1) = "auto";
+    feval ("axis", args);
+    mark_modified ();
+  }
+
+  void toggle_grid (void)
+  {
+    octave_value_list args;
+    if (fp.get_currentaxes ().ok ())
+      args(0) = fp.get_currentaxes ().as_octave_value ();
+
+    feval ("grid", args);
+    mark_modified ();
+  }
+
+  void pixel2pos (const graphics_handle& ax, int px, int py, double& xx,
+                  double& yy) const
+  {
+    pixel2pos ( gh_manager::get_object (ax), px, py, xx, yy);
+  }
+
+  void pixel2pos (graphics_object ax, int px, int py, double& xx,
+                  double& yy) const
+  {
+    if (ax && ax.isa ("axes"))
+      {
+        axes::properties& ap =
+          dynamic_cast<axes::properties&> (ax.get_properties ());
+        ColumnVector pp = ap.pixel2coord (px, py);
+        xx = pp(0);
+        yy = pp(1);
+      }
+  }
+
+  graphics_handle pixel2axes_or_ca (int px, int py )
+  {
+    Matrix kids = fp.get_children ();
+    int len = kids.length ();
+
+    for (int k = 0; k < len; k++)
+      {
+        graphics_handle hnd = gh_manager::lookup (kids(k));
+
+        if (hnd.ok ())
+          {
+            graphics_object kid = gh_manager::get_object (hnd);
+
+            if (kid.valid_object () && kid.isa ("axes"))
+              {
+                Matrix bb = kid.get_properties ().get_boundingbox (true);
+
+                if (bb(0) <= px && px < (bb(0)+bb(2))
+                    && bb(1) <= py && py < (bb(1)+bb(3)))
+                  {
+                    return hnd;
+                  }
+              }
+          }
+      }
+    return fp.get_currentaxes ();
+  }
+
+  void pixel2status (const graphics_handle& ax, int px0, int py0,
+                     int px1 = -1, int py1 = -1)
+  {
+    pixel2status (gh_manager::get_object (ax), px0, py0, px1, py1);
+  }
+
+  void pixel2status (graphics_object ax, int px0, int py0,
+                     int px1 = -1, int py1 = -1)
+  {
+    double x0, y0, x1, y1;
+    std::stringstream cbuf;
+    cbuf.precision (4);
+    cbuf.width (6);
+    pixel2pos (ax, px0, py0, x0, y0);
+    cbuf << "[" << x0 << ", " << y0 << "]";
+    if (px1 >= 0)
+      {
+        pixel2pos (ax, px1, py1, x1, y1);
+        cbuf << " -> ["<< x1 << ", " << y1 << "]";
+      }
+
+    status->value (cbuf.str ().c_str ());
+    status->redraw ();
+  }
+
+  void view2status (graphics_object ax)
+  {
+     if (ax && ax.isa ("axes"))
+       {
+         axes::properties& ap =
+           dynamic_cast<axes::properties&> (ax.get_properties ());
+         std::stringstream cbuf;
+         cbuf.precision (4);
+         cbuf.width (6);
+         Matrix v (1,2,0);
+         v = ap.get ("view").matrix_value ();
+         cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]";
+
+         status->value (cbuf.str ().c_str ());
+         status->redraw ();
+       }
+  }
+
+  void set_currentpoint (int px, int py)
+  {
+    if (!fp.is_beingdeleted ())
+      {
+        Matrix pos (1,2,0);
+        pos(0) = px;
+        pos(1) = h () - status_h - menu_h - py;
+        fp.set_currentpoint (pos);
+      }
+  }
+
+  void set_axes_currentpoint (graphics_object ax, int px, int py)
+  {
+    if (ax.valid_object ())
+      {
+        axes::properties& ap =
+          dynamic_cast<axes::properties&> (ax.get_properties ());
+
+        double xx, yy;
+        pixel2pos (ax, px, py, xx, yy);
+
+        Matrix pos (2,3,0);
+        pos(0,0) = xx;
+        pos(1,0) = yy;
+        pos(0,1) = xx;
+        pos(1,1) = yy;
+
+        ap.set_currentpoint (pos);
+      }
+  }
+
+  int key2shift (int key)
+  {
+    if (key == FL_Shift_L || key == FL_Shift_R)
+      return FL_SHIFT;
+
+    if (key == FL_Control_L || key == FL_Control_R)
+      return FL_CTRL;
+
+    if (key == FL_Alt_L || key == FL_Alt_R)
+      return FL_ALT;
+
+    if (key == FL_Meta_L || key == FL_Meta_R)
+      return FL_META;
+
+    return 0;
+  }
+
+  int key2ascii (int key)
+  {
+    if (key < 256) return key;
+    if (key == FL_Tab) return '\t';
+    if (key == FL_Enter) return 0x0a;
+    if (key == FL_BackSpace) return 0x08;
+    if (key == FL_Escape) return 0x1b;
+
+    return 0;
+  }
+
+  Cell modifier2cell ()
+  {
+    string_vector mod;
+
+    if (shift & FL_SHIFT)
+      mod.append (std::string ("shift"));
+    if (shift & FL_CTRL)
+      mod.append (std::string ("control"));
+    if (shift & FL_ALT || shift & FL_META)
+      mod.append (std::string ("alt"));
+
+    return Cell (mod);
+  }
+
+  void resize (int xx,int yy,int ww,int hh)
+  {
+    Fl_Window::resize (xx, yy, ww, hh);
+
+    Matrix pos (1,4,0);
+    pos(0) = xx;
+    pos(1) = yy;
+    pos(2) = ww;
+    pos(3) = hh - status_h - menu_h;
+
+    fp.set_boundingbox (pos, true);
+  }
+
+  void draw (void)
+  {
+    Matrix pos = fp.get_boundingbox (true);
+    Fl_Window::resize (pos(0), pos(1), pos(2), pos(3) + status_h + menu_h);
+
+    return Fl_Window::draw ();
+  }
+
+  int handle (int event)
+  {
+    graphics_handle gh;
+
+    graphics_object fig = gh_manager::get_object (fp.get___myhandle__ ());
+    int retval = Fl_Window::handle (event);
+
+    // We only handle events which are in the canvas area.
+    if (!Fl::event_inside (canvas))
+      return retval;
+
+    if (!fp.is_beingdeleted ())
+      {
+        switch (event)
+          {
+          case FL_KEYDOWN:
+            {
+              int key = Fl::event_key ();
+
+              shift |= key2shift (key);
+              int key_a = key2ascii (key);
+              if (key_a && fp.get_keypressfcn ().is_defined ())
+                {
+                  Octave_map evt;
+                  evt.assign ("Character", octave_value (key_a));
+                  evt.assign ("Key", octave_value (std::tolower (key_a)));
+                  evt.assign ("Modifier", octave_value (modifier2cell ()));
+                  fp.execute_keypressfcn (evt);
+                }
+              switch (key)
+                {
+                case 'a':
+                case 'A':
+                  axis_auto ();
+                break;
+
+                case 'g':
+                case 'G':
+                  toggle_grid ();
+                break;
+
+                case 'p':
+                case 'P':
+                  gui_mode = pan_zoom;
+                break;
+
+                case 'r':
+                case 'R':
+                  gui_mode = rotate_zoom;
+                break;
+                }
+            }
+            break;
+
+          case FL_KEYUP:
+            {
+              int key = Fl::event_key ();
+
+              shift &= (~key2shift (key));
+              int key_a = key2ascii (key);
+              if (key_a && fp.get_keyreleasefcn ().is_defined ())
+                {
+                  Octave_map evt;
+                  evt.assign ("Character", octave_value (key_a));
+                  evt.assign ("Key", octave_value (std::tolower (key_a)));
+                  evt.assign ("Modifier", octave_value (modifier2cell ()));
+                  fp.execute_keyreleasefcn (evt);
+                }
+            }
+            break;
+
+          case FL_MOVE:
+            pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()),
+                          Fl::event_x (), Fl::event_y ());
+            break;
+
+          case FL_PUSH:
+            pos_x = Fl::event_x ();
+            pos_y = Fl::event_y ();
+
+            set_currentpoint (Fl::event_x (), Fl::event_y ());
+
+            gh = pixel2axes_or_ca (pos_x, pos_y);
+
+            if (gh.ok ())
+              {
+                ax_obj = gh_manager::get_object (gh);
+                set_axes_currentpoint (ax_obj, pos_x, pos_y);
+              }
+
+            fp.execute_windowbuttondownfcn ();
+
+            if (Fl::event_button () == 1 || Fl::event_button () == 3)
+              return 1;
+
+            break;
+
+          case FL_DRAG:
+            if (fp.get_windowbuttonmotionfcn ().is_defined ())
+              {
+                set_currentpoint (Fl::event_x (), Fl::event_y ());
+                fp.execute_windowbuttonmotionfcn ();
+              }
+
+            if (Fl::event_button () == 1)
+              {
+                if (ax_obj && ax_obj.isa ("axes"))
+                  {
+                    if (gui_mode == pan_zoom)
+                      pixel2status (ax_obj, pos_x, pos_y,
+                                    Fl::event_x (), Fl::event_y ());
+                    else
+                      view2status (ax_obj);
+                    axes::properties& ap =
+                      dynamic_cast<axes::properties&> (ax_obj.get_properties ());
+
+                    double x0, y0, x1, y1;
+                    Matrix pos = fp.get_boundingbox (true);
+                    pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
+                    pixel2pos (ax_obj, Fl::event_x (), Fl::event_y (), x1, y1);
+
+                    if (gui_mode == pan_zoom)
+                      ap.translate_view (x0, x1, y0, y1);
+                    else if (gui_mode == rotate_zoom)
+                      {
+                        double daz, del;
+                        daz = (Fl::event_x () - pos_x) / pos(2) * 360;
+                        del = (Fl::event_y () - pos_y) / pos(3) * 360;
+                        ap.rotate_view (del, daz);
+                      }
+
+                    pos_x = Fl::event_x ();
+                    pos_y = Fl::event_y ();
+                    mark_modified ();
+                  }
+                return 1;
+              }
+            else if (Fl::event_button () == 3)
+              {
+                pixel2status (ax_obj, pos_x, pos_y,
+                              Fl::event_x (), Fl::event_y ());
+                Matrix zoom_box (1,4,0);
+                zoom_box (0) = pos_x;
+                zoom_box (1) = pos_y;
+                zoom_box (2) =  Fl::event_x ();
+                zoom_box (3) =  Fl::event_y ();
+                canvas->set_zoom_box (zoom_box);
+                canvas->zoom (true);
+                canvas->redraw ();
+              }
+
+            break;
+
+          case FL_MOUSEWHEEL:
+            {
+              graphics_object ax =
+                gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (),
+                                                          Fl::event_y ()));
+              if (ax && ax.isa ("axes"))
+                {
+                  axes::properties& ap =
+                    dynamic_cast<axes::properties&> (ax.get_properties ());
+
+                  // Determine if we're zooming in or out.
+                  const double factor =
+                    (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed;
+
+                  // Get the point we're zooming about.
+                  double x1, y1;
+                  pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1);
+
+                  ap.zoom_about_point (x1, y1, factor, false);
+                  mark_modified ();
+                }
+            }
+          return 1;
+
+          case FL_RELEASE:
+            if (fp.get_windowbuttonupfcn ().is_defined ())
+              {
+                set_currentpoint (Fl::event_x (), Fl::event_y ());
+                fp.execute_windowbuttonupfcn ();
+              }
+
+            if (Fl::event_button () == 1)
+              {
+                if ( Fl::event_clicks () == 1)
+                  {
+                    if (ax_obj && ax_obj.isa ("axes"))
+                      {
+                        axes::properties& ap =
+                          dynamic_cast<axes::properties&> (ax_obj.get_properties ());
+                        ap.set_xlimmode ("auto");
+                        ap.set_ylimmode ("auto");
+                        ap.set_zlimmode ("auto");
+                        mark_modified ();
+                      }
+                  }
+              }
+            if (Fl::event_button () == 3)
+              {
+                // End of drag -- zoom.
+                if (canvas->zoom ())
+                  {
+                    canvas->zoom (false);
+                    double x0,y0,x1,y1;
+                    if (ax_obj && ax_obj.isa ("axes"))
+                      {
+                        axes::properties& ap =
+                          dynamic_cast<axes::properties&> (ax_obj.get_properties ());
+                        pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
+                        int pos_x1 = Fl::event_x ();
+                        int pos_y1 = Fl::event_y ();
+                        pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1);
+                        Matrix xl (1,2,0);
+                        Matrix yl (1,2,0);
+                        int dx = abs (pos_x - pos_x1);
+                        int dy = abs (pos_y - pos_y1);
+                        // Smallest zoom box must be 4 pixels square
+                        if ((dx > 4) && (dy > 4))
+                          {
+                            if (x0 < x1)
+                              {
+                                xl(0) = x0;
+                                xl(1) = x1;
+                              }
+                            else
+                              {
+                                xl(0) = x1;
+                                xl(1) = x0;
+                              }
+                            if (y0 < y1)
+                              {
+                                yl(0) = y0;
+                                yl(1) = y1;
+                              }
+                            else
+                              {
+                                yl(0) = y1;
+                                yl(1) = y0;
+                              }
+                            ap.zoom (xl, yl);
+                          }
+                        mark_modified ();
+                      }
+                  }
+              }
+            break;
+          }
+      }
+
+    return retval;
+  }
+};
+
+class figure_manager
+{
+public:
+
+  static bool instance_ok (void)
+  {
+    bool retval = true;
+
+    if (! instance)
+      instance = new figure_manager ();
+
+    if (! instance)
+      {
+        ::error ("unable to create figure_manager object!");
+
+        retval = false;
+      }
+
+    return retval;
+  }
+
+  ~figure_manager (void)
+  {
+    close_all ();
+  }
+
+  static void close_all (void)
+  {
+    if (instance_ok ())
+      instance->do_close_all ();
+  }
+
+  static void new_window (figure::properties& fp)
+  {
+    if (instance_ok ())
+      instance->do_new_window (fp);
+  }
+
+  static void delete_window (int idx)
+  {
+    if (instance_ok ())
+      instance->do_delete_window (idx);
+  }
+
+  static void delete_window (const std::string& idx_str)
+  {
+    delete_window (str2idx (idx_str));
+  }
+
+  static void renumber_figure (const std::string& idx_str, double new_number)
+  {
+    if (instance_ok ())
+      instance->do_renumber_figure (str2idx (idx_str), new_number);
+  }
+
+  static void toggle_window_visibility (int idx, bool is_visible)
+  {
+    if (instance_ok ())
+      instance->do_toggle_window_visibility (idx, is_visible);
+  }
+
+  static void toggle_window_visibility (const std::string& idx_str,
+                                        bool is_visible)
+  {
+    toggle_window_visibility (str2idx (idx_str), is_visible);
+  }
+
+  static void mark_modified (int idx)
+  {
+    if (instance_ok ())
+      instance->do_mark_modified (idx);
+  }
+
+  static void mark_modified (const graphics_handle& gh)
+  {
+    mark_modified (hnd2idx (gh));
+  }
+
+  static void set_name (int idx)
+  {
+    if (instance_ok ())
+      instance->do_set_name (idx);
+  }
+
+  static void set_name (const std::string& idx_str)
+  {
+    set_name (str2idx (idx_str));
+  }
+
+  static Matrix get_size (int idx)
+  {
+    return instance_ok () ? instance->do_get_size (idx) : Matrix ();
+  }
+
+  static Matrix get_size (const graphics_handle& gh)
+  {
+    return get_size (hnd2idx (gh));
+  }
+
+  static void print (const graphics_handle& gh, const std::string& cmd,
+                     const std::string& term)
+  {
+    if (instance_ok ())
+      instance->do_print (hnd2idx (gh), cmd, term);
+  }
+
+  static void uimenu_update (const graphics_handle& figh,
+                             const graphics_handle& uimenuh, int id)
+  {
+    if (instance_ok ())
+      instance->do_uimenu_update (hnd2idx (figh), uimenuh, id);
+  }
+
+  static void update_canvas (const graphics_handle& gh,
+                             const graphics_handle& ca)
+  {
+    if (instance_ok ())
+      instance->do_update_canvas (hnd2idx (gh), ca);
+  }
+
+  static void toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
+  {
+    if (instance_ok ())
+      instance->do_toggle_menubar_visibility (fig_idx, menubar_is_figure);
+  }
+
+  static void toggle_menubar_visibility (const std::string& fig_idx_str,
+                                         bool menubar_is_figure)
+  {
+    toggle_menubar_visibility (str2idx (fig_idx_str), menubar_is_figure);
+  }
+
+private:
+
+  static figure_manager *instance;
+
+  figure_manager (void) { }
+
+  // No copying!
+  figure_manager (const figure_manager&);
+  figure_manager& operator = (const figure_manager&);
+
+  // Singelton -- hide all of the above.
+
+  static int curr_index;
+  typedef std::map<int, plot_window*> window_map;
+  typedef window_map::iterator wm_iterator;;
+  window_map windows;
+
+  static std::string fltk_idx_header;
+
+  void do_close_all (void)
+  {
+    wm_iterator win;
+    for (win = windows.begin (); win != windows.end (); win++)
+      delete win->second;
+    windows.clear ();
+  }
+
+  void do_new_window (figure::properties& fp)
+  {
+    int idx = figprops2idx (fp);
+
+    if (idx >= 0 && windows.find (idx) == windows.end ())
+      {
+        Matrix pos = fp.get_boundingbox (true);
+
+        int x = pos(0);
+        int y = pos(1);
+        int w = pos(2);
+        int h = pos(3);
+
+        idx2figprops (curr_index, fp);
+
+        windows[curr_index++] = new plot_window (x, y, w, h, fp);
+      }
+  }
+
+  void do_delete_window (int idx)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      {
+        delete win->second;
+        windows.erase (win);
+      }
+  }
+
+  void do_renumber_figure (int idx, double new_number)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->renumber (new_number);
+  }
+
+  void do_toggle_window_visibility (int idx, bool is_visible)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      {
+        if (is_visible)
+          win->second->show ();
+        else
+          win->second->hide ();
+
+        win->second->redraw ();
+      }
+  }
+
+  void do_toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
+  {
+    wm_iterator win = windows.find (fig_idx);
+
+    if (win != windows.end ())
+      {
+        if (menubar_is_figure)
+          win->second->show_menubar ();
+        else
+          win->second->hide_menubar ();
+
+        win->second->redraw ();
+      }
+  }
+
+  void do_mark_modified (int idx)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->mark_modified ();
+  }
+
+  void do_set_name (int idx)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->set_name ();
+  }
+
+  Matrix do_get_size (int idx)
+  {
+    Matrix sz (1, 2, 0.0);
+
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      {
+        sz(0) = win->second->w ();
+        sz(1) = win->second->h ();
+      }
+
+    return sz;
+  }
+
+  void do_print (int idx, const std::string& cmd, const std::string& term)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->print (cmd, term);
+  }
+
+  void do_uimenu_update (int idx, const graphics_handle& gh, int id)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->uimenu_update (gh, id);
+  }
+
+  void do_update_canvas (int idx, const graphics_handle& ca)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      {
+        if (ca.ok ())
+          win->second->show_canvas ();
+        else
+          win->second->hide_canvas ();
+      }
+  }
+
+  static int str2idx (const caseless_str& clstr)
+  {
+    int ind;
+    if (clstr.find (fltk_idx_header,0) == 0)
+      {
+        std::istringstream istr (clstr.substr (fltk_idx_header.size ()));
+        if (istr >> ind)
+          return ind;
+      }
+    error ("figure_manager: could not recognize fltk index");
+    return -1;
+  }
+
+  void idx2figprops (int idx, figure::properties& fp)
+  {
+    std::ostringstream ind_str;
+    ind_str << fltk_idx_header << idx;
+    fp.set___plot_stream__ (ind_str.str ());
+  }
+
+  static int figprops2idx (const figure::properties& fp)
+  {
+    if (fp.get___graphics_toolkit__ () == FLTK_GRAPHICS_TOOLKIT_NAME)
+      {
+        octave_value ps = fp.get___plot_stream__ ();
+        if (ps.is_string ())
+          return str2idx (ps.string_value ());
+        else
+          return 0;
+      }
+    error ("figure_manager: figure is not fltk");
+    return -1;
+  }
+
+  static int hnd2idx (double h)
+  {
+    graphics_object fobj = gh_manager::get_object (h);
+    if (fobj &&  fobj.isa ("figure"))
+      {
+        figure::properties& fp =
+          dynamic_cast<figure::properties&> (fobj.get_properties ());
+        return figprops2idx (fp);
+      }
+    error ("figure_manager: H (= %g) is not a figure", h);
+    return -1;
+  }
+
+  static int hnd2idx (const graphics_handle& fh)
+  {
+    return hnd2idx (fh.value ());
+  }
+};
+
+figure_manager *figure_manager::instance = 0;
+
+std::string figure_manager::fltk_idx_header="fltk index=";
+int figure_manager::curr_index = 1;
+
+static bool toolkit_loaded = false;
+
+static int
+__fltk_redraw__ (void)
+{
+  if (toolkit_loaded)
+    {
+      // We scan all figures and add those which use FLTK.
+      graphics_object obj = gh_manager::get_object (0);
+      if (obj && obj.isa ("root"))
+        {
+          base_properties& props = obj.get_properties ();
+          Matrix children = props.get_all_children ();
+
+          for (octave_idx_type n = 0; n < children.numel (); n++)
+            {
+              graphics_object fobj = gh_manager::get_object (children (n));
+              if (fobj && fobj.isa ("figure"))
+                {
+                  figure::properties& fp =
+                      dynamic_cast<figure::properties&> (fobj.get_properties ());
+                  if (fp.get___graphics_toolkit__ ()
+                      == FLTK_GRAPHICS_TOOLKIT_NAME)
+                    figure_manager::new_window (fp);
+                }
+            }
+        }
+
+      // it seems that we have to call Fl::check twice to get everything drawn
+      Fl::check ();
+      Fl::check ();
+    }
+
+  return 0;
+}
+
+class fltk_graphics_toolkit : public base_graphics_toolkit
+{
+public:
+  fltk_graphics_toolkit (void)
+    : base_graphics_toolkit (FLTK_GRAPHICS_TOOLKIT_NAME) { }
+
+  ~fltk_graphics_toolkit (void) { }
+
+  bool is_valid (void) const { return true; }
+
+  bool initialize (const graphics_object& go)
+    { return go.isa ("figure"); }
+
+  void finalize (const graphics_object& go)
+  {
+    if (go.isa ("figure"))
+      {
+        octave_value ov = go.get (caseless_str ("__plot_stream__"));
+
+        if (! ov.is_empty ())
+          figure_manager::delete_window (ov.string_value ());
+      }
+  }
+
+  void uimenu_set_fltk_label (graphics_object uimenu_obj)
+  {
+    if (uimenu_obj.valid_object ())
+      {
+        uimenu::properties& uimenup =
+          dynamic_cast<uimenu::properties&> (uimenu_obj.get_properties ());
+        std::string fltk_label = uimenup.get_label ();
+        graphics_object go = gh_manager::get_object (uimenu_obj.get_parent ());
+        if (go.isa ("uimenu"))
+          fltk_label = dynamic_cast<const uimenu::properties&> (go.get_properties ()).get_fltk_label ()
+            + "/"
+            + fltk_label;
+        else if (go.isa ("figure"))
+          ;
+        else
+          error ("unexpected parent object\n");
+
+        uimenup.set_fltk_label (fltk_label);
+      }
+  }
+
+  void update (const graphics_object& go, int id)
+  {
+    if (go.isa ("figure"))
+      {
+        octave_value ov = go.get (caseless_str ("__plot_stream__"));
+
+        if (! ov.is_empty ())
+          {
+            const figure::properties& fp =
+              dynamic_cast<const figure::properties&> (go.get_properties ());
+
+            switch (id)
+              {
+              case base_properties::ID_VISIBLE:
+                figure_manager::toggle_window_visibility
+                  (ov.string_value (), fp.is_visible ());
+                break;
+
+              case figure::properties::ID_MENUBAR:
+                figure_manager::toggle_menubar_visibility
+                  (ov.string_value (), fp.menubar_is ("figure"));
+                break;
+
+              case figure::properties::ID_CURRENTAXES:
+                figure_manager::update_canvas
+                  (go.get_handle (), fp.get_currentaxes ());
+                break;
+
+              case figure::properties::ID_NAME:
+              case figure::properties::ID_NUMBERTITLE:
+                figure_manager::set_name (ov.string_value ());
+                break;
+
+              case figure::properties::ID_INTEGERHANDLE:
+                {
+                  std::string tmp = ov.string_value ();
+                  graphics_handle gh = fp.get___myhandle__ ();
+                  figure_manager::renumber_figure (tmp, gh.value ());
+                  figure_manager::set_name (tmp);
+                }
+                break;
+              }
+          }
+      }
+    else if (go.isa ("uimenu"))
+      {
+        if (id == uimenu::properties::ID_LABEL)
+          uimenu_set_fltk_label (go);
+
+        graphics_object fig = go.get_ancestor ("figure");
+        figure_manager::uimenu_update (fig.get_handle (), go.get_handle (), id);
+      }
+  }
+
+  void redraw_figure (const graphics_object& go) const
+  {
+    figure_manager::mark_modified (go.get_handle ());
+
+    __fltk_redraw__ ();
+  }
+
+  void print_figure (const graphics_object& go,
+                     const std::string& term,
+                     const std::string& file_cmd, bool /*mono*/,
+                     const std::string& /*debug_file*/) const
+  {
+    figure_manager::print (go.get_handle (), file_cmd, term);
+    redraw_figure (go);
+  }
+
+  Matrix get_canvas_size (const graphics_handle& fh) const
+  {
+    return figure_manager::get_size (fh);
+  }
+
+  double get_screen_resolution (void) const
+  {
+    // FLTK doesn't give this info.
+    return 72.0;
+  }
+
+  Matrix get_screen_size (void) const
+  {
+    Matrix sz (1, 2, 0.0);
+    sz(0) = Fl::w ();
+    sz(1) = Fl::h ();
+    return sz;
+  }
+
+  void close (void)
+  {
+    if (toolkit_loaded)
+      {
+        munlock ("__init_fltk__");
+
+        figure_manager::close_all ();
+        gtk_manager::unload_toolkit (FLTK_GRAPHICS_TOOLKIT_NAME);
+        toolkit_loaded = false;
+
+        octave_value_list args;
+        args(0) = "__fltk_redraw__";
+        feval ("remove_input_event_hook", args, 0);
+
+        // FIXME ???
+        Fl::wait (fltk_maxtime);
+      }
+  }
+};
+
+// Initialize the fltk graphics toolkit.
+
+DEFUN_DLD (__init_fltk__, , , "")
+{
+  if (! toolkit_loaded)
+    {
+      mlock ();
+
+      graphics_toolkit tk (new fltk_graphics_toolkit ());
+      gtk_manager::load_toolkit (tk);
+      toolkit_loaded = true;
+
+      octave_value_list args;
+      args(0) = "__fltk_redraw__";
+      feval ("add_input_event_hook", args, 0);
+    }
+
+  octave_value retval;
+  return retval;
+}
+
+DEFUN_DLD (__fltk_redraw__, , , "")
+{
+  __fltk_redraw__ ();
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__fltk_maxtime__, args, ,"")
+{
+  octave_value retval = fltk_maxtime;
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_real_scalar ())
+        fltk_maxtime = args(0).double_value ();
+      else
+        error ("argument must be a real scalar");
+    }
+
+  return retval;
+}
+
+#endif
+
+// FIXME -- This function should be abstracted and made potentially
+// available to all graphics toolkits.  This suggests putting it in
+// graphics.cc as is done for drawnow() and having the master
+// mouse_wheel_zoom function call fltk_mouse_wheel_zoom.  The same
+// should be done for gui_mode and fltk_gui_mode.  For now (2011.01.30),
+// just changing function names and docstrings.
+
+DEFUN_DLD (mouse_wheel_zoom, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{speed} =} mouse_wheel_zoom ()\n\
+@deftypefnx {Built-in Function} {} mouse_wheel_zoom (@var{speed})\n\
+Query or set the mouse wheel zoom factor.\n\
+\n\
+This function is currently implemented only for the FLTK graphics toolkit.\n\
+@seealso{gui_mode}\n\
+@end deftypefn")
+{
+#if defined (HAVE_FLTK)
+  octave_value retval = wheel_zoom_speed;
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_real_scalar ())
+        wheel_zoom_speed = args(0).double_value ();
+      else
+        error ("mouse_wheel_zoom: SPEED must be a real scalar");
+    }
+
+  return retval;
+#else
+  error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
+  return octave_value ();
+#endif
+}
+
+DEFUN_DLD (gui_mode, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{mode} =} gui_mode ()\n\
+@deftypefnx {Built-in Function} {} gui_mode (@var{mode})\n\
+Query or set the GUI mode for the current graphics toolkit.\n\
+The @var{mode} argument can be one of the following strings:\n\
+\n\
+@table @asis\n\
+@item '2d'\n\
+Allows panning and zooming of current axes.\n\
+\n\
+@item '3d'\n\
+Allows rotating and zooming of current axes.\n\
+\n\
+@item 'none'\n\
+Mouse inputs have no effect.\n\
+@end table\n\
+\n\
+This function is currently implemented only for the FLTK graphics toolkit.\n\
+@seealso{mouse_wheel_zoom}\n\
+@end deftypefn")
+{
+#if defined (HAVE_FLTK)
+  caseless_str mode_str;
+
+  if (gui_mode == pan_zoom)
+    mode_str = "2d";
+  else if (gui_mode == rotate_zoom)
+    mode_str = "3d";
+  else
+    mode_str = "none";
+
+  bool failed = false;
+
+  if (args.length () == 1)
+    {
+      if (args(0).is_string ())
+        {
+          mode_str = args(0).string_value ();
+
+          if (mode_str.compare ("2d"))
+            gui_mode = pan_zoom;
+          else if (mode_str.compare ("3d"))
+            gui_mode = rotate_zoom;
+          else if (mode_str.compare ("none"))
+            gui_mode = none;
+          else
+            failed = true;
+        }
+      else
+        failed = true;
+    }
+
+  if (failed)
+    error ("MODE must be one of the strings: \"2D\", \"3D\", or \"none\"");
+
+  return octave_value (mode_str);
+#else
+  error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
+  return octave_value ();
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__init_gnuplot__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,193 @@
+/*
+
+Copyright (C) 2007-2012 John W. Eaton
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+
+To initialize:
+
+  graphics_toolkit ("gnuplot");
+  plot (randn (1e3, 1));
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "graphics.h"
+#include "parse.h"
+#include "variables.h"
+
+// PKG_ADD: register_graphics_toolkit ("gnuplot");
+
+static bool toolkit_loaded = false;
+
+class gnuplot_graphics_toolkit : public base_graphics_toolkit
+{
+public:
+  gnuplot_graphics_toolkit (void)
+      : base_graphics_toolkit ("gnuplot") { }
+
+  ~gnuplot_graphics_toolkit (void) { }
+
+  bool is_valid (void) const { return true; }
+
+  bool initialize (const graphics_object& go)
+    {
+      return go.isa ("figure");
+    }
+
+  void finalize (const graphics_object& go)
+    {
+      if (go.isa ("figure"))
+        {
+          const figure::properties& props =
+              dynamic_cast<const figure::properties&> (go.get_properties ());
+
+          send_quit (props.get___plot_stream__ ());
+        }
+    }
+
+  void update (const graphics_object& go, int id)
+    {
+      if (go.isa ("figure"))
+        {
+          graphics_object obj (go);
+
+          figure::properties& props =
+              dynamic_cast<figure::properties&> (obj.get_properties ());
+
+          switch (id)
+            {
+            case base_properties::ID_VISIBLE:
+              if (! props.is_visible ())
+                {
+                  send_quit (props.get___plot_stream__ ());
+                  props.set___plot_stream__ (Matrix ());
+                  props.set___enhanced__ (false);
+                }
+              break;
+            }
+        }
+    }
+
+  void redraw_figure (const graphics_object& go) const
+    {
+      octave_value_list args;
+      args(0) = go.get_handle ().as_octave_value ();
+      feval ("__gnuplot_drawnow__", args);
+    }
+
+  void print_figure (const graphics_object& go, const std::string& term,
+                     const std::string& file, bool mono,
+                     const std::string& debug_file) const
+    {
+      octave_value_list args;
+      if (! debug_file.empty ())
+        args(4) = debug_file;
+      args(3) = mono;
+      args(2) = file;
+      args(1) = term;
+      args(0) = go.get_handle ().as_octave_value ();
+      feval ("__gnuplot_drawnow__", args);
+    }
+
+  Matrix get_canvas_size (const graphics_handle&) const
+    {
+      Matrix sz (1, 2, 0.0);
+      return sz;
+    }
+
+  double get_screen_resolution (void) const
+    { return 72.0; }
+
+  Matrix get_screen_size (void) const
+    { return Matrix (1, 2, 0.0); }
+
+  void close (void)
+  {
+    if (toolkit_loaded)
+      {
+        munlock ("__init_gnuplot__");
+
+        gtk_manager::unload_toolkit ("gnuplot");
+
+        toolkit_loaded = false;
+      }
+  }
+
+private:
+
+  void send_quit (const octave_value& pstream) const
+    {
+      if (! pstream.is_empty ())
+        {
+          octave_value_list args;
+          Matrix fids = pstream.matrix_value ();
+
+          if (! error_state)
+            {
+              args(1) = "\nquit;\n";
+              args(0) = fids(0);
+              feval ("fputs", args);
+
+              args.resize (1);
+              feval ("fflush", args);
+              feval ("pclose", args);
+
+              if (fids.numel () > 1)
+                {
+                  args(0) = fids(1);
+                  feval ("pclose", args);
+
+                  if (fids.numel () > 2)
+                    {
+                      args(0) = fids(2);
+                      feval ("waitpid", args);
+                    }
+                }
+            }
+        }
+    }
+};
+
+// Initialize the fltk graphics toolkit.
+
+DEFUN_DLD (__init_gnuplot__, , , "")
+{
+  octave_value retval;
+
+  if (! toolkit_loaded)
+    {
+      mlock ();
+
+      graphics_toolkit tk (new gnuplot_graphics_toolkit ());
+      gtk_manager::load_toolkit (tk);
+
+      toolkit_loaded = true;
+    }
+
+  return retval;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__magick_read__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,1216 @@
+/*
+
+Copyright (C) 2002-2012 Andy Adler
+Copyright (C) 2008 Thomas L. Scofield
+Copyright (C) 2010 David Grundberg
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cmath>
+
+#include "file-stat.h"
+#include "oct-env.h"
+#include "oct-time.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "ov-struct.h"
+
+#ifdef HAVE_MAGICK
+
+#include <Magick++.h>
+#include <clocale>
+
+octave_value_list
+read_indexed_images (std::vector<Magick::Image>& imvec,
+                     const Array<int>& frameidx, bool wantalpha)
+{
+  octave_value_list output;
+
+  int rows = imvec[0].baseRows ();
+  int columns = imvec[0].baseColumns ();
+  int nframes = frameidx.length ();
+
+  dim_vector idim = dim_vector ();
+  idim.resize (4);
+  idim(0) = rows;
+  idim(1) = columns;
+  idim(2) = 1;
+  idim(3) = nframes;
+
+  Array<int> idx (dim_vector (4, 1));
+
+  Magick::ImageType type = imvec[0].type ();
+
+  unsigned int mapsize = imvec[0].colorMapSize ();
+  unsigned int i = mapsize;
+  unsigned int depth = 0;
+  while (i >>= 1)
+    depth++;
+  i = 0;
+  depth--;
+  while (depth >>= 1)
+    i++;
+  depth = 1 << i;
+
+  switch (depth)
+    {
+    case 1:
+    case 2:
+    case 4:
+    case 8:
+      {
+        uint8NDArray im = uint8NDArray (idim);
+
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
+
+            i = 0;
+            idx(3) = frame;
+
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = static_cast<octave_uint8> (pix[i++]);
+                  }
+              }
+          }
+
+        output(0) = octave_value (im);
+      }
+      break;
+
+    case 16:
+      {
+        uint16NDArray im = uint16NDArray (idim);
+
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
+
+            i = 0;
+            idx(3) = frame;
+
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = static_cast<octave_uint16> (pix[i++]);
+                  }
+              }
+          }
+
+        output(0) = octave_value (im);
+      }
+      break;
+
+    default:
+      error ("__magic_read__: index depths greater than 16-bit are not supported");
+      return octave_value_list ();
+    }
+
+  Matrix map = Matrix (mapsize, 3);
+  Matrix alpha;
+
+  switch (type)
+    {
+    case Magick::PaletteMatteType:
+#if 0
+      warning ("palettematte");
+      Matrix map (mapsize, 3);
+      Matrix alpha (mapsize, 1);
+      for (i = 0; i < mapsize; i++)
+        {
+          warning ("%d", i);
+          Magick::ColorRGB c = imvec[0].colorMap (i);
+          map(i,0) = c.red ();
+          map(i,1) = c.green ();
+          map(i,2) = c.blue ();
+          alpha(i,1) = c.alpha ();
+        }
+      break;
+#endif
+
+    case Magick::PaletteType:
+      alpha = Matrix (0, 0);
+      for (i = 0; i < mapsize; i++)
+        {
+          Magick::ColorRGB c = imvec[0].colorMap (i);
+          map(i,0) = c.red ();
+          map(i,1) = c.green ();
+          map(i,2) = c.blue ();
+        }
+      break;
+
+    default:
+      error ("__magick_read__: unsupported indexed image type");
+      return octave_value_list ();
+    }
+
+  if (wantalpha)
+    output(2) = alpha;
+
+  output(1) = map;
+
+  return output;
+}
+
+template <class T>
+octave_value_list
+read_images (const std::vector<Magick::Image>& imvec,
+             const Array<int>& frameidx, unsigned int depth)
+{
+  typedef typename T::element_type P;
+
+  octave_value_list retval (3, Matrix ());
+
+  T im;
+
+  int rows = imvec[0].baseRows ();
+  int columns = imvec[0].baseColumns ();
+  int nframes = frameidx.length ();
+
+  dim_vector idim = dim_vector ();
+  idim.resize (4);
+  idim(0) = rows;
+  idim(1) = columns;
+  idim(2) = 1;
+  idim(3) = nframes;
+
+  Magick::ImageType type = imvec[0].type ();
+  const int divisor = ((uint64_t (1) << QuantumDepth) - 1) / 
+                      ((uint64_t (1) << depth) - 1);
+
+  switch (type)
+    {
+    case Magick::BilevelType:
+    case Magick::GrayscaleType:
+      {
+        im = T (idim);
+        P *vec = im.fortran_vec ();
+
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            const Magick::PixelPacket *pix
+              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            P *rbuf = vec;
+            for (int y = 0; y < rows; y++)
+              {
+                for (int x = 0; x < columns; x++)
+                  {
+                    *rbuf = pix->red / divisor;
+                    pix++;
+                    rbuf += rows;
+                  }
+                rbuf -= rows * columns - 1;
+              }
+
+            // Next frame.
+            vec += rows * columns * idim(2);
+          }
+        }
+      break;
+
+    case Magick::GrayscaleMatteType:
+      {
+        idim(2) = 2;
+        im = T (idim);
+        P *vec = im.fortran_vec ();
+
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            const Magick::PixelPacket *pix
+              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            P *rbuf = vec;
+            P *obuf = vec + rows * columns;
+            for (int y = 0; y < rows; y++)
+              {
+                for (int x = 0; x < columns; x++)
+                  {
+                    *rbuf = pix->red / divisor;
+                    *obuf = pix->opacity / divisor;
+                    pix++;
+                    rbuf += rows;
+                    obuf += rows;
+                  }
+                rbuf -= rows * columns - 1;
+                obuf -= rows * columns - 1;
+              }
+
+            // Next frame.
+            vec += rows * columns * idim(2);
+          }
+        }
+      break;
+
+    case Magick::PaletteType:
+    case Magick::TrueColorType:
+      {
+        idim(2) = 3;
+        im = T (idim);
+        P *vec = im.fortran_vec ();
+
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            const Magick::PixelPacket *pix
+              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            P *rbuf = vec;
+            P *gbuf = vec + rows * columns;
+            P *bbuf = vec + rows * columns * 2;
+            for (int y = 0; y < rows; y++)
+              {
+                for (int x = 0; x < columns; x++)
+                  {
+                    *rbuf = pix->red / divisor;
+                    *gbuf = pix->green / divisor;
+                    *bbuf = pix->blue / divisor;
+                    pix++;
+                    rbuf += rows;
+                    gbuf += rows;
+                    bbuf += rows;
+                  }
+                rbuf -= rows * columns - 1;
+                gbuf -= rows * columns - 1;
+                bbuf -= rows * columns - 1;
+              }
+
+            // Next frame.
+            vec += rows * columns * idim(2);
+          }
+        }
+      break;
+
+    case Magick::PaletteMatteType:
+    case Magick::TrueColorMatteType:
+    case Magick::ColorSeparationType:
+      {
+        idim(2) = 4;
+        im = T (idim);
+        P *vec = im.fortran_vec ();
+
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            const Magick::PixelPacket *pix
+              = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+            P *rbuf = vec;
+            P *gbuf = vec + rows * columns;
+            P *bbuf = vec + rows * columns * 2;
+            P *obuf = vec + rows * columns * 3;
+            for (int y = 0; y < rows; y++)
+              {
+                for (int x = 0; x < columns; x++)
+                  {
+                    *rbuf = pix->red / divisor;
+                    *gbuf = pix->green / divisor;
+                    *bbuf = pix->blue / divisor;
+                    *obuf = pix->opacity / divisor;
+                    pix++;
+                    rbuf += rows;
+                    gbuf += rows;
+                    bbuf += rows;
+                    obuf += rows;
+                  }
+                rbuf -= rows * columns - 1;
+                gbuf -= rows * columns - 1;
+                bbuf -= rows * columns - 1;
+                obuf -= rows * columns - 1;
+              }
+
+            // Next frame.
+            vec += rows * columns * idim(2);
+          }
+        }
+      break;
+
+    default:
+      error ("__magick_read__: undefined ImageMagick image type");
+      return retval;
+    }
+
+  retval(0) = im;
+
+  return retval;
+}
+
+#endif
+
+static void
+maybe_initialize_magick (void)
+{
+#ifdef HAVE_MAGICK
+
+  static bool initialized = false;
+
+  if (! initialized)
+    {
+      // Save the locale as GraphicsMagick might change this (depending on version)
+      const char *static_locale = setlocale (LC_ALL, NULL);
+      const std::string locale (static_locale);
+
+      std::string program_name = octave_env::get_program_invocation_name ();
+
+      Magick::InitializeMagick (program_name.c_str ());
+
+      // Restore locale from before GraphicsMagick initialisation
+      setlocale (LC_ALL, locale.c_str ());
+
+      if (QuantumDepth < 32)
+        warning ("your version of %s limits images to %d bits per pixel",
+                 MagickPackageName, QuantumDepth);
+
+      initialized = true;
+    }
+#endif
+}
+
+DEFUN_DLD (__magick_read__, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Function File} {@var{m} =} __magick_read__ (@var{fname}, @var{index})\n\
+@deftypefnx {Function File} {[@var{m}, @var{colormap}] =} __magick_read__ (@var{fname}, @var{index})\n\
+@deftypefnx {Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__ (@var{fname}, @var{index})\n\
+Read images with ImageMagick++.  In general you should not be using this\n\
+function.  Instead use @code{imread}.\n\
+@seealso{imread}\n\
+@end deftypefn")
+{
+  octave_value_list output;
+
+#ifdef HAVE_MAGICK
+
+  maybe_initialize_magick ();
+
+  if (args.length () > 3 || args.length () < 1 || ! args(0).is_string ()
+      || nargout > 3)
+    {
+      print_usage ();
+      return output;
+    }
+
+  Array<int> frameidx;
+  bool all_frames = false;
+
+  if (args.length () == 2 && args(1).is_real_type ())
+    frameidx = args(1).int_vector_value ();
+  else if (args.length () == 3 && args(1).is_string ()
+           && args(1).string_value () == "frames")
+    {
+      if (args(2).is_string () && args(2).string_value () == "all")
+        all_frames = true;
+      else if (args(2).is_real_type ())
+        frameidx = args(2).int_vector_value ();
+    }
+  else
+    {
+      frameidx = Array<int> (dim_vector (1, 1));
+      frameidx(0) = 1;
+    }
+
+  std::vector<Magick::Image> imvec;
+
+  try
+    {
+      // Read a file into vector of image objects
+      Magick::readImages (&imvec, args(0).string_value ());
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+      return output;
+    }
+
+  int nframes = imvec.size ();
+  if (all_frames)
+    {
+      frameidx = Array<int> (dim_vector (1, nframes));
+      for (int i = 0; i < frameidx.length (); i++)
+        frameidx(i) = i;
+    }
+  else
+    {
+      for (int i = 0; i < frameidx.length (); i++)
+        {
+          frameidx(i) = frameidx(i) - 1;
+
+          if (frameidx(i) >= nframes || frameidx(i) < 0)
+            {
+              error ("__magick_read__: invalid INDEX vector");
+              return output;
+            }
+        }
+    }
+
+  Magick::ClassType klass = imvec[0].classType ();
+
+  if (klass == Magick::PseudoClass && nargout > 1)
+    output = read_indexed_images (imvec, frameidx, (nargout == 3));
+  else
+    {
+      unsigned int depth = imvec[0].modulusDepth ();
+      if (depth > 1)
+        {
+          --depth;
+          int i = 1;
+          while (depth >>= 1)
+            i++;
+          depth = 1 << i;
+        }
+
+      switch (depth)
+        {
+        case 1:
+          output = read_images<boolNDArray> (imvec, frameidx, depth);
+          break;
+
+        case 2:
+        case 4:
+        case 8:
+          output = read_images<uint8NDArray> (imvec, frameidx, depth) ;
+          break;
+
+        case 16:
+          output = read_images<uint16NDArray> (imvec, frameidx, depth);
+          break;
+
+        case 32:
+        case 64:
+        default:
+          error ("__magick_read__: image depths greater than 16-bit are not supported");
+        }
+    }
+#else
+
+  error ("imread: image reading capabilities were disabled when Octave was compiled");
+
+#endif
+
+  return output;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
+#ifdef HAVE_MAGICK
+
+static void
+jpg_settings (std::vector<Magick::Image>& imvec,
+              const Octave_map& options,
+              bool)
+{
+  bool something_set = false;
+
+  // Quality setting
+  octave_value result;
+  Octave_map::const_iterator p;
+  bool found_it = false;
+
+  for (p = options.begin (); p != options.end (); p++)
+    {
+      if (options.key (p) == "Quality")
+        {
+          found_it = true;
+          result = options.contents (p).elem (0);
+          break;
+        }
+    }
+
+  if (found_it && (! result.is_empty ()))
+    {
+      something_set = true;
+
+      if (result.is_real_type ())
+        {
+          int qlev = result.int_value ();
+
+          if (qlev < 0 || qlev > 100)
+            warning ("warning: Quality setting invalid--use default of 75");
+          else
+            {
+              for (size_t fnum = 0; fnum < imvec.size (); fnum++)
+                imvec[fnum].quality (static_cast<unsigned int>(qlev));
+            }
+        }
+      else
+        warning ("warning: Quality setting invalid--use default of 75");
+    }
+
+  // Other settings go here
+
+  if (! something_set)
+    warning ("__magick_write__ warning: all write parameters ignored");
+}
+
+static void
+encode_bool_image (std::vector<Magick::Image>& imvec, const octave_value& img)
+{
+  unsigned int nframes = 1;
+  boolNDArray m = img.bool_array_value ();
+
+  dim_vector dsizes = m.dims ();
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+
+  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
+
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+
+  for (unsigned int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im (Magick::Geometry (columns, rows), "black");
+      im.classType (Magick::DirectClass);
+      im.depth (1);
+
+      for (int y = 0; y < columns; y++)
+        {
+          idx(1) = y;
+
+          for (int x = 0; x < rows; x++)
+            {
+              if (nframes > 1)
+                {
+                  idx(2) = 0;
+                  idx(3) = ii;
+                }
+
+              idx(0) = x;
+
+              if (m(idx))
+                im.pixelColor (y, x, "white");
+            }
+        }
+
+      im.quantizeColorSpace (Magick::GRAYColorspace);
+      im.quantizeColors (2);
+      im.quantize ();
+
+      imvec.push_back (im);
+    }
+}
+
+template <class T>
+static void
+encode_uint_image (std::vector<Magick::Image>& imvec,
+                   const octave_value& img,
+                   bool has_map)
+{
+  unsigned int bitdepth = 0;
+  T m;
+
+  if (img.is_uint8_type ())
+    {
+      bitdepth = 8;
+      m = img.uint8_array_value ();
+    }
+  else if (img.is_uint16_type ())
+    {
+      bitdepth = 16;
+      m = img.uint16_array_value ();
+    }
+  else
+    error ("__magick_write__: invalid image class");
+
+  dim_vector dsizes = m.dims ();
+  unsigned int nframes = 1;
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+
+  bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2));
+  bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4));
+
+  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+
+  unsigned int div_factor = (1 << bitdepth) - 1;
+
+  for (unsigned int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im (Magick::Geometry (columns, rows), "black");
+
+      im.depth (bitdepth);
+
+      if (has_map)
+        im.classType (Magick::PseudoClass);
+      else
+        im.classType (Magick::DirectClass);
+
+      if (is_color)
+        {
+          if (has_alpha)
+            im.type (Magick::TrueColorMatteType);
+          else
+            im.type (Magick::TrueColorType);
+
+          Magick::ColorRGB c;
+
+          for (int y = 0; y < columns; y++)
+            {
+              idx(1) = y;
+
+              for (int x = 0; x < rows; x++)
+                {
+                  idx(0) = x;
+
+                  if (nframes > 1)
+                    idx(3) = ii;
+
+                  idx(2) = 0;
+                  c.red (static_cast<double>(m(idx)) / div_factor);
+
+                  idx(2) = 1;
+                  c.green (static_cast<double>(m(idx)) / div_factor);
+
+                  idx(2) = 2;
+                  c.blue (static_cast<double>(m(idx)) / div_factor);
+
+                  if (has_alpha)
+                    {
+                      idx(2) = 3;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                    }
+
+                  im.pixelColor (y, x, c);
+                }
+            }
+        }
+      else
+        {
+          if (has_alpha)
+            im.type (Magick::GrayscaleMatteType);
+          else
+            im.type (Magick::GrayscaleType);
+
+          Magick::ColorGray c;
+
+          for (int y = 0; y < columns; y++)
+            {
+              idx(1) = y;
+
+              for (int x=0; x < rows; x++)
+                {
+                  idx(0) = x;
+
+                  if (nframes > 1)
+                    {
+                      idx(2) = 0;
+                      idx(3) = ii;
+                    }
+
+                  if (has_alpha)
+                    {
+                      idx(2) = 1;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                      idx(2) = 0;
+                    }
+
+                  c.shade (static_cast<double>(m(idx)) / div_factor);
+
+                  im.pixelColor (y, x, c);
+                }
+            }
+
+          im.quantizeColorSpace (Magick::GRAYColorspace);
+          im.quantizeColors (1 << bitdepth);
+          im.quantize ();
+        }
+
+      imvec.push_back (im);
+    }
+}
+
+static void
+encode_map (std::vector<Magick::Image>& imvec, const NDArray& cmap)
+{
+  unsigned int mapsize = cmap.dim1 ();
+
+  for (size_t fnum = 0; fnum < imvec.size (); fnum++)
+    {
+      imvec[fnum].colorMapSize (mapsize);
+      imvec[fnum].type (Magick::PaletteType);
+    }
+
+  for (unsigned int ii = 0; ii < mapsize; ii++)
+    {
+      Magick::ColorRGB c (cmap(ii,0), cmap(ii,1), cmap(ii,2));
+
+      // FIXME -- is this case needed?
+      if (cmap.dim2 () == 4)
+        c.alpha (cmap(ii,3));
+
+      try
+        {
+          for_each (imvec.begin (), imvec.end (),
+                    Magick::colorMapImage (ii, c));
+        }
+      catch (Magick::Warning& w)
+        {
+          warning ("Magick++ warning: %s", w.what ());
+        }
+      catch (Magick::ErrorCoder& e)
+        {
+          warning ("Magick++ coder error: %s", e.what ());
+        }
+      catch (Magick::Exception& e)
+        {
+          error ("Magick++ exception: %s", e.what ());
+        }
+    }
+}
+
+static void
+write_image (const std::string& filename, const std::string& fmt,
+             const octave_value& img,
+             const octave_value& map = octave_value (),
+             const octave_value& params = octave_value ())
+{
+  std::vector<Magick::Image> imvec;
+
+  bool has_map = map.is_defined ();
+
+  if (has_map)
+    {
+      error ("__magick_write__: direct saving of indexed images not currently supported; use ind2rgb and save converted image");
+      return;
+    }
+
+  if (img.is_bool_type ())
+    encode_bool_image (imvec, img);
+  else if (img.is_uint8_type ())
+    encode_uint_image<uint8NDArray> (imvec, img, has_map);
+  else if (img.is_uint16_type ())
+    encode_uint_image<uint16NDArray> (imvec, img, has_map);
+  else
+    error ("__magick_write__: image type not supported");
+
+  if (! error_state && has_map)
+    {
+      NDArray cmap = map.array_value ();
+
+      if (! error_state)
+        encode_map (imvec, cmap);
+    }
+
+  if (! error_state && params.is_defined ())
+    {
+      Octave_map options = params.map_value ();
+
+      // Insert calls here to handle parameters for various image formats
+      if (fmt == "jpg" || fmt == "jpeg")
+        jpg_settings (imvec, options, has_map);
+      else
+        warning ("warning: your parameter(s) currently not supported");
+    }
+
+  try
+    {
+      Magick::writeImages (imvec.begin (), imvec.end (), fmt + ":" + filename);
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+    }
+}
+
+#endif
+
+DEFUN_DLD (__magick_write__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Function File} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img})\n\
+@deftypefnx {Function File} {} __magick_write__ (@var{fname}, @var{fmt}, @var{img}, @var{map})\n\
+Write images with ImageMagick++.  In general you should not be using this\n\
+function.  Instead use @code{imwrite}.\n\
+@seealso{imread}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_MAGICK
+  maybe_initialize_magick ();
+
+  int nargin = args.length ();
+
+  if (nargin > 2)
+    {
+      std::string filename = args(0).string_value ();
+
+      if (! error_state)
+        {
+          std::string fmt = args(1).string_value ();
+
+          if (! error_state)
+            {
+              if (nargin > 4)
+                write_image (filename, fmt, args(2), args(3), args(4));
+              else if (nargin > 3)
+                if (args(3).is_real_type ())
+                  write_image (filename, fmt, args(2), args(3));
+                else
+                  write_image (filename, fmt, args(2), octave_value (), args(3));
+              else
+                write_image (filename, fmt, args(2));
+            }
+          else
+            error ("__magick_write__: FMT must be string");
+        }
+      else
+        error ("__magick_write__: FNAME must be a string");
+    }
+  else
+    print_usage ();
+#else
+
+  error ("__magick_write__: not available in this version of Octave");
+
+#endif
+
+return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
+#ifdef HAVE_MAGICK
+
+template<class T>
+static octave_value
+magick_to_octave_value (const T magick)
+{
+  return octave_value (magick);
+}
+
+static octave_value
+magick_to_octave_value (const Magick::EndianType magick)
+{
+  switch (magick)
+    {
+      case Magick::LSBEndian:
+        return octave_value ("little-endian");
+
+      case Magick::MSBEndian:
+        return octave_value ("big-endian");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ResolutionType magick)
+{
+  switch (magick)
+    {
+      case Magick::PixelsPerInchResolution:
+        return octave_value ("pixels per inch");
+
+      case Magick::PixelsPerCentimeterResolution:
+        return octave_value ("pixels per centimeter");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ImageType magick)
+{
+  switch (magick)
+    {
+      case Magick::BilevelType:
+      case Magick::GrayscaleType:
+      case Magick::GrayscaleMatteType:
+        return octave_value ("grayscale");
+
+      case Magick::PaletteType:
+      case Magick::PaletteMatteType:
+        return octave_value ("indexed");
+
+      case Magick::TrueColorType:
+      case Magick::TrueColorMatteType:
+      case Magick::ColorSeparationType:
+        return octave_value ("truecolor");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+// We put this in a try-block because GraphicsMagick will throw
+// exceptions if a parameter isn't present in the current image.
+#define GET_PARAM(NAME, OUTNAME) \
+  try \
+    { \
+      info.contents (OUTNAME)(frame,0) = magick_to_octave_value (im.NAME ()); \
+    } \
+  catch (Magick::Warning& w) \
+    { \
+    }
+
+#endif
+
+DEFUN_DLD (__magick_finfo__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __magick_finfo__ (@var{fname})\n\
+Read image information with GraphicsMagick++.  In general you should\n\
+not be using this function.  Instead use @code{imfinfo}.\n\
+@seealso{imfinfo, imread}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_MAGICK
+
+  maybe_initialize_magick ();
+
+  if (args.length () < 1 || ! args (0).is_string ())
+    {
+      print_usage ();
+      return retval;
+    }
+
+  const std::string filename = args (0).string_value ();
+
+  try
+    {
+      // Read the file.
+      std::vector<Magick::Image> imvec;
+      Magick::readImages (&imvec, args(0).string_value ());
+      int nframes = imvec.size ();
+
+      // Create the right size for the output.
+
+      static const char *fields[] =
+        {
+          "Filename",
+          "FileModDate",
+          "FileSize",
+          "Height",
+          "Width",
+          "BitDepth",
+          "Format",
+          "LongFormat",
+          "XResolution",
+          "YResolution",
+          "TotalColors",
+          "TileName",
+          "AnimationDelay",
+          "AnimationIterations",
+          "ByteOrder",
+          "Gamma",
+          "Matte",
+          "ModulusDepth",
+          "Quality",
+          "QuantizeColors",
+          "ResolutionUnits",
+          "ColorType",
+          "View",
+          0
+        };
+
+      Octave_map info (string_vector (fields), dim_vector (nframes, 1));
+
+      file_stat fs (filename);
+
+      std::string filetime;
+
+      if (fs)
+        {
+          octave_localtime mtime = fs.mtime ();
+
+          filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S");
+        }
+      else
+        {
+          std::string msg = fs.error ();
+
+          error ("imfinfo: error reading `%s': %s",
+                 filename.c_str (), msg.c_str ());
+
+          return retval;
+        }
+
+      // For each frame in the image (some images contain multiple
+      // layers, each to be treated like a separate image).
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          Magick::Image im = imvec[frame];
+
+          // Add file name and timestamp.
+          info.contents ("Filename")(frame,0) = filename;
+          info.contents ("FileModDate")(frame,0) = filetime;
+
+          // Annoying CamelCase naming is for Matlab compatibility.
+          GET_PARAM (fileSize, "FileSize")
+          GET_PARAM (rows, "Height")
+          GET_PARAM (columns, "Width")
+          GET_PARAM (depth, "BitDepth")
+          GET_PARAM (magick, "Format")
+          GET_PARAM (format, "LongFormat")
+          GET_PARAM (xResolution, "XResolution")
+          GET_PARAM (yResolution, "YResolution")
+          GET_PARAM (totalColors, "TotalColors")
+          GET_PARAM (tileName, "TileName")
+          GET_PARAM (animationDelay, "AnimationDelay")
+          GET_PARAM (animationIterations, "AnimationIterations")
+          GET_PARAM (endian, "ByteOrder")
+          GET_PARAM (gamma, "Gamma")
+          GET_PARAM (matte, "Matte")
+          GET_PARAM (modulusDepth, "ModulusDepth")
+          GET_PARAM (quality, "Quality")
+          GET_PARAM (quantizeColors, "QuantizeColors")
+          GET_PARAM (resolutionUnits, "ResolutionUnits")
+          GET_PARAM (type, "ColorType")
+          GET_PARAM (view, "View")
+        }
+
+      retval = octave_value (info);
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+      return retval;
+    }
+
+#else
+
+  error ("imfinfo: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
+#undef GET_PARAM
+
+// Determine the file formats supported by GraphicsMagick.  This is
+// called once at the beginning of imread or imwrite to determine
+// exactly which file formats are supported, so error messages can be
+// displayed properly.
+
+DEFUN_DLD (__magick_format_list__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} __magick_format_list__ (@var{formats})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_MAGICK
+  maybe_initialize_magick ();
+
+  std::list<std::string> accepted_formats;
+
+  if (args.length () == 1)
+    {
+      Cell c = args (0).cell_value ();
+
+      if (! error_state)
+        {
+          for (octave_idx_type i = 0; i < c.nelem (); i++)
+            {
+              try
+                {
+                  std::string fmt = c.elem (i).string_value ();
+
+                  Magick::CoderInfo info(fmt);
+
+                  if (info.isReadable () && info.isWritable ())
+                    accepted_formats.push_back (fmt);
+                }
+              catch (Magick::Exception& e)
+                {
+                  // Do nothing: exception here are simply missing formats.
+                }
+            }
+        }
+      else
+        error ("__magick_format_list__: expecting a cell array of image format names");
+    }
+  else
+    print_usage ();
+
+  retval = Cell (accepted_formats);
+
+#else
+
+  error ("__magick_format_list__: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/__voronoi__.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,334 @@
+/*
+
+Copyright (C) 2000-2012 Kai Habel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+20. Augiust 2000 - Kai Habel: first release
+*/
+
+/*
+2003-12-14 Rafael Laboissiere <rafael@laboissiere.net>
+Added optional second argument to pass options to the underlying
+qhull command
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdio>
+
+#include <list>
+
+#include "lo-ieee.h"
+
+#include "Cell.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "unwind-prot.h"
+
+#if defined (HAVE_QHULL)
+# include "oct-qhull.h"
+# if defined (NEED_QHULL_VERSION)
+char qh_version[] = "__voronoi__.oct 2007-07-24";
+# endif
+#endif
+
+static void
+close_fcn (FILE *f)
+{
+  gnulib::fclose (f);
+}
+
+DEFUN_DLD (__voronoi__, args, ,
+        "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{C}, @var{F} =} __voronoi__ (@var{caller}, @var{pts})\n\
+@deftypefnx {Loadable Function} {@var{C}, @var{F} =} __voronoi__ (@var{caller}, @var{pts}, @var{options})\n\
+@deftypefnx {Loadable Function} {@var{C}, @var{F}, @var{Inf_Pts} =} __voronoi__ (@dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  std::string caller = args(0).string_value ();
+
+#if defined (HAVE_QHULL)
+
+  retval(0) = 0.0;
+
+  int nargin = args.length ();
+  if (nargin < 2 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix points = args(1).matrix_value ();
+  const octave_idx_type dim = points.columns ();
+  const octave_idx_type num_points = points.rows ();
+
+  points = points.transpose ();
+
+  std::string options;
+
+  if (dim <= 4)
+    options = " Qbb";
+  else
+    options = " Qbb Qx";
+
+  if (nargin == 3)
+    {
+      octave_value opt_arg = args(2);
+
+      if (opt_arg.is_string ())
+        options = " " + opt_arg.string_value ();
+      else if (opt_arg.is_empty ())
+        ; // Use default options.
+      else if (opt_arg.is_cellstr ())
+        {
+          options = "";
+
+          Array<std::string> tmp = opt_arg.cellstr_value ();
+
+          for (octave_idx_type i = 0; i < tmp.numel (); i++)
+            options += " " + tmp(i);
+        }
+      else
+        {
+          error ("%s: OPTIONS must be a string, cell array of strings, or empty",
+                 caller.c_str ());
+          return retval;
+        }
+    }
+
+  boolT ismalloc = false;
+
+  unwind_protect frame;
+
+  // Replace the outfile pointer with stdout for debugging information.
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
+  FILE *outfile = gnulib::fopen ("NUL", "w");
+#else
+  FILE *outfile = gnulib::fopen ("/dev/null", "w");
+#endif
+  FILE *errfile = stderr;
+
+  if (outfile)
+    frame.add_fcn (close_fcn, outfile);
+  else
+    {
+      error ("__voronoi__: unable to create temporary file for output");
+      return retval;
+    }
+
+  // qh_new_qhull command and points arguments are not const...
+
+  std::string cmd = "qhull v" + options;
+
+  OCTAVE_LOCAL_BUFFER (char, cmd_str, cmd.length () + 1);
+
+  strcpy (cmd_str, cmd.c_str ());
+
+  int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
+                               ismalloc, cmd_str, outfile, errfile);
+  if (! exitcode) 
+    {
+      // Calling findgood_all provides the number of Voronoi vertices
+      // (sets qh num_good).
+
+      qh_findgood_all (qh facet_list);
+
+      octave_idx_type num_voronoi_regions
+        = qh num_vertices - qh_setsize (qh del_vertices);
+
+      octave_idx_type num_voronoi_vertices = qh num_good;
+
+      // Find the voronoi centers for all facets.
+
+      qh_setvoronoi_all ();
+
+      facetT *facet;
+      vertexT *vertex;
+      octave_idx_type k;
+
+      // Find the number of Voronoi vertices for each Voronoi cell and
+      // store them in NI so we can use them later to set the dimensions
+      // of the RowVector objects used to collect them.
+
+      FORALLfacets
+        {
+          facet->seen = false;
+        }
+      
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, ni, num_voronoi_regions);
+      for (octave_idx_type i = 0; i < num_voronoi_regions; i++)
+        ni[i] = 0;
+
+      k = 0;
+
+      FORALLvertices
+        {
+          if (qh hull_dim == 3)
+            qh_order_vertexneighbors (vertex);
+          
+          bool infinity_seen = false;
+
+          facetT *neighbor, **neighborp;
+
+          FOREACHneighbor_ (vertex)
+            {
+              if (neighbor->upperdelaunay)
+                {
+                  if (! infinity_seen)
+                    {
+                      infinity_seen = true;
+                      ni[k]++;
+                    }
+                }
+              else
+                {
+                  neighbor->seen = true;
+                  ni[k]++;
+                }
+            }
+
+          k++;
+        }
+
+      // If Qhull finds fewer regions than points, we will pad the end
+      // of the at_inf and C arrays so that they always contain at least
+      // as many elements as the given points array.
+
+      // FIXME -- is it possible (or does it make sense) for
+      // num_voronoi_regions to ever be larger than num_points?
+
+      octave_idx_type nr = (num_points > num_voronoi_regions
+                            ? num_points : num_voronoi_regions);
+
+      boolMatrix at_inf (nr, 1, false);
+
+      // The list of Voronoi vertices.  The first element is always
+      // Inf.
+      Matrix F (num_voronoi_vertices+1, dim);
+
+      for (octave_idx_type d = 0; d < dim; d++)
+        F(0,d) = octave_Inf;
+
+      // The cell array of vectors of indices into F that represent the
+      // vertices of the Voronoi regions (cells).
+
+      Cell C (nr, 1);
+
+      // Now loop through the list of vertices again and store the
+      // coordinates of the Voronoi vertices and the lists of indices
+      // for the cells.
+
+      FORALLfacets
+        {
+          facet->seen = false;
+        }
+
+      octave_idx_type i = 0;
+      k = 0;
+
+      FORALLvertices
+        {
+          if (qh hull_dim == 3)
+            qh_order_vertexneighbors (vertex);
+
+          bool infinity_seen = false;
+
+          octave_idx_type idx = qh_pointid (vertex->point);
+
+          octave_idx_type num_vertices = ni[k++];
+
+          // Qhull seems to sometimes produces regions with a single
+          // vertex.  Is that a bug?  How can a region have just one
+          // vertex?  Let's skip it.
+
+          if (num_vertices == 1)
+            continue;
+
+          RowVector facet_list (num_vertices);
+
+          octave_idx_type m = 0;
+
+          facetT *neighbor, **neighborp;
+
+          FOREACHneighbor_(vertex)
+            {
+              if (neighbor->upperdelaunay)
+                {
+                  if (! infinity_seen)
+                    {
+                      infinity_seen = true;
+                      facet_list(m++) = 1;
+                      at_inf(idx) = true;
+                    }
+                }
+              else
+                {
+                  if (! neighbor->seen)
+                    {
+                      i++;
+                      for (octave_idx_type d = 0; d < dim; d++)
+                        F(i,d) = neighbor->center[d];
+
+                      neighbor->seen = true;
+                      neighbor->visitid = i;
+                    }
+
+                  facet_list(m++) = neighbor->visitid + 1;
+                }
+            }
+
+          C(idx) = facet_list;
+        }
+
+      retval(2) = at_inf;
+      retval(1) = C;
+      retval(0) = F;
+    }
+  else
+    error ("%s: qhull failed", caller.c_str ());
+
+  // Free memory from Qhull
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("%s: qhull did not free %d bytes of long memory (%d pieces)",
+             caller.c_str (), totlong, curlong);
+
+#else
+  error ("%s: not available in this version of Octave", caller.c_str ());
+#endif
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/amd.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,206 @@
+/*
+
+Copyright (C) 2008-2012 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to amd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-map.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define AMD_NAME(name) amd_l ## name
+#else
+#define AMD_NAME(name) amd ## name
+#endif
+
+DEFUN_DLD (amd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} amd (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} amd (@var{S}, @var{opts})\n\
+\n\
+Return the approximate minimum degree permutation of a matrix.  This\n\
+permutation such that the Cholesky@tie{}factorization of @code{@var{S}\n\
+(@var{p}, @var{p})} tends to be sparser than the Cholesky@tie{}factorization\n\
+of @var{S} itself.  @code{amd} is typically faster than @code{symamd} but\n\
+serves a similar purpose.\n\
+\n\
+The optional parameter @var{opts} is a structure that controls the\n\
+behavior of @code{amd}.  The fields of the structure are\n\
+\n\
+@table @asis\n\
+@item @var{opts}.dense\n\
+Determines what @code{amd} considers to be a dense row or column of the\n\
+input matrix.  Rows or columns with more than @code{max(16, (dense *\n\
+sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{S},\n\
+are ignored by @code{amd} during the calculation of the permutation\n\
+The value of dense must be a positive scalar and its default value is 10.0\n\
+\n\
+@item @var{opts}.aggressive\n\
+If this value is a non zero scalar, then @code{amd} performs aggressive\n\
+absorption.  The default is not to perform aggressive absorption.\n\
+@end table\n\
+\n\
+The author of the code itself is Timothy A. Davis\n\
+@email{davis@@cise.ufl.edu}, University of Florida (see\n\
+@url{http://www.cise.ufl.edu/research/sparse/amd}).\n\
+@seealso{symamd, colamd}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_AMD
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      octave_idx_type n_row, n_col;
+      const octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0).sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+        }
+      else
+        {
+          if (args(0).is_complex_type ())
+            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+          else
+            sm = SparseMatrix (args(0).matrix_value ());
+
+          n_row = sm.rows ();
+          n_col = sm.cols ();
+          ridx = sm.xridx ();
+          cidx = sm.xcidx ();
+        }
+
+      if (!error_state && n_row != n_col)
+        error ("amd: matrix S must be square");
+
+      if (!error_state)
+        {
+          OCTAVE_LOCAL_BUFFER (double, Control, AMD_CONTROL);
+          AMD_NAME (_defaults) (Control) ;
+          if (nargin > 1)
+            {
+              octave_scalar_map arg1 = args(1).scalar_map_value ();
+
+              if (!error_state)
+                {
+                  octave_value tmp;
+
+                  tmp = arg1.getfield ("dense");
+                  if (tmp.is_defined ())
+                    Control[AMD_DENSE] = tmp.double_value ();
+
+                  tmp = arg1.getfield ("aggressive");
+                  if (tmp.is_defined ())
+                    Control[AMD_AGGRESSIVE] = tmp.double_value ();
+                }
+              else
+                error ("amd: OPTS argument must be a scalar structure");
+            }
+
+          if (!error_state)
+            {
+              OCTAVE_LOCAL_BUFFER (octave_idx_type, P, n_col);
+              Matrix xinfo (AMD_INFO, 1);
+              double *Info = xinfo.fortran_vec ();
+
+              // FIXME -- how can we manage the memory allocation of
+              // amd in a cleaner manner?
+              amd_malloc = malloc;
+              amd_free = free;
+              amd_calloc = calloc;
+              amd_realloc = realloc;
+              amd_printf = printf;
+
+              octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P,
+                                                          Control, Info);
+
+              switch (result)
+                {
+                case AMD_OUT_OF_MEMORY:
+                  error ("amd: out of memory");
+                  break;
+                case AMD_INVALID:
+                  error ("amd: matrix S is corrupted");
+                  break;
+                default:
+                  {
+                    if (nargout > 1)
+                      retval(1) = xinfo;
+
+                    Matrix Pout (1, n_col);
+                    for (octave_idx_type i = 0; i < n_col; i++)
+                      Pout.xelem (i) = P[i] + 1;
+
+                    retval(0) = Pout;
+                  }
+                }
+            }
+        }
+    }
+#else
+
+  error ("amd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/ccolamd.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,583 @@
+/*
+
+Copyright (C) 2005-2012 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to ccolamd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define CCOLAMD_NAME(name) ccolamd_l ## name
+#define CSYMAMD_NAME(name) csymamd_l ## name
+#else
+#define CCOLAMD_NAME(name) ccolamd ## name
+#define CSYMAMD_NAME(name) csymamd ## name
+#endif
+
+DEFUN_DLD (ccolamd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} ccolamd (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs})\n\
+@deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs}, @var{cmember})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})\n\
+\n\
+Constrained column approximate minimum degree permutation.\n\
+@code{@var{p} = ccolamd (@var{S})} returns the column approximate minimum\n\
+degree permutation vector for the sparse matrix @var{S}.  For a non-symmetric\n\
+matrix\n\
+@var{S},\n\
+@code{@var{S}(:, @var{p})} tends to have sparser LU@tie{}factors than\n\
+@var{S}.  @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))} also\n\
+tends to be sparser than @code{chol (@var{S}' * @var{S})}.  @code{@var{p} =\n\
+ccolamd (@var{S}, 1)} optimizes the ordering for @code{lu (@var{S}(:,\n\
+@var{p}))}.  The ordering is followed by a column elimination tree\n\
+post-ordering.\n\
+\n\
+@var{knobs} is an optional 1-element to 5-element input vector, with a\n\
+default value of @code{[0 10 10 1 0]} if not present or empty.  Entries not\n\
+present are set to their defaults.\n\
+\n\
+@table @code\n\
+@item @var{knobs}(1)\n\
+if nonzero, the ordering is optimized for @code{lu (S(:, p))}.  It will be a\n\
+poor ordering for @code{chol (@var{S}(:, @var{p})' * @var{S}(:,\n\
+@var{p}))}.  This is the most important knob for ccolamd.\n\
+\n\
+@item @var{knobs}(2)\n\
+if @var{S} is m-by-n, rows with more than @code{max (16, @var{knobs}(2) *\n\
+sqrt (n))} entries are ignored.\n\
+\n\
+@item @var{knobs}(3)\n\
+columns with more than @code{max (16, @var{knobs}(3) * sqrt (min (@var{m},\n\
+@var{n})))} entries are ignored and ordered last in the output permutation\n\
+(subject to the cmember constraints).\n\
+\n\
+@item @var{knobs}(4)\n\
+if nonzero, aggressive absorption is performed.\n\
+\n\
+@item @var{knobs}(5)\n\
+if nonzero, statistics and knobs are printed.\n\
+\n\
+@end table\n\
+\n\
+@var{cmember} is an optional vector of length @math{n}.  It defines the\n\
+constraints on the column ordering.  If @code{@var{cmember}(j) = @var{c}},\n\
+then column @var{j} is in constraint set @var{c} (@var{c} must be in the\n\
+range 1 to\n\
+n).  In the output permutation @var{p}, all columns in set 1 appear\n\
+first, followed by all columns in set 2, and so on.  @code{@var{cmember} =\n\
+ones (1,n)} if not present or empty.\n\
+@code{ccolamd (@var{S}, [], 1 : n)} returns @code{1 : n}\n\
+\n\
+@code{@var{p} = ccolamd (@var{S})} is about the same as\n\
+@code{@var{p} = colamd (@var{S})}.  @var{knobs} and its default values\n\
+differ.  @code{colamd} always does aggressive absorption, and it finds an\n\
+ordering suitable for both @code{lu (@var{S}(:, @var{p}))} and @code{chol\n\
+(@var{S}(:, @var{p})' * @var{S}(:, @var{p}))}; it cannot optimize its\n\
+ordering for @code{lu (@var{S}(:, @var{p}))} to the extent that\n\
+@code{ccolamd (@var{S}, 1)} can.\n\
+\n\
+@var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
+statistics are in @code{@var{stats}(1 : 3)}.  @code{@var{stats}(1)} and\n\
+@code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
+ignored by @sc{ccolamd} and @code{@var{stats}(3)} is the number of garbage\n\
+collections performed on the internal data structure used by @sc{ccolamd}\n\
+(roughly of size @code{2.2 * nnz (@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
+integers).\n\
+\n\
+@code{@var{stats}(4 : 7)} provide information if CCOLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
+such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats}(8 : 20)} is always zero in\n\
+the current version of @sc{ccolamd} (reserved for future use).\n\
+\n\
+The authors of the code itself are S. Larimore, T. Davis (Univ. of Florida)\n\
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
+and a grant from Sandia National Lab.  See\n\
+@url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
+colamd, symamd, and other related orderings.\n\
+@seealso{colamd, csymamd}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_CCOLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+
+  if (nargout > 2 || nargin < 1 || nargin > 3)
+    usage ("ccolamd: incorrect number of input and/or output arguments");
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);
+      CCOLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin > 1)
+        {
+          NDArray User_knobs = args(1).array_value ();
+          int nel_User_knobs = User_knobs.length ();
+
+          if (nel_User_knobs > 0)
+            knobs[CCOLAMD_LU] = (User_knobs(0) != 0);
+          if (nel_User_knobs > 1)
+            knobs[CCOLAMD_DENSE_ROW] = User_knobs(1);
+          if (nel_User_knobs > 2)
+            knobs[CCOLAMD_DENSE_COL] = User_knobs(2);
+          if (nel_User_knobs > 3)
+            knobs[CCOLAMD_AGGRESSIVE] = (User_knobs(3) != 0);
+          if (nel_User_knobs > 4)
+            spumoni = (User_knobs(4) != 0);
+
+          // print knob settings if spumoni is set
+          if (spumoni)
+            {
+              octave_stdout << "\nccolamd version " << CCOLAMD_MAIN_VERSION << "."
+                            <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE
+                            << ":\nknobs(1): " << User_knobs(0) << ", order for ";
+              if (knobs[CCOLAMD_LU] != 0)
+                octave_stdout << "lu (A)\n";
+              else
+                octave_stdout << "chol (A'*A)\n";
+
+              if (knobs[CCOLAMD_DENSE_ROW] >= 0)
+                octave_stdout << "knobs(2): " << User_knobs(1)
+                              << ", rows with > max (16,"
+                              << knobs[CCOLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
+                              << " entries removed\n";
+              else
+                octave_stdout << "knobs(2): " << User_knobs(1)
+                              << ", no dense rows removed\n";
+
+              if (knobs[CCOLAMD_DENSE_COL] >= 0)
+                octave_stdout << "knobs(3): " << User_knobs(2)
+                              << ", cols with > max (16,"
+                              << knobs[CCOLAMD_DENSE_COL] << "*sqrt (size(A)))"
+                              << " entries removed\n";
+              else
+                octave_stdout << "knobs(3): " << User_knobs(2)
+                              << ", no dense columns removed\n";
+
+              if (knobs[CCOLAMD_AGGRESSIVE] != 0)
+                octave_stdout << "knobs(4): " << User_knobs(3)
+                              << ", aggressive absorption: yes";
+              else
+                octave_stdout << "knobs(4): " << User_knobs(3)
+                              << ", aggressive absorption: no";
+
+              octave_stdout << "knobs(5): " << User_knobs(4)
+                            << ", statistics and knobs printed\n";
+            }
+        }
+
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseComplexMatrix scm;
+      SparseMatrix sm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0). sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              nnz = scm.nnz ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              nnz = sm.nnz ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+        }
+      else
+        {
+          if (args(0).is_complex_type ())
+            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+          else
+            sm = SparseMatrix (args(0).matrix_value ());
+
+          n_row = sm.rows ();
+          n_col = sm.cols ();
+          nnz = sm.nnz ();
+          ridx = sm.xridx ();
+          cidx = sm.xcidx ();
+        }
+
+      // Allocate workspace for ccolamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+      for (octave_idx_type i = 0; i < n_col+1; i++)
+        p[i] = cidx[i];
+
+      octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+      for (octave_idx_type i = 0; i < nnz; i++)
+        A[i] = ridx[i];
+
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+
+      if (nargin > 2)
+        {
+          NDArray in_cmember = args(2).array_value ();
+          octave_idx_type cslen = in_cmember.length ();
+          OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+          for (octave_idx_type i = 0; i < cslen; i++)
+            // convert cmember from 1-based to 0-based
+            cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
+
+          if (cslen != n_col)
+            error ("ccolamd: CMEMBER must be of length equal to #cols of A");
+          else
+            // Order the columns (destroys A)
+            if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, cmember))
+              {
+                CCOLAMD_NAME (_report) (stats) ;
+                error ("ccolamd: internal error!");
+                return retval;
+              }
+        }
+      else
+        {
+          // Order the columns (destroys A)
+          if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, 0))
+            {
+              CCOLAMD_NAME (_report) (stats) ;
+              error ("ccolamd: internal error!");
+              return retval;
+            }
+        }
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+        out_perm(i) = p[i] + 1;
+
+      retval(0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+        CCOLAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+        {
+          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+            out_stats(i) = stats[i] ;
+          retval(1) = out_stats;
+
+          // 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 (CCOLAMD_INFO1) ++ ;
+          out_stats (CCOLAMD_INFO2) ++ ;
+        }
+    }
+
+#else
+
+  error ("ccolamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (csymamd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} csymamd (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs})\n\
+@deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs}, @var{cmember})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\
+\n\
+For a symmetric positive definite matrix @var{S}, returns the permutation\n\
+vector @var{p} such that @code{@var{S}(@var{p},@var{p})} tends to have a\n\
+sparser Cholesky@tie{}factor than @var{S}.  Sometimes @code{csymamd} works\n\
+well for symmetric indefinite matrices too.  The matrix @var{S} is assumed\n\
+to be symmetric; only the strictly lower triangular part is referenced.\n\
+@var{S} must be square.  The ordering is followed by an elimination tree\n\
+post-ordering.\n\
+\n\
+@var{knobs} is an optional 1-element to 3-element input vector, with a\n\
+default value of @code{[10 1 0]} if present or empty.  Entries not\n\
+present are set to their defaults.\n\
+\n\
+@table @code\n\
+@item @var{knobs}(1)\n\
+If @var{S} is n-by-n, then rows and columns with more than\n\
+@code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\
+last in the output permutation (subject to the cmember constraints).\n\
+\n\
+@item @var{knobs}(2)\n\
+If nonzero, aggressive absorption is performed.\n\
+\n\
+@item @var{knobs}(3)\n\
+If nonzero, statistics and knobs are printed.\n\
+\n\
+@end table\n\
+\n\
+@var{cmember} is an optional vector of length n. It defines the constraints\n\
+on the ordering.  If @code{@var{cmember}(j) = @var{S}}, then row/column j is\n\
+in constraint set @var{c} (@var{c} must be in the range 1 to n).  In the\n\
+output permutation @var{p}, rows/columns in set 1 appear first, followed\n\
+by all rows/columns in set 2, and so on.  @code{@var{cmember} = ones (1,n)}\n\
+if not present or empty.  @code{csymamd (@var{S},[],1:n)} returns @code{1:n}.\n\
+\n\
+@code{@var{p} = csymamd (@var{S})} is about the same as @code{@var{p} =\n\
+symamd (@var{S})}.  @var{knobs} and its default values differ.\n\
+\n\
+@code{@var{stats}(4:7)} provide information if CCOLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
+such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats}(8:20)} is always zero in\n\
+the current version of @sc{ccolamd} (reserved for future use).\n\
+\n\
+The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
+and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
+by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\
+and a grant from Sandia National Lab.  See\n\
+@url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\
+colamd, symamd, and other related orderings.\n\
+@seealso{symamd, ccolamd}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#if HAVE_CCOLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+
+  if (nargout > 2 || nargin < 1 || nargin > 3)
+    usage ("ccolamd: incorrect number of input and/or output arguments");
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS);
+      CCOLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin > 1)
+        {
+          NDArray User_knobs = args(1).array_value ();
+          int nel_User_knobs = User_knobs.length ();
+
+          if (nel_User_knobs > 0)
+            knobs[CCOLAMD_DENSE_ROW] = User_knobs(0);
+          if (nel_User_knobs > 0)
+            knobs[CCOLAMD_AGGRESSIVE] = User_knobs(1);
+          if (nel_User_knobs > 1)
+            spumoni = static_cast<int> (User_knobs(2));
+
+          // print knob settings if spumoni is set
+          if (spumoni)
+            {
+              octave_stdout << "\ncsymamd version " << CCOLAMD_MAIN_VERSION << "."
+                            <<  CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE << "\n";
+
+              if (knobs[CCOLAMD_DENSE_ROW] >= 0)
+                octave_stdout << "knobs(1): " << User_knobs(0)
+                              << ", rows/cols with > max (16,"
+                              << knobs[CCOLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
+                              << " entries removed\n";
+              else
+                octave_stdout << "knobs(1): " << User_knobs(0)
+                              << ", no dense rows/cols removed\n";
+
+              if (knobs[CCOLAMD_AGGRESSIVE] != 0)
+                octave_stdout << "knobs(2): " << User_knobs(1)
+                              << ", aggressive absorption: yes";
+              else
+                octave_stdout << "knobs(2): " << User_knobs(1)
+                              << ", aggressive absorption: no";
+
+
+              octave_stdout << "knobs(3): " << User_knobs(2)
+                            << ", statistics and knobs printed\n";
+            }
+        }
+
+      octave_idx_type n_row, n_col;
+      octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0).sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+        }
+      else
+        {
+          if (args(0).is_complex_type ())
+            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+          else
+            sm = SparseMatrix (args(0).matrix_value ());
+
+          n_row = sm.rows ();
+          n_col = sm.cols ();
+          ridx = sm.xridx ();
+          cidx = sm.xcidx ();
+        }
+
+      if (n_row != n_col)
+        {
+          error ("csymamd: matrix S must be square");
+          return retval;
+        }
+
+      // Allocate workspace for symamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+
+      if (nargin > 2)
+        {
+          NDArray in_cmember = args(2).array_value ();
+          octave_idx_type cslen = in_cmember.length ();
+          OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+          for (octave_idx_type i = 0; i < cslen; i++)
+            // convert cmember from 1-based to 0-based
+            cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
+
+          if (cslen != n_col)
+            error ("csymamd: CMEMBER must be of length equal to #cols of A");
+          else
+            if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
+                                  &calloc, &free, cmember, -1))
+              {
+                CSYMAMD_NAME (_report) (stats) ;
+                error ("csymamd: internal error!") ;
+                return retval;
+              }
+        }
+      else
+        {
+          if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
+                                &calloc, &free, 0, -1))
+            {
+              CSYMAMD_NAME (_report) (stats) ;
+              error ("csymamd: internal error!") ;
+              return retval;
+            }
+        }
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+        out_perm(i) = perm[i] + 1;
+
+      retval(0) = out_perm;
+
+      // Return the stats vector
+      if (nargout == 2)
+        {
+          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+            out_stats(i) = stats[i] ;
+          retval(1) = out_stats;
+
+          // 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 (CCOLAMD_INFO1) ++ ;
+          out_stats (CCOLAMD_INFO2) ++ ;
+        }
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+        CSYMAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+        {
+          NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
+          for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
+            out_stats(i) = stats[i] ;
+          retval(1) = out_stats;
+
+          // 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 (CCOLAMD_INFO1) ++ ;
+          out_stats (CCOLAMD_INFO2) ++ ;
+        }
+    }
+
+#else
+
+  error ("csymamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/chol.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,1385 @@
+/*
+
+Copyright (C) 1996-2012 John W. Eaton
+Copyright (C) 2008-2009 Jaroslav Hajek
+Copyright (C) 2008-2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxCHOL.h"
+#include "dbleCHOL.h"
+#include "fCmplxCHOL.h"
+#include "floatCHOL.h"
+#include "SparseCmplxCHOL.h"
+#include "SparsedbleCHOL.h"
+#include "oct-spparms.h"
+#include "sparse-util.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+template <class CHOLT>
+static octave_value
+get_chol_r (const CHOLT& fact)
+{
+  return octave_value (fact.chol_matrix (),
+                       MatrixType (MatrixType::Upper));
+}
+
+template <class CHOLT>
+static octave_value
+get_chol_l (const CHOLT& fact)
+{
+  return octave_value (fact.chol_matrix ().transpose (),
+                       MatrixType (MatrixType::Lower));
+}
+
+DEFUN_DLD (chol, args, nargout,
+"-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{R} =} chol (@var{A})\n\
+@deftypefnx {Loadable Function} {[@var{R}, @var{p}] =} chol (@var{A})\n\
+@deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S})\n\
+@deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S}, \"vector\")\n\
+@deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"lower\")\n\
+@deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"upper\")\n\
+@cindex Cholesky factorization\n\
+Compute the Cholesky@tie{}factor, @var{R}, of the symmetric positive definite\n\
+matrix @var{A}, where\n\
+@tex\n\
+$ R^T R = A $.\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+@var{R}' * @var{R} = @var{A}.\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+\n\
+Called with one output argument @code{chol} fails if @var{A} or @var{S} is\n\
+not positive definite.  With two or more output arguments @var{p} flags\n\
+whether the matrix was positive definite and @code{chol} does not fail.  A\n\
+zero value indicated that the matrix was positive definite and the @var{R}\n\
+gives the factorization, and @var{p} will have a positive value otherwise.\n\
+\n\
+If called with 3 outputs then a sparsity preserving row/column permutation\n\
+is applied to @var{A} prior to the factorization.  That is @var{R}\n\
+is the factorization of @code{@var{A}(@var{Q},@var{Q})} such that\n\
+@tex\n\
+$ R^T R = Q^T A Q$.\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+@var{R}' * @var{R} = @var{Q}' * @var{A} * @var{Q}.\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+\n\
+The sparsity preserving permutation is generally returned as a matrix.\n\
+However, given the flag \"vector\", @var{Q} will be returned as a vector\n\
+such that\n\
+@tex\n\
+$ R^T R = A (Q, Q)$.\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+@var{R}' * @var{R} = @var{A}(@var{Q}, @var{Q}).\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+\n\
+Called with either a sparse or full matrix and using the \"lower\" flag,\n\
+@code{chol} returns the lower triangular factorization such that\n\
+@tex\n\
+$ L L^T = A $.\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+@var{L} * @var{L}' = @var{A}.\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+\n\
+For full matrices, if the \"lower\" flag is set only the lower triangular\n\
+part of the matrix is used for the factorization, otherwise the upper\n\
+triangular part is used.\n\
+\n\
+In general the lower triangular factorization is significantly faster for\n\
+sparse matrices.\n\
+@seealso{cholinv, chol2inv}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  bool LLt = false;
+  bool vecout = false;
+
+  if (nargin < 1 || nargin > 3 || nargout > 3
+      || (! args(0).is_sparse_type () && nargout > 2))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  int n = 1;
+  while (n < nargin && ! error_state)
+    {
+      std::string tmp = args(n++).string_value ();
+
+      if (! error_state )
+        {
+          if (tmp.compare ("vector") == 0)
+            vecout = true;
+          else if (tmp.compare ("lower") == 0)
+            // FIXME currently the option "lower" is handled by transposing the
+            //  matrix, factorizing it with the lapack function DPOTRF ('U', ...)
+            //  and finally transposing the factor. It would be more efficient to use
+            //  DPOTRF ('L', ...) in this case.
+            LLt = true;
+          else if (tmp.compare ("upper") == 0)
+            LLt = false;
+          else
+            error ("chol: unexpected second or third input");
+        }
+      else
+        error ("chol: expecting trailing string arguments");
+    }
+
+  if (! error_state)
+    {
+      octave_value arg = args(0);
+
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+      bool natural = (nargout != 3);
+
+      int arg_is_empty = empty_arg ("chol", nr, nc);
+
+      if (arg_is_empty < 0)
+        return retval;
+      if (arg_is_empty > 0)
+        return octave_value (Matrix ());
+
+      if (arg.is_sparse_type ())
+        {
+          if (arg.is_real_type ())
+            {
+              SparseMatrix m = arg.sparse_matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+                  SparseCHOL fact (m, info, natural);
+                  if (nargout == 3)
+                    {
+                      if (vecout)
+                        retval(2) = fact.perm ();
+                      else
+                        retval(2) = fact.Q ();
+                    }
+
+                  if (nargout > 1 || info == 0)
+                    {
+                      retval(1) = fact.P ();
+                      if (LLt)
+                        retval(0) = fact.L ();
+                      else
+                        retval(0) = fact.R ();
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else if (arg.is_complex_type ())
+            {
+              SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+                  SparseComplexCHOL fact (m, info, natural);
+
+                  if (nargout == 3)
+                    {
+                      if (vecout)
+                        retval(2) = fact.perm ();
+                      else
+                        retval(2) = fact.Q ();
+                    }
+
+                  if (nargout > 1 || info == 0)
+                    {
+                      retval(1) = fact.P ();
+                      if (LLt)
+                        retval(0) = fact.L ();
+                      else
+                        retval(0) = fact.R ();
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else
+            gripe_wrong_type_arg ("chol", arg);
+        }
+      else if (arg.is_single_type ())
+        {
+          if (arg.is_real_type ())
+            {
+              FloatMatrix m = arg.float_matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+
+                  FloatCHOL fact;
+                  if (LLt)
+                    fact = FloatCHOL (m.transpose (), info);
+                  else
+                    fact = FloatCHOL (m, info);
+
+                  if (nargout == 2 || info == 0)
+                    {
+                      retval(1) = info;
+                      if (LLt)
+                        retval(0) = get_chol_l (fact);
+                      else
+                        retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else if (arg.is_complex_type ())
+            {
+              FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+
+                  FloatComplexCHOL fact;
+                  if (LLt)
+                    fact = FloatComplexCHOL (m.transpose (), info);
+                  else
+                    fact = FloatComplexCHOL (m, info);
+
+                  if (nargout == 2 || info == 0)
+                    {
+                      retval(1) = info;
+                      if (LLt)
+                        retval(0) = get_chol_l (fact);
+                      else
+                        retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else
+            gripe_wrong_type_arg ("chol", arg);
+        }
+      else
+        {
+          if (arg.is_real_type ())
+            {
+              Matrix m = arg.matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+                  
+                  CHOL fact;
+                  if (LLt)
+                     fact = CHOL (m.transpose (), info);
+                  else
+                    fact = CHOL (m, info);
+
+                  if (nargout == 2 || info == 0)
+                    {
+                      retval(1) = info;
+                      if (LLt)
+                        retval(0) = get_chol_l (fact);
+                      else
+                        retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else if (arg.is_complex_type ())
+            {
+              ComplexMatrix m = arg.complex_matrix_value ();
+
+              if (! error_state)
+                {
+                  octave_idx_type info;
+                  
+                  ComplexCHOL fact;
+                  if (LLt)
+                    fact = ComplexCHOL (m.transpose (), info);
+                  else
+                    fact = ComplexCHOL (m, info);
+
+                  if (nargout == 2 || info == 0)
+                    {
+                      retval(1) = info;
+                      if (LLt)
+                        retval(0) = get_chol_l (fact);
+                      else
+                        retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    error ("chol: input matrix must be positive definite");
+                }
+            }
+          else
+            gripe_wrong_type_arg ("chol", arg);
+        }
+    }
+
+  return retval;
+}
+
+/*
+%!assert (chol ([2, 1; 1, 1]), [sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)], sqrt (eps))
+%!assert (chol (single ([2, 1; 1, 1])), single ([sqrt(2), 1/sqrt(2); 0, 1/sqrt(2)]), sqrt (eps ("single")))
+
+%!error chol ()
+%!error <matrix must be positive definite> chol ([1, 2; 3, 4])
+%!error <requires square matrix> chol ([1, 2; 3, 4; 5, 6])
+%!error <unexpected second or third input> chol (1, 2)
+*/
+
+DEFUN_DLD (cholinv, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} cholinv (@var{A})\n\
+Use the Cholesky@tie{}factorization to compute the inverse of the\n\
+symmetric positive definite matrix @var{A}.\n\
+@seealso{chol, chol2inv, inv}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+
+      if (nr == 0 || nc == 0)
+        retval = Matrix ();
+      else
+        {
+          if (arg.is_sparse_type ())
+            {
+              if (arg.is_real_type ())
+                {
+                  SparseMatrix m = arg.sparse_matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      SparseCHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else if (arg.is_complex_type ())
+                {
+                  SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      SparseComplexCHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else
+                gripe_wrong_type_arg ("cholinv", arg);
+            }
+          else if (arg.is_single_type ())
+            {
+              if (arg.is_real_type ())
+                {
+                  FloatMatrix m = arg.float_matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      FloatCHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else if (arg.is_complex_type ())
+                {
+                  FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      FloatComplexCHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else
+                gripe_wrong_type_arg ("chol", arg);
+            }
+          else
+            {
+              if (arg.is_real_type ())
+                {
+                  Matrix m = arg.matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      CHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else if (arg.is_complex_type ())
+                {
+                  ComplexMatrix m = arg.complex_matrix_value ();
+
+                  if (! error_state)
+                    {
+                      octave_idx_type info;
+                      ComplexCHOL chol (m, info);
+                      if (info == 0)
+                        retval = chol.inverse ();
+                      else
+                        error ("cholinv: A must be positive definite");
+                    }
+                }
+              else
+                gripe_wrong_type_arg ("chol", arg);
+            }
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared A, Ainv
+%! A = [2,0.2;0.2,1];
+%! Ainv = inv (A);
+%!test
+%! Ainv1 = cholinv (A);
+%! assert (norm (Ainv-Ainv1), 0, 1e-10);
+%!testif HAVE_CHOLMOD
+%! Ainv2 = inv (sparse (A));
+%! assert (norm (Ainv-Ainv2), 0, 1e-10);
+%!testif HAVE_CHOLMOD
+%! Ainv3 = cholinv (sparse (A));
+%! assert (norm (Ainv-Ainv3), 0, 1e-10);
+*/
+
+DEFUN_DLD (chol2inv, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} chol2inv (@var{U})\n\
+Invert a symmetric, positive definite square matrix from its Cholesky\n\
+decomposition, @var{U}.  Note that @var{U} should be an upper-triangular\n\
+matrix with positive diagonal elements.  @code{chol2inv (@var{U})}\n\
+provides @code{inv (@var{U}'*@var{U})} but it is much faster than\n\
+using @code{inv}.\n\
+@seealso{chol, cholinv, inv}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      octave_value arg = args(0);
+
+      octave_idx_type nr = arg.rows ();
+      octave_idx_type nc = arg.columns ();
+
+      if (nr == 0 || nc == 0)
+        retval = Matrix ();
+      else
+        {
+          if (arg.is_sparse_type ())
+            {
+              if (arg.is_real_type ())
+                {
+                  SparseMatrix r = arg.sparse_matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else if (arg.is_complex_type ())
+                {
+                  SparseComplexMatrix r = arg.sparse_complex_matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else
+                gripe_wrong_type_arg ("chol2inv", arg);
+            }
+          else if (arg.is_single_type ())
+            {
+              if (arg.is_real_type ())
+                {
+                  FloatMatrix r = arg.float_matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else if (arg.is_complex_type ())
+                {
+                  FloatComplexMatrix r = arg.float_complex_matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else
+                gripe_wrong_type_arg ("chol2inv", arg);
+
+            }
+          else
+            {
+              if (arg.is_real_type ())
+                {
+                  Matrix r = arg.matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else if (arg.is_complex_type ())
+                {
+                  ComplexMatrix r = arg.complex_matrix_value ();
+
+                  if (! error_state)
+                    retval = chol2inv (r);
+                }
+              else
+                gripe_wrong_type_arg ("chol2inv", arg);
+            }
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN_DLD (cholupdate, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})\n\
+Update or downdate a Cholesky@tie{}factorization.  Given an upper triangular\n\
+matrix @var{R} and a column vector @var{u}, attempt to determine another\n\
+upper triangular matrix @var{R1} such that\n\
+\n\
+@itemize @bullet\n\
+@item\n\
+@var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
+if @var{op} is \"+\"\n\
+\n\
+@item\n\
+@var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\
+if @var{op} is \"-\"\n\
+@end itemize\n\
+\n\
+If @var{op} is \"-\", @var{info} is set to\n\
+\n\
+@itemize\n\
+@item 0 if the downdate was successful,\n\
+\n\
+@item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,\n\
+\n\
+@item 2 if @var{R} is singular.\n\
+@end itemize\n\
+\n\
+If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
+@seealso{chol, qrupdate}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin > 3 || nargin < 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argu = args(1);
+
+  if (argr.is_numeric_type () && argu.is_numeric_type ()
+      && (nargin < 3 || args(2).is_string ()))
+    {
+      octave_idx_type n = argr.rows ();
+
+      std::string op = (nargin < 3) ? "+" : args(2).string_value ();
+
+      bool down = op == "-";
+
+      if (down || op == "+")
+        if (argr.columns () == n && argu.rows () == n && argu.columns () == 1)
+          {
+            int err = 0;
+            if (argr.is_single_type () || argu.is_single_type ())
+              {
+                if (argr.is_real_type () && argu.is_real_type ())
+                  {
+                    // real case
+                    FloatMatrix R = argr.float_matrix_value ();
+                    FloatColumnVector u = argu.float_column_vector_value ();
+
+                    FloatCHOL fact;
+                    fact.set (R);
+
+                    if (down)
+                      err = fact.downdate (u);
+                    else
+                      fact.update (u);
+
+                    retval(0) = get_chol_r (fact);
+                  }
+                else
+                  {
+                    // complex case
+                    FloatComplexMatrix R = argr.float_complex_matrix_value ();
+                    FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
+
+                    FloatComplexCHOL fact;
+                    fact.set (R);
+
+                    if (down)
+                      err = fact.downdate (u);
+                    else
+                      fact.update (u);
+
+                    retval(0) = get_chol_r (fact);
+                  }
+              }
+            else
+              {
+                if (argr.is_real_type () && argu.is_real_type ())
+                  {
+                    // real case
+                    Matrix R = argr.matrix_value ();
+                    ColumnVector u = argu.column_vector_value ();
+
+                    CHOL fact;
+                    fact.set (R);
+
+                    if (down)
+                      err = fact.downdate (u);
+                    else
+                      fact.update (u);
+
+                    retval(0) = get_chol_r (fact);
+                  }
+                else
+                  {
+                    // complex case
+                    ComplexMatrix R = argr.complex_matrix_value ();
+                    ComplexColumnVector u = argu.complex_column_vector_value ();
+
+                    ComplexCHOL fact;
+                    fact.set (R);
+
+                    if (down)
+                      err = fact.downdate (u);
+                    else
+                      fact.update (u);
+
+                    retval(0) = get_chol_r (fact);
+                  }
+              }
+
+            if (nargout > 1)
+              retval(1) = err;
+            else if (err == 1)
+              error ("cholupdate: downdate violates positiveness");
+            else if (err == 2)
+              error ("cholupdate: singular matrix");
+          }
+        else
+          error ("cholupdate: dimension mismatch between R and U");
+      else
+        error ("cholupdate: OP must be \"+\" or \"-\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!shared A, u, Ac, uc
+%! A = [  0.436997  -0.131721   0.124120  -0.061673 ;
+%!       -0.131721   0.738529   0.019851  -0.140295 ;
+%!        0.124120   0.019851   0.354879  -0.059472 ;
+%!       -0.061673  -0.140295  -0.059472   0.600939 ];
+%!
+%! u = [  0.98950 ;
+%!        0.39844 ;
+%!        0.63484 ;
+%!        0.13351 ];
+%! Ac = [  0.5585528 + 0.0000000i  -0.1662088 - 0.0315341i   0.0107873 + 0.0236411i  -0.0276775 - 0.0186073i ;
+%!        -0.1662088 + 0.0315341i   0.6760061 + 0.0000000i   0.0011452 - 0.0475528i   0.0145967 + 0.0247641i ;
+%!         0.0107873 - 0.0236411i   0.0011452 + 0.0475528i   0.6263149 - 0.0000000i  -0.1585837 - 0.0719763i ;
+%!        -0.0276775 + 0.0186073i   0.0145967 - 0.0247641i  -0.1585837 + 0.0719763i   0.6034234 - 0.0000000i ];
+%!
+%! uc = [ 0.54267 + 0.91519i ;
+%!        0.99647 + 0.43141i ;
+%!        0.83760 + 0.68977i ;
+%!        0.39160 + 0.90378i ];
+
+%!test
+%! R = chol (A);
+%! R1 = cholupdate (R, u);
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - R'*R - u*u', Inf) < 1e1*eps);
+%!
+%! R1 = cholupdate (R1, u, "-");
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1 - R, Inf) < 1e1*eps);
+
+%!test
+%! R = chol (Ac);
+%! R1 = cholupdate (R, uc);
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - R'*R - uc*uc', Inf) < 1e1*eps);
+%!
+%! R1 = cholupdate (R1, uc, "-");
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1 - R, Inf) < 1e1*eps);
+
+%!test
+%! R = chol (single (A));
+%! R1 = cholupdate (R, single (u));
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1'*R1 - R'*R - single (u*u'), Inf) < 1e1*eps ("single"));
+%!
+%! R1 = cholupdate (R1, single (u), "-");
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1 - R, Inf) < 2e1*eps ("single"));
+
+%!test
+%! R = chol (single (Ac));
+%! R1 = cholupdate (R, single (uc));
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1'*R1 - R'*R - single (uc*uc'), Inf) < 1e1*eps ("single"));
+%!
+%! R1 = cholupdate (R1, single (uc), "-");
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1 - R, Inf) < 2e1*eps ("single"));
+*/
+
+DEFUN_DLD (cholinsert, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{R1} =} cholinsert (@var{R}, @var{j}, @var{u})\n\
+@deftypefnx {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})\n\
+Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
+triangular, return the Cholesky@tie{}factorization of\n\
+@var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and\n\
+@w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.\n\
+On return, @var{info} is set to\n\
+\n\
+@itemize\n\
+@item 0 if the insertion was successful,\n\
+\n\
+@item 1 if @var{A1} is not positive definite,\n\
+\n\
+@item 2 if @var{R} is singular.\n\
+@end itemize\n\
+\n\
+If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
+@seealso{chol, cholupdate, choldelete}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argj = args(1);
+  octave_value argu = args(2);
+
+  if (argr.is_numeric_type () && argu.is_numeric_type ()
+      && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n && argu.rows () == n+1 && argu.columns () == 1)
+        {
+          if (j > 0 && j <= n+1)
+            {
+              int err = 0;
+              if (argr.is_single_type () || argu.is_single_type ())
+                {
+                  if (argr.is_real_type () && argu.is_real_type ())
+                    {
+                      // real case
+                      FloatMatrix R = argr.float_matrix_value ();
+                      FloatColumnVector u = argu.float_column_vector_value ();
+
+                      FloatCHOL fact;
+                      fact.set (R);
+                      err = fact.insert_sym (u, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+                      FloatComplexColumnVector u = argu.float_complex_column_vector_value ();
+
+                      FloatComplexCHOL fact;
+                      fact.set (R);
+                      err = fact.insert_sym (u, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+              else
+                {
+                  if (argr.is_real_type () && argu.is_real_type ())
+                    {
+                      // real case
+                      Matrix R = argr.matrix_value ();
+                      ColumnVector u = argu.column_vector_value ();
+
+                      CHOL fact;
+                      fact.set (R);
+                      err = fact.insert_sym (u, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      ComplexMatrix R = argr.complex_matrix_value ();
+                      ComplexColumnVector u = argu.complex_column_vector_value ();
+
+                      ComplexCHOL fact;
+                      fact.set (R);
+                      err = fact.insert_sym (u, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+
+              if (nargout > 1)
+                retval(1) = err;
+              else if (err == 1)
+                error ("cholinsert: insertion violates positiveness");
+              else if (err == 2)
+                error ("cholinsert: singular matrix");
+              else if (err == 3)
+                error ("cholinsert: diagonal element must be real");
+            }
+          else
+            error ("cholinsert: index J out of range");
+        }
+      else
+        error ("cholinsert: dimension mismatch between R and U");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! u2 = [  0.35080 ;
+%!         0.63930 ;
+%!         3.31057 ;
+%!        -0.13825 ;
+%!         0.45266 ];
+%!
+%! R = chol (A);
+%!
+%! j = 3;  p = [1:j-1, j+1:5];
+%! R1 = cholinsert (R, j, u2);
+%! A1 = R1'*R1;
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (A1(p,p) - A, Inf) < 1e1*eps);
+
+%!test
+%! u2 = [  0.35080  + 0.04298i;
+%!         0.63930  + 0.23778i;
+%!         3.31057  + 0.00000i;
+%!        -0.13825  + 0.19879i;
+%!         0.45266  + 0.50020i];
+%!
+%! R = chol (Ac);
+%!
+%! j = 3;  p = [1:j-1, j+1:5];
+%! R1 = cholinsert (R, j, u2);
+%! A1 = R1'*R1;
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (A1(p,p) - Ac, Inf) < 1e1*eps);
+
+%!test
+%! u2 = single ([  0.35080 ;
+%!                 0.63930 ;
+%!                 3.31057 ;
+%!                -0.13825 ;
+%!                 0.45266 ]);
+%!
+%! R = chol (single (A));
+%!
+%! j = 3;  p = [1:j-1, j+1:5];
+%! R1 = cholinsert (R, j, u2);
+%! A1 = R1'*R1;
+%!
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (A1(p,p) - A, Inf) < 1e1*eps ("single"));
+
+%!test
+%! u2 = single ([  0.35080  + 0.04298i;
+%!                 0.63930  + 0.23778i;
+%!                 3.31057  + 0.00000i;
+%!                -0.13825  + 0.19879i;
+%!                 0.45266  + 0.50020i]);
+%!
+%! R = chol (single (Ac));
+%!
+%! j = 3;  p = [1:j-1, j+1:5];
+%! R1 = cholinsert (R, j, u2);
+%! A1 = R1'*R1;
+%!
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (A1(p,p) - single (Ac), Inf) < 2e1*eps ("single"));
+
+%!test
+%! cu = chol (triu (A), "upper");
+%! cl = chol (tril (A), "lower");
+%! assert (cu, cl', eps);
+
+%!test
+%! cca  = chol (Ac);
+%!
+%! ccal  = chol (Ac, "lower");
+%! ccal2 = chol (tril (Ac), "lower");
+%!
+%! ccau  = chol (Ac, "upper");
+%! ccau2 = chol (triu (Ac), "upper");
+%!
+%! assert (cca'*cca,     Ac, eps);
+%! assert (ccau'*ccau,   Ac, eps);
+%! assert (ccau2'*ccau2, Ac, eps);
+%!
+%! assert (cca, ccal',  eps);
+%! assert (cca, ccau,   eps);
+%! assert (cca, ccal2', eps);
+%! assert (cca, ccau2,  eps);
+
+%!test
+%! cca  = chol (single (Ac));
+%!
+%! ccal  = chol (single (Ac), "lower");
+%! ccal2 = chol (tril (single (Ac)), "lower");
+%!
+%! ccau  = chol (single (Ac), "upper");
+%! ccau2 = chol (triu (single (Ac)), "upper");
+%!
+%! assert (cca'*cca,     single (Ac), eps ("single"));
+%! assert (ccau'*ccau,   single (Ac), eps ("single"));
+%! assert (ccau2'*ccau2, single (Ac), eps ("single"));
+%!
+%! assert (cca, ccal',  eps ("single"));
+%! assert (cca, ccau,   eps ("single"));
+%! assert (cca, ccal2', eps ("single"));
+%! assert (cca, ccau2,  eps ("single"));
+
+%!test
+%! a = [12,  2,  3,  4;
+%!       2, 14,  5,  3;
+%!       3,  5, 16,  6;
+%!       4,  3,  6, 16];
+%!
+%! b = [0,  1,  2,  3;
+%!     -1,  0,  1,  2;
+%!     -2, -1,  0,  1;
+%!     -3, -2, -1,  0];
+%!
+%! ca = a + i*b;
+%!   
+%! cca  = chol (ca);
+%!
+%! ccal  = chol (ca, "lower");
+%! ccal2 = chol (tril (ca), "lower");
+%!
+%! ccau  = chol (ca, "upper");
+%! ccau2 = chol (triu (ca), "upper");
+%!
+%! assert (cca'*cca,     ca, 16*eps);
+%! assert (ccau'*ccau,   ca, 16*eps);
+%! assert (ccau2'*ccau2, ca, 16*eps);
+%!
+%! assert (cca, ccal',  16*eps);
+%! assert (cca, ccau,   16*eps);
+%! assert (cca, ccal2', 16*eps);
+%! assert (cca, ccau2,  16*eps);
+*/
+
+DEFUN_DLD (choldelete, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\
+Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
+triangular, return the Cholesky@tie{}factorization of @w{A(p,p)}, where\n\
+@w{p = [1:j-1,j+1:n+1]}.\n\
+@seealso{chol, cholupdate, cholinsert}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argj = args(1);
+
+  if (argr.is_numeric_type () && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n)
+        {
+          if (j > 0 && j <= n)
+            {
+              if (argr.is_single_type ())
+                {
+                  if (argr.is_real_type ())
+                    {
+                      // real case
+                      FloatMatrix R = argr.float_matrix_value ();
+
+                      FloatCHOL fact;
+                      fact.set (R);
+                      fact.delete_sym (j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+                      FloatComplexCHOL fact;
+                      fact.set (R);
+                      fact.delete_sym (j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+              else
+                {
+                  if (argr.is_real_type ())
+                    {
+                      // real case
+                      Matrix R = argr.matrix_value ();
+
+                      CHOL fact;
+                      fact.set (R);
+                      fact.delete_sym (j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      ComplexMatrix R = argr.complex_matrix_value ();
+
+                      ComplexCHOL fact;
+                      fact.set (R);
+                      fact.delete_sym (j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+            }
+          else
+            error ("choldelete: index J out of range");
+        }
+      else
+        error ("choldelete: matrix R must be square");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! R = chol (A);
+%!
+%! j = 3;  p = [1:j-1,j+1:4];
+%! R1 = choldelete (R, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
+
+%!test
+%! R = chol (Ac);
+%!
+%! j = 3;  p = [1:j-1,j+1:4];
+%! R1 = choldelete (R, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
+
+%!test
+%! R = chol (single (A));
+%!
+%! j = 3;  p = [1:j-1,j+1:4];
+%! R1 = choldelete (R, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
+
+%!test
+%! R = chol (single (Ac));
+%!
+%! j = 3;  p = [1:j-1,j+1:4];
+%! R1 = choldelete (R,j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), single (0));
+%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
+*/
+
+DEFUN_DLD (cholshift, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})\n\
+Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
+positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
+triangular, return the Cholesky@tie{}factorization of\n\
+@w{@var{A}(p,p)}, where @w{p} is the permutation @*\n\
+@code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
+ or @*\n\
+@code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
+\n\
+@seealso{chol, cholinsert, choldelete}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+
+  octave_value_list retval;
+
+  if (nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argr = args(0);
+  octave_value argi = args(1);
+  octave_value argj = args(2);
+
+  if (argr.is_numeric_type () && argi.is_real_scalar () && argj.is_real_scalar ())
+    {
+      octave_idx_type n = argr.rows ();
+      octave_idx_type i = argi.scalar_value ();
+      octave_idx_type j = argj.scalar_value ();
+
+      if (argr.columns () == n)
+        {
+          if (j > 0 && j <= n+1 && i > 0 && i <= n+1)
+            {
+
+              if (argr.is_single_type () && argi.is_single_type () &&
+                  argj.is_single_type ())
+                {
+                  if (argr.is_real_type ())
+                    {
+                      // real case
+                      FloatMatrix R = argr.float_matrix_value ();
+
+                      FloatCHOL fact;
+                      fact.set (R);
+                      fact.shift_sym (i-1, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+                      FloatComplexCHOL fact;
+                      fact.set (R);
+                      fact.shift_sym (i-1, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+              else
+                {
+                  if (argr.is_real_type ())
+                    {
+                      // real case
+                      Matrix R = argr.matrix_value ();
+
+                      CHOL fact;
+                      fact.set (R);
+                      fact.shift_sym (i-1, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                  else
+                    {
+                      // complex case
+                      ComplexMatrix R = argr.complex_matrix_value ();
+
+                      ComplexCHOL fact;
+                      fact.set (R);
+                      fact.shift_sym (i-1, j-1);
+
+                      retval(0) = get_chol_r (fact);
+                    }
+                }
+            }
+          else
+            error ("cholshift: index I or J is out of range");
+        }
+      else
+        error ("cholshift: R must be a square matrix");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! R = chol (A);
+%!
+%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
+%!
+%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1) - R1, Inf), 0);
+%! assert (norm (R1'*R1 - A(p,p), Inf) < 1e1*eps);
+
+%!test
+%! R = chol (Ac);
+%!
+%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
+%!
+%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - Ac(p,p), Inf) < 1e1*eps);
+
+%!test
+%! R = chol (single (A));
+%! 
+%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
+%!
+%! j = 1;  i = 3;  p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - single (A(p,p)), Inf) < 1e1*eps ("single"));
+
+%!test
+%! R = chol (single (Ac));
+%!
+%! i = 1;  j = 3;  p = [1:i-1, shift(i:j,-1), j+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
+%!
+%! j = 1; i = 3; p = [1:j-1, shift(j:i,+1), i+1:4];
+%! R1 = cholshift (R, i, j);
+%!
+%! assert (norm (triu (R1)-R1, Inf), 0);
+%! assert (norm (R1'*R1 - single (Ac(p,p)), Inf) < 1e1*eps ("single"));
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/colamd.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,768 @@
+/*
+
+Copyright (C) 2004-2012 David Bateman
+Copyright (C) 1998-2004 Andy Adler
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// This is the octave interface to colamd, which bore the copyright given
+// in the help of the functions.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <string>
+#include <vector>
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "pager.h"
+#include "ov-re-mat.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+#include "oct-sparse.h"
+#include "oct-locbuf.h"
+
+#ifdef IDX_TYPE_LONG
+#define COLAMD_NAME(name) colamd_l ## name
+#define SYMAMD_NAME(name) symamd_l ## name
+#else
+#define COLAMD_NAME(name) colamd ## name
+#define SYMAMD_NAME(name) symamd ## name
+#endif
+
+// The symmetric column elimination tree code take from the Davis LDL code.
+// Copyright given elsewhere in this file.
+static void
+symetree (const octave_idx_type *ridx, const octave_idx_type *cidx,
+          octave_idx_type *Parent, octave_idx_type *P, octave_idx_type n)
+{
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Flag, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Pinv, (P ? n : 0));
+  if (P)
+    // If P is present then compute Pinv, the inverse of P
+    for (octave_idx_type k = 0 ; k < n ; k++)
+      Pinv[P[k]] = k ;
+
+  for (octave_idx_type k = 0 ; k < n ; k++)
+    {
+      // L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k)
+      Parent[k] = n ;                // parent of k is not yet known
+      Flag[k] = k ;                  // mark node k as visited
+      octave_idx_type kk = (P) ? (P[k]) : (k) ;  // kth original, or permuted, column
+      octave_idx_type p2 = cidx[kk+1] ;
+      for (octave_idx_type p = cidx[kk] ; p < p2 ; p++)
+        {
+          // A (i,k) is nonzero (original or permuted A)
+          octave_idx_type i = (Pinv) ? (Pinv[ridx[p]]) : (ridx[p]) ;
+          if (i < k)
+            {
+              // follow path from i to root of etree, stop at flagged node
+              for ( ; Flag[i] != k ; i = Parent[i])
+                {
+                  // find parent of i if not yet determined
+                  if (Parent[i] == n)
+                    Parent[i] = k ;
+                  Flag[i] = k ;        // mark i as visited
+                }
+            }
+        }
+    }
+}
+
+// The elimination tree post-ordering code below is taken from SuperLU
+static inline octave_idx_type
+make_set (octave_idx_type i, octave_idx_type *pp)
+{
+  pp[i] = i;
+  return i;
+}
+
+static inline octave_idx_type
+link (octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
+{
+  pp[s] = t;
+  return t;
+}
+
+static inline octave_idx_type
+find (octave_idx_type i, octave_idx_type *pp)
+{
+  register octave_idx_type p, gp;
+
+  p = pp[i];
+  gp = pp[p];
+
+  while (gp != p)
+    {
+      pp[i] = gp;
+      i = gp;
+      p = pp[i];
+      gp = pp[p];
+    }
+
+  return p;
+}
+
+static octave_idx_type
+etdfs (octave_idx_type v, octave_idx_type *first_kid,
+       octave_idx_type *next_kid, octave_idx_type *post,
+       octave_idx_type postnum)
+{
+  for (octave_idx_type w = first_kid[v]; w != -1; w = next_kid[w])
+    postnum = etdfs (w, first_kid, next_kid, post, postnum);
+
+  post[postnum++] = v;
+
+  return postnum;
+}
+
+static void
+tree_postorder (octave_idx_type n, octave_idx_type *parent,
+                octave_idx_type *post)
+{
+  // Allocate storage for working arrays and results
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, first_kid, n+1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, next_kid, n+1);
+
+  // Set up structure describing children
+  for (octave_idx_type v = 0; v <= n; first_kid[v++] = -1)
+    /* do nothing */;
+
+  for (octave_idx_type v = n-1; v >= 0; v--)
+    {
+      octave_idx_type dad = parent[v];
+      next_kid[v] = first_kid[dad];
+      first_kid[dad] = v;
+    }
+
+  // Depth-first search from dummy root vertex #n
+  etdfs (n, first_kid, next_kid, post, 0);
+}
+
+static void
+coletree (const octave_idx_type *ridx, const octave_idx_type *colbeg,
+          octave_idx_type *colend, octave_idx_type *parent,
+          octave_idx_type nr, octave_idx_type nc)
+{
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, root, nc);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, pp, nc);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, firstcol, nr);
+
+  // Compute firstcol[row] = first nonzero column in row
+  for (octave_idx_type row = 0; row < nr; firstcol[row++] = nc)
+    /* do nothing */;
+
+  for (octave_idx_type col = 0; col < nc; col++)
+    for (octave_idx_type p = colbeg[col]; p < colend[col]; p++)
+      {
+        octave_idx_type row = ridx[p];
+        if (firstcol[row] > col)
+          firstcol[row] = col;
+      }
+
+  // Compute etree by Liu's algorithm for symmetric matrices,
+  // except use (firstcol[r],c) in place of an edge (r,c) of A.
+  // Thus each row clique in A'*A is replaced by a star
+  // centered at its first vertex, which has the same fill.
+  for (octave_idx_type col = 0; col < nc; col++)
+    {
+      octave_idx_type cset = make_set (col, pp);
+      root[cset] = col;
+      parent[col] = nc;
+      for (octave_idx_type p = colbeg[col]; p < colend[col]; p++)
+        {
+          octave_idx_type row = firstcol[ridx[p]];
+          if (row >= col)
+            continue;
+          octave_idx_type rset = find (row, pp);
+          octave_idx_type rroot = root[rset];
+          if (rroot != col)
+            {
+              parent[rroot] = col;
+              cset = link (cset, rset, pp);
+              root[cset] = col;
+            }
+        }
+    }
+}
+
+DEFUN_DLD (colamd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} colamd (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} colamd (@var{S}, @var{knobs})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S}, @var{knobs})\n\
+\n\
+Column approximate minimum degree permutation.\n\
+@code{@var{p} = colamd (@var{S})} returns the column approximate minimum\n\
+degree permutation vector for the sparse matrix @var{S}.  For a\n\
+non-symmetric matrix @var{S}, @code{@var{S}(:,@var{p})} tends to have\n\
+sparser LU@tie{}factors than @var{S}.  The Cholesky@tie{}factorization of\n\
+@code{@var{S}(:,@var{p})' * @var{S}(:,@var{p})} also tends to be sparser\n\
+than that of @code{@var{S}' * @var{S}}.\n\
+\n\
+@var{knobs} is an optional one- to three-element input vector.  If @var{S} is\n\
+m-by-n, then rows with more than @code{max(16,@var{knobs}(1)*sqrt(n))}\n\
+entries are ignored.  Columns with more than\n\
+@code{max (16,@var{knobs}(2)*sqrt(min(m,n)))} entries are removed prior to\n\
+ordering, and ordered last in the output permutation @var{p}.  Only\n\
+completely dense rows or columns are removed if @code{@var{knobs}(1)} and\n\
+@code{@var{knobs}(2)} are < 0, respectively.  If @code{@var{knobs}(3)} is\n\
+nonzero, @var{stats} and @var{knobs} are printed.  The default is\n\
+@code{@var{knobs} = [10 10 0]}.  Note that @var{knobs} differs from earlier\n\
+versions of colamd.\n\
+\n\
+@var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
+statistics are in @code{@var{stats}(1:3)}.  @code{@var{stats}(1)} and\n\
+@code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
+ignored by @sc{colamd} and @code{@var{stats}(3)} is the number of garbage\n\
+collections performed on the internal data structure used by @sc{colamd}\n\
+(roughly of size @code{2.2 * nnz(@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
+integers).\n\
+\n\
+Octave built-in functions are intended to generate valid sparse matrices,\n\
+with no duplicate entries, with ascending row indices of the nonzeros\n\
+in each column, with a non-negative number of entries in each column (!)\n\
+and so on.  If a matrix is invalid, then @sc{colamd} may or may not be able\n\
+to continue.  If there are duplicate entries (a row index appears two or\n\
+more times in the same column) or if the row indices in a column are out\n\
+of order, then @sc{colamd} can correct these errors by ignoring the duplicate\n\
+entries and sorting each column of its internal copy of the matrix\n\
+@var{S} (the input matrix @var{S} is not repaired, however).  If a matrix\n\
+is invalid in other ways then @sc{colamd} cannot continue, an error message\n\
+is printed, and no output arguments (@var{p} or @var{stats}) are returned.\n\
+@sc{colamd} is thus a simple way to check a sparse matrix to see if it's\n\
+valid.\n\
+\n\
+@code{@var{stats}(4:7)} provide information if COLAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
+invalid.  @code{@var{stats}(5)} is the rightmost column index that is\n\
+unsorted or contains duplicate entries, or zero if no such column exists.\n\
+@code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
+index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
+such row index exists.  @code{@var{stats}(7)} is the number of duplicate\n\
+or out-of-order row indices.  @code{@var{stats}(8:20)} is always zero in\n\
+the current version of @sc{colamd} (reserved for future use).\n\
+\n\
+The ordering is followed by a column elimination tree post-ordering.\n\
+\n\
+The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
+Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
+Ng, Oak Ridge National Laboratory.  (see\n\
+@url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
+@seealso{colperm, symamd, ccolamd}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_COLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+
+  if (nargout > 2 || nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);
+      COLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin == 2)
+        {
+          NDArray User_knobs = args(1).array_value ();
+          int nel_User_knobs = User_knobs.length ();
+
+          if (nel_User_knobs > 0)
+            knobs[COLAMD_DENSE_ROW] = User_knobs(0);
+          if (nel_User_knobs > 1)
+            knobs[COLAMD_DENSE_COL] = User_knobs(1) ;
+          if (nel_User_knobs > 2)
+            spumoni = static_cast<int> (User_knobs(2));
+
+          // print knob settings if spumoni is set
+          if (spumoni)
+            {
+
+              octave_stdout << "\ncolamd version " << COLAMD_MAIN_VERSION << "."
+                            <<  COLAMD_SUB_VERSION << ", " << COLAMD_DATE << ":\n";
+
+              if (knobs[COLAMD_DENSE_ROW] >= 0)
+                octave_stdout << "knobs(1): " << User_knobs (0)
+                              << ", rows with > max (16,"
+                              << knobs[COLAMD_DENSE_ROW] << "*sqrt (size(A,2)))"
+                              << " entries removed\n";
+              else
+                octave_stdout << "knobs(1): " << User_knobs (0)
+                              << ", only completely dense rows removed\n";
+
+              if (knobs[COLAMD_DENSE_COL] >= 0)
+                octave_stdout << "knobs(2): " << User_knobs (1)
+                              << ", cols with > max (16,"
+                              << knobs[COLAMD_DENSE_COL] << "*sqrt (size(A)))"
+                              << " entries removed\n";
+              else
+                octave_stdout << "knobs(2): " << User_knobs (1)
+                              << ", only completely dense columns removed\n";
+
+              octave_stdout << "knobs(3): " << User_knobs (2)
+                            << ", statistics and knobs printed\n";
+
+            }
+        }
+
+      octave_idx_type n_row, n_col, nnz;
+      octave_idx_type *ridx, *cidx;
+      SparseComplexMatrix scm;
+      SparseMatrix sm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0). sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              nnz = scm.nnz ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              nnz = sm.nnz ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+        }
+      else
+        {
+          if (args(0).is_complex_type ())
+            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+          else
+            sm = SparseMatrix (args(0).matrix_value ());
+
+          n_row = sm.rows ();
+          n_col = sm.cols ();
+          nnz = sm.nnz ();
+          ridx = sm.xridx ();
+          cidx = sm.xcidx ();
+        }
+
+      // Allocate workspace for colamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+      for (octave_idx_type i = 0; i < n_col+1; i++)
+        p[i] = cidx[i];
+
+      octave_idx_type Alen = COLAMD_NAME (_recommended) (nnz, n_row, n_col);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+      for (octave_idx_type i = 0; i < nnz; i++)
+        A[i] = ridx[i];
+
+      // Order the columns (destroys A)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
+      if (! COLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats))
+        {
+          COLAMD_NAME (_report) (stats) ;
+          error ("colamd: internal error!");
+          return retval;
+        }
+
+      // column elimination tree post-ordering (reuse variables)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col + 1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col + 1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+
+      for (octave_idx_type i = 0; i < n_col; i++)
+        {
+          colbeg[i] = cidx[p[i]];
+          colend[i] = cidx[p[i]+1];
+        }
+
+      coletree (ridx, colbeg, colend, etree, n_row, n_col);
+
+      // Calculate the tree post-ordering
+      tree_postorder (n_col, etree, colbeg);
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+        out_perm(i) = p[colbeg[i]] + 1;
+
+      retval(0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+        COLAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+        {
+          NDArray out_stats (dim_vector (1, COLAMD_STATS));
+          for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
+            out_stats(i) = stats[i] ;
+          retval(1) = out_stats;
+
+          // 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) ++ ;
+        }
+    }
+
+#else
+
+  error ("colamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (symamd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} symamd (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} symamd (@var{S}, @var{knobs})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S}, @var{knobs})\n\
+\n\
+For a symmetric positive definite matrix @var{S}, returns the permutation\n\
+vector p such that @code{@var{S}(@var{p}, @var{p})} tends to have a\n\
+sparser Cholesky@tie{}factor than @var{S}.  Sometimes @code{symamd} works\n\
+well for symmetric indefinite matrices too.  The matrix @var{S} is assumed\n\
+to be symmetric; only the strictly lower triangular part is referenced.\n\
+@var{S} must be square.\n\
+\n\
+@var{knobs} is an optional one- to two-element input vector.  If @var{S} is\n\
+n-by-n, then rows and columns with more than\n\
+@code{max (16,@var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,\n\
+and ordered last in the output permutation @var{p}.  No rows/columns are\n\
+removed if @code{@var{knobs}(1) < 0}.  If @code{@var{knobs} (2)} is nonzero,\n\
+@code{stats} and @var{knobs} are printed.  The default is @code{@var{knobs}\n\
+= [10 0]}.  Note that @var{knobs} differs from earlier versions of symamd.\n\
+\n\
+@var{stats} is an optional 20-element output vector that provides data\n\
+about the ordering and the validity of the input matrix @var{S}.  Ordering\n\
+statistics are in @code{@var{stats}(1:3)}.  @code{@var{stats}(1) =\n\
+@var{stats}(2)} is the number of dense or empty rows and columns\n\
+ignored by SYMAMD and @code{@var{stats}(3)} is the number of garbage\n\
+collections performed on the internal data structure used by SYMAMD\n\
+(roughly of size @code{8.4 * nnz (tril (@var{S}, -1)) + 9 * @var{n}}\n\
+integers).\n\
+\n\
+Octave built-in functions are intended to generate valid sparse matrices,\n\
+with no duplicate entries, with ascending row indices of the nonzeros\n\
+in each column, with a non-negative number of entries in each column (!)\n\
+and so on.  If a matrix is invalid, then SYMAMD may or may not be able\n\
+to continue.  If there are duplicate entries (a row index appears two or\n\
+more times in the same column) or if the row indices in a column are out\n\
+of order, then SYMAMD can correct these errors by ignoring the duplicate\n\
+entries and sorting each column of its internal copy of the matrix S (the\n\
+input matrix S is not repaired, however).  If a matrix is invalid in\n\
+other ways then SYMAMD cannot continue, an error message is printed, and\n\
+no output arguments (@var{p} or @var{stats}) are returned.  SYMAMD is\n\
+thus a simple way to check a sparse matrix to see if it's valid.\n\
+\n\
+@code{@var{stats}(4:7)} provide information if SYMAMD was able to\n\
+continue.  The matrix is OK if @code{@var{stats} (4)} is zero, or 1\n\
+if invalid.  @code{@var{stats}(5)} is the rightmost column index that\n\
+is unsorted or contains duplicate entries, or zero if no such column\n\
+exists.  @code{@var{stats}(6)} is the last seen duplicate or out-of-order\n\
+row index in the column index given by @code{@var{stats}(5)}, or zero\n\
+if no such row index exists.  @code{@var{stats}(7)} is the number of\n\
+duplicate or out-of-order row indices.  @code{@var{stats}(8:20)} is\n\
+always zero in the current version of SYMAMD (reserved for future use).\n\
+\n\
+The ordering is followed by a column elimination tree post-ordering.\n\
+\n\
+The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
+Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
+developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
+Ng, Oak Ridge National Laboratory.  (see\n\
+@url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
+@seealso{colperm, colamd}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_COLAMD
+
+  int nargin = args.length ();
+  int spumoni = 0;
+
+  if (nargout > 2 || nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      // Get knobs
+      OCTAVE_LOCAL_BUFFER (double, knobs, COLAMD_KNOBS);
+      COLAMD_NAME (_set_defaults) (knobs);
+
+      // Check for user-passed knobs
+      if (nargin == 2)
+        {
+          NDArray User_knobs = args(1).array_value ();
+          int nel_User_knobs = User_knobs.length ();
+
+          if (nel_User_knobs > 0)
+            knobs[COLAMD_DENSE_ROW] = User_knobs(COLAMD_DENSE_ROW);
+          if (nel_User_knobs > 1)
+            spumoni = static_cast<int> (User_knobs (1));
+        }
+
+      // print knob settings if spumoni is set
+      if (spumoni > 0)
+        octave_stdout << "symamd: dense row/col fraction: "
+                      << knobs[COLAMD_DENSE_ROW] << std::endl;
+
+      octave_idx_type n_row, n_col;
+      octave_idx_type *ridx, *cidx;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0).sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+        }
+      else
+        {
+          if (args(0).is_complex_type ())
+            sm = SparseMatrix (real (args(0).complex_matrix_value ()));
+          else
+            sm = SparseMatrix (args(0).matrix_value ());
+
+          n_row = sm.rows ();
+          n_col = sm.cols ();
+          ridx = sm.xridx ();
+          cidx = sm.xcidx ();
+        }
+
+      if (n_row != n_col)
+        {
+          error ("symamd: matrix S must be square");
+          return retval;
+        }
+
+      // Allocate workspace for symamd
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
+      if (!SYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, &calloc, &free))
+        {
+          SYMAMD_NAME (_report) (stats) ;
+          error ("symamd: internal error!") ;
+          return retval;
+        }
+
+      // column elimination tree post-ordering
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+      symetree (ridx, cidx, etree, perm, n_col);
+
+      // Calculate the tree post-ordering
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
+      tree_postorder (n_col, etree, post);
+
+      // return the permutation vector
+      NDArray out_perm (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+        out_perm(i) = perm[post[i]] + 1;
+
+      retval(0) = out_perm;
+
+      // print stats if spumoni > 0
+      if (spumoni > 0)
+        SYMAMD_NAME (_report) (stats) ;
+
+      // Return the stats vector
+      if (nargout == 2)
+        {
+          NDArray out_stats (dim_vector (1, COLAMD_STATS));
+          for (octave_idx_type i = 0 ; i < COLAMD_STATS ; i++)
+            out_stats(i) = stats[i] ;
+          retval(1) = out_stats;
+
+          // 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) ++ ;
+        }
+    }
+
+#else
+
+  error ("symamd: not available in this version of Octave");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (etree, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} etree (@var{S})\n\
+@deftypefnx {Loadable Function} {@var{p} =} etree (@var{S}, @var{typ})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{S}, @var{typ})\n\
+\n\
+Return the elimination tree for the matrix @var{S}.  By default @var{S}\n\
+is assumed to be symmetric and the symmetric elimination tree is\n\
+returned.  The argument @var{typ} controls whether a symmetric or\n\
+column elimination tree is returned.  Valid values of @var{typ} are\n\
+\"sym\" or \"col\", for symmetric or column elimination tree respectively\n\
+\n\
+Called with a second argument, @code{etree} also returns the postorder\n\
+permutations on the tree.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargout > 2 || nargin < 1 || nargin > 2)
+    print_usage ();
+  else
+    {
+      octave_idx_type n_row, n_col;
+      octave_idx_type *ridx, *cidx;
+      bool is_sym = true;
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+
+      if (args(0).is_sparse_type ())
+        {
+          if (args(0).is_complex_type ())
+            {
+              scm = args(0).sparse_complex_matrix_value ();
+              n_row = scm.rows ();
+              n_col = scm.cols ();
+              ridx = scm.xridx ();
+              cidx = scm.xcidx ();
+            }
+          else
+            {
+              sm = args(0).sparse_matrix_value ();
+              n_row = sm.rows ();
+              n_col = sm.cols ();
+              ridx = sm.xridx ();
+              cidx = sm.xcidx ();
+            }
+
+        }
+      else
+        {
+          error ("etree: S must be a sparse matrix");
+          return retval;
+        }
+
+      if (nargin == 2)
+        {
+          if (args(1).is_string ())
+            {
+              std::string str = args(1).string_value ();
+              if (str.find ("C") == 0 || str.find ("c") == 0)
+                is_sym = false;
+            }
+          else
+            {
+              error ("etree: TYP must be a string");
+              return retval;
+            }
+        }
+
+      // column elimination tree post-ordering (reuse variables)
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
+
+      if (is_sym)
+        {
+          if (n_row != n_col)
+            {
+              error ("etree: S is marked as symmetric, but is not square");
+              return retval;
+            }
+
+          symetree (ridx, cidx, etree, 0, n_col);
+        }
+      else
+        {
+          OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col);
+          OCTAVE_LOCAL_BUFFER (octave_idx_type, colend, n_col);
+
+          for (octave_idx_type i = 0; i < n_col; i++)
+            {
+              colbeg[i] = cidx[i];
+              colend[i] = cidx[i+1];
+            }
+
+          coletree (ridx, colbeg, colend, etree, n_row, n_col);
+        }
+
+      NDArray tree (dim_vector (1, n_col));
+      for (octave_idx_type i = 0; i < n_col; i++)
+        // We flag a root with n_col while Matlab does it with zero
+        // Convert for matlab compatiable output
+        if (etree[i] == n_col)
+          tree(i) = 0;
+        else
+          tree(i) = etree[i] + 1;
+
+      retval(0) = tree;
+
+      if (nargout == 2)
+        {
+          // Calculate the tree post-ordering
+          OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
+          tree_postorder (n_col, etree, post);
+
+          NDArray postorder (dim_vector (1, n_col));
+          for (octave_idx_type i = 0; i < n_col; i++)
+            postorder(i) = post[i] + 1;
+
+          retval(1) = postorder;
+        }
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/config-module.awk	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,77 @@
+BEGIN {
+  FS = "|";
+  nfiles = 0;
+
+  print "## DO NOT EDIT -- generated from module-files by config-module.awk";
+  print ""
+  print "EXTRA_DIST += \\"
+  print "  dldfcn/config-module.sh \\"
+  print "  dldfcn/config-module.awk \\"
+  print "  dldfcn/module-files \\"
+  print "  dldfcn/oct-qhull.h"
+  print ""
+}
+/^#.*/ { next; }
+{
+  nfiles++;
+  files[nfiles] = $1;
+  cppflags[nfiles] = $2;
+  ldflags[nfiles] = $3;
+  libraries[nfiles] = $4;
+} END {
+  sep = " \\\n";
+  print "DLDFCN_SRC = \\";
+  for (i = 1; i <= nfiles; i++) {
+    if (i == nfiles)
+      sep = "\n";
+    printf ("  dldfcn/%s%s", files[i], sep);
+  }
+  print "";
+
+  sep = " \\\n";
+  print "DLDFCN_LIBS = $(DLDFCN_SRC:.cc=.la)";
+  print "";
+  print "if AMCOND_ENABLE_DYNAMIC_LINKING";
+  print "";
+  print "octlib_LTLIBRARIES += $(DLDFCN_LIBS)";
+  print "";
+  print "## Use stamp files to avoid problems with checking timestamps";
+  print "## of symbolic links";
+  print "";
+  for (i = 1; i <= nfiles; i++) {
+    basename = files[i];
+    sub (/\.cc$/, "", basename);
+    printf ("dldfcn/$(am__leading_dot)%s.oct-stamp: dldfcn/%s.la\n", basename, basename);
+    print "\trm -f $(<:.la=.oct)";
+    print "\tla=$(<F) && \\";
+    print "\t  of=$(<F:.la=.oct) && \\";
+    print "\t  cd dldfcn && \\";
+    print "\t  $(LN_S) .libs/`$(SED) -n -e \"s/dlname='\\([^']*\\)'/\\1/p\" < $$la` $$of && \\";
+    print "\t  touch $(@F)";
+    print "";
+  }
+  print "else";
+  print "";
+  print "noinst_LTLIBRARIES += $(DLDFCN_LIBS)";
+  print "";
+  print "endif";
+
+  for (i = 1; i <= nfiles; i++) {
+    basename = files[i];
+    sub (/\.cc$/, "", basename);
+    print "";
+    printf ("dldfcn_%s_la_SOURCES = dldfcn/%s\n",
+	    basename, files[i]);
+    if (cppflags[i])
+      {
+        printf ("dldfcn/%s.df: CPPFLAGS += %s\n",
+                basename, cppflags[i]);
+        printf ("dldfcn_%s_la_CPPFLAGS = $(AM_CPPFLAGS) %s\n",
+                basename, cppflags[i]);
+      }
+    printf ("dldfcn_%s_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED_LDFLAG) %s $(OCT_LINK_OPTS)\n",
+            basename, ldflags[i]);
+    printf ("dldfcn_%s_la_LIBADD = $(DLD_LIBOCTINTERP_LIBADD) ../liboctave/liboctave.la ../libcruft/libcruft.la %s $(OCT_LINK_DEPS)\n",
+            basename, libraries[i]);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/config-module.sh	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+set -e
+
+: ${AWK=awk}
+
+if [ $# -eq 1 ]; then
+  top_srcdir="$1";
+else
+  top_srcdir="../.."
+fi
+
+move_if_change="$top_srcdir/build-aux/move-if-change"
+
+dld_dir=$top_srcdir/src/dldfcn
+
+$AWK -f $dld_dir/config-module.awk < $dld_dir/module-files > $dld_dir/module.mk-t
+
+$move_if_change $dld_dir/module.mk-t $dld_dir/module.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/convhulln.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,316 @@
+/*
+
+Copyright (C) 2000-2012 Kai Habel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+29. July 2000 - Kai Habel: first release
+2002-04-22 Paul Kienzle
+* Use warning(...) function rather than writing to cerr
+2006-05-01 Tom Holroyd
+* add support for consistent winding in all dimensions; output is
+* guaranteed to be simplicial.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sstream>
+
+#include "Cell.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "parse.h"
+#include "unwind-prot.h"
+
+#if defined (HAVE_QHULL)
+# include "oct-qhull.h"
+# if defined (NEED_QHULL_VERSION)
+char qh_version[] = "convhulln.oct 2007-07-24";
+# endif
+#endif
+
+static void
+close_fcn (FILE *f)
+{
+  gnulib::fclose (f);
+}
+
+DEFUN_DLD (convhulln, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{h} =} convhulln (@var{pts})\n\
+@deftypefnx {Loadable Function} {@var{h} =} convhulln (@var{pts}, @var{options})\n\
+@deftypefnx {Loadable Function} {[@var{h}, @var{v}] =} convhulln (@dots{})\n\
+Compute the convex hull of the set of points @var{pts} which is a matrix\n\
+of size [n, dim] containing n points in a space of dimension dim.\n\
+The hull @var{h} is an index vector into the set of points and specifies\n\
+which points form the enclosing hull.\n\
+\n\
+An optional second argument, which must be a string or cell array of strings,\n\
+contains options passed to the underlying qhull command.\n\
+See the documentation for the Qhull library for details\n\
+@url{http://www.qhull.org/html/qh-quick.htm#options}.\n\
+The default options depend on the dimension of the input:\n\
+\n\
+@itemize\n\
+@item 2D, 3D, 4D: @var{options} = @code{@{\"Qt\"@}}\n\
+\n\
+@item 5D and higher: @var{options} = @code{@{\"Qt\", \"Qx\"@}}\n\
+@end itemize\n\
+\n\
+If @var{options} is not present or @code{[]} then the default arguments are\n\
+used.  Otherwise, @var{options} replaces the default argument list.\n\
+To append user options to the defaults it is necessary to repeat the\n\
+default arguments in @var{options}.  Use a null string to pass no arguments.\n\
+\n\
+If the second output @var{v} is requested the volume of the enclosing\n\
+convex hull is calculated.\n\n\
+@seealso{convhull, delaunayn, voronoin}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#if defined (HAVE_QHULL)
+
+  int nargin = args.length ();
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  Matrix points (args(0).matrix_value ());
+  const octave_idx_type dim = points.columns ();
+  const octave_idx_type num_points = points.rows ();
+
+  points = points.transpose ();
+
+  std::string options;
+
+  if (dim <= 4)
+    options = " Qt";
+  else
+    options = " Qt Qx";
+
+  if (nargin == 2)
+    {
+      if (args(1).is_string ())
+        options = " " + args(1).string_value ();
+      else if (args(1).is_empty ())
+        ; // Use default options.
+      else if (args(1).is_cellstr ())
+        {
+          options = "";
+
+          Array<std::string> tmp = args(1).cellstr_value ();
+
+          for (octave_idx_type i = 0; i < tmp.numel (); i++)
+            options += " " + tmp(i);
+        }
+      else
+        {
+          error ("convhulln: OPTIONS must be a string, cell array of strings, or empty");
+          return retval;
+        }
+     }
+
+  boolT ismalloc = false;
+
+  unwind_protect frame;
+
+  // Replace the outfile pointer with stdout for debugging information.
+#if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
+  FILE *outfile = gnulib::fopen ("NUL", "w");
+#else
+  FILE *outfile = gnulib::fopen ("/dev/null", "w");
+#endif
+  FILE *errfile = stderr;
+
+  if (outfile)
+    frame.add_fcn (close_fcn, outfile);
+  else
+    {
+      error ("convhulln: unable to create temporary file for output");
+      return retval;
+    }
+
+  // qh_new_qhull command and points arguments are not const...
+
+  std::string cmd = "qhull" + options;
+
+  OCTAVE_LOCAL_BUFFER (char, cmd_str, cmd.length () + 1);
+
+  strcpy (cmd_str, cmd.c_str ());
+
+  int exitcode = qh_new_qhull (dim, num_points, points.fortran_vec (),
+                               ismalloc, cmd_str, outfile, errfile);
+  if (! exitcode)
+    {
+      bool nonsimp_seen = false;
+
+      octave_idx_type nf = qh num_facets;
+
+      Matrix idx (nf, dim + 1);
+
+      facetT *facet;
+
+      octave_idx_type i = 0;
+
+      FORALLfacets
+        {
+          octave_idx_type j = 0;
+
+          if (! nonsimp_seen && ! facet->simplicial)
+            {
+              nonsimp_seen = true;
+
+              if (cmd.find ("QJ") != std::string::npos)
+                {
+                  // Should never happen with QJ.
+                  error ("convhulln: qhull failed: option 'QJ' returned non-simplicial facet");
+                  return retval;
+                }
+            }
+
+          if (dim == 3)
+            {
+              setT *vertices = qh_facet3vertex (facet);
+
+              vertexT *vertex, **vertexp;
+
+              FOREACHvertex_ (vertices)
+                idx(i, j++) = 1 + qh_pointid(vertex->point);
+
+              qh_settempfree (&vertices);
+            }
+          else
+            {
+              if (facet->toporient ^ qh_ORIENTclock)
+                {
+                  vertexT *vertex, **vertexp;
+
+                  FOREACHvertex_ (facet->vertices)
+                    idx(i, j++) = 1 + qh_pointid(vertex->point);
+                }
+              else
+                {
+                  vertexT *vertex, **vertexp;
+
+                  FOREACHvertexreverse12_ (facet->vertices)
+                    idx(i, j++) = 1 + qh_pointid(vertex->point);
+                }
+            }
+          if (j < dim)
+            warning ("convhulln: facet %d only has %d vertices", i, j);
+
+          i++;
+        }
+
+      // Remove extra dimension if all facets were simplicial.
+
+      if (! nonsimp_seen)
+        idx.resize (nf, dim, 0.0);
+
+      if (nargout == 2)
+        {
+          // Calculate volume of convex hull, taken from qhull src/geom2.c.
+
+          realT area;
+          realT dist;
+
+          FORALLfacets
+            {
+              if (! facet->normal)
+                continue;
+
+              if (facet->upperdelaunay && qh ATinfinity)
+                continue;
+
+              facet->f.area = area = qh_facetarea (facet);
+              facet->isarea = True;
+
+              if (qh DELAUNAY)
+                {
+                  if (facet->upperdelaunay == qh UPPERdelaunay)
+                    qh totarea += area;
+                }
+              else
+                {
+                  qh totarea += area;
+                  qh_distplane (qh interior_point, facet, &dist);
+                  qh totvol += -dist * area/ qh hull_dim;
+                }
+            }
+
+          retval(1) = octave_value (qh totvol);
+        }
+
+      retval(0) = idx;
+    }
+  else
+    error ("convhulln: qhull failed");
+
+  // Free memory from Qhull
+  qh_freeqhull (! qh_ALL);
+
+  int curlong, totlong;
+  qh_memfreeshort (&curlong, &totlong);
+
+  if (curlong || totlong)
+    warning ("convhulln: did not free %d bytes of long memory (%d pieces)",
+             totlong, curlong);
+
+#else
+  error ("convhulln: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+%!testif HAVE_QHULL
+%! cube = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1];
+%! [h, v] = convhulln (cube, "Qt");
+%! assert (size (h), [12 3]); 
+%! h = sortrows (sort (h, 2), [1:3]);
+%! assert (h, [1 2 4; 1 2 6; 1 4 8; 1 5 6; 1 5 8; 2 3 4; 2 3 7; 2 6 7; 3 4 7; 4 7 8; 5 6 7; 5 7 8]);
+%! assert (v, 1, 10*eps);
+%! [h2, v2] = convhulln (cube); % Test defaut option = "Qt"
+%! assert (size (h2), size (h));
+%! h2 = sortrows (sort (h2, 2), [1:3]);
+%! assert (h2, h);
+%! assert (v2, v, 10*eps);
+
+%!testif HAVE_QHULL
+%! cube = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1];
+%! [h, v] = convhulln (cube, "QJ");
+%! assert (size (h), [12 3]); 
+%! assert (sortrows (sort (h, 2), [1:3]), [1 2 4; 1 2 5; 1 4 5; 2 3 4; 2 3 6; 2 5 6; 3 4 8; 3 6 7; 3 7 8; 4 5 8; 5 6 8; 6 7 8]);
+%! assert (v, 1.0, 1e6*eps);
+
+%!testif HAVE_QHULL
+%! tetrahedron = [1 1 1;-1 -1 1;-1 1 -1;1 -1 -1];
+%! [h, v] = convhulln (tetrahedron);
+%! h = sortrows (sort (h, 2), [1 2 3]);
+%! assert (h, [1 2 3;1 2 4; 1 3 4; 2 3 4]);
+%! assert (v, 8/3, 10*eps);
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/dmperm.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,229 @@
+/*
+
+Copyright (C) 2005-2012 David Bateman
+Copyright (C) 1998-2005 Andy Adler
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+#include "oct-sparse.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "SparseQR.h"
+#include "SparseCmplxQR.h"
+
+#ifdef IDX_TYPE_LONG
+#define CXSPARSE_NAME(name) cs_dl ## name
+#else
+#define CXSPARSE_NAME(name) cs_di ## name
+#endif
+
+static RowVector
+put_int (octave_idx_type *p, octave_idx_type n)
+{
+  RowVector ret (n);
+  for (octave_idx_type i = 0; i < n; i++)
+    ret.xelem (i) = p[i] + 1;
+  return ret;
+}
+
+#if HAVE_CXSPARSE
+static octave_value_list
+dmperm_internal (bool rank, const octave_value arg, int nargout)
+{
+  octave_value_list retval;
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+  SparseMatrix m;
+  SparseComplexMatrix cm;
+  CXSPARSE_NAME () csm;
+  csm.m = nr;
+  csm.n = nc;
+  csm.x = 0;
+  csm.nz = -1;
+
+  if (arg.is_real_type ())
+    {
+      m = arg.sparse_matrix_value ();
+      csm.nzmax = m.nnz ();
+      csm.p = m.xcidx ();
+      csm.i = m.xridx ();
+    }
+  else
+    {
+      cm = arg.sparse_complex_matrix_value ();
+      csm.nzmax = cm.nnz ();
+      csm.p = cm.xcidx ();
+      csm.i = cm.xridx ();
+    }
+
+  if (!error_state)
+    {
+      if (nargout <= 1 || rank)
+        {
+#if defined(CS_VER) && (CS_VER >= 2)
+          octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
+#else
+          octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm);
+#endif
+          if (rank)
+            {
+              octave_idx_type r = 0;
+              for (octave_idx_type i = 0; i < nc; i++)
+                if (jmatch[nr+i] >= 0)
+                  r++;
+              retval(0) = static_cast<double>(r);
+            }
+          else
+            retval(0) = put_int (jmatch + nr, nc);
+          CXSPARSE_NAME (_free) (jmatch);
+        }
+      else
+        {
+#if defined(CS_VER) && (CS_VER >= 2)
+          CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm, 0);
+#else
+          CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm);
+#endif
+
+          //retval(5) = put_int (dm->rr, 5);
+          //retval(4) = put_int (dm->cc, 5);
+#if defined(CS_VER) && (CS_VER >= 2)
+          retval(3) = put_int (dm->s, dm->nb+1);
+          retval(2) = put_int (dm->r, dm->nb+1);
+          retval(1) = put_int (dm->q, nc);
+          retval(0) = put_int (dm->p, nr);
+#else
+          retval(3) = put_int (dm->S, dm->nb+1);
+          retval(2) = put_int (dm->R, dm->nb+1);
+          retval(1) = put_int (dm->Q, nc);
+          retval(0) = put_int (dm->P, nr);
+#endif
+          CXSPARSE_NAME (_dfree) (dm);
+        }
+    }
+  return retval;
+}
+#endif
+
+DEFUN_DLD (dmperm, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{p} =} dmperm (@var{S})\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{S}] =} dmperm (@var{S})\n\
+\n\
+@cindex Dulmage-Mendelsohn decomposition\n\
+Perform a Dulmage-Mendelsohn permutation of the sparse matrix @var{S}.\n\
+With a single output argument @code{dmperm} performs the row permutations\n\
+@var{p} such that @code{@var{S}(@var{p},:)} has no zero elements on the\n\
+diagonal.\n\
+\n\
+Called with two or more output arguments, returns the row and column\n\
+permutations, such that @code{@var{S}(@var{p}, @var{q})} is in block\n\
+triangular form.  The values of @var{r} and @var{S} define the boundaries\n\
+of the blocks.  If @var{S} is square then @code{@var{r} == @var{S}}.\n\
+\n\
+The method used is described in: A. Pothen & C.-J. Fan. @cite{Computing the\n\
+Block Triangular Form of a Sparse Matrix}. ACM Trans. Math. Software,\n\
+16(4):303-324, 1990.\n\
+@seealso{colamd, ccolamd}\n\
+@end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if HAVE_CXSPARSE
+  retval = dmperm_internal (false, args(0), nargout);
+#else
+  error ("dmperm: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+%!testif HAVE_CXSPARSE
+%! n = 20;
+%! a = speye (n,n);
+%! a = a(randperm (n),:);
+%! assert (a(dmperm (a),:), speye (n));
+
+%!testif HAVE_CXSPARSE
+%! n = 20;
+%! d = 0.2;
+%! a = tril (sprandn (n,n,d), -1) + speye (n,n);
+%! a = a(randperm (n), randperm (n));
+%! [p,q,r,s] = dmperm (a);
+%! assert (tril (a(p,q), -1), sparse (n, n));
+*/
+
+DEFUN_DLD (sprank, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{p} =} sprank (@var{S})\n\
+@cindex structural rank\n\
+\n\
+Calculate the structural rank of the sparse matrix @var{S}.  Note that\n\
+only the structure of the matrix is used in this calculation based on\n\
+a Dulmage-Mendelsohn permutation to block triangular form.  As such the\n\
+numerical rank of the matrix @var{S} is bounded by\n\
+@code{sprank (@var{S}) >= rank (@var{S})}.  Ignoring floating point errors\n\
+@code{sprank (@var{S}) == rank (@var{S})}.\n\
+@seealso{dmperm}\n\
+@end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if HAVE_CXSPARSE
+  retval = dmperm_internal (true, args(0), nargout);
+#else
+  error ("sprank: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/*
+%!testif HAVE_CXSPARSE
+%! assert (sprank (speye (20)), 20)
+%!testif HAVE_CXSPARSE
+%! assert (sprank ([1,0,2,0;2,0,4,0]), 2)
+
+%!error sprank (1,2)
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/eigs.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,1521 @@
+/*
+
+Copyright (C) 2005-2012 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "quit.h"
+#include "variables.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-map.h"
+#include "pager.h"
+#include "unwind-prot.h"
+
+#include "eigs-base.cc"
+
+// Global pointer for user defined function.
+static octave_function *eigs_fcn = 0;
+
+// Have we warned about imaginary values returned from user function?
+static bool warned_imaginary = false;
+
+// Is this a recursive call?
+static int call_depth = 0;
+
+ColumnVector
+eigs_func (const ColumnVector &x, int &eigs_error)
+{
+  ColumnVector retval;
+  octave_value_list args;
+  args(0) = x;
+
+  if (eigs_fcn)
+    {
+      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+        {
+          eigs_error = 1;
+          gripe_user_supplied_eval ("eigs");
+          return retval;
+        }
+
+      if (tmp.length () && tmp(0).is_defined ())
+        {
+          if (! warned_imaginary && tmp(0).is_complex_type ())
+            {
+              warning ("eigs: ignoring imaginary part returned from user-supplied function");
+              warned_imaginary = true;
+            }
+
+          retval = ColumnVector (tmp(0).vector_value ());
+
+          if (error_state)
+            {
+              eigs_error = 1;
+              gripe_user_supplied_eval ("eigs");
+            }
+        }
+      else
+        {
+          eigs_error = 1;
+          gripe_user_supplied_eval ("eigs");
+        }
+    }
+
+  return retval;
+}
+
+ComplexColumnVector
+eigs_complex_func (const ComplexColumnVector &x, int &eigs_error)
+{
+  ComplexColumnVector retval;
+  octave_value_list args;
+  args(0) = x;
+
+  if (eigs_fcn)
+    {
+      octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
+
+      if (error_state)
+        {
+          eigs_error = 1;
+          gripe_user_supplied_eval ("eigs");
+          return retval;
+        }
+
+      if (tmp.length () && tmp(0).is_defined ())
+        {
+          retval = ComplexColumnVector (tmp(0).complex_vector_value ());
+
+          if (error_state)
+            {
+              eigs_error = 1;
+              gripe_user_supplied_eval ("eigs");
+            }
+        }
+      else
+        {
+          eigs_error = 1;
+          gripe_user_supplied_eval ("eigs");
+        }
+    }
+
+  return retval;
+}
+
+DEFUN_DLD (eigs, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{d} =} eigs (@var{A})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})\n\
+Calculate a limited number of eigenvalues and eigenvectors of @var{A},\n\
+based on a selection criteria.  The number of eigenvalues and eigenvectors to\n\
+calculate is given by @var{k} and defaults to 6.\n\
+\n\
+By default, @code{eigs} solve the equation\n\
+@tex\n\
+$A \\nu = \\lambda \\nu$,\n\
+@end tex\n\
+@ifinfo\n\
+@code{A * v = lambda * v},\n\
+@end ifinfo\n\
+where\n\
+@tex\n\
+$\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\
+@end tex\n\
+@ifinfo\n\
+@code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\
+@end ifinfo\n\
+is the corresponding eigenvector.  If given the positive definite matrix\n\
+@var{B} then @code{eigs} solves the general eigenvalue equation\n\
+@tex\n\
+$A \\nu = \\lambda B \\nu$.\n\
+@end tex\n\
+@ifinfo\n\
+@code{A * v = lambda * B * v}.\n\
+@end ifinfo\n\
+\n\
+The argument @var{sigma} determines which eigenvalues are returned.\n\
+@var{sigma} can be either a scalar or a string.  When @var{sigma} is a\n\
+scalar, the @var{k} eigenvalues closest to @var{sigma} are returned.  If\n\
+@var{sigma} is a string, it must have one of the following values.\n\
+\n\
+@table @asis\n\
+@item \"lm\"\n\
+Largest Magnitude (default).\n\
+\n\
+@item \"sm\"\n\
+Smallest Magnitude.\n\
+\n\
+@item \"la\"\n\
+Largest Algebraic (valid only for real symmetric problems).\n\
+\n\
+@item \"sa\"\n\
+Smallest Algebraic (valid only for real symmetric problems).\n\
+\n\
+@item \"be\"\n\
+Both Ends, with one more from the high-end if @var{k} is odd (valid only for\n\
+real symmetric problems).\n\
+\n\
+@item \"lr\"\n\
+Largest Real part (valid only for complex or unsymmetric problems).\n\
+\n\
+@item \"sr\"\n\
+Smallest Real part (valid only for complex or unsymmetric problems).\n\
+\n\
+@item \"li\"\n\
+Largest Imaginary part (valid only for complex or unsymmetric problems).\n\
+\n\
+@item \"si\"\n\
+Smallest Imaginary part (valid only for complex or unsymmetric problems).\n\
+@end table\n\
+\n\
+If @var{opts} is given, it is a structure defining possible options that\n\
+@code{eigs} should use.  The fields of the @var{opts} structure are:\n\
+\n\
+@table @code\n\
+@item issym\n\
+If @var{af} is given, then flags whether the function @var{af} defines a\n\
+symmetric problem.  It is ignored if @var{A} is given.  The default is false.\n\
+\n\
+@item isreal\n\
+If @var{af} is given, then flags whether the function @var{af} defines a\n\
+real problem.  It is ignored if @var{A} is given.  The default is true.\n\
+\n\
+@item tol\n\
+Defines the required convergence tolerance, calculated as\n\
+@code{tol * norm (A)}.  The default is @code{eps}.\n\
+\n\
+@item maxit\n\
+The maximum number of iterations.  The default is 300.\n\
+\n\
+@item p\n\
+The number of Lanzcos basis vectors to use.  More vectors will result in\n\
+faster convergence, but a greater use of memory.  The optimal value of\n\
+@code{p} is problem dependent and should be in the range @var{k} to @var{n}.\n\
+The default value is @code{2 * @var{k}}.\n\
+\n\
+@item v0\n\
+The starting vector for the algorithm.  An initial vector close to the\n\
+final vector will speed up convergence.  The default is for @sc{arpack}\n\
+to randomly generate a starting vector.  If specified, @code{v0} must be\n\
+an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}\n\
+\n\
+@item disp\n\
+The level of diagnostic printout (0|1|2).  If @code{disp} is 0 then\n\
+diagnostics are disabled.  The default value is 0.\n\
+\n\
+@item cholB\n\
+Flag if @code{chol (@var{B})} is passed rather than @var{B}.  The default is\n\
+false.\n\
+\n\
+@item permB\n\
+The permutation vector of the Cholesky@tie{}factorization of @var{B} if\n\
+@code{cholB} is true.  That is @code{chol (@var{B}(permB, permB))}.  The\n\
+default is @code{1:@var{n}}.\n\
+\n\
+@end table\n\
+\n\
+It is also possible to represent @var{A} by a function denoted @var{af}.\n\
+@var{af} must be followed by a scalar argument @var{n} defining the length\n\
+of the vector argument accepted by @var{af}.  @var{af} can be\n\
+a function handle, an inline function, or a string.  When @var{af} is a\n\
+string it holds the name of the function to use.\n\
+\n\
+@var{af} is a function of the form @code{y = af (x)}\n\
+where the required return value of @var{af} is determined by\n\
+the value of @var{sigma}.  The four possible forms are\n\
+\n\
+@table @code\n\
+@item A * x\n\
+if @var{sigma} is not given or is a string other than \"sm\".\n\
+\n\
+@item A \\ x\n\
+if @var{sigma} is 0 or \"sm\".\n\
+\n\
+@item (A - sigma * I) \\ x\n\
+for the standard eigenvalue problem, where @code{I} is the identity matrix of\n\
+the same size as @var{A}.\n\
+\n\
+@item (A - sigma * B) \\ x\n\
+for the general eigenvalue problem.\n\
+@end table\n\
+\n\
+The return arguments of @code{eigs} depend on the number of return arguments\n\
+requested.  With a single return argument, a vector @var{d} of length @var{k}\n\
+is returned containing the @var{k} eigenvalues that have been found.  With\n\
+two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns\n\
+are the @var{k} eigenvectors corresponding to the returned eigenvalues.  The\n\
+eigenvalues themselves are returned in @var{d} in the form of a\n\
+@var{n}-by-@var{k} matrix, where the elements on the diagonal are the\n\
+eigenvalues.\n\
+\n\
+Given a third return argument @var{flag}, @code{eigs} returns the status\n\
+of the convergence.  If @var{flag} is 0 then all eigenvalues have converged.\n\
+Any other value indicates a failure to converge.\n\
+\n\
+This function is based on the @sc{arpack} package, written by R. Lehoucq,\n\
+K. Maschhoff, D. Sorensen, and C. Yang.  For more information see\n\
+@url{http://www.caam.rice.edu/software/ARPACK/}.\n\
+\n\
+@seealso{eig, svds}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+#ifdef HAVE_ARPACK
+  int nargin = args.length ();
+  std::string fcn_name;
+  octave_idx_type n = 0;
+  octave_idx_type k = 6;
+  Complex sigma = 0.;
+  double sigmar, sigmai;
+  bool have_sigma = false;
+  std::string typ = "LM";
+  Matrix amm, bmm, bmt;
+  ComplexMatrix acm, bcm, bct;
+  SparseMatrix asmm, bsmm, bsmt;
+  SparseComplexMatrix ascm, bscm, bsct;
+  int b_arg = 0;
+  bool have_b = false;
+  bool have_a_fun = false;
+  bool a_is_complex = false;
+  bool b_is_complex = false;
+  bool symmetric = false;
+  bool sym_tested = false;
+  bool cholB = false;
+  bool a_is_sparse = false;
+  ColumnVector permB;
+  int arg_offset = 0;
+  double tol = DBL_EPSILON;
+  int maxit = 300;
+  int disp = 0;
+  octave_idx_type p = -1;
+  ColumnVector resid;
+  ComplexColumnVector cresid;
+  octave_idx_type info = 1;
+
+  warned_imaginary = false;
+
+  unwind_protect frame;
+
+  frame.protect_var (call_depth);
+  call_depth++;
+
+  if (call_depth > 1)
+    {
+      error ("eigs: invalid recursive call");
+      if (fcn_name.length ())
+        clear_function (fcn_name);
+      return retval;
+    }
+
+  if (nargin == 0)
+    print_usage ();
+  else if (args(0).is_function_handle () || args(0).is_inline_function ()
+           || args(0).is_string ())
+    {
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          std::string fname = "function y = ";
+          fcn_name = unique_symbol_name ("__eigs_fcn_");
+          fname.append (fcn_name);
+          fname.append ("(x) y = ");
+          eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname,
+                                       "; endfunction");
+        }
+      else
+        eigs_fcn = args(0).function_value ();
+
+      if (!eigs_fcn)
+        {
+          error ("eigs: unknown function");
+          return retval;
+        }
+
+      if (nargin < 2)
+        {
+          error ("eigs: incorrect number of arguments");
+          return retval;
+        }
+      else
+        {
+          n = args(1).nint_value ();
+          arg_offset = 1;
+          have_a_fun = true;
+        }
+    }
+  else
+    {
+      if (args(0).is_complex_type ())
+        {
+          if (args(0).is_sparse_type ())
+            {
+              ascm = (args(0).sparse_complex_matrix_value ());
+              a_is_sparse = true;
+            }
+          else
+            acm = (args(0).complex_matrix_value ());
+          a_is_complex = true;
+          symmetric = false; // ARPACK doesn't special case complex symmetric
+          sym_tested = true;
+        }
+      else
+        {
+          if (args(0).is_sparse_type ())
+            {
+              asmm = (args(0).sparse_matrix_value ());
+              a_is_sparse = true;
+            }
+          else
+            {
+              amm = (args(0).matrix_value ());
+            }
+        }
+
+    }
+
+  // Note hold off reading B till later to avoid issues of double
+  // copies of the matrix if B is full/real while A is complex.
+  if (!error_state && nargin > 1 + arg_offset &&
+      !(args(1 + arg_offset).is_real_scalar ()))
+    {
+      if (args(1+arg_offset).is_complex_type ())
+        {
+          b_arg = 1+arg_offset;
+          have_b = true;
+          b_is_complex = true;
+          arg_offset++;
+        }
+      else
+        {
+          b_arg = 1+arg_offset;
+          have_b = true;
+          arg_offset++;
+        }
+    }
+
+  if (!error_state && nargin > (1+arg_offset))
+    k = args(1+arg_offset).nint_value ();
+
+  if (!error_state && nargin > (2+arg_offset))
+    {
+      if (args(2+arg_offset).is_string ())
+        {
+          typ = args(2+arg_offset).string_value ();
+
+          // Use STL function to convert to upper case
+          transform (typ.begin (), typ.end (), typ.begin (), toupper);
+
+          sigma = 0.;
+        }
+      else
+        {
+          sigma = args(2+arg_offset).complex_value ();
+
+          if (! error_state)
+            have_sigma = true;
+          else
+            {
+              error ("eigs: SIGMA must be a scalar or a string");
+              return retval;
+            }
+        }
+    }
+
+  sigmar = std::real (sigma);
+  sigmai = std::imag (sigma);
+
+  if (!error_state && nargin > (3+arg_offset))
+    {
+      if (args(3+arg_offset).is_map ())
+        {
+          octave_scalar_map map = args(3+arg_offset).scalar_map_value ();
+
+          if (! error_state)
+            {
+              octave_value tmp;
+
+              // issym is ignored for complex matrix inputs
+              tmp = map.getfield ("issym");
+              if (tmp.is_defined () && !sym_tested)
+                {
+                  symmetric = tmp.double_value () != 0.;
+                  sym_tested = true;
+                }
+
+              // isreal is ignored if A is not a function
+              tmp = map.getfield ("isreal");
+              if (tmp.is_defined () && have_a_fun)
+                a_is_complex = ! (tmp.double_value () != 0.);
+
+              tmp = map.getfield ("tol");
+              if (tmp.is_defined ())
+                tol = tmp.double_value ();
+
+              tmp = map.getfield ("maxit");
+              if (tmp.is_defined ())
+                maxit = tmp.nint_value ();
+
+              tmp = map.getfield ("p");
+              if (tmp.is_defined ())
+                p = tmp.nint_value ();
+
+              tmp = map.getfield ("v0");
+              if (tmp.is_defined ())
+                {
+                  if (a_is_complex || b_is_complex)
+                    cresid = ComplexColumnVector (tmp.complex_vector_value ());
+                  else
+                    resid = ColumnVector (tmp.vector_value ());
+                }
+
+              tmp = map.getfield ("disp");
+              if (tmp.is_defined ())
+                disp = tmp.nint_value ();
+
+              tmp = map.getfield ("cholB");
+              if (tmp.is_defined ())
+                cholB = tmp.double_value () != 0.;
+
+              tmp = map.getfield ("permB");
+              if (tmp.is_defined ())
+                permB = ColumnVector (tmp.vector_value ()) - 1.0;
+            }
+          else
+            {
+              error ("eigs: OPTS argument must be a scalar structure");
+              return retval;
+            }
+        }
+      else
+        {
+          error ("eigs: OPTS argument must be a structure");
+          return retval;
+        }
+    }
+
+  if (nargin > (4+arg_offset))
+    {
+      error ("eigs: incorrect number of arguments");
+      return retval;
+    }
+
+  // Test undeclared (no issym) matrix inputs for symmetry
+  if (!sym_tested && !have_a_fun)
+    {
+      if (a_is_sparse)
+        symmetric = asmm.is_symmetric ();
+      else
+        symmetric = amm.is_symmetric ();
+    }
+
+  if (have_b)
+    {
+      if (a_is_complex || b_is_complex)
+        {
+          if (a_is_sparse)
+            bscm = args(b_arg).sparse_complex_matrix_value ();
+          else
+            bcm = args(b_arg).complex_matrix_value ();
+        }
+      else
+        {
+          if (a_is_sparse)
+            bsmm = args(b_arg).sparse_matrix_value ();
+          else
+            bmm = args(b_arg).matrix_value ();
+        }
+    }
+
+  // Mode 1 for SM mode seems unstable for some reason.
+  // Use Mode 3 instead, with sigma = 0.
+  if (!error_state && !have_sigma && typ == "SM")
+    have_sigma = true;
+
+  if (!error_state)
+    {
+      octave_idx_type nconv;
+      if (a_is_complex || b_is_complex)
+        {
+          ComplexMatrix eig_vec;
+          ComplexColumnVector eig_val;
+
+
+          if (have_a_fun)
+            nconv = EigsComplexNonSymmetricFunc
+              (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val,
+               cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+          else if (have_sigma)
+            {
+              if (a_is_sparse)
+                nconv = EigsComplexNonSymmetricMatrixShift
+                  (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB,
+                   cresid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                   maxit);
+              else
+                nconv = EigsComplexNonSymmetricMatrixShift
+                  (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
+                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+            }
+          else
+            {
+              if (a_is_sparse)
+                nconv = EigsComplexNonSymmetricMatrix
+                  (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid,
+                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+              else
+                nconv = EigsComplexNonSymmetricMatrix
+                  (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
+                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+            }
+
+          if (nargout < 2)
+            retval(0) = eig_val;
+          else
+            {
+              retval(2) = double (info);
+              retval(1) = ComplexDiagMatrix (eig_val);
+              retval(0) = eig_vec;
+            }
+        }
+      else if (sigmai != 0.)
+        {
+          // Promote real problem to a complex one.
+          ComplexMatrix eig_vec;
+          ComplexColumnVector eig_val;
+
+          if (have_a_fun)
+            nconv = EigsComplexNonSymmetricFunc
+              (eigs_complex_func, n, typ,  sigma, k, p, info, eig_vec, eig_val,
+               cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+          else
+            {
+              if (a_is_sparse)
+                nconv = EigsComplexNonSymmetricMatrixShift
+                  (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec,
+                   eig_val, SparseComplexMatrix (bsmm), permB, cresid,
+                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+              else
+                nconv = EigsComplexNonSymmetricMatrixShift
+                  (ComplexMatrix (amm), sigma, k, p, info, eig_vec,
+                   eig_val, ComplexMatrix (bmm), permB, cresid,
+                   octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
+            }
+
+          if (nargout < 2)
+            retval(0) = eig_val;
+          else
+            {
+              retval(2) = double (info);
+              retval(1) = ComplexDiagMatrix (eig_val);
+              retval(0) = eig_vec;
+            }
+        }
+      else
+        {
+          if (symmetric)
+            {
+              Matrix eig_vec;
+              ColumnVector eig_val;
+
+              if (have_a_fun)
+                nconv = EigsRealSymmetricFunc
+                  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
+                   resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                   maxit);
+              else if (have_sigma)
+                {
+                  if (a_is_sparse)
+                    nconv = EigsRealSymmetricMatrixShift
+                      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                  else
+                    nconv = EigsRealSymmetricMatrixShift
+                      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                }
+              else
+                {
+                  if (a_is_sparse)
+                    nconv = EigsRealSymmetricMatrix
+                      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                  else
+                    nconv = EigsRealSymmetricMatrix
+                      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                }
+
+              if (nargout < 2)
+                retval(0) = eig_val;
+              else
+                {
+                  retval(2) = double (info);
+                  retval(1) = DiagMatrix (eig_val);
+                  retval(0) = eig_vec;
+                }
+            }
+          else
+            {
+              ComplexMatrix eig_vec;
+              ComplexColumnVector eig_val;
+
+              if (have_a_fun)
+                nconv = EigsRealNonSymmetricFunc
+                  (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
+                   resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                   maxit);
+              else if (have_sigma)
+                {
+                  if (a_is_sparse)
+                    nconv = EigsRealNonSymmetricMatrixShift
+                      (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                  else
+                    nconv = EigsRealNonSymmetricMatrixShift
+                      (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                }
+              else
+                {
+                  if (a_is_sparse)
+                    nconv = EigsRealNonSymmetricMatrix
+                      (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                  else
+                    nconv = EigsRealNonSymmetricMatrix
+                      (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
+                       resid, octave_stdout, tol, (nargout > 1), cholB, disp,
+                       maxit);
+                }
+
+              if (nargout < 2)
+                retval(0) = eig_val;
+              else
+                {
+                  retval(2) = double (info);
+                  retval(1) = ComplexDiagMatrix (eig_val);
+                  retval(0) = eig_vec;
+                }
+            }
+        }
+
+      if (nconv <= 0)
+        warning ("eigs: None of the %d requested eigenvalues converged", k);
+      else if (nconv < k)
+        warning ("eigs: Only %d of the %d requested eigenvalues converged",
+                 nconv, k);
+    }
+
+  if (! fcn_name.empty ())
+    clear_function (fcn_name);
+#else
+  error ("eigs: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+/* #### SPARSE MATRIX VERSIONS #### */
+
+/*
+## Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]);
+%! d0 = eig (A);
+%! d2 = sort (d0);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); # initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (d1, d0(end:-1:(end-k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "la");
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sa");
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "be");
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, "be");
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! AA = speye (10);
+%! fn = @(x) AA * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! assert (eigs (fn, 10, AA, 3, "lm", opts), [1; 1; 1], 10*eps);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "la");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sa");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "be");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
+
+/*
+## Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (d0));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
+
+/*
+## Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]);
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
+
+/* #### FULL MATRIX VERSIONS #### */
+
+/*
+## Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]));
+%! d0 = eig (A);
+%! d2 = sort (d0);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (d1, d0(end:-1:(end-k)),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "la");
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sa");
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "be");
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, "be");
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "la");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sa");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "be");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
+
+/*
+## Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]));
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (d0));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
+
+/*
+## Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]));
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/fftw.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,269 @@
+/*
+
+Copyright (C) 2006-2012 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "oct-fftw.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "ov.h"
+
+DEFUN_DLD (fftw, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{method} =} fftw (\"planner\")\n\
+@deftypefnx {Loadable Function} {} fftw (\"planner\", @var{method})\n\
+@deftypefnx {Loadable Function} {@var{wisdom} =} fftw (\"dwisdom\")\n\
+@deftypefnx {Loadable Function} {} fftw (\"dwisdom\", @var{wisdom})\n\
+\n\
+Manage @sc{fftw} wisdom data.  Wisdom data can be used to significantly\n\
+accelerate the calculation of the FFTs, but implies an initial cost\n\
+in its calculation.  When the @sc{fftw} libraries are initialized, they read\n\
+a system wide wisdom file (typically in @file{/etc/fftw/wisdom}), allowing\n\
+wisdom to be shared between applications other than Octave.  Alternatively,\n\
+the @code{fftw} function can be used to import wisdom.  For example,\n\
+\n\
+@example\n\
+@var{wisdom} = fftw (\"dwisdom\")\n\
+@end example\n\
+\n\
+@noindent\n\
+will save the existing wisdom used by Octave to the string @var{wisdom}.\n\
+This string can then be saved to a file and restored using the @code{save}\n\
+and @code{load} commands respectively.  This existing wisdom can be\n\
+reimported as follows\n\
+\n\
+@example\n\
+fftw (\"dwisdom\", @var{wisdom})\n\
+@end example\n\
+\n\
+If @var{wisdom} is an empty matrix, then the wisdom used is cleared.\n\
+\n\
+During the calculation of Fourier transforms further wisdom is generated.\n\
+The fashion in which this wisdom is generated is also controlled by\n\
+the @code{fftw} function.  There are five different manners in which the\n\
+wisdom can be treated:\n\
+\n\
+@table @asis\n\
+@item \"estimate\"\n\
+Specifies that no run-time measurement of the optimal means of\n\
+calculating a particular is performed, and a simple heuristic is used\n\
+to pick a (probably sub-optimal) plan.  The advantage of this method is\n\
+that there is little or no overhead in the generation of the plan, which\n\
+is appropriate for a Fourier transform that will be calculated once.\n\
+\n\
+@item \"measure\"\n\
+In this case a range of algorithms to perform the transform is considered\n\
+and the best is selected based on their execution time.\n\
+\n\
+@item \"patient\"\n\
+Similar to \"measure\", but a wider range of algorithms is considered.\n\
+\n\
+@item \"exhaustive\"\n\
+Like \"measure\", but all possible algorithms that may be used to\n\
+treat the transform are considered.\n\
+\n\
+@item \"hybrid\"\n\
+As run-time measurement of the algorithm can be expensive, this is a\n\
+compromise where \"measure\" is used for transforms up to the size of 8192\n\
+and beyond that the \"estimate\" method is used.\n\
+@end table\n\
+\n\
+The default method is \"estimate\".  The current method can\n\
+be queried with\n\
+\n\
+@example\n\
+@var{method} = fftw (\"planner\")\n\
+@end example\n\
+\n\
+@noindent\n\
+or set by using\n\
+\n\
+@example\n\
+fftw (\"planner\", @var{method})\n\
+@end example\n\
+\n\
+Note that calculated wisdom will be lost when restarting Octave.  However,\n\
+the wisdom data can be reloaded if it is saved to a file as described\n\
+above.  Saved wisdom files should not be used on different platforms since\n\
+they will not be efficient and the point of calculating the wisdom is lost.\n\
+@seealso{fft, ifft, fft2, ifft2, fftn, ifftn}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#if defined (HAVE_FFTW)
+  if (args(0).is_string ())
+    {
+      std::string arg0 = args(0).string_value ();
+
+      if (!error_state)
+        {
+          // Use STL function to convert to lower case
+          std::transform (arg0.begin (), arg0.end (), arg0.begin (), tolower);
+
+          if (nargin == 2)
+            {
+              std::string arg1 = args(1).string_value ();
+              if (!error_state)
+                {
+                  if (arg0 == "planner")
+                    {
+                      std::transform (arg1.begin (), arg1.end (),
+                                      arg1.begin (), tolower);
+                      octave_fftw_planner::FftwMethod meth
+                        = octave_fftw_planner::UNKNOWN;
+                      octave_float_fftw_planner::FftwMethod methf
+                        = octave_float_fftw_planner::UNKNOWN;
+
+                      if (arg1 == "estimate")
+                        {
+                          meth = octave_fftw_planner::ESTIMATE;
+                          methf = octave_float_fftw_planner::ESTIMATE;
+                        }
+                      else if (arg1 == "measure")
+                        {
+                          meth = octave_fftw_planner::MEASURE;
+                          methf = octave_float_fftw_planner::MEASURE;
+                        }
+                      else if (arg1 == "patient")
+                        {
+                          meth = octave_fftw_planner::PATIENT;
+                          methf = octave_float_fftw_planner::PATIENT;
+                        }
+                      else if (arg1 == "exhaustive")
+                        {
+                          meth = octave_fftw_planner::EXHAUSTIVE;
+                          methf = octave_float_fftw_planner::EXHAUSTIVE;
+                        }
+                      else if (arg1 == "hybrid")
+                        {
+                          meth = octave_fftw_planner::HYBRID;
+                          methf = octave_float_fftw_planner::HYBRID;
+                        }
+                      else
+                        error ("unrecognized planner METHOD");
+
+                      if (!error_state)
+                        {
+                          meth = octave_fftw_planner::method (meth);
+                          octave_float_fftw_planner::method (methf);
+
+                          if (meth == octave_fftw_planner::MEASURE)
+                            retval = octave_value ("measure");
+                          else if (meth == octave_fftw_planner::PATIENT)
+                            retval = octave_value ("patient");
+                          else if (meth == octave_fftw_planner::EXHAUSTIVE)
+                            retval = octave_value ("exhaustive");
+                          else if (meth == octave_fftw_planner::HYBRID)
+                            retval = octave_value ("hybrid");
+                          else
+                            retval = octave_value ("estimate");
+                        }
+                    }
+                  else if (arg0 == "dwisdom")
+                    {
+                      char *str = fftw_export_wisdom_to_string ();
+
+                      if (arg1.length () < 1)
+                        fftw_forget_wisdom ();
+                      else if (! fftw_import_wisdom_from_string (arg1.c_str ()))
+                        error ("could not import supplied WISDOM");
+
+                      if (!error_state)
+                        retval = octave_value (std::string (str));
+
+                      free (str);
+                    }
+                  else if (arg0 == "swisdom")
+                    {
+                      char *str = fftwf_export_wisdom_to_string ();
+
+                      if (arg1.length () < 1)
+                        fftwf_forget_wisdom ();
+                      else if (! fftwf_import_wisdom_from_string (arg1.c_str ()))
+                        error ("could not import supplied WISDOM");
+
+                      if (!error_state)
+                        retval = octave_value (std::string (str));
+
+                      free (str);
+                    }
+                  else
+                    error ("unrecognized argument");
+                }
+            }
+          else
+            {
+              if (arg0 == "planner")
+                {
+                  octave_fftw_planner::FftwMethod meth =
+                    octave_fftw_planner::method ();
+
+                  if (meth == octave_fftw_planner::MEASURE)
+                    retval = octave_value ("measure");
+                  else if (meth == octave_fftw_planner::PATIENT)
+                    retval = octave_value ("patient");
+                  else if (meth == octave_fftw_planner::EXHAUSTIVE)
+                    retval = octave_value ("exhaustive");
+                  else if (meth == octave_fftw_planner::HYBRID)
+                    retval = octave_value ("hybrid");
+                  else
+                    retval = octave_value ("estimate");
+                }
+              else if (arg0 == "dwisdom")
+                {
+                  char *str = fftw_export_wisdom_to_string ();
+                  retval = octave_value (std::string (str));
+                  free (str);
+                }
+              else if (arg0 == "swisdom")
+                {
+                  char *str = fftwf_export_wisdom_to_string ();
+                  retval = octave_value (std::string (str));
+                  free (str);
+                }
+              else
+                error ("unrecognized argument");
+            }
+        }
+    }
+#else
+
+  warning ("fftw: this copy of Octave was not configured to use the FFTW3 planner");
+
+#endif
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/module-files	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,22 @@
+# FILE|CPPFLAGS|LDFLAGS|LIBRARIES
+__delaunayn__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
+__dsearchn__.cc
+__fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
+__glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS)
+__init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
+__init_gnuplot__.cc
+__magick_read__.cc|$(MAGICK_CPPFLAGS)|$(MAGICK_LDFLAGS)|$(MAGICK_LIBS)
+__voronoi__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
+amd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+ccolamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+chol.cc
+colamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+convhulln.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
+dmperm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+eigs.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)
+fftw.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS)
+qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS)
+symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
+tsearch.cc
+urlwrite.cc|$(CURL_CPPFLAGS)|$(CURL_LDFLAGS)|$(CURL_LIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/oct-qhull.h	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 2012 John W. Eaton
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_oct_qhull_h)
+#define octave_oct_qhull_h 1
+
+#include <cstdio>
+
+extern "C" {
+
+#if defined (HAVE_LIBQHULL_LIBQHULL_H)
+# include <libqhull/libqhull.h>
+# include <libqhull/qset.h>
+# include <libqhull/geom.h>
+# include <libqhull/poly.h>
+# include <libqhull/io.h>
+#elif defined (HAVE_QHULL_LIBQHULL_H) || defined (HAVE_QHULL_QHULL_H)
+# if defined (HAVE_QHULL_LIBQHULL_H)
+#  include <qhull/libqhull.h>
+# else
+#  include <qhull/qhull.h>
+# endif
+# include <qhull/qset.h>
+# include <qhull/geom.h>
+# include <qhull/poly.h>
+# include <qhull/io.h>
+#elif defined (HAVE_LIBQHULL_H) || defined (HAVE_QHULL_H)
+# if defined (HAVE_LIBQHULL_H)
+#  include <libqhull.h>
+# else
+#  include <qhull.h>
+# endif
+# include <qset.h>
+# include <geom.h>
+# include <poly.h>
+# include <io.h>
+#endif
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/qr.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,1598 @@
+/*
+
+Copyright (C) 1996-2012 John W. Eaton
+Copyright (C) 2008-2009 Jaroslav Hajek
+Copyright (C) 2008-2009 VZLU Prague
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CmplxQR.h"
+#include "CmplxQRP.h"
+#include "dbleQR.h"
+#include "dbleQRP.h"
+#include "fCmplxQR.h"
+#include "fCmplxQRP.h"
+#include "floatQR.h"
+#include "floatQRP.h"
+#include "SparseQR.h"
+#include "SparseCmplxQR.h"
+
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+template <class MT>
+static octave_value
+get_qr_r (const base_qr<MT>& fact)
+{
+  MT R = fact.R ();
+  if (R.is_square () && fact.regular ())
+    return octave_value (R, MatrixType (MatrixType::Upper));
+  else
+    return R;
+}
+
+// [Q, R] = qr (X):      form Q unitary and R upper triangular such
+//                        that Q * R = X
+//
+// [Q, R] = qr (X, 0):    form the economy decomposition such that if X is
+//                        m by n then only the first n columns of Q are
+//                        computed.
+//
+// [Q, R, P] = qr (X):    form QRP factorization of X where
+//                        P is a permutation matrix such that
+//                        A * P = Q * R
+//
+// [Q, R, P] = qr (X, 0): form the economy decomposition with
+//                        permutation vector P such that Q * R = X (:, P)
+//
+// qr (X) alone returns the output of the LAPACK routine dgeqrf, such
+// that R = triu (qr (X))
+
+DEFUN_DLD (qr, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A})\n\
+@deftypefnx {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A}, '0')\n\
+@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B})\n\
+@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B}, '0')\n\
+@cindex QR factorization\n\
+Compute the QR@tie{}factorization of @var{A}, using standard @sc{lapack}\n\
+subroutines.  For example, given the matrix @code{@var{A} = [1, 2; 3, 4]},\n\
+\n\
+@example\n\
+[@var{Q}, @var{R}] = qr (@var{A})\n\
+@end example\n\
+\n\
+@noindent\n\
+returns\n\
+\n\
+@example\n\
+@group\n\
+@var{Q} =\n\
+\n\
+  -0.31623  -0.94868\n\
+  -0.94868   0.31623\n\
+\n\
+@var{R} =\n\
+\n\
+  -3.16228  -4.42719\n\
+   0.00000  -0.63246\n\
+@end group\n\
+@end example\n\
+\n\
+The @code{qr} factorization has applications in the solution of least\n\
+squares problems\n\
+@tex\n\
+$$\n\
+\\min_x \\left\\Vert A x - b \\right\\Vert_2\n\
+$$\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+min norm(A x - b)\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+for overdetermined systems of equations (i.e.,\n\
+@tex\n\
+$A$\n\
+@end tex\n\
+@ifnottex\n\
+@var{A}\n\
+@end ifnottex\n\
+ is a tall, thin matrix).  The QR@tie{}factorization is\n\
+@tex\n\
+$QR = A$ where $Q$ is an orthogonal matrix and $R$ is upper triangular.\n\
+@end tex\n\
+@ifnottex\n\
+@code{@var{Q} * @var{Q} = @var{A}} where @var{Q} is an orthogonal matrix and\n\
+@var{R} is upper triangular.\n\
+@end ifnottex\n\
+\n\
+If given a second argument of '0', @code{qr} returns an economy-sized\n\
+QR@tie{}factorization, omitting zero rows of @var{R} and the corresponding\n\
+columns of @var{Q}.\n\
+\n\
+If the matrix @var{A} is full, the permuted QR@tie{}factorization\n\
+@code{[@var{Q}, @var{R}, @var{P}] = qr (@var{A})} forms the\n\
+QR@tie{}factorization such that the diagonal entries of @var{R} are\n\
+decreasing in magnitude order.  For example, given the matrix @code{a = [1,\n\
+2; 3, 4]},\n\
+\n\
+@example\n\
+[@var{Q}, @var{R}, @var{P}] = qr (@var{A})\n\
+@end example\n\
+\n\
+@noindent\n\
+returns\n\
+\n\
+@example\n\
+@group\n\
+@var{Q} =\n\
+\n\
+  -0.44721  -0.89443\n\
+  -0.89443   0.44721\n\
+\n\
+@var{R} =\n\
+\n\
+  -4.47214  -3.13050\n\
+   0.00000   0.44721\n\
+\n\
+@var{P} =\n\
+\n\
+   0  1\n\
+   1  0\n\
+@end group\n\
+@end example\n\
+\n\
+The permuted @code{qr} factorization @code{[@var{Q}, @var{R}, @var{P}] = qr\n\
+(@var{A})} factorization allows the construction of an orthogonal basis of\n\
+@code{span (A)}.\n\
+\n\
+If the matrix @var{A} is sparse, then compute the sparse\n\
+QR@tie{}factorization of @var{A}, using @sc{CSparse}.  As the matrix @var{Q}\n\
+is in general a full matrix, this function returns the @var{Q}-less\n\
+factorization @var{R} of @var{A}, such that @code{@var{R} = chol (@var{A}' *\n\
+@var{A})}.\n\
+\n\
+If the final argument is the scalar @code{0} and the number of rows is\n\
+larger than the number of columns, then an economy factorization is\n\
+returned.  That is @var{R} will have only @code{size (@var{A},1)} rows.\n\
+\n\
+If an additional matrix @var{B} is supplied, then @code{qr} returns\n\
+@var{C}, where @code{@var{C} = @var{Q}' * @var{B}}.  This allows the\n\
+least squares approximation of @code{@var{A} \\ @var{B}} to be calculated\n\
+as\n\
+\n\
+@example\n\
+@group\n\
+[@var{C}, @var{R}] = qr (@var{A}, @var{B})\n\
+x = @var{R} \\ @var{C}\n\
+@end group\n\
+@end example\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > (args(0).is_sparse_type () ? 3 : 2))
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  int arg_is_empty = empty_arg ("qr", arg.rows (), arg.columns ());
+
+  if (arg_is_empty < 0)
+    return retval;
+
+  if (arg.is_sparse_type ())
+    {
+      bool economy = false;
+      bool is_cmplx = false;
+      int have_b = 0;
+
+      if (arg.is_complex_type ())
+        is_cmplx = true;
+      if (nargin > 1)
+        {
+          have_b = 1;
+          if (args(nargin-1).is_scalar_type ())
+            {
+              int val = args(nargin-1).int_value ();
+              if (val == 0)
+                {
+                  economy = true;
+                  have_b = (nargin > 2 ? 2 : 0);
+                }
+            }
+          if (have_b > 0 && args(have_b).is_complex_type ())
+            is_cmplx = true;
+        }
+
+      if (!error_state)
+        {
+          if (have_b && nargout < 2)
+            error ("qr: incorrect number of output arguments");
+          else if (is_cmplx)
+            {
+              SparseComplexQR q (arg.sparse_complex_matrix_value ());
+              if (!error_state)
+                {
+                  if (have_b > 0)
+                    {
+                      retval(1) = q.R (economy);
+                      retval(0) = q.C (args(have_b).complex_matrix_value ());
+                      if (arg.rows () < arg.columns ())
+                        warning ("qr: non minimum norm solution for under-determined problem");
+                    }
+                  else if (nargout > 1)
+                    {
+                      retval(1) = q.R (economy);
+                      retval(0) = q.Q ();
+                    }
+                  else
+                    retval(0) = q.R (economy);
+                }
+            }
+          else
+            {
+              SparseQR q (arg.sparse_matrix_value ());
+              if (!error_state)
+                {
+                  if (have_b > 0)
+                    {
+                      retval(1) = q.R (economy);
+                      retval(0) = q.C (args(have_b).matrix_value ());
+                      if (args(0).rows () < args(0).columns ())
+                        warning ("qr: non minimum norm solution for under-determined problem");
+                    }
+                  else if (nargout > 1)
+                    {
+                      retval(1) = q.R (economy);
+                      retval(0) = q.Q ();
+                    }
+                  else
+                    retval(0) = q.R (economy);
+                }
+            }
+        }
+    }
+  else
+    {
+      QR::type type = (nargout == 0 || nargout == 1) ? QR::raw
+        : (nargin == 2 ? QR::economy : QR::std);
+
+      if (arg.is_single_type ())
+        {
+          if (arg.is_real_type ())
+            {
+              FloatMatrix m = arg.float_matrix_value ();
+
+              if (! error_state)
+                {
+                  switch (nargout)
+                    {
+                    case 0:
+                    case 1:
+                      {
+                        FloatQR fact (m, type);
+                        retval(0) = fact.R ();
+                      }
+                      break;
+
+                    case 2:
+                      {
+                        FloatQR fact (m, type);
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+
+                    default:
+                      {
+                        FloatQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+                    }
+                }
+            }
+          else if (arg.is_complex_type ())
+            {
+              FloatComplexMatrix m = arg.float_complex_matrix_value ();
+
+              if (! error_state)
+                {
+                  switch (nargout)
+                    {
+                    case 0:
+                    case 1:
+                      {
+                        FloatComplexQR fact (m, type);
+                        retval(0) = fact.R ();
+                      }
+                      break;
+
+                    case 2:
+                      {
+                        FloatComplexQR fact (m, type);
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+
+                    default:
+                      {
+                        FloatComplexQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+                    }
+                }
+            }
+        }
+      else
+        {
+          if (arg.is_real_type ())
+            {
+              Matrix m = arg.matrix_value ();
+
+              if (! error_state)
+                {
+                  switch (nargout)
+                    {
+                    case 0:
+                    case 1:
+                      {
+                        QR fact (m, type);
+                        retval(0) = fact.R ();
+                      }
+                      break;
+
+                    case 2:
+                      {
+                        QR fact (m, type);
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+
+                    default:
+                      {
+                        QRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+                    }
+                }
+            }
+          else if (arg.is_complex_type ())
+            {
+              ComplexMatrix m = arg.complex_matrix_value ();
+
+              if (! error_state)
+                {
+                  switch (nargout)
+                    {
+                    case 0:
+                    case 1:
+                      {
+                        ComplexQR fact (m, type);
+                        retval(0) = fact.R ();
+                      }
+                      break;
+
+                    case 2:
+                      {
+                        ComplexQR fact (m, type);
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+
+                    default:
+                      {
+                        ComplexQRP fact (m, type);
+                        if (type == QR::economy)
+                          retval(2) = fact.Pvec ();
+                        else
+                          retval(2) = fact.P ();
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                      break;
+                    }
+                }
+            }
+          else
+            gripe_wrong_type_arg ("qr", arg);
+        }
+    }
+
+  return retval;
+}
+
+/*
+%!test
+%! a = [0, 2, 1; 2, 1, 2];
+%!
+%! [q, r] = qr (a);
+%! [qe, re] = qr (a, 0);
+%!
+%! assert (q * r, a, sqrt (eps));
+%! assert (qe * re, a, sqrt (eps));
+
+%!test
+%! a = [0, 2, 1; 2, 1, 2];
+%!
+%! [q, r, p] = qr (a);  # FIXME: not giving right dimensions. 
+%! [qe, re, pe] = qr (a, 0);
+%!
+%! assert (q * r, a * p, sqrt (eps));
+%! assert (qe * re, a(:, pe), sqrt (eps));
+
+%!test
+%! a = [0, 2; 2, 1; 1, 2];
+%!
+%! [q, r] = qr (a);
+%! [qe, re] = qr (a, 0);
+%!
+%! assert (q * r, a, sqrt (eps));
+%! assert (qe * re, a, sqrt (eps));
+
+%!test
+%! a = [0, 2; 2, 1; 1, 2];
+%!
+%! [q, r, p] = qr (a);
+%! [qe, re, pe] = qr (a, 0);
+%!
+%! assert (q * r, a * p, sqrt (eps));
+%! assert (qe * re, a(:, pe), sqrt (eps));
+
+%!error qr ()
+%!error qr ([1, 2; 3, 4], 0, 2)
+
+%!function retval = __testqr (q, r, a, p)
+%!  tol = 100*eps (class (q));
+%!  retval = 0;
+%!  if (nargin == 3)
+%!    n1 = norm (q*r - a);
+%!    n2 = norm (q'*q - eye (columns (q)));
+%!    retval = (n1 < tol && n2 < tol);
+%!  else
+%!    n1 = norm (q'*q - eye (columns (q)));
+%!    retval = (n1 < tol);
+%!    if (isvector (p))
+%!      n2 = norm (q*r - a(:,p));
+%!      retval = (retval && n2 < tol);
+%!    else
+%!      n2 = norm (q*r - a*p);
+%!      retval = (retval && n2 < tol);
+%!    endif
+%!  endif
+%!endfunction
+
+%!test
+%! t = ones (24, 1);
+%! j = 1;
+%!
+%! if (false)  # eliminate big matrix tests
+%!   a = rand (5000, 20);
+%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%!
+%!   a = a+1i*eps;
+%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%! endif
+%!
+%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
+%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = a+1i*eps;
+%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = [ ones(1,15); sqrt(eps)*eye(15) ];
+%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = a+1i*eps;
+%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = [ 611   196  -192   407    -8   -52   -49    29
+%!       196   899   113  -192   -71   -43    -8   -44
+%!      -192   113   899   196    61    49     8    52
+%!       407  -192   196   611     8    44    59   -23
+%!        -8   -71    61     8   411  -599   208   208
+%!       -52   -43    49    44  -599   411   208   208
+%!       -49    -8     8    59   208   208    99  -911
+%!        29   -44    52   -23   208   208  -911    99 ];
+%! [q,r] = qr (a);
+%!
+%! assert (all (t) && norm (q*r - a) < 5000*eps);
+
+%!test
+%! a = single ([0, 2, 1; 2, 1, 2]);
+%!
+%! [q, r] = qr (a);
+%! [qe, re] = qr (a, 0);
+%!
+%! assert (q * r, a, sqrt (eps ("single")));
+%! assert (qe * re, a, sqrt (eps ("single")));
+
+%!test
+%! a = single ([0, 2, 1; 2, 1, 2]);
+%!
+%! [q, r, p] = qr (a);  # FIXME: not giving right dimensions.
+%! [qe, re, pe] = qr (a, 0);
+%!
+%! assert (q * r, a * p, sqrt (eps ("single")));
+%! assert (qe * re, a(:, pe), sqrt (eps ("single")));
+
+%!test
+%! a = single ([0, 2; 2, 1; 1, 2]);
+%!
+%! [q, r] = qr (a);
+%! [qe, re] = qr (a, 0);
+%!
+%! assert (q * r, a, sqrt (eps ("single")));
+%! assert (qe * re, a, sqrt (eps ("single")));
+
+%!test
+%! a = single ([0, 2; 2, 1; 1, 2]);
+%!
+%! [q, r, p] = qr (a);
+%! [qe, re, pe] = qr (a, 0);
+%!
+%! assert (q * r, a * p, sqrt (eps ("single")));
+%! assert (qe * re, a(:, pe), sqrt (eps ("single")));
+
+%!error qr ()
+%!error qr ([1, 2; 3, 4], 0, 2)
+
+%!test
+%! t = ones (24, 1);
+%! j = 1;
+%!
+%! if (false)  # eliminate big matrix tests
+%!   a = rand (5000,20);
+%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%!
+%!   a = a+1i*eps ("single");
+%!   [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%!   [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%!   [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%!   [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%! endif
+%!
+%! a = [ ones(1,15); sqrt(eps("single"))*eye(15) ];
+%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = a+1i*eps ("single");
+%! [q,r]   = qr (a);   t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a');  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a);   t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a');  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = [ ones(1,15); sqrt(eps("single"))*eye(15) ];
+%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a', p);
+%!
+%! a = a+1i*eps ("single");
+%! [q,r]   = qr (a, 0);  t(j++) = __testqr (q, r, a);
+%! [q,r]   = qr (a',0);  t(j++) = __testqr (q, r, a');
+%! [q,r,p] = qr (a, 0);  t(j++) = __testqr (q, r, a, p);
+%! [q,r,p] = qr (a',0);  t(j++) = __testqr (q, r, a',p);
+%!
+%! a = [ 611   196  -192   407    -8   -52   -49    29
+%!       196   899   113  -192   -71   -43    -8   -44
+%!      -192   113   899   196    61    49     8    52
+%!       407  -192   196   611     8    44    59   -23
+%!        -8   -71    61     8   411  -599   208   208
+%!       -52   -43    49    44  -599   411   208   208
+%!       -49    -8     8    59   208   208    99  -911
+%!        29   -44    52   -23   208   208  -911    99 ];
+%! [q,r] = qr (a);
+%!
+%! assert (all (t) && norm (q*r-a) < 5000*eps ("single"));
+
+## The deactivated tests below can't be tested till rectangular back-subs is
+## implemented for sparse matrices.
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = sprandn (n,n,d) + speye (n,n);
+%! r = qr (a);
+%! assert (r'*r, a'*a, 1e-10)
+
+%!testif HAVE_COLAMD
+%! n = 20;  d = 0.2;
+%! a = sprandn (n,n,d) + speye (n,n);
+%! q = symamd (a);
+%! a = a(q,q);
+%! r = qr (a);
+%! assert (r'*r, a'*a, 1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = sprandn (n,n,d) + speye (n,n);
+%! [c,r] = qr (a, ones (n,1));
+%! assert (r\c, full (a)\ones (n,1), 10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = sprandn (n,n,d) + speye (n,n);
+%! b = randn (n,2);
+%! [c,r] = qr (a, b);
+%! assert (r\c, full (a)\b, 10e-10)
+
+%% Test under-determined systems!!
+%!#testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = sprandn (n,n+1,d) + speye (n,n+1);
+%! b = randn (n,2);
+%! [c,r] = qr (a, b);
+%! assert (r\c, full (a)\b, 10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = 1i*sprandn (n,n,d) + speye (n,n);
+%! r = qr (a);
+%! assert (r'*r,a'*a,1e-10)
+
+%!testif HAVE_COLAMD
+%! n = 20;  d = 0.2;
+%! a = 1i*sprandn (n,n,d) + speye (n,n);
+%! q = symamd (a);
+%! a = a(q,q);
+%! r = qr (a);
+%! assert (r'*r, a'*a, 1e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = 1i*sprandn (n,n,d) + speye (n,n);
+%! [c,r] = qr (a, ones (n,1));
+%! assert (r\c, full (a)\ones (n,1), 10e-10)
+
+%!testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = 1i*sprandn (n,n,d) + speye (n,n);
+%! b = randn (n,2);
+%! [c,r] = qr (a, b);
+%! assert (r\c, full (a)\b, 10e-10)
+
+%% Test under-determined systems!!
+%!#testif HAVE_CXSPARSE
+%! n = 20;  d = 0.2;
+%! a = 1i*sprandn (n,n+1,d) + speye (n,n+1);
+%! b = randn (n,2);
+%! [c,r] = qr (a, b);
+%! assert (r\c, full (a)\b, 10e-10)
+
+%!error qr (sprandn (10,10,0.2), ones (10,1))
+*/
+
+static
+bool check_qr_dims (const octave_value& q, const octave_value& r,
+                    bool allow_ecf = false)
+{
+  octave_idx_type m = q.rows (), k = r.rows (), n = r.columns ();
+  return ((q.ndims () == 2 && r.ndims () == 2 && k == q.columns ())
+            && (m == k || (allow_ecf && k == n && k < m)));
+}
+
+static
+bool check_index (const octave_value& i, bool vector_allowed = false)
+{
+  return ((i.is_real_type () || i.is_integer_type ())
+          && (i.is_scalar_type () || vector_allowed));
+}
+
+DEFUN_DLD (qrupdate, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrupdate (@var{Q}, @var{R}, @var{u}, @var{v})\n\
+Given a QR@tie{}factorization of a real or complex matrix\n\
+@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization\n\
+of @w{@var{A} + @var{u}*@var{v}'}, where @var{u} and @var{v} are\n\
+column vectors (rank-1 update) or matrices with equal number of columns\n\
+(rank-k update).  Notice that the latter case is done as a sequence of rank-1\n\
+updates; thus, for k large enough, it will be both faster and more accurate\n\
+to recompute the factorization from scratch.\n\
+\n\
+The QR@tie{}factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+@seealso{qr, qrinsert, qrdelete}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argu = args(2);
+  octave_value argv = args(3);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ()
+      && argu.is_numeric_type () && argv.is_numeric_type ())
+    {
+      if (check_qr_dims (argq, argr, true))
+        {
+          if (argq.is_real_type ()
+              && argr.is_real_type ()
+              && argu.is_real_type ()
+              && argv.is_real_type ())
+            {
+              // all real case
+              if (argq.is_single_type ()
+                  || argr.is_single_type ()
+                  || argu.is_single_type ()
+                  || argv.is_single_type ())
+                {
+                  FloatMatrix Q = argq.float_matrix_value ();
+                  FloatMatrix R = argr.float_matrix_value ();
+                  FloatMatrix u = argu.float_matrix_value ();
+                  FloatMatrix v = argv.float_matrix_value ();
+
+                  FloatQR fact (Q, R);
+                  fact.update (u, v);
+
+                  retval(1) = get_qr_r (fact);
+                  retval(0) = fact.Q ();
+                }
+              else
+                {
+                  Matrix Q = argq.matrix_value ();
+                  Matrix R = argr.matrix_value ();
+                  Matrix u = argu.matrix_value ();
+                  Matrix v = argv.matrix_value ();
+
+                  QR fact (Q, R);
+                  fact.update (u, v);
+
+                  retval(1) = get_qr_r (fact);
+                  retval(0) = fact.Q ();
+                }
+            }
+          else
+            {
+              // complex case
+              if (argq.is_single_type ()
+                  || argr.is_single_type ()
+                  || argu.is_single_type ()
+                  || argv.is_single_type ())
+                {
+                  FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+                  FloatComplexMatrix R = argr.float_complex_matrix_value ();
+                  FloatComplexMatrix u = argu.float_complex_matrix_value ();
+                  FloatComplexMatrix v = argv.float_complex_matrix_value ();
+
+                  FloatComplexQR fact (Q, R);
+                  fact.update (u, v);
+
+                  retval(1) = get_qr_r (fact);
+                  retval(0) = fact.Q ();
+                }
+              else
+                {
+                  ComplexMatrix Q = argq.complex_matrix_value ();
+                  ComplexMatrix R = argr.complex_matrix_value ();
+                  ComplexMatrix u = argu.complex_matrix_value ();
+                  ComplexMatrix v = argv.complex_matrix_value ();
+
+                  ComplexQR fact (Q, R);
+                  fact.update (u, v);
+
+                  retval(1) = get_qr_r (fact);
+                  retval(0) = fact.Q ();
+                }
+            }
+        }
+      else
+        error ("qrupdate: Q and R dimensions don't match");
+    }
+  else
+    error ("qrupdate: Q, R, U, and V must be numeric");
+
+  return retval;
+}
+
+/*
+%!shared A, u, v, Ac, uc, vc
+%! A = [0.091364  0.613038  0.999083;
+%!      0.594638  0.425302  0.603537;
+%!      0.383594  0.291238  0.085574;
+%!      0.265712  0.268003  0.238409;
+%!      0.669966  0.743851  0.445057 ];
+%!
+%! u = [0.85082;
+%!      0.76426;
+%!      0.42883;
+%!      0.53010;
+%!      0.80683 ];
+%!
+%! v = [0.98810;
+%!      0.24295;
+%!      0.43167 ];
+%!
+%! Ac = [0.620405 + 0.956953i  0.480013 + 0.048806i  0.402627 + 0.338171i;
+%!      0.589077 + 0.658457i  0.013205 + 0.279323i  0.229284 + 0.721929i;
+%!      0.092758 + 0.345687i  0.928679 + 0.241052i  0.764536 + 0.832406i;
+%!      0.912098 + 0.721024i  0.049018 + 0.269452i  0.730029 + 0.796517i;
+%!      0.112849 + 0.603871i  0.486352 + 0.142337i  0.355646 + 0.151496i ];
+%!
+%! uc = [0.20351 + 0.05401i;
+%!      0.13141 + 0.43708i;
+%!      0.29808 + 0.08789i;
+%!      0.69821 + 0.38844i;
+%!      0.74871 + 0.25821i ];
+%!
+%! vc = [0.85839 + 0.29468i;
+%!      0.20820 + 0.93090i;
+%!      0.86184 + 0.34689i ];
+%!
+
+%!test
+%! [Q,R] = qr (A);
+%! [Q,R] = qrupdate (Q, R, u, v);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R)-R), Inf) == 0);
+%! assert (norm (vec (Q*R - A - u*v'), Inf) < norm (A)*1e1*eps);
+%!
+%!test
+%! [Q,R] = qr (Ac);
+%! [Q,R] = qrupdate (Q, R, uc, vc);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R)-R), Inf) == 0);
+%! assert (norm (vec (Q*R - Ac - uc*vc'), Inf) < norm (Ac)*1e1*eps);
+
+%!test
+%! [Q,R] = qr (single (A));
+%! [Q,R] = qrupdate (Q, R, single (u), single (v));
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R)-R), Inf) == 0);
+%! assert (norm (vec (Q*R - single (A) - single (u)*single (v)'), Inf) < norm (single (A))*1e1*eps ("single"));
+%!
+%!test
+%! [Q,R] = qr (single (Ac));
+%! [Q,R] = qrupdate (Q, R, single (uc), single (vc));
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R)-R), Inf) == 0);
+%! assert (norm (vec (Q*R - single (Ac) - single (uc)*single (vc)'), Inf) < norm (single (Ac))*1e1*eps ("single"));
+*/
+
+DEFUN_DLD (qrinsert, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrinsert (@var{Q}, @var{R}, @var{j}, @var{x}, @var{orient})\n\
+Given a QR@tie{}factorization of a real or complex matrix\n\
+@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
+@w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be\n\
+inserted into @var{A} (if @var{orient} is @code{\"col\"}), or the\n\
+QR@tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}\n\
+is a row vector to be inserted into @var{A} (if @var{orient} is\n\
+@code{\"row\"}).\n\
+\n\
+The default value of @var{orient} is @code{\"col\"}.\n\
+If @var{orient} is @code{\"col\"},\n\
+@var{u} may be a matrix and @var{j} an index vector\n\
+resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
+@w{B(:,@var{j})} gives @var{u} and @w{B(:,@var{j}) = []} gives @var{A}.\n\
+Notice that the latter case is done as a sequence of k insertions;\n\
+thus, for k large enough, it will be both faster and more accurate to\n\
+recompute the factorization from scratch.\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+the QR@tie{}factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+@seealso{qr, qrupdate, qrdelete}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin < 4 || nargin > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argj = args(2);
+  octave_value argx = args(3);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ()
+      && argx.is_numeric_type ()
+      && (nargin < 5 || args(4).is_string ()))
+    {
+      std::string orient = (nargin < 5) ? "col" : args(4).string_value ();
+
+      bool col = orient == "col";
+
+      if (col || orient == "row")
+        if (check_qr_dims (argq, argr, col)
+            && (col || argx.rows () == 1))
+          {
+            if (check_index (argj, col))
+              {
+                MArray<octave_idx_type> j
+                  = argj.octave_idx_type_vector_value ();
+
+                octave_idx_type one = 1;
+
+                if (argq.is_real_type ()
+                    && argr.is_real_type ()
+                    && argx.is_real_type ())
+                  {
+                    // real case
+                    if (argq.is_single_type ()
+                        || argr.is_single_type ()
+                        || argx.is_single_type ())
+                      {
+                        FloatMatrix Q = argq.float_matrix_value ();
+                        FloatMatrix R = argr.float_matrix_value ();
+                        FloatMatrix x = argx.float_matrix_value ();
+
+                        FloatQR fact (Q, R);
+
+                        if (col)
+                          fact.insert_col (x, j-one);
+                        else
+                          fact.insert_row (x.row (0), j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+
+                      }
+                    else
+                      {
+                        Matrix Q = argq.matrix_value ();
+                        Matrix R = argr.matrix_value ();
+                        Matrix x = argx.matrix_value ();
+
+                        QR fact (Q, R);
+
+                        if (col)
+                          fact.insert_col (x, j-one);
+                        else
+                          fact.insert_row (x.row (0), j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+
+                      }
+                  }
+                else
+                  {
+                    // complex case
+                    if (argq.is_single_type ()
+                        || argr.is_single_type ()
+                        || argx.is_single_type ())
+                      {
+                        FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+                        FloatComplexMatrix R = argr.float_complex_matrix_value ();
+                        FloatComplexMatrix x = argx.float_complex_matrix_value ();
+
+                        FloatComplexQR fact (Q, R);
+
+                        if (col)
+                          fact.insert_col (x, j-one);
+                        else
+                          fact.insert_row (x.row (0), j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                    else
+                      {
+                        ComplexMatrix Q = argq.complex_matrix_value ();
+                        ComplexMatrix R = argr.complex_matrix_value ();
+                        ComplexMatrix x = argx.complex_matrix_value ();
+
+                        ComplexQR fact (Q, R);
+
+                        if (col)
+                          fact.insert_col (x, j-one);
+                        else
+                          fact.insert_row (x.row (0), j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                  }
+
+              }
+            else
+              error ("qrinsert: invalid index J");
+          }
+        else
+          error ("qrinsert: dimension mismatch");
+
+      else
+        error ("qrinsert: ORIENT must be \"col\" or \"row\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! [Q,R] = qr (A);
+%! [Q,R] = qrinsert (Q, R, 3, u);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [A(:,1:2) u A(:,3)]), Inf) < norm (A)*1e1*eps);
+%!test
+%! [Q,R] = qr (Ac);
+%! [Q,R] = qrinsert (Q, R, 3, uc);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [Ac(:,1:2) uc Ac(:,3)]), Inf) < norm (Ac)*1e1*eps);
+%!test
+%! x = [0.85082  0.76426  0.42883 ];
+%!
+%! [Q,R] = qr (A);
+%! [Q,R] = qrinsert (Q, R, 3, x, "row");
+%! assert (norm (vec (Q'*Q - eye (6)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [A(1:2,:);x;A(3:5,:)]), Inf) < norm (A)*1e1*eps);
+%!test
+%! x = [0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ];
+%!
+%! [Q,R] = qr (Ac);
+%! [Q,R] = qrinsert (Q, R, 3, x, "row");
+%! assert (norm (vec (Q'*Q - eye (6)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [Ac(1:2,:);x;Ac(3:5,:)]), Inf) < norm (Ac)*1e1*eps);
+
+%!test
+%! [Q,R] = qr (single (A));
+%! [Q,R] = qrinsert (Q, R, 3, single (u));
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - single ([A(:,1:2) u A(:,3)])), Inf) < norm (single (A))*1e1*eps ("single"));
+%!test
+%! [Q,R] = qr (single (Ac));
+%! [Q,R] = qrinsert (Q, R, 3, single (uc));
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - single ([Ac(:,1:2) uc Ac(:,3)])), Inf) < norm (single (Ac))*1e1*eps ("single"));
+%!test
+%! x = single ([0.85082  0.76426  0.42883 ]);
+%!
+%! [Q,R] = qr (single (A));
+%! [Q,R] = qrinsert (Q, R, 3, x, "row");
+%! assert (norm (vec (Q'*Q - eye (6,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - single ([A(1:2,:);x;A(3:5,:)])), Inf) < norm (single (A))*1e1*eps ("single"));
+%!test
+%! x = single ([0.20351 + 0.05401i  0.13141 + 0.43708i  0.29808 + 0.08789i ]);
+%!
+%! [Q,R] = qr (single (Ac));
+%! [Q,R] = qrinsert (Q, R, 3, x, "row");
+%! assert (norm (vec (Q'*Q - eye (6,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - single ([Ac(1:2,:);x;Ac(3:5,:)])), Inf) < norm (single (Ac))*1e1*eps ("single"));
+*/
+
+DEFUN_DLD (qrdelete, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrdelete (@var{Q}, @var{R}, @var{j}, @var{orient})\n\
+Given a QR@tie{}factorization of a real or complex matrix\n\
+@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
+@w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted\n\
+(if @var{orient} is \"col\"), or the QR@tie{}factorization of\n\
+@w{[A(1:j-1,:);A(j+1:n,:)]}, i.e., @var{A} with one row deleted (if\n\
+@var{orient} is \"row\").\n\
+\n\
+The default value of @var{orient} is \"col\".\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+@var{j} may be an index vector\n\
+resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
+@w{A(:,@var{j}) = []} gives @var{B}.\n\
+Notice that the latter case is done as a sequence of k deletions;\n\
+thus, for k large enough, it will be both faster and more accurate to\n\
+recompute the factorization from scratch.\n\
+\n\
+If @var{orient} is @code{\"col\"},\n\
+the QR@tie{}factorization supplied may be either full\n\
+(Q is square) or economized (R is square).\n\
+\n\
+If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+@seealso{qr, qrinsert, qrupdate}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin < 3 || nargin > 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argj = args(2);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ()
+      && (nargin < 4 || args(3).is_string ()))
+    {
+      std::string orient = (nargin < 4) ? "col" : args(3).string_value ();
+
+      bool col = orient == "col";
+
+      if (col || orient == "row")
+        if (check_qr_dims (argq, argr, col))
+          {
+            if (check_index (argj, col))
+              {
+                MArray<octave_idx_type> j
+                  = argj.octave_idx_type_vector_value ();
+
+                octave_idx_type one = 1;
+
+                if (argq.is_real_type ()
+                    && argr.is_real_type ())
+                  {
+                    // real case
+                    if (argq.is_single_type ()
+                        || argr.is_single_type ())
+                      {
+                        FloatMatrix Q = argq.float_matrix_value ();
+                        FloatMatrix R = argr.float_matrix_value ();
+
+                        FloatQR fact (Q, R);
+
+                        if (col)
+                          fact.delete_col (j-one);
+                        else
+                          fact.delete_row (j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                    else
+                      {
+                        Matrix Q = argq.matrix_value ();
+                        Matrix R = argr.matrix_value ();
+
+                        QR fact (Q, R);
+
+                        if (col)
+                          fact.delete_col (j-one);
+                        else
+                          fact.delete_row (j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                  }
+                else
+                  {
+                    // complex case
+                    if (argq.is_single_type ()
+                        || argr.is_single_type ())
+                      {
+                        FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+                        FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+                        FloatComplexQR fact (Q, R);
+
+                        if (col)
+                          fact.delete_col (j-one);
+                        else
+                          fact.delete_row (j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                    else
+                      {
+                        ComplexMatrix Q = argq.complex_matrix_value ();
+                        ComplexMatrix R = argr.complex_matrix_value ();
+
+                        ComplexQR fact (Q, R);
+
+                        if (col)
+                          fact.delete_col (j-one);
+                        else
+                          fact.delete_row (j(0)-one);
+
+                        retval(1) = get_qr_r (fact);
+                        retval(0) = fact.Q ();
+                      }
+                  }
+              }
+            else
+              error ("qrdelete: invalid index J");
+          }
+        else
+          error ("qrdelete: dimension mismatch");
+
+      else
+        error ("qrdelete: ORIENT must be \"col\" or \"row\"");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!test
+%! AA = [0.091364  0.613038  0.027504  0.999083;
+%!       0.594638  0.425302  0.562834  0.603537;
+%!       0.383594  0.291238  0.742073  0.085574;
+%!       0.265712  0.268003  0.783553  0.238409;
+%!       0.669966  0.743851  0.457255  0.445057 ];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 16*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps);
+%!
+%!test
+%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3);
+%! assert (norm (vec (Q'*Q - eye (5)), Inf) < 16*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps);
+%!
+%!test
+%! AA = [0.091364  0.613038  0.027504  0.999083;
+%!       0.594638  0.425302  0.562834  0.603537;
+%!       0.383594  0.291238  0.742073  0.085574;
+%!       0.265712  0.268003  0.783553  0.238409;
+%!       0.669966  0.743851  0.457255  0.445057 ];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3, "row");
+%! assert (norm (vec (Q'*Q - eye (4)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps);
+%!
+%!test
+%! AA = [0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!       0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!       0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!       0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!       0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ] * I;
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3, "row");
+%! assert (norm (vec (Q'*Q - eye (4)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps);
+
+%!test
+%! AA = single ([0.091364  0.613038  0.027504  0.999083;
+%!               0.594638  0.425302  0.562834  0.603537;
+%!               0.383594  0.291238  0.742073  0.085574;
+%!               0.265712  0.268003  0.783553  0.238409;
+%!               0.669966  0.743851  0.457255  0.445057 ]);
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3);
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%!test
+%! AA = single ([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!               0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!               0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!               0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!               0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3);
+%! assert (norm (vec (Q'*Q - eye (5,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(:,1:2) AA(:,4)]), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%!test
+%! AA = single ([0.091364  0.613038  0.027504  0.999083;
+%!               0.594638  0.425302  0.562834  0.603537;
+%!               0.383594  0.291238  0.742073  0.085574;
+%!               0.265712  0.268003  0.783553  0.238409;
+%!               0.669966  0.743851  0.457255  0.445057 ]);
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3, "row");
+%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1.5e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
+%!testif HAVE_QRUPDATE
+%! # Same test as above but with more precicision
+%! AA = single ([0.091364  0.613038  0.027504  0.999083;
+%!               0.594638  0.425302  0.562834  0.603537;
+%!               0.383594  0.291238  0.742073  0.085574;
+%!               0.265712  0.268003  0.783553  0.238409;
+%!               0.669966  0.743851  0.457255  0.445057 ]);
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3, "row");
+%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%!test
+%! AA = single ([0.364554 + 0.993117i  0.669818 + 0.510234i  0.426568 + 0.041337i  0.847051 + 0.233291i;
+%!              0.049600 + 0.242783i  0.448946 + 0.484022i  0.141155 + 0.074420i  0.446746 + 0.392706i;
+%!              0.581922 + 0.657416i  0.581460 + 0.030016i  0.219909 + 0.447288i  0.201144 + 0.069132i;
+%!              0.694986 + 0.000571i  0.682327 + 0.841712i  0.807537 + 0.166086i  0.192767 + 0.358098i;
+%!              0.945002 + 0.066788i  0.350492 + 0.642638i  0.579629 + 0.048102i  0.600170 + 0.636938i ]) * I;
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrdelete (Q, R, 3, "row");
+%! assert (norm (vec (Q'*Q - eye (4,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
+*/
+
+DEFUN_DLD (qrshift, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{Q1}, @var{R1}] =} qrshift (@var{Q}, @var{R}, @var{i}, @var{j})\n\
+Given a QR@tie{}factorization of a real or complex matrix\n\
+@w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
+@var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization\n\
+of @w{@var{A}(:,p)}, where @w{p} is the permutation @*\n\
+@code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
+ or @*\n\
+@code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}.  @*\n\
+\n\
+@seealso{qr, qrinsert, qrdelete}\n\
+@end deftypefn")
+{
+  octave_idx_type nargin = args.length ();
+  octave_value_list retval;
+
+  if (nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value argq = args(0);
+  octave_value argr = args(1);
+  octave_value argi = args(2);
+  octave_value argj = args(3);
+
+  if (argq.is_numeric_type () && argr.is_numeric_type ())
+    {
+      if (check_qr_dims (argq, argr, true))
+        {
+          if (check_index (argi) && check_index (argj))
+            {
+              octave_idx_type i = argi.int_value ();
+              octave_idx_type j = argj.int_value ();
+
+              if (argq.is_real_type ()
+                  && argr.is_real_type ())
+                {
+                  // all real case
+                  if (argq.is_single_type ()
+                      && argr.is_single_type ())
+                    {
+                      FloatMatrix Q = argq.float_matrix_value ();
+                      FloatMatrix R = argr.float_matrix_value ();
+
+                      FloatQR fact (Q, R);
+                      fact.shift_cols (i-1, j-1);
+
+                      retval(1) = get_qr_r (fact);
+                      retval(0) = fact.Q ();
+                    }
+                  else
+                    {
+                      Matrix Q = argq.matrix_value ();
+                      Matrix R = argr.matrix_value ();
+
+                      QR fact (Q, R);
+                      fact.shift_cols (i-1, j-1);
+
+                      retval(1) = get_qr_r (fact);
+                      retval(0) = fact.Q ();
+                    }
+                }
+              else
+                {
+                  // complex case
+                  if (argq.is_single_type ()
+                      && argr.is_single_type ())
+                    {
+                      FloatComplexMatrix Q = argq.float_complex_matrix_value ();
+                      FloatComplexMatrix R = argr.float_complex_matrix_value ();
+
+                      FloatComplexQR fact (Q, R);
+                      fact.shift_cols (i-1, j-1);
+
+                      retval(1) = get_qr_r (fact);
+                      retval(0) = fact.Q ();
+                    }
+                  else
+                    {
+                      ComplexMatrix Q = argq.complex_matrix_value ();
+                      ComplexMatrix R = argr.complex_matrix_value ();
+
+                      ComplexQR fact (Q, R);
+                      fact.shift_cols (i-1, j-1);
+
+                      retval(1) = get_qr_r (fact);
+                      retval(0) = fact.Q ();
+                    }
+                }
+            }
+          else
+            error ("qrshift: invalid index I or J");
+        }
+      else
+        error ("qrshift: dimensions mismatch");
+    }
+  else
+    error ("qrshift: Q and R must be numeric");
+
+  return retval;
+}
+
+/*
+%!test
+%! AA = A.';
+%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
+%!
+%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
+%!
+%!test
+%! AA = Ac.';
+%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
+%!
+%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3)), Inf) < 1e1*eps);
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps);
+
+%!test
+%! AA = single (A).';
+%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%!test
+%! AA = single (Ac).';
+%! i = 2;  j = 4;  p = [1:i-1, shift(i:j,-1), j+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
+%!
+%! j = 2;  i = 4;  p = [1:j-1, shift(j:i,+1), i+1:5];
+%!
+%! [Q,R] = qr (AA);
+%! [Q,R] = qrshift (Q, R, i, j);
+%! assert (norm (vec (Q'*Q - eye (3,"single")), Inf) < 1e1*eps ("single"));
+%! assert (norm (vec (triu (R) - R), Inf) == 0);
+%! assert (norm (vec (Q*R - AA(:,p)), Inf) < norm (AA)*1e1*eps ("single"));
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/symbfact.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,363 @@
+/*
+
+Copyright (C) 2005-2012 David Bateman
+Copyright (C) 1998-2005 Andy Adler
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SparseCmplxCHOL.h"
+#include "SparsedbleCHOL.h"
+#include "oct-spparms.h"
+#include "sparse-util.h"
+#include "oct-locbuf.h"
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN_DLD (symbfact, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {[@var{count}, @var{h}, @var{parent}, @var{post}, @var{r}] =} symbfact (@var{S})\n\
+@deftypefnx {Loadable Function} {[@dots{}] =} symbfact (@var{S}, @var{typ})\n\
+@deftypefnx {Loadable Function} {[@dots{}] =} symbfact (@var{S}, @var{typ}, @var{mode})\n\
+\n\
+Perform a symbolic factorization analysis on the sparse matrix @var{S}.\n\
+Where\n\
+\n\
+@table @var\n\
+@item S\n\
+@var{S} is a complex or real sparse matrix.\n\
+\n\
+@item typ\n\
+Is the type of the factorization and can be one of\n\
+\n\
+@table @samp\n\
+@item sym\n\
+Factorize @var{S}.  This is the default.\n\
+\n\
+@item col\n\
+Factorize @code{@var{S}' * @var{S}}.\n\
+\n\
+@item row\n\
+Factorize @xcode{@var{S} * @var{S}'}.\n\
+\n\
+@item lo\n\
+Factorize @xcode{@var{S}'}\n\
+@end table\n\
+\n\
+@item mode\n\
+The default is to return the Cholesky@tie{}factorization for @var{r}, and if\n\
+@var{mode} is 'L', the conjugate transpose of the Cholesky@tie{}factorization\n\
+is returned.  The conjugate transpose version is faster and uses less\n\
+memory, but returns the same values for @var{count}, @var{h}, @var{parent}\n\
+and @var{post} outputs.\n\
+@end table\n\
+\n\
+The output variables are\n\
+\n\
+@table @var\n\
+@item count\n\
+The row counts of the Cholesky@tie{}factorization as determined by @var{typ}.\n\
+\n\
+@item h\n\
+The height of the elimination tree.\n\
+\n\
+@item parent\n\
+The elimination tree itself.\n\
+\n\
+@item post\n\
+A sparse boolean matrix whose structure is that of the Cholesky\n\
+factorization as determined by @var{typ}.\n\
+@end table\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin < 1  || nargin > 3 || nargout > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+#ifdef HAVE_CHOLMOD
+
+  cholmod_common Common;
+  cholmod_common *cm = &Common;
+  CHOLMOD_NAME(start) (cm);
+
+  double spu = octave_sparse_params::get_key ("spumoni");
+  if (spu == 0.)
+    {
+      cm->print = -1;
+      cm->print_function = 0;
+    }
+  else
+    {
+      cm->print = static_cast<int> (spu) + 2;
+      cm->print_function =&SparseCholPrint;
+    }
+
+  cm->error_handler = &SparseCholError;
+  cm->complex_divide = CHOLMOD_NAME(divcomplex);
+  cm->hypotenuse = CHOLMOD_NAME(hypot);
+
+  double dummy;
+  cholmod_sparse Astore;
+  cholmod_sparse *A = &Astore;
+  A->packed = true;
+  A->sorted = true;
+  A->nz = 0;
+#ifdef IDX_TYPE_LONG
+  A->itype = CHOLMOD_LONG;
+#else
+  A->itype = CHOLMOD_INT;
+#endif
+  A->dtype = CHOLMOD_DOUBLE;
+  A->stype = 1;
+  A->x = &dummy;
+
+  if (args(0).is_real_type ())
+    {
+      const SparseMatrix a = args(0).sparse_matrix_value ();
+      A->nrow = a.rows ();
+      A->ncol = a.cols ();
+      A->p = a.cidx ();
+      A->i = a.ridx ();
+      A->nzmax = a.nnz ();
+      A->xtype = CHOLMOD_REAL;
+
+      if (a.rows () > 0 && a.cols () > 0)
+        A->x = a.data ();
+    }
+  else if (args(0).is_complex_type ())
+    {
+      const SparseComplexMatrix a = args(0).sparse_complex_matrix_value ();
+      A->nrow = a.rows ();
+      A->ncol = a.cols ();
+      A->p = a.cidx ();
+      A->i = a.ridx ();
+      A->nzmax = a.nnz ();
+      A->xtype = CHOLMOD_COMPLEX;
+
+      if (a.rows () > 0 && a.cols () > 0)
+        A->x = a.data ();
+    }
+  else
+    gripe_wrong_type_arg ("symbfact", args(0));
+
+  octave_idx_type coletree = false;
+  octave_idx_type n = A->nrow;
+
+  if (nargin > 1)
+    {
+      char ch;
+      std::string str = args(1).string_value ();
+      ch = tolower (str.c_str ()[0]);
+      if (ch == 'r')
+        A->stype = 0;
+      else if (ch == 'c')
+        {
+          n = A->ncol;
+          coletree = true;
+          A->stype = 0;
+        }
+      else if (ch == 's')
+        A->stype = 1;
+      else if (ch == 's')
+        A->stype = -1;
+      else
+        error ("symbfact: unrecognized TYP in symbolic factorization");
+    }
+
+  if (A->stype && A->nrow != A->ncol)
+    error ("symbfact: S must be a square matrix");
+
+  if (!error_state)
+    {
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Parent, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Post, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, ColCount, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, First, n);
+      OCTAVE_LOCAL_BUFFER (octave_idx_type, Level, n);
+
+      cholmod_sparse *F = CHOLMOD_NAME(transpose) (A, 0, cm);
+      cholmod_sparse *Aup, *Alo;
+
+      if (A->stype == 1 || coletree)
+        {
+          Aup = A ;
+          Alo = F ;
+        }
+      else
+        {
+          Aup = F ;
+          Alo = A ;
+        }
+
+      CHOLMOD_NAME(etree) (Aup, Parent, cm);
+
+      if (cm->status < CHOLMOD_OK)
+        {
+          error ("matrix corrupted");
+          goto symbfact_error;
+        }
+
+      if (CHOLMOD_NAME(postorder) (Parent, n, 0, Post, cm) != n)
+        {
+          error ("postorder failed");
+          goto symbfact_error;
+        }
+
+      CHOLMOD_NAME(rowcolcounts) (Alo, 0, 0, Parent, Post, 0,
+                                  ColCount, First, Level, cm);
+
+      if (cm->status < CHOLMOD_OK)
+        {
+          error ("matrix corrupted");
+          goto symbfact_error;
+        }
+
+      if (nargout > 4)
+        {
+          cholmod_sparse *A1, *A2;
+
+          if (A->stype == 1)
+            {
+              A1 = A;
+              A2 = 0;
+            }
+          else if (A->stype == -1)
+            {
+              A1 = F;
+              A2 = 0;
+            }
+          else if (coletree)
+            {
+              A1 = F;
+              A2 = A;
+            }
+          else
+            {
+              A1 = A;
+              A2 = F;
+            }
+
+          // count the total number of entries in L
+          octave_idx_type lnz = 0 ;
+          for (octave_idx_type j = 0 ; j < n ; j++)
+            lnz += ColCount[j];
+
+
+          // allocate the output matrix L (pattern-only)
+          SparseBoolMatrix L (n, n, lnz);
+
+          // initialize column pointers
+          lnz = 0;
+          for (octave_idx_type j = 0 ; j < n ; j++)
+            {
+              L.xcidx(j) = lnz;
+              lnz += ColCount[j];
+            }
+          L.xcidx(n) = lnz;
+
+
+          /* create a copy of the column pointers */
+          octave_idx_type *W = First;
+          for (octave_idx_type j = 0 ; j < n ; j++)
+            W[j] = L.xcidx (j);
+
+          // get workspace for computing one row of L
+          cholmod_sparse *R = cholmod_allocate_sparse (n, 1, n, false, true,
+                                                       0, CHOLMOD_PATTERN, cm);
+          octave_idx_type *Rp = static_cast<octave_idx_type *>(R->p);
+          octave_idx_type *Ri = static_cast<octave_idx_type *>(R->i);
+
+          // compute L one row at a time
+          for (octave_idx_type k = 0 ; k < n ; k++)
+            {
+              // get the kth row of L and store in the columns of L
+              CHOLMOD_NAME (row_subtree) (A1, A2, k, Parent, R, cm) ;
+              for (octave_idx_type p = 0 ; p < Rp[1] ; p++)
+                L.xridx (W[Ri[p]]++) = k ;
+
+              // add the diagonal entry
+              L.xridx (W[k]++) = k ;
+            }
+
+          // free workspace
+          cholmod_free_sparse (&R, cm) ;
+
+
+          // transpose L to get R, or leave as is
+          if (nargin < 3)
+            L = L.transpose ();
+
+          // fill numerical values of L with one's
+          for (octave_idx_type p = 0 ; p < lnz ; p++)
+            L.xdata(p) = true;
+
+          retval(4) = L;
+        }
+
+      ColumnVector tmp (n);
+      if (nargout > 3)
+        {
+          for (octave_idx_type i = 0; i < n; i++)
+            tmp(i) = Post[i] + 1;
+          retval(3) = tmp;
+        }
+
+      if (nargout > 2)
+        {
+          for (octave_idx_type i = 0; i < n; i++)
+            tmp(i) = Parent[i] + 1;
+          retval(2) = tmp;
+        }
+
+      if (nargout > 1)
+        {
+          /* compute the elimination tree height */
+          octave_idx_type height = 0 ;
+          for (int i = 0 ; i < n ; i++)
+            height = (height > Level[i] ? height : Level[i]);
+          height++ ;
+          retval(1) = static_cast<double> (height);
+        }
+
+      for (octave_idx_type i = 0; i < n; i++)
+        tmp(i) = ColCount[i];
+      retval(0) = tmp;
+    }
+
+ symbfact_error:
+#else
+  error ("symbfact: not available in this version of Octave");
+#endif
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/symrcm.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,702 @@
+/*
+
+Copyright (C) 2007-2012 Michael Weitzel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+An implementation of the Reverse Cuthill-McKee algorithm (symrcm)
+
+The implementation of this algorithm is based in the descriptions found in
+
+@INPROCEEDINGS{,
+        author = {E. Cuthill and J. McKee},
+        title = {Reducing the Bandwidth of Sparse Symmetric Matrices},
+        booktitle = {Proceedings of the 24th ACM National Conference},
+        publisher = {Brandon Press},
+        pages = {157 -- 172},
+        location = {New Jersey},
+        year = {1969}
+}
+
+@BOOK{,
+        author = {Alan George and Joseph W. H. Liu},
+        title = {Computer Solution of Large Sparse Positive Definite Systems},
+        publisher = {Prentice Hall Series in Computational Mathematics},
+        ISBN = {0-13-165274-5},
+        year = {1981}
+}
+
+The algorithm represents a heuristic approach to the NP-complete minimum
+bandwidth problem.
+
+Written by Michael Weitzel <michael.weitzel@@uni-siegen.de>
+                           <weitzel@@ldknet.org>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov.h"
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "utils.h"
+#include "oct-locbuf.h"
+
+#include "ov-re-mat.h"
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+#include "oct-sparse.h"
+
+// A node struct for the Cuthill-McKee algorithm
+struct CMK_Node
+{
+  // the node's id (matrix row index)
+  octave_idx_type id;
+  // the node's degree
+  octave_idx_type deg;
+  // minimal distance to the root of the spanning tree
+  octave_idx_type dist;
+};
+
+// A simple queue.
+// Queues Q have a fixed maximum size N (rows,cols of the matrix) and are
+// stored in an array. qh and qt point to queue head and tail.
+
+// Enqueue operation (adds a node "o" at the tail)
+
+inline static void
+Q_enq (CMK_Node *Q, octave_idx_type N, octave_idx_type& qt, const CMK_Node& o)
+{
+  Q[qt] = o;
+  qt = (qt + 1) % (N + 1);
+}
+
+// Dequeue operation (removes a node from the head)
+
+inline static CMK_Node
+Q_deq (CMK_Node * Q, octave_idx_type N, octave_idx_type& qh)
+{
+  CMK_Node r = Q[qh];
+  qh = (qh + 1) % (N + 1);
+  return r;
+}
+
+// Predicate (queue empty)
+#define Q_empty(Q, N, qh, qt)   ((qh) == (qt))
+
+// A simple, array-based binary heap (used as a priority queue for nodes)
+
+// the left descendant of entry i
+#define LEFT(i)         (((i) << 1) + 1)        // = (2*(i)+1)
+// the right descendant of entry i
+#define RIGHT(i)        (((i) << 1) + 2)        // = (2*(i)+2)
+// the parent of entry i
+#define PARENT(i)       (((i) - 1) >> 1)        // = floor(((i)-1)/2)
+
+// Builds a min-heap (the root contains the smallest element). A is an array
+// with the graph's nodes, i is a starting position, size is the length of A.
+
+static void
+H_heapify_min (CMK_Node *A, octave_idx_type i, octave_idx_type size)
+{
+  octave_idx_type j = i;
+  for (;;)
+    {
+      octave_idx_type l = LEFT(j);
+      octave_idx_type r = RIGHT(j);
+
+      octave_idx_type smallest;
+      if (l < size && A[l].deg < A[j].deg)
+        smallest = l;
+      else
+        smallest = j;
+
+      if (r < size && A[r].deg < A[smallest].deg)
+        smallest = r;
+
+      if (smallest != j)
+        {
+          std::swap (A[j], A[smallest]);
+          j = smallest;
+        }
+      else
+        break;
+    }
+}
+
+// Heap operation insert. Running time is O(log(n))
+
+static void
+H_insert (CMK_Node *H, octave_idx_type& h, const CMK_Node& o)
+{
+  octave_idx_type i = h++;
+
+  H[i] = o;
+
+  if (i == 0)
+    return;
+  do
+    {
+      octave_idx_type p = PARENT(i);
+      if (H[i].deg < H[p].deg)
+        {
+          std::swap (H[i], H[p]);
+
+          i = p;
+        }
+      else
+        break;
+    }
+  while (i > 0);
+}
+
+// Heap operation remove-min. Removes the smalles element in O(1) and
+// reorganizes the heap optionally in O(log(n))
+
+inline static CMK_Node
+H_remove_min (CMK_Node *H, octave_idx_type& h, int reorg/*=1*/)
+{
+  CMK_Node r = H[0];
+  H[0] = H[--h];
+  if (reorg)
+    H_heapify_min (H, 0, h);
+  return r;
+}
+
+// Predicate (heap empty)
+#define H_empty(H, h)   ((h) == 0)
+
+// Helper function for the Cuthill-McKee algorithm. Tries to determine a
+// pseudo-peripheral node of the graph as starting node.
+
+static octave_idx_type
+find_starting_node (octave_idx_type N, const octave_idx_type *ridx,
+                    const octave_idx_type *cidx, const octave_idx_type *ridx2,
+                    const octave_idx_type *cidx2, octave_idx_type *D,
+                    octave_idx_type start)
+{
+  CMK_Node w;
+
+  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
+  boolNDArray btmp (dim_vector (1, N), false);
+  bool *visit = btmp.fortran_vec ();
+
+  octave_idx_type qh = 0;
+  octave_idx_type qt = 0;
+  CMK_Node x;
+  x.id = start;
+  x.deg = D[start];
+  x.dist = 0;
+  Q_enq (Q, N, qt, x);
+  visit[start] = true;
+
+  // distance level
+  octave_idx_type level = 0;
+  // current largest "eccentricity"
+  octave_idx_type max_dist = 0;
+
+  for (;;)
+    {
+      while (! Q_empty (Q, N, qh, qt))
+        {
+          CMK_Node v = Q_deq (Q, N, qh);
+
+          if (v.dist > x.dist || (v.id != x.id && v.deg > x.deg))
+            x = v;
+
+          octave_idx_type i = v.id;
+
+          // add all unvisited neighbors to the queue
+          octave_idx_type j1 = cidx[i];
+          octave_idx_type j2 = cidx2[i];
+          while (j1 < cidx[i+1] || j2 < cidx2[i+1])
+            {
+              OCTAVE_QUIT;
+
+              if (j1 == cidx[i+1])
+                {
+                  octave_idx_type r2 = ridx2[j2++];
+                  if (! visit[r2])
+                    {
+                      // the distance of node j is dist(i)+1
+                      w.id = r2;
+                      w.deg = D[r2];
+                      w.dist = v.dist+1;
+                      Q_enq (Q, N, qt, w);
+                      visit[r2] = true;
+
+                      if (w.dist > level)
+                        level = w.dist;
+                    }
+                }
+              else if (j2 == cidx2[i+1])
+                {
+                  octave_idx_type r1 = ridx[j1++];
+                  if (! visit[r1])
+                    {
+                      // the distance of node j is dist(i)+1
+                      w.id = r1;
+                      w.deg = D[r1];
+                      w.dist = v.dist+1;
+                      Q_enq (Q, N, qt, w);
+                      visit[r1] = true;
+
+                      if (w.dist > level)
+                        level = w.dist;
+                    }
+                }
+              else
+                {
+                  octave_idx_type r1 = ridx[j1];
+                  octave_idx_type r2 = ridx2[j2];
+                  if (r1 <= r2)
+                    {
+                      if (! visit[r1])
+                        {
+                          w.id = r1;
+                          w.deg = D[r1];
+                          w.dist = v.dist+1;
+                          Q_enq (Q, N, qt, w);
+                          visit[r1] = true;
+
+                          if (w.dist > level)
+                            level = w.dist;
+                        }
+                      j1++;
+                      if (r1 == r2)
+                        j2++;
+                    }
+                  else
+                    {
+                      if (! visit[r2])
+                        {
+                          w.id = r2;
+                          w.deg = D[r2];
+                          w.dist = v.dist+1;
+                          Q_enq (Q, N, qt, w);
+                          visit[r2] = true;
+
+                          if (w.dist > level)
+                            level = w.dist;
+                        }
+                      j2++;
+                    }
+                }
+            }
+        } // finish of BFS
+
+      if (max_dist < x.dist)
+        {
+          max_dist = x.dist;
+
+          for (octave_idx_type i = 0; i < N; i++)
+            visit[i] = false;
+
+          visit[x.id] = true;
+          x.dist = 0;
+          qt = qh = 0;
+          Q_enq (Q, N, qt, x);
+        }
+      else
+        break;
+    }
+  return x.id;
+}
+
+// Calculates the node's degrees. This means counting the non-zero elements
+// in the symmetric matrix' rows. This works for non-symmetric matrices
+// as well.
+
+static octave_idx_type
+calc_degrees (octave_idx_type N, const octave_idx_type *ridx,
+              const octave_idx_type *cidx, octave_idx_type *D)
+{
+  octave_idx_type max_deg = 0;
+
+  for (octave_idx_type i = 0; i < N; i++)
+    D[i] = 0;
+
+  for (octave_idx_type j = 0; j < N; j++)
+    {
+      for (octave_idx_type i = cidx[j]; i < cidx[j+1]; i++)
+        {
+          OCTAVE_QUIT;
+          octave_idx_type k = ridx[i];
+          // there is a non-zero element (k,j)
+          D[k]++;
+          if (D[k] > max_deg)
+            max_deg = D[k];
+          // if there is no element (j,k) there is one in
+          // the symmetric matrix:
+          if (k != j)
+            {
+              bool found = false;
+              for (octave_idx_type l = cidx[k]; l < cidx[k + 1]; l++)
+                {
+                  OCTAVE_QUIT;
+
+                  if (ridx[l] == j)
+                    {
+                      found = true;
+                      break;
+                    }
+                  else if (ridx[l] > j)
+                    break;
+                }
+
+              if (! found)
+                {
+                  // A(j,k) == 0
+                  D[j]++;
+                  if (D[j] > max_deg)
+                    max_deg = D[j];
+                }
+            }
+        }
+    }
+  return max_deg;
+}
+
+// Transpose of the structure of a square sparse matrix
+
+static void
+transpose (octave_idx_type N, const octave_idx_type *ridx,
+           const octave_idx_type *cidx, octave_idx_type *ridx2,
+           octave_idx_type *cidx2)
+{
+  octave_idx_type nz = cidx[N];
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, w, N + 1);
+  for (octave_idx_type i = 0; i < N; i++)
+    w[i] = 0;
+  for (octave_idx_type i = 0; i < nz; i++)
+    w[ridx[i]]++;
+  nz = 0;
+  for (octave_idx_type i = 0; i < N; i++)
+    {
+      OCTAVE_QUIT;
+      cidx2[i] = nz;
+      nz += w[i];
+      w[i] = cidx2[i];
+    }
+  cidx2[N] = nz;
+  w[N] = nz;
+
+  for (octave_idx_type j = 0; j < N; j++)
+    for (octave_idx_type k = cidx[j]; k < cidx[j + 1]; k++)
+      {
+        OCTAVE_QUIT;
+        octave_idx_type q = w[ridx[k]]++;
+        ridx2[q] = j;
+      }
+}
+
+// An implementation of the Cuthill-McKee algorithm.
+DEFUN_DLD (symrcm, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})\n\
+Return the symmetric reverse Cuthill-McKee permutation of @var{S}.\n\
+@var{p} is a permutation vector such that\n\
+@code{@var{S}(@var{p}, @var{p})} tends to have its diagonal elements\n\
+closer to the diagonal than @var{S}.  This is a good preordering for LU\n\
+or Cholesky@tie{}factorization of matrices that come from ``long, skinny''\n\
+problems.  It works for both symmetric and asymmetric @var{S}.\n\
+\n\
+The algorithm represents a heuristic approach to the NP-complete\n\
+bandwidth minimization problem.  The implementation is based in the\n\
+descriptions found in\n\
+\n\
+E. Cuthill, J. McKee. @cite{Reducing the Bandwidth of Sparse Symmetric\n\
+Matrices}. Proceedings of the 24th ACM National Conference, 157--172\n\
+1969, Brandon Press, New Jersey.\n\
+\n\
+A. George, J.W.H. Liu. @cite{Computer Solution of Large Sparse\n\
+Positive Definite Systems}, Prentice Hall Series in Computational\n\
+Mathematics, ISBN 0-13-165274-5, 1981.\n\
+\n\
+@seealso{colperm, colamd, symamd}\n\
+@end deftypefn")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg = args(0);
+
+  // the parameter of the matrix is converted into a sparse matrix
+  //(if necessary)
+  octave_idx_type *cidx;
+  octave_idx_type *ridx;
+  SparseMatrix Ar;
+  SparseComplexMatrix Ac;
+
+  if (arg.is_real_type ())
+    {
+      Ar = arg.sparse_matrix_value ();
+      // Note cidx/ridx are const, so use xridx and xcidx...
+      cidx = Ar.xcidx ();
+      ridx = Ar.xridx ();
+    }
+  else
+    {
+      Ac = arg.sparse_complex_matrix_value ();
+      cidx = Ac.xcidx ();
+      ridx = Ac.xridx ();
+    }
+
+  if (error_state)
+    return retval;
+
+  octave_idx_type nr = arg.rows ();
+  octave_idx_type nc = arg.columns ();
+
+  if (nr != nc)
+    {
+      gripe_square_matrix_required ("symrcm");
+      return retval;
+    }
+
+  if (nr == 0 && nc == 0)
+    return octave_value (NDArray (dim_vector (1, 0)));
+
+  // sizes of the heaps
+  octave_idx_type s = 0;
+
+  // head- and tail-indices for the queue
+  octave_idx_type qt = 0, qh = 0;
+  CMK_Node v, w;
+  // dimension of the matrix
+  octave_idx_type N = nr;
+
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, cidx2, N + 1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, ridx2, cidx[N]);
+  transpose (N, ridx, cidx, ridx2, cidx2);
+
+  // the permutation vector
+  NDArray P (dim_vector (1, N));
+
+  // compute the node degrees
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, D, N);
+  octave_idx_type max_deg = calc_degrees (N, ridx, cidx, D);
+
+  // if none of the nodes has a degree > 0 (a matrix of zeros)
+  // the return value corresponds to the identity permutation
+  if (max_deg == 0)
+    {
+      for (octave_idx_type i = 0; i < N; i++)
+        P(i) = i;
+      return octave_value (P);
+    }
+
+  // a heap for the a node's neighbors. The number of neighbors is
+  // limited by the maximum degree max_deg:
+  OCTAVE_LOCAL_BUFFER (CMK_Node, S, max_deg);
+
+  // a queue for the BFS. The array is always one element larger than
+  // the number of entries that are stored.
+  OCTAVE_LOCAL_BUFFER (CMK_Node, Q, N+1);
+
+  // a counter (for building the permutation)
+  octave_idx_type c = -1;
+
+  // upper bound for the bandwidth (=quality of solution)
+  // initialize the bandwidth of the graph with 0. B contains the
+  // the maximum of the theoretical lower limits of the subgraphs
+  // bandwidths.
+  octave_idx_type B = 0;
+
+  // mark all nodes as unvisited; with the exception of the nodes
+  // that have degree==0 and build a CC of the graph.
+
+  boolNDArray btmp (dim_vector (1, N), false);
+  bool *visit = btmp.fortran_vec ();
+
+  do
+    {
+      // locate an unvisited starting node of the graph
+      octave_idx_type i;
+      for (i = 0; i < N; i++)
+        if (! visit[i])
+          break;
+
+      // locate a probably better starting node
+      v.id = find_starting_node (N, ridx, cidx, ridx2, cidx2, D, i);
+
+      // mark the node as visited and enqueue it (a starting node
+      // for the BFS). Since the node will be a root of a spanning
+      // tree, its dist is 0.
+      v.deg = D[v.id];
+      v.dist = 0;
+      visit[v.id] = true;
+      Q_enq (Q, N, qt, v);
+
+      // lower bound for the bandwidth of a subgraph
+      // keep a "level" in the spanning tree (= min. distance to the
+      // root) for determining the bandwidth of the computed
+      // permutation P
+      octave_idx_type Bsub = 0;
+      // min. dist. to the root is 0
+      octave_idx_type level = 0;
+      // the root is the first/only node on level 0
+      octave_idx_type level_N = 1;
+
+      while (! Q_empty (Q, N, qh, qt))
+        {
+          v = Q_deq (Q, N, qh);
+          i = v.id;
+
+          c++;
+
+          // for computing the inverse permutation P where
+          // A(inv(P),inv(P)) or P'*A*P is banded
+          //         P(i) = c;
+
+          // for computing permutation P where
+          // A(P(i),P(j)) or P*A*P' is banded
+          P(c) = i;
+
+          // put all unvisited neighbors j of node i on the heap
+          s = 0;
+          octave_idx_type j1 = cidx[i];
+          octave_idx_type j2 = cidx2[i];
+
+          OCTAVE_QUIT;
+          while (j1 < cidx[i+1] || j2 < cidx2[i+1])
+            {
+              OCTAVE_QUIT;
+              if (j1 == cidx[i+1])
+                {
+                  octave_idx_type r2 = ridx2[j2++];
+                  if (! visit[r2])
+                    {
+                      // the distance of node j is dist(i)+1
+                      w.id = r2;
+                      w.deg = D[r2];
+                      w.dist = v.dist+1;
+                      H_insert (S, s, w);
+                      visit[r2] = true;
+                    }
+                }
+              else if (j2 == cidx2[i+1])
+                {
+                  octave_idx_type r1 = ridx[j1++];
+                  if (! visit[r1])
+                    {
+                      w.id = r1;
+                      w.deg = D[r1];
+                      w.dist = v.dist+1;
+                      H_insert (S, s, w);
+                      visit[r1] = true;
+                    }
+                }
+              else
+                {
+                  octave_idx_type r1 = ridx[j1];
+                  octave_idx_type r2 = ridx2[j2];
+                  if (r1 <= r2)
+                    {
+                      if (! visit[r1])
+                        {
+                          w.id = r1;
+                          w.deg = D[r1];
+                          w.dist = v.dist+1;
+                          H_insert (S, s, w);
+                          visit[r1] = true;
+                        }
+                      j1++;
+                      if (r1 == r2)
+                        j2++;
+                    }
+                  else
+                    {
+                      if (! visit[r2])
+                        {
+                          w.id = r2;
+                          w.deg = D[r2];
+                          w.dist = v.dist+1;
+                          H_insert (S, s, w);
+                          visit[r2] = true;
+                        }
+                      j2++;
+                    }
+                }
+            }
+
+          // add the neighbors to the queue (sorted by node degree)
+          while (! H_empty (S, s))
+            {
+              OCTAVE_QUIT;
+
+              // locate a neighbor of i with minimal degree in O(log(N))
+              v = H_remove_min (S, s, 1);
+
+              // entered the BFS a new level?
+              if (v.dist > level)
+                {
+                  // adjustment of bandwith:
+                  // "[...] the minimum bandwidth that
+                  // can be obtained [...] is the
+                  //  maximum number of nodes per level"
+                  if (Bsub < level_N)
+                    Bsub = level_N;
+
+                  level = v.dist;
+                  // v is the first node on the new level
+                  level_N = 1;
+                }
+              else
+                {
+                  // there is no new level but another node on
+                  // this level:
+                  level_N++;
+                }
+
+              // enqueue v in O(1)
+              Q_enq (Q, N, qt, v);
+            }
+
+          // synchronize the bandwidth with level_N once again:
+          if (Bsub < level_N)
+            Bsub = level_N;
+        }
+      // finish of BFS. If there are still unvisited nodes in the graph
+      // then it is split into CCs. The computed bandwidth is the maximum
+      // of all subgraphs. Update:
+      if (Bsub > B)
+        B = Bsub;
+    }
+  // are there any nodes left?
+  while (c+1 < N);
+
+  // compute the reverse-ordering
+  s = N / 2 - 1;
+  for (octave_idx_type i = 0, j = N - 1; i <= s; i++, j--)
+    std::swap (P.elem (i), P.elem (j));
+
+  // increment all indices, since Octave is not C
+  return octave_value (P+1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/tsearch.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,186 @@
+/*
+
+Copyright (C) 2002-2012 Andreas Stahel
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Andreas Stahel <Andreas.Stahel@hta-bi.bfh.ch>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "lo-ieee.h"
+#include "lo-math.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "parse.h"
+
+inline double max (double a, double b, double c)
+{
+  if (a < b)
+    return (b < c ? c : b);
+  else
+    return (a < c ? c : a);
+}
+
+inline double min (double a, double b, double c)
+{
+  if (a > b)
+    return (b > c ? c : b);
+  else
+    return (a > c ? c : a);
+}
+
+#define REF(x,k,i) x(static_cast<octave_idx_type>(elem((k), (i))) - 1)
+
+// for large data set the algorithm is very slow
+// one should presort (how?) either the elements of the points of evaluation
+// to cut down the time needed to decide which triangle contains the
+// given point
+
+// e.g., build up a neighbouring triangle structure and use a simplex-like
+// method to traverse it
+
+DEFUN_DLD (tsearch, args, ,
+        "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{idx} =} tsearch (@var{x}, @var{y}, @var{t}, @var{xi}, @var{yi})\n\
+Search for the enclosing Delaunay convex hull.  For @code{@var{t} =\n\
+delaunay (@var{x}, @var{y})}, finds the index in @var{t} containing the\n\
+points @code{(@var{xi}, @var{yi})}.  For points outside the convex hull,\n\
+@var{idx} is NaN.\n\
+@seealso{delaunay, delaunayn}\n\
+@end deftypefn")
+{
+  const double eps=1.0e-12;
+
+  octave_value_list retval;
+  const int nargin = args.length ();
+  if (nargin != 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  const ColumnVector x (args(0).vector_value ());
+  const ColumnVector y (args(1).vector_value ());
+  const Matrix elem (args(2).matrix_value ());
+  const ColumnVector xi (args(3).vector_value ());
+  const ColumnVector yi (args(4).vector_value ());
+
+  if (error_state)
+    return retval;
+
+  const octave_idx_type nelem = elem.rows ();
+
+  ColumnVector minx (nelem);
+  ColumnVector maxx (nelem);
+  ColumnVector miny (nelem);
+  ColumnVector maxy (nelem);
+  for (octave_idx_type k = 0; k < nelem; k++)
+    {
+      minx(k) = min (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) - eps;
+      maxx(k) = max (REF (x, k, 0), REF (x, k, 1), REF (x, k, 2)) + eps;
+      miny(k) = min (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) - eps;
+      maxy(k) = max (REF (y, k, 0), REF (y, k, 1), REF (y, k, 2)) + eps;
+    }
+
+  const octave_idx_type np = xi.length ();
+  ColumnVector values (np);
+
+  double x0 = 0.0, y0 = 0.0;
+  double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
+
+  octave_idx_type k = nelem; // k is a counter of elements
+  for (octave_idx_type kp = 0; kp < np; kp++)
+    {
+      const double xt = xi(kp);
+      const double yt = yi(kp);
+
+      // check if last triangle contains the next point
+      if (k < nelem)
+        {
+          const double dx1 = xt - x0;
+          const double dx2 = yt - y0;
+          const double c1 = (a22 * dx1 - a21 * dx2) / det;
+          const double c2 = (-a12 * dx1 + a11 * dx2) / det;
+          if (c1 >= -eps && c2 >= -eps && (c1 + c2) <= (1 + eps))
+            {
+              values(kp) = double(k+1);
+              continue;
+            }
+        }
+
+      // it doesn't, so go through all elements
+      for (k = 0; k < nelem; k++)
+        {
+          OCTAVE_QUIT;
+          if (xt >= minx(k) && xt <= maxx(k) && yt >= miny(k) && yt <= maxy(k))
+            {
+              // element inside the minimum rectangle: examine it closely
+              x0  = REF (x, k, 0);
+              y0  = REF (y, k, 0);
+              a11 = REF (x, k, 1) - x0;
+              a12 = REF (y, k, 1) - y0;
+              a21 = REF (x, k, 2) - x0;
+              a22 = REF (y, k, 2) - y0;
+              det = a11 * a22 - a21 * a12;
+
+              // solve the system
+              const double dx1 = xt - x0;
+              const double dx2 = yt - y0;
+              const double c1 = (a22 * dx1 - a21 * dx2) / det;
+              const double c2 = (-a12 * dx1 + a11 * dx2) / det;
+              if ((c1 >= -eps) && (c2 >= -eps) && ((c1 + c2) <= (1 + eps)))
+                {
+                  values(kp) = double(k+1);
+                  break;
+                }
+            } //endif # examine this element closely
+        } //endfor # each element
+
+      if (k == nelem)
+        values(kp) = lo_ieee_nan_value ();
+
+    } //endfor # kp
+
+  retval(0) = values;
+
+  return retval;
+}
+
+/*
+%!shared x, y, tri
+%! x = [-1;-1;1];
+%! y = [-1;1;-1];
+%! tri = [1, 2, 3];
+%!assert (tsearch (x,y,tri,-1,-1), 1)
+%!assert (tsearch (x,y,tri, 1,-1), 1)
+%!assert (tsearch (x,y,tri,-1, 1), 1)
+%!assert (tsearch (x,y,tri,-1/3, -1/3), 1)
+%!assert (tsearch (x,y,tri, 1, 1), NaN)
+
+%!error tsearch ()
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dldfcn/urlwrite.cc	Tue Jul 31 21:57:58 2012 -0400
@@ -0,0 +1,1740 @@
+// urlwrite and urlread, a curl front-end for octave
+/*
+
+Copyright (C) 2006-2012 Alexander Barth
+Copyright (C) 2009 David Bateman
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// Author: Alexander Barth <abarth@marine.usf.edu>
+// Adapted-By: jwe
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include "dir-ops.h"
+#include "file-ops.h"
+#include "file-stat.h"
+#include "oct-env.h"
+#include "glob-match.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "oct-map.h"
+#include "oct-refcount.h"
+#include "unwind-prot.h"
+
+#ifdef HAVE_CURL
+
+#include <curl/curl.h>
+#include <curl/curlver.h>
+#include <curl/easy.h>
+
+// Backwards compatibility for curl < 7.17.0
+#if LIBCURL_VERSION_NUM < 0x071100
+#define CURLOPT_DIRLISTONLY CURLOPT_FTPLISTONLY
+#endif
+
+static int
+write_data (void *buffer, size_t size, size_t nmemb, void *streamp)
+{
+  std::ostream& stream = *(static_cast<std::ostream*> (streamp));
+  stream.write (static_cast<const char*> (buffer), size*nmemb);
+  return (stream.fail () ? 0 : size * nmemb);
+}
+
+static int
+read_data (void *buffer, size_t size, size_t nmemb, void *streamp)
+{
+  std::istream& stream = *(static_cast<std::istream*> (streamp));
+  stream.read (static_cast<char*> (buffer), size*nmemb);
+  if (stream.eof ())
+    return stream.gcount ();
+  else
+    return (stream.fail () ? 0 : size * nmemb);
+}
+
+static size_t
+throw_away (void *, size_t size, size_t nmemb, void *)
+{
+  return static_cast<size_t>(size * nmemb);
+}
+
+class
+curl_handle
+{
+private:
+  class
+  curl_handle_rep
+  {
+  public:
+    curl_handle_rep (void) : count (1), valid (true), ascii (false)
+      {
+        curl = curl_easy_init ();
+        if (!curl)
+          error ("can not create curl handle");
+      }
+
+    ~curl_handle_rep (void)
+      {
+        if (curl)
+          curl_easy_cleanup (curl);
+      }
+
+    bool is_valid (void) const
+      {
+        return valid;
+      }
+
+    bool perform (bool curlerror) const
+      {
+        bool retval = false;
+        if (!error_state)
+          {
+            BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+
+            errnum = curl_easy_perform (curl);
+            if (errnum != CURLE_OK)
+              {
+                if (curlerror)
+                  error ("%s", curl_easy_strerror (errnum));
+              }
+            else
+              retval = true;
+
+            END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
+          }
+        return retval;
+      }
+
+    CURL* handle (void) const
+      {
+        return curl;
+      }
+
+    bool is_ascii (void) const
+      {
+        return ascii;
+      }
+
+    bool is_binary (void) const
+      {
+        return !ascii;
+      }
+
+    octave_refcount<size_t> count;
+    std::string host;
+    bool valid;
+    bool ascii;
+    mutable CURLcode errnum;
+
+  private:
+    CURL *curl;
+
+    // No copying!
+
+    curl_handle_rep (const curl_handle_rep& ov);
+
+    curl_handle_rep& operator = (const curl_handle_rep&);
+  };
+
+public:
+
+// I'd love to rewrite this as a private method of the curl_handle
+// class, but you can't pass the va_list from the wrapper setopt to
+// the curl_easy_setopt function.
+#define setopt(option, parameter) \
+  { \
+    CURLcode res = curl_easy_setopt (rep->handle (), option, parameter); \
+    if (res != CURLE_OK) \
+      error ("%s", curl_easy_strerror (res)); \
+  }
+
+  curl_handle (void) : rep (new curl_handle_rep ())
+    {
+      rep->valid = false;
+    }
+
+  curl_handle (const std::string& _host, const std::string& user,
+               const std::string& passwd) :
+    rep (new curl_handle_rep ())
+    {
+      rep->host = _host;
+      init (user, passwd, std::cin, octave_stdout);
+
+      std::string url = "ftp://" + _host;
+      setopt (CURLOPT_URL, url.c_str ());
+
+      // Setup the link, with no transfer
+      if (!error_state)
+        perform ();
+    }
+
+  curl_handle (const std::string& url, const std::string& method,
+               const Cell& param, std::ostream& os, bool& retval) :
+    rep (new curl_handle_rep ())
+    {
+      retval = false;
+
+      init ("", "", std::cin, os);
+
+      setopt (CURLOPT_NOBODY, 0);
+
+      // Don't need to store the parameters here as we can't change
+      // the URL after the handle is created
+      std::string query_string = form_query_string (param);
+
+      if (method == "get")
+        {
+          query_string = url + "?" + query_string;
+          setopt (CURLOPT_URL, query_string.c_str ());
+        }
+      else if (method == "post")
+        {
+          setopt (CURLOPT_URL, url.c_str ());
+          setopt (CURLOPT_POSTFIELDS, query_string.c_str ());
+        }
+      else
+        setopt (CURLOPT_URL, url.c_str ());
+
+      if (!error_state)
+        retval = perform (false);
+    }
+
+  curl_handle (const curl_handle& h) : rep (h.rep)
+    {
+      rep->count++;
+    }
+
+  ~curl_handle (void)
+    {
+      if (--rep->count == 0)
+        delete rep;
+    }
+
+  curl_handle& operator = (const curl_handle& h)
+    {
+      if (this != &h)
+        {
+          if (--rep->count == 0)
+            delete rep;
+
+          rep = h.rep;
+          rep->count++;
+        }
+      return *this;
+    }
+
+  bool is_valid (void) const
+    {
+      return rep->is_valid ();
+    }
+
+  std::string lasterror (void) const
+    {
+      return std::string (curl_easy_strerror (rep->errnum));
+    }
+
+  void set_ostream (std::ostream& os) const
+    {
+      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&os));
+    }
+
+  void set_istream (std::istream& is) const
+    {
+      setopt (CURLOPT_READDATA, static_cast<void*> (&is));
+    }
+
+  void ascii (void) const
+    {
+      setopt (CURLOPT_TRANSFERTEXT, 1);
+      rep->ascii = true;
+    }
+
+  void binary (void) const
+    {
+      setopt (CURLOPT_TRANSFERTEXT, 0);
+      rep->ascii = false;
+    }
+
+  bool is_ascii (void) const
+    {
+      return rep->is_ascii ();
+    }
+
+  bool is_binary (void) const
+    {
+      return rep->is_binary ();
+    }
+
+  void cwd (const std::string& path) const
+    {
+      struct curl_slist *slist = 0;
+      std::string cmd = "cwd " + path;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      setopt (CURLOPT_POSTQUOTE, slist);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+    }
+
+  void del (const std::string& file) const
+    {
+      struct curl_slist *slist = 0;
+      std::string cmd = "dele " + file;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      setopt (CURLOPT_POSTQUOTE, slist);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+    }
+
+  void rmdir (const std::string& path) const
+    {
+      struct curl_slist *slist = 0;
+      std::string cmd = "rmd " + path;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      setopt (CURLOPT_POSTQUOTE, slist);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+    }
+
+  bool mkdir (const std::string& path, bool curlerror = true) const
+    {
+      bool retval = false;
+      struct curl_slist *slist = 0;
+      std::string cmd = "mkd " + path;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      setopt (CURLOPT_POSTQUOTE, slist);
+      if (! error_state)
+        retval = perform (curlerror);
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+      return retval;
+    }
+
+  void rename (const std::string& oldname, const std::string& newname) const
+    {
+      struct curl_slist *slist = 0;
+      std::string cmd = "rnfr " + oldname;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      cmd = "rnto " + newname;
+      slist = curl_slist_append (slist, cmd.c_str ());
+      setopt (CURLOPT_POSTQUOTE, slist);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+    }
+
+  void put (const std::string& file, std::istream& is) const
+    {
+      std::string url = "ftp://" + rep->host + "/" + file;
+      setopt (CURLOPT_URL, url.c_str ());
+      setopt (CURLOPT_UPLOAD, 1);
+      setopt (CURLOPT_NOBODY, 0);
+      set_istream (is);
+      if (! error_state)
+        perform ();
+      set_istream (std::cin);
+      setopt (CURLOPT_NOBODY, 1);
+      setopt (CURLOPT_UPLOAD, 0);
+      url = "ftp://" + rep->host;
+      setopt (CURLOPT_URL, url.c_str ());
+    }
+
+  void get (const std::string& file, std::ostream& os) const
+    {
+      std::string url = "ftp://" + rep->host + "/" + file;
+      setopt (CURLOPT_URL, url.c_str ());
+      setopt (CURLOPT_NOBODY, 0);
+      set_ostream (os);
+      if (! error_state)
+        perform ();
+      set_ostream (octave_stdout);
+      setopt (CURLOPT_NOBODY, 1);
+      url = "ftp://" + rep->host;
+      setopt (CURLOPT_URL, url.c_str ());
+    }
+
+  void dir (void) const
+    {
+      std::string url = "ftp://" + rep->host + "/";
+      setopt (CURLOPT_URL, url.c_str ());
+      setopt (CURLOPT_NOBODY, 0);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_NOBODY, 1);
+      url = "ftp://" + rep->host;
+      setopt (CURLOPT_URL, url.c_str ());
+    }
+
+  string_vector list (void) const
+    {
+      std::ostringstream buf;
+      std::string url = "ftp://" + rep->host + "/";
+      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&buf));
+      setopt (CURLOPT_URL, url.c_str ());
+      setopt (CURLOPT_DIRLISTONLY, 1);
+      setopt (CURLOPT_NOBODY, 0);
+      if (! error_state)
+        perform ();
+      setopt (CURLOPT_NOBODY, 1);
+      url = "ftp://" + rep->host;
+      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&octave_stdout));
+      setopt (CURLOPT_DIRLISTONLY, 0);
+      setopt (CURLOPT_URL, url.c_str ());
+
+      // Count number of directory entries
+      std::string str = buf.str ();
+      octave_idx_type n = 0;
+      size_t pos = 0;
+      while (true)
+        {
+          pos = str.find_first_of ('\n', pos);
+          if (pos == std::string::npos)
+            break;
+          pos++;
+          n++;
+        }
+      string_vector retval (n);
+      pos = 0;
+      for (octave_idx_type i = 0; i < n; i++)
+        {
+          size_t newpos = str.find_first_of ('\n', pos);
+          if (newpos == std::string::npos)
+            break;
+
+          retval(i) = str.substr(pos, newpos - pos);
+          pos = newpos + 1;
+        }
+      return retval;
+    }
+
+  void get_fileinfo (const std::string& filename, double& filesize,
+                     time_t& filetime, bool& fileisdir) const
+    {
+      std::string path = pwd ();
+
+      std::string url = "ftp://" + rep->host + "/" + path + "/" + filename;
+      setopt (CURLOPT_URL, url.c_str ());
+      setopt (CURLOPT_FILETIME, 1);
+      setopt (CURLOPT_HEADERFUNCTION, throw_away);
+      setopt (CURLOPT_WRITEFUNCTION, throw_away);
+
+      // FIXME
+      // The MDTM command fails for a directory on the servers I tested
+      // so this is a means of testing for directories. It also means
+      // I can't get the date of directories!
+      if (! error_state)
+        {
+          if (! perform (false))
+            {
+              fileisdir = true;
+              filetime = -1;
+              filesize = 0;
+            }
+          else
+            {
+              fileisdir = false;
+              time_t ft;
+              curl_easy_getinfo (rep->handle (), CURLINFO_FILETIME, &ft);
+              filetime = ft;
+              double fs;
+              curl_easy_getinfo (rep->handle (),
+                                 CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fs);
+              filesize = fs;
+            }
+        }
+
+      setopt (CURLOPT_WRITEFUNCTION, write_data);
+      setopt (CURLOPT_HEADERFUNCTION, 0);
+      setopt (CURLOPT_FILETIME, 0);
+      url = "ftp://" + rep->host;
+      setopt (CURLOPT_URL, url.c_str ());
+
+      // The MDTM command seems to reset the path to the root with the
+      // servers I tested with, so cd again into the correct path. Make
+      // the path absolute so that this will work even with servers that
+      // don't end up in the root after an MDTM command.
+      cwd ("/" + path);
+    }
+
+  std::string pwd (void) const
+    {
+      struct curl_slist *slist = 0;
+      std::string retval;
+      std::ostringstream buf;
+
+      slist = curl_slist_append (slist, "pwd");
+      setopt (CURLOPT_POSTQUOTE, slist);
+      setopt (CURLOPT_HEADERFUNCTION, write_data);
+      setopt (CURLOPT_WRITEHEADER, static_cast<void *>(&buf));
+
+      if (! error_state)
+        {
+          perform ();
+          retval = buf.str ();
+
+          // Can I assume that the path is alway in "" on the last line
+          size_t pos2 = retval.rfind ('"');
+          size_t pos1 = retval.rfind ('"', pos2 - 1);
+          retval = retval.substr (pos1 + 1, pos2 - pos1 - 1);
+        }
+      setopt (CURLOPT_HEADERFUNCTION, 0);
+      setopt (CURLOPT_WRITEHEADER, 0);
+      setopt (CURLOPT_POSTQUOTE, 0);
+      curl_slist_free_all (slist);
+
+      return retval;
+    }
+
+  bool perform (bool curlerror = true) const
+    {
+      return rep->perform (curlerror);
+    }
+
+private:
+  curl_handle_rep *rep;
+
+  std::string form_query_string (const Cell& param)
+    {
+      std::ostringstream query;
+
+      for (int i = 0; i < param.numel (); i += 2)
+        {
+          std::string name = param(i).string_value ();
+          std::string text = param(i+1).string_value ();
+
+          // Encode strings.
+          char *enc_name = curl_easy_escape (rep->handle (), name.c_str (),
+                                             name.length ());
+          char *enc_text = curl_easy_escape (rep->handle (), text.c_str (),
+                                             text.length ());
+
+          query << enc_name << "=" << enc_text;
+
+          curl_free (enc_name);
+          curl_free (enc_text);
+
+          if (i < param.numel ()-1)
+            query << "&";
+        }
+
+      query.flush ();
+
+      return query.str ();
+    }
+
+  void init (const std::string& user, const std::string& passwd,
+             std::istream& is, std::ostream& os)
+    {
+      // No data transfer by default
+      setopt (CURLOPT_NOBODY, 1);
+
+      // Set the username and password
+      std::string userpwd = user;
+      if (! passwd.empty ())
+        userpwd += ":" + passwd;
+      if (! userpwd.empty ())
+        setopt (CURLOPT_USERPWD, userpwd.c_str ());
+
+      // Define our callback to get called when there's data to be written.
+      setopt (CURLOPT_WRITEFUNCTION, write_data);
+
+      // Set a pointer to our struct to pass to the callback.
+      setopt (CURLOPT_WRITEDATA, static_cast<void*> (&os));
+
+      // Define our callback to get called when there's data to be read
+      setopt (CURLOPT_READFUNCTION, read_data);
+
+      // Set a pointer to our struct to pass to the callback.
+      setopt (CURLOPT_READDATA, static_cast<void*> (&is));
+
+      // Follow redirects.
+      setopt (CURLOPT_FOLLOWLOCATION, true);
+
+      // Don't use EPSV since connecting to sites that don't support it
+      // will hang for some time (3 minutes?) before moving on to try PASV
+      // instead.
+      setopt (CURLOPT_FTP_USE_EPSV, false);
+
+      setopt (CURLOPT_NOPROGRESS, true);
+      setopt (CURLOPT_FAILONERROR, true);
+
+      setopt (CURLOPT_POSTQUOTE, 0);
+      setopt (CURLOPT_QUOTE, 0);
+    }
+
+#undef setopt
+};
+
+class
+curl_handles
+{
+public:
+
+  typedef std::map<std::string, curl_handle>::iterator iterator;
+  typedef std::map<std::string, curl_handle>::const_iterator const_iterator;
+
+  curl_handles (void) : map ()
+   {
+     curl_global_init (CURL_GLOBAL_DEFAULT);
+   }
+
+  ~curl_handles (void)
+    {
+      // Remove the elements of the map explicitly as they should
+      // be deleted before the call to curl_global_cleanup
+      map.erase (begin (), end ());
+
+      curl_global_cleanup ();
+    }
+
+  iterator begin (void) { return iterator (map.begin ()); }
+  const_iterator begin (void) const { return const_iterator (map.begin ()); }
+
+  iterator end (void) { return iterator (map.end ()); }
+  const_iterator end (void) const { return const_iterator (map.end ()); }
+
+  iterator seek (const std::string& k) { return map.find (k); }
+  const_iterator seek (const std::string& k) const { return map.find (k); }
+
+  std::string key (const_iterator p) const { return p->first; }
+
+  curl_handle& contents (const std::string& k)
+    {
+      return map[k];
+    }
+
+  curl_handle contents (const std::string& k) const
+    {
+      const_iterator p = seek (k);
+      return p != end () ? p->second : curl_handle ();
+    }
+
+  curl_handle& contents (iterator p)
+    { return p->second; }
+
+  curl_handle contents (const_iterator p) const
+    { return p->second; }
+
+  void del (const std::string& k)
+    {
+      iterator p = map.find (k);
+
+      if (p != map.end ())
+        map.erase (p);
+    }
+
+private:
+  std::map<std::string, curl_handle> map;
+};
+
+static curl_handles handles;
+
+static void
+cleanup_urlwrite (std::string filename)
+{
+  octave_unlink (filename);
+}
+
+static void
+reset_path (const curl_handle curl)
+{
+  curl.cwd ("..");
+}
+
+static void
+delete_file (std::string file)
+{
+  octave_unlink (file);
+}
+#endif
+
+DEFUN_DLD (urlwrite, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} urlwrite (@var{url}, @var{localfile})\n\
+@deftypefnx {Loadable Function} {@var{f} =} urlwrite (@var{url}, @var{localfile})\n\
+@deftypefnx {Loadable Function} {[@var{f}, @var{success}] =} urlwrite (@var{url}, @var{localfile})\n\
+@deftypefnx {Loadable Function} {[@var{f}, @var{success}, @var{message}] =} urlwrite (@var{url}, @var{localfile})\n\
+Download a remote file specified by its @var{url} and save it as\n\
+@var{localfile}.  For example:\n\
+\n\
+@example\n\
+@group\n\
+urlwrite (\"ftp://ftp.octave.org/pub/octave/README\",\n\
+          \"README.txt\");\n\
+@end group\n\
+@end example\n\
+\n\
+The full path of the downloaded file is returned in @var{f}.  The\n\
+variable @var{success} is 1 if the download was successful,\n\
+otherwise it is 0 in which case @var{message} contains an error\n\
+message.  If no output argument is specified and an error occurs,\n\
+then the error is signaled through Octave's error handling mechanism.\n\
+\n\
+This function uses libcurl.  Curl supports, among others, the HTTP,\n\
+FTP and FILE protocols.  Username and password may be specified in\n\
+the URL, for example:\n\
+\n\
+@example\n\
+@group\n\
+urlwrite (\"http://username:password@@example.com/file.txt\",\n\
+          \"file.txt\");\n\
+@end group\n\
+@end example\n\
+\n\
+GET and POST requests can be specified by @var{method} and @var{param}.\n\
+The parameter @var{method} is either @samp{get} or @samp{post}\n\
+and @var{param} is a cell array of parameter and value pairs.\n\
+For example:\n\
+\n\
+@example\n\
+@group\n\
+urlwrite (\"http://www.google.com/search\", \"search.html\",\n\
+          \"get\", @{\"query\", \"octave\"@});\n\
+@end group\n\
+@end example\n\
+@seealso{urlread}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_CURL
+
+  int nargin = args.length ();
+
+  // verify arguments
+  if (nargin != 2 && nargin != 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string url = args(0).string_value ();
+
+  if (error_state)
+    {
+      error ("urlwrite: URL must be a character string");
+      return retval;
+    }
+
+  // name to store the file if download is succesful
+  std::string filename = args(1).string_value ();
+
+  if (error_state)
+    {
+      error ("urlwrite: LOCALFILE must be a character string");
+      return retval;
+    }
+
+  std::string method;
+  Cell param; // empty cell array
+
+  if (nargin == 4)
+    {
+      method = args(2).string_value ();
+
+      if (error_state)
+        {
+          error ("urlwrite: METHOD must be \"get\" or \"post\"");
+          return retval;
+        }
+
+      if (method != "get" && method != "post")
+        {
+          error ("urlwrite: METHOD must be \"get\" or \"post\"");
+          return retval;
+        }
+
+      param = args(3).cell_value ();
+
+      if (error_state)
+        {
+          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell");
+          return retval;
+        }
+
+
+      if (param.numel () % 2 == 1 )
+        {
+          error ("urlwrite: number of elements in PARAM must be even");
+          return retval;
+        }
+    }
+
+  // The file should only be deleted if it doesn't initially exist, we
+  // create it, and the download fails.  We use unwind_protect to do
+  // it so that the deletion happens no matter how we exit the function.
+
+  file_stat fs (filename);
+
+  std::ofstream ofile (filename.c_str (), std::ios::out | std::ios::binary);
+
+  if (! ofile.is_open ())
+    {
+      error ("urlwrite: unable to open file");
+      return retval;
+    }
+
+  unwind_protect_safe frame;
+
+  frame.add_fcn (cleanup_urlwrite, filename);
+
+  bool ok;
+  curl_handle curl = curl_handle (url, method, param, ofile, ok);
+
+  ofile.close ();
+
+  if (!error_state)
+    frame.discard ();
+  else
+    frame.run ();
+
+  if (nargout > 0)
+    {
+      if (ok)
+        {
+          retval(2) = std::string ();
+          retval(1) = true;
+          retval(0) = octave_env::make_absolute (filename);
+        }
+      else
+        {
+          retval(2) = curl.lasterror ();
+          retval(1) = false;
+          retval(0) = std::string ();
+        }
+    }
+
+  if (nargout < 2 && ! ok)
+    error ("urlwrite: curl: %s", curl.lasterror ().c_str ());
+
+#else
+  error ("urlwrite: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (urlread, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{s} =} urlread (@var{url})\n\
+@deftypefnx {Loadable Function} {[@var{s}, @var{success}] =} urlread (@var{url})\n\
+@deftypefnx {Loadable Function} {[@var{s}, @var{success}, @var{message}] =} urlread (@var{url})\n\
+@deftypefnx {Loadable Function} {[@dots{}] =} urlread (@var{url}, @var{method}, @var{param})\n\
+Download a remote file specified by its @var{url} and return its content\n\
+in string @var{s}.  For example:\n\
+\n\
+@example\n\
+s = urlread (\"ftp://ftp.octave.org/pub/octave/README\");\n\
+@end example\n\
+\n\
+The variable @var{success} is 1 if the download was successful,\n\
+otherwise it is 0 in which case @var{message} contains an error\n\
+message.  If no output argument is specified and an error occurs,\n\
+then the error is signaled through Octave's error handling mechanism.\n\
+\n\
+This function uses libcurl.  Curl supports, among others, the HTTP,\n\
+FTP and FILE protocols.  Username and password may be specified in the\n\
+URL@.  For example:\n\
+\n\
+@example\n\
+s = urlread (\"http://user:password@@example.com/file.txt\");\n\
+@end example\n\
+\n\
+GET and POST requests can be specified by @var{method} and @var{param}.\n\
+The parameter @var{method} is either @samp{get} or @samp{post}\n\
+and @var{param} is a cell array of parameter and value pairs.\n\
+For example:\n\
+\n\
+@example\n\
+@group\n\
+s = urlread (\"http://www.google.com/search\", \"get\",\n\
+            @{\"query\", \"octave\"@});\n\
+@end group\n\
+@end example\n\
+@seealso{urlwrite}\n\
+@end deftypefn")
+{
+  // Octave's return value
+  octave_value_list retval;
+
+#ifdef HAVE_CURL
+
+  int nargin = args.length ();
+
+  // verify arguments
+  if (nargin != 1  && nargin != 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string url = args(0).string_value ();
+
+  if (error_state)
+    {
+      error ("urlread: URL must be a character string");
+      return retval;
+    }
+
+  std::string method;
+  Cell param; // empty cell array
+
+  if (nargin == 3)
+    {
+      method = args(1).string_value ();
+
+      if (error_state)
+        {
+          error ("urlread: METHOD must be \"get\" or \"post\"");
+          return retval;
+        }
+
+      if (method != "get" && method != "post")
+        {
+          error ("urlread: METHOD must be \"get\" or \"post\"");
+          return retval;
+        }
+
+      param = args(2).cell_value ();
+
+      if (error_state)
+        {
+          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell");
+          return retval;
+        }
+
+      if (param.numel () % 2 == 1 )
+        {
+          error ("urlread: number of elements in PARAM must be even");
+          return retval;
+        }
+    }
+
+  std::ostringstream buf;
+
+  bool ok;
+  curl_handle curl = curl_handle (url, method, param, buf, ok);
+
+  if (nargout > 0)
+    {
+      // Return empty string if no error occured.
+      retval(2) = ok ? "" : curl.lasterror ();
+      retval(1) = ok;
+      retval(0) = buf.str ();
+    }
+
+  if (nargout < 2 && ! ok)
+    error ("urlread: curl: %s", curl.lasterror().c_str());
+
+#else
+  error ("urlread: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__ftp__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} __ftp__ (@var{handle}, @var{host})\n\
+@deftypefnx {Loadable Function} {} __ftp__ (@var{handle}, @var{host}, @var{username}, @var{password})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+  std::string handle;
+  std::string host;
+  std::string user = "anonymous";
+  std::string passwd = "";
+
+  if (nargin < 2 || nargin > 4)
+    error ("incorrect number of arguments");
+  else
+    {
+      handle = args(0).string_value ();
+      host = args(1).string_value ();
+
+      if (nargin > 1)
+        user = args(2).string_value ();
+
+      if (nargin > 2)
+        passwd = args(3).string_value ();
+
+      if (!error_state)
+        {
+          handles.contents (handle) = curl_handle (host, user, passwd);
+
+          if (error_state)
+            handles.del (handle);
+        }
+    }
+#else
+  error ("__ftp__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_pwd__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_pwd__ (@var{handle})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  octave_value retval;
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    error ("__ftp_pwd__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            retval = curl.pwd ();
+          else
+            error ("__ftp_pwd__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_pwd__: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__ftp_cwd__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_cwd__ (@var{handle}, @var{path})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 1 && nargin != 2)
+    error ("__ftp_cwd__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string path = "";
+
+      if (nargin > 1)
+        path  = args(1).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.cwd (path);
+          else
+            error ("__ftp_cwd__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_cwd__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_dir__, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_dir__ (@var{handle})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  octave_value retval;
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    error ("__ftp_dir__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            {
+              if (nargout == 0)
+                curl.dir ();
+              else
+                {
+                  string_vector sv = curl.list ();
+                  octave_idx_type n = sv.length ();
+                  if (n == 0)
+                    {
+                      string_vector flds (5);
+                      flds(0) = "name";
+                      flds(1) = "date";
+                      flds(2) = "bytes";
+                      flds(3) = "isdir";
+                      flds(4) = "datenum";
+                      retval = octave_map (flds);
+                    }
+                  else
+                    {
+                      octave_map st;
+                      Cell filectime (dim_vector (n, 1));
+                      Cell filesize (dim_vector (n, 1));
+                      Cell fileisdir (dim_vector (n, 1));
+                      Cell filedatenum (dim_vector (n, 1));
+
+                      st.assign ("name", Cell (sv));
+
+                      for (octave_idx_type i = 0; i < n; i++)
+                        {
+                          time_t ftime;
+                          bool fisdir;
+                          double fsize;
+
+                          curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
+
+                          fileisdir (i) = fisdir;
+                          filectime (i) = ctime (&ftime);
+                          filesize (i) = fsize;
+                          filedatenum (i) = double (ftime);
+                        }
+                      st.assign ("date", filectime);
+                      st.assign ("bytes", filesize);
+                      st.assign ("isdir", fileisdir);
+                      st.assign ("datenum", filedatenum);
+                      retval = st;
+                    }
+                }
+            }
+          else
+            error ("__ftp_dir__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_dir__: not available in this version of Octave");
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__ftp_ascii__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_ascii__ (@var{handle})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    error ("__ftp_ascii__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.ascii ();
+          else
+            error ("__ftp_ascii__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_ascii__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_binary__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_binary__ (@var{handle})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    error ("__ftp_binary__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.binary ();
+          else
+            error ("__ftp_binary__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_binary__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_close__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_close__ (@var{handle})\n\
+ Undocumented internal function\n\
+ @end deftypefn")
+ {
+ #ifdef HAVE_CURL
+   int nargin = args.length ();
+
+   if (nargin != 1)
+     error ("__ftp_close__: incorrect number of arguments");
+   else
+     {
+       std::string handle = args(0).string_value ();
+
+       if (!error_state)
+         handles.del (handle);
+     }
+ #else
+   error ("__ftp_close__: not available in this version of Octave");
+ #endif
+
+   return octave_value ();
+ }
+
+DEFUN_DLD (__ftp_mode__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_mode__ (@var{handle})\n\
+ Undocumented internal function\n\
+ @end deftypefn")
+ {
+   octave_value retval;
+ #ifdef HAVE_CURL
+   int nargin = args.length ();
+
+   if (nargin != 1)
+     error ("__ftp_mode__: incorrect number of arguments");
+   else
+     {
+       std::string handle = args(0).string_value ();
+
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            retval = (curl.is_ascii () ? "ascii" : "binary");
+          else
+            error ("__ftp_binary__: invalid ftp handle");
+        }
+     }
+ #else
+   error ("__ftp_mode__: not available in this version of Octave");
+ #endif
+
+   return retval;
+ }
+
+DEFUN_DLD (__ftp_delete__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_delete__ (@var{handle}, @var{path})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 2)
+    error ("__ftp_delete__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string file = args(1).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.del (file);
+          else
+            error ("__ftp_delete__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_delete__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_rmdir__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_rmdir__ (@var{handle}, @var{path})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 2)
+    error ("__ftp_rmdir__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string dir = args(1).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.rmdir (dir);
+          else
+            error ("__ftp_rmdir__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_rmdir__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_mkdir__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_mkdir__ (@var{handle}, @var{path})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 2)
+    error ("__ftp_mkdir__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string dir = args(1).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.mkdir (dir);
+          else
+            error ("__ftp_mkdir__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_mkdir__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+DEFUN_DLD (__ftp_rename__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_rename__ (@var{handle}, @var{path})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 3)
+    error ("__ftp_rename__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string oldname = args(1).string_value ();
+      std::string newname = args(2).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            curl.rename (oldname, newname);
+          else
+            error ("__ftp_rename__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_rename__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
+
+#ifdef HAVE_CURL
+static string_vector
+mput_directory (const curl_handle& curl, const std::string& base,
+                const std::string& dir)
+{
+  string_vector retval;
+
+  if (! curl.mkdir (dir, false))
+    warning ("__ftp_mput__: can not create the remote directory ""%s""",
+             (base.length () == 0 ? dir : base +
+              file_ops::dir_sep_str () + dir).c_str ());
+
+  curl.cwd (dir);
+
+  if (! error_state)
+    {
+      unwind_protect_safe frame;
+
+      frame.add_fcn (reset_path, curl);
+
+      std::string realdir = base.length () == 0 ? dir : base +
+                         file_ops::dir_sep_str () + dir;
+
+      dir_entry dirlist (realdir);
+
+      if (dirlist)
+        {
+          string_vector files = dirlist.read ();
+
+          for (octave_idx_type i = 0; i < files.length (); i++)
+            {
+              std::string file = files (i);
+
+              if (file == "." || file == "..")
+                continue;
+
+              std::string realfile = realdir + file_ops::dir_sep_str () + file;
+              file_stat fs (realfile);
+
+              if (! fs.exists ())
+                {
+                  error ("__ftp__mput: file ""%s"" does not exist",
+                         realfile.c_str ());
+                  break;
+                }
+
+              if (fs.is_dir ())
+                {
+                  retval.append (mput_directory (curl, realdir, file));
+
+                  if (error_state)
+                    break;
+                }
+              else
+                {
+                  // FIXME Does ascii mode need to be flagged here?
+                  std::ifstream ifile (realfile.c_str (), std::ios::in |
+                                       std::ios::binary);
+
+                  if (! ifile.is_open ())
+                    {
+                      error ("__ftp_mput__: unable to open file ""%s""",
+                             realfile.c_str ());
+                      break;
+                    }
+
+                  curl.put (file, ifile);
+
+                  ifile.close ();
+
+                  if (error_state)
+                    break;
+
+                  retval.append (realfile);
+                }
+            }
+        }
+      else
+        error ("__ftp_mput__: can not read the directory ""%s""",
+               realdir.c_str ());
+    }
+
+  return retval;
+}
+#endif
+
+DEFUN_DLD (__ftp_mput__, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_mput__ (@var{handle}, @var{files})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  string_vector retval;
+
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 2)
+    error ("__ftp_mput__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string pat = args(1).string_value ();
+
+      if (!error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            {
+              glob_match pattern (file_ops::tilde_expand (pat));
+              string_vector files = pattern.glob ();
+
+              for (octave_idx_type i = 0; i < files.length (); i++)
+                {
+                  std::string file = files (i);
+
+                  file_stat fs (file);
+
+                  if (! fs.exists ())
+                    {
+                      error ("__ftp__mput: file does not exist");
+                      break;
+                    }
+
+                  if (fs.is_dir ())
+                    {
+                      retval.append (mput_directory (curl, "", file));
+                      if (error_state)
+                        break;
+                    }
+                  else
+                    {
+                      // FIXME Does ascii mode need to be flagged here?
+                      std::ifstream ifile (file.c_str (), std::ios::in |
+                                           std::ios::binary);
+
+                      if (! ifile.is_open ())
+                        {
+                          error ("__ftp_mput__: unable to open file");
+                          break;
+                        }
+
+                      curl.put (file, ifile);
+
+                      ifile.close ();
+
+                      if (error_state)
+                        break;
+
+                      retval.append (file);
+                    }
+                }
+            }
+          else
+            error ("__ftp_mput__: invalid ftp handle");
+        }
+    }
+#else
+  error ("__ftp_mput__: not available in this version of Octave");
+#endif
+
+  return (nargout > 0 ? octave_value (retval) : octave_value ());
+}
+
+#ifdef HAVE_CURL
+static void
+getallfiles (const curl_handle& curl, const std::string& dir,
+             const std::string& target)
+{
+  std::string sep = file_ops::dir_sep_str ();
+  file_stat fs (dir);
+
+  if (!fs || !fs.is_dir ())
+    {
+      std::string msg;
+      int status = octave_mkdir (dir, 0777, msg);
+
+      if (status < 0)
+        error ("__ftp_mget__: can't create directory %s%s%s. %s",
+               target.c_str (), sep.c_str (), dir.c_str (), msg.c_str ());
+    }
+
+  if (! error_state)
+    {
+      curl.cwd (dir);
+
+      if (! error_state)
+        {
+          unwind_protect_safe frame;
+
+          frame.add_fcn (reset_path, curl);
+
+          string_vector sv = curl.list ();
+
+          for (octave_idx_type i = 0; i < sv.length (); i++)
+            {
+              time_t ftime;
+              bool fisdir;
+              double fsize;
+
+              curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
+
+              if (fisdir)
+                getallfiles (curl, sv(i), target + dir + sep);
+              else
+                {
+                  std::string realfile = target + dir + sep + sv(i);
+                  std::ofstream ofile (realfile.c_str (),
+                                       std::ios::out |
+                                       std::ios::binary);
+
+                  if (! ofile.is_open ())
+                    {
+                      error ("__ftp_mget__: unable to open file");
+                      break;
+                    }
+
+                  unwind_protect_safe frame2;
+
+                  frame2.add_fcn (delete_file, realfile);
+
+                  curl.get (sv(i), ofile);
+
+                  ofile.close ();
+
+                  if (!error_state)
+                    frame2.discard ();
+                  else
+                    frame2.run ();
+                }
+
+              if (error_state)
+                break;
+            }
+        }
+    }
+}
+#endif
+
+DEFUN_DLD (__ftp_mget__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __ftp_mget__ (@var{handle}, @var{files})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
+
+  if (nargin != 2 && nargin != 3)
+    error ("__ftp_mget__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
+      std::string file = args(1).string_value ();
+      std::string target;
+
+      if (nargin == 3)
+        target = args(2).string_value () + file_ops::dir_sep_str ();
+
+      if (! error_state)
+        {
+          const curl_handle curl = handles.contents (handle);
+
+          if (curl.is_valid ())
+            {
+              string_vector sv = curl.list ();
+              octave_idx_type n = 0;
+              glob_match pattern (file);
+
+              for (octave_idx_type i = 0; i < sv.length (); i++)
+                {
+                  if (pattern.match (sv(i)))
+                    {
+                      n++;
+
+                      time_t ftime;
+                      bool fisdir;
+                      double fsize;
+
+                      curl.get_fileinfo (sv(i), fsize, ftime, fisdir);
+
+                      if (fisdir)
+                        getallfiles (curl, sv(i), target);
+                      else
+                        {
+                          std::ofstream ofile ((target + sv(i)).c_str (),
+                                               std::ios::out |
+                                               std::ios::binary);
+
+                          if (! ofile.is_open ())
+                            {
+                              error ("__ftp_mget__: unable to open file");
+                              break;
+                            }
+
+                          unwind_protect_safe frame;
+
+                          frame.add_fcn (delete_file, target + sv(i));
+
+                          curl.get (sv(i), ofile);
+
+                          ofile.close ();
+
+                          if (!error_state)
+                            frame.discard ();
+                          else
+                            frame.run ();
+                        }
+
+                      if (error_state)
+                        break;
+                    }
+                }
+              if (n == 0)
+                error ("__ftp_mget__: file not found");
+            }
+        }
+    }
+#else
+  error ("__ftp_mget__: not available in this version of Octave");
+#endif
+
+  return octave_value ();
+}
--- a/src/link-deps.mk	Tue Jul 31 20:46:47 2012 -0400
+++ b/src/link-deps.mk	Tue Jul 31 21:57:58 2012 -0400
@@ -3,7 +3,7 @@
 if AMCOND_ENABLE_DYNAMIC_LINKING
   LIBOCTINTERP_LINK_DEPS =
 else
-  LIBOCTINTERP_LINK_DEPS = $(DLD_FUNCTIONS_LIBS)
+  LIBOCTINTERP_LINK_DEPS = $(DLDFCN_LIBS)
 endif
 
 LIBOCTINTERP_LINK_DEPS += \