view liboctave/UMFPACK.patch @ 5164:57077d0ddc8e

[project @ 2005-02-25 19:55:24 by jwe]
author jwe
date Fri, 25 Feb 2005 19:55:28 +0000
parents
children
line wrap: on
line source

--- UMFPACKv4.4.orig/AMD/Makefile	2004-01-29 20:40:44.000000000 +0100
+++ UMFPACK/AMD/Makefile	2005-02-01 22:00:38.917972334 +0100
@@ -28,11 +28,18 @@
 	( cd Demo   ; make cross )
 	- cat Doc/License
 
+# compile a Octave version
+# (not compiled by "make all")
+octave:
+	( cd OCTAVE ; make )
+	- cat Doc/License
+
 # remove object files, but keep the compiled programs and library archives
 clean:
 	( cd Source ; make clean )
 	( cd Demo   ; make clean )
 	( cd MATLAB ; make clean )
+	( cd OCTAVE ; make clean )
 	( cd Doc    ; make clean )
 
 # clean, and then remove compiled programs and library archives
@@ -40,6 +47,7 @@
 	( cd Source ; make purge )
 	( cd Demo   ; make purge )
 	( cd MATLAB ; make purge )
+	( cd OCTAVE ; make purge )
 	( cd Doc    ; make purge )
 
 # create PDF documents for the original distribution
--- UMFPACKv4.4.orig/UMFPACK/Makefile	2004-01-29 20:40:48.000000000 +0100
+++ UMFPACK/UMFPACK/Makefile	2005-02-01 22:00:38.916972398 +0100
@@ -32,12 +32,19 @@
 hb:
 	( cd Demo   ; make hb )
 
+# compile a Octave version
+# (not compiled by "make all")
+octave:
+	( cd OCTAVE ; make )
+	- cat Doc/License
+
 # remove object files, but keep the compiled programs and library archives
 clean:
 	( cd ../AMD ; make clean )
 	( cd Source ; make clean )
 	( cd Demo   ; make clean )
 	( cd MATLAB ; make clean )
+	( cd OCTAVE ; make clean )
 	( cd Doc    ; make clean )
 
 # clean, and then remove compiled programs and library archives
@@ -46,6 +53,7 @@
 	( cd Source ; make purge )
 	( cd Demo   ; make purge )
 	( cd MATLAB ; make purge )
+	( cd OCTAVE ; make purge )
 	( cd Doc    ; make purge )
 
 # create PDF documents for the original distribution
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/Contents.m UMFPACK/UMFPACK/OCTAVE/Contents.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/Contents.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/Contents.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,1 +1,22 @@
+%Contents of the UMFPACK sparse matrix toolbox:
+%
+% umfpack           computes x=A\b, x=A/b, or lu (A) for a sparse matrix A
+% umfpack_make      to compile umfpack for use in MATLAB
+% umfpack_report    prints optional control settings and statistics
+% umfpack_demo      a long demo
+% umfpack_simple    a simple demo
+% umfpack_btf       factorize A using a block triangular form
+% umfpack_solve     x = A\b or x = b/A 
+% lu_normest        estimates norm (L*U-A, 1) without forming L*U-A
+% luflop	    given L and U, computes # of flops required to compute them
+%
+% See also:
+% amd		    symmetric minimum degree ordering
+% colamd            unsymmetric column approx minimum degree ordering
+% symamd            symmetric approx minimum degree ordering, based on colamd
+%
+% UMFPACK Version 4.3 (Jan. 16, 2004),  Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  Type umfpack_details for License.
+
+help Contents
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/GNUmakefile	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/GNUmakefile	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,248 @@
+#-------------------------------------------------------------------------------
+# UMFPACK GNUmakefile for the UMFPACK OCTAVE oct-file (GNU "make" only)
+#-------------------------------------------------------------------------------
+
+.PRECIOUS: %.o
+
+# UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+# Davis.  All Rights Reserved.  See ../README for License.
+
+all: umfpack luflop
+
+include ../Make/Make.include
+
+MKOCT = mkoctfile $(CONFIG) -DNRECIPROCAL -I/usr/include/atlas -I../Include -I../Source -I../../AMD/Include -I../../AMD/Source
+
+OCT_SPARSE_INC = -I../../../
+
+
+#-------------------------------------------------------------------------------
+# source files
+#-------------------------------------------------------------------------------
+
+# non-user-callable umf_*.[ch] files:
+UMFCH = umf_assemble umf_blas3_update \
+	umf_build_tuples umf_create_element \
+	umf_dump umf_extend_front umf_garbage_collection \
+	umf_get_memory umf_init_front umf_kernel \
+	umf_kernel_init umf_kernel_wrapup \
+	umf_local_search umf_lsolve umf_ltsolve \
+	umf_mem_alloc_element umf_mem_alloc_head_block \
+	umf_mem_alloc_tail_block umf_mem_free_tail_block \
+	umf_mem_init_memoryspace \
+	umf_report_vector umf_row_search umf_scale_column \
+	umf_set_stats umf_solve umf_symbolic_usage umf_transpose \
+	umf_tuple_lengths umf_usolve umf_utsolve umf_valid_numeric \
+	umf_valid_symbolic umf_grow_front umf_start_front umf_2by2 \
+	umf_store_lu umf_scale
+
+# non-user-callable umf_*.[ch] files, int/long versions only (no real/complex):
+UMFINT = umf_analyze umf_apply_order umf_colamd umf_free umf_fsize \
+	umf_is_permutation umf_malloc umf_realloc umf_report_perm \
+	umf_singletons
+
+# non-user-callable and user-callable amd_*.[ch] files (int/long versions only):
+AMD = amd_aat amd_1 amd_2 amd_dump amd_postorder amd_post_tree amd_defaults \
+	amd_order amd_control amd_info amd_valid
+
+# non-user-callable, created from umf_ltsolve.c, umf_utsolve.c,
+# umf_triplet.c, and umf_assemble.c , with int/long and real/complex versions:
+UMF_CREATED = umf_lhsolve umf_uhsolve umf_triplet_map_nox \
+	umf_triplet_nomap_x umf_triplet_nomap_nox umf_triplet_map_x \
+	umf_assemble_fixq umf_store_lu_drop
+
+# non-user-callable, int/long and real/complex versions:
+UMF = $(UMF_CREATED) $(UMFCH)
+
+# user-callable umfpack_*.[ch] files (int/long and real/complex):
+UMFPACK = umfpack_col_to_triplet umfpack_defaults umfpack_free_numeric \
+	umfpack_free_symbolic umfpack_get_numeric umfpack_get_lunz \
+	umfpack_get_symbolic umfpack_get_determinant umfpack_numeric \
+	umfpack_qsymbolic umfpack_report_control umfpack_report_info \
+	umfpack_report_matrix umfpack_report_numeric umfpack_report_perm \
+	umfpack_report_status umfpack_report_symbolic umfpack_report_triplet \
+	umfpack_report_vector umfpack_solve umfpack_symbolic \
+	umfpack_transpose umfpack_triplet_to_col umfpack_scale \
+	umfpack_load_numeric umfpack_save_numeric \
+	umfpack_load_symbolic umfpack_save_symbolic
+
+# user-callable, created from umfpack_solve.c (umfpack_wsolve.h exists, though):
+# with int/long and real/complex versions:
+UMFPACKW = umfpack_wsolve
+
+USER = $(UMFPACKW) $(UMFPACK)
+
+# user-callable, only one version for int/long, real/complex, *.[ch] files:
+GENERIC = umfpack_timer umfpack_tictoc
+
+#-------------------------------------------------------------------------------
+# include files:
+#-------------------------------------------------------------------------------
+
+AMDH = ../../AMD/Source/amd_internal.h ../../AMD/Include/amd.h
+
+INC1 = umf_config.h umf_version.h umf_internal.h umf_triplet.h
+
+INC = ../Include/umfpack.h \
+	$(addprefix ../Source/, $(INC1)) \
+	$(addprefix ../Source/, $(addsuffix .h,$(UMFCH))) \
+	$(addprefix ../Source/, $(addsuffix .h,$(UMFINT))) \
+	$(addprefix ../Include/, $(addsuffix .h,$(USER))) \
+	$(addprefix ../Include/, $(addsuffix .h,$(GENERIC))) \
+	$(AMDH)
+
+#-------------------------------------------------------------------------------
+# Create the umfpack and amd oct-file for OCTAVE (int versions only)
+#-------------------------------------------------------------------------------
+
+OCTI   = $(addsuffix .o, $(subst umf_,umf_o_,$(UMFINT)))
+OCTDI  = $(addsuffix .o, $(subst umf_,umf_od_,$(UMF)) $(subst umfpack_,umfpack_od_,$(USER)))
+OCTZI  = $(addsuffix .o, $(subst umf_,umf_oz_,$(UMF)) $(subst umfpack_,umfpack_oz_,$(USER)) )
+OCTAMD = $(addsuffix .o, $(subst amd_,amd_o_,$(AMD)))
+OCTGN  = $(addsuffix .o, $(subst umfpack_,umfpack_o_,$(GENERIC)))
+
+OCTUMFPACK = $(OCTI) $(OCTDI) $(OCTZI) $(OCTGN)
+
+OCTUMFPACK_LIB = umfpack_octave.o
+
+# Note that mkoctfile has an "-o" option, but it doesn't work in conjunction
+# with the "-c" option, thus the need for $(MV) commands.
+# If it did, then the rules would be much simpler:
+#	$(MKOCT) -DDINT -c $< -o $@
+
+#----------------------------------------
+# integer-only routines (no real/complex):
+#----------------------------------------
+
+amd_o_%.o: ../../AMD/Source/amd_%.c $(AMDH)
+	$(MKOCT) -DDINT -c $<
+	- $(MV) ../../AMD/Source/amd_$*.o $@
+
+
+umf_o_%.o: ../Source/umf_%.c $(INC)
+	$(MKOCT) -DDINT -c $<
+	- $(MV) ../Source/umf_$*.o $@
+
+#----------------------------------------
+# Double precision, int version, for OCTAVE
+#----------------------------------------
+
+umf_od_%.o: ../Source/umf_%.c $(INC)
+	$(MKOCT) -DDINT -c $<
+	- $(MV) ../Source/umf_$*.o $@
+
+umf_od_%hsolve.o: ../Source/umf_%tsolve.c $(INC)
+	$(MKOCT) -DDINT -DCONJUGATE_SOLVE -c $<
+	- $(MV) ../Source/umf_$*tsolve.o $@
+
+umf_od_triplet_map_x.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DDINT -DDO_MAP -DDO_VALUES -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_od_triplet_map_nox.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DDINT -DDO_MAP -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_od_triplet_nomap_x.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DDINT -DDO_VALUES -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_od_triplet_nomap_nox.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DDINT -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_od_assemble_fixq.o: ../Source/umf_assemble.c $(INC)
+	$(MKOCT) -DDINT -DFIXQ -c $<
+	- $(MV) ../Source/umf_assemble.o $@
+
+umf_od_store_lu_drop.o: ../Source/umf_store_lu.c $(INC)
+	$(MKOCT) -DDINT -DDROP -c $<
+	- $(MV) ../Source/umf_store_lu.o $@
+
+umfpack_od_wsolve.o: ../Source/umfpack_solve.c $(INC)
+	$(MKOCT) -DDINT -DWSOLVE -c $<
+	- $(MV) ../Source/umfpack_solve.o $@
+
+umfpack_od_%.o: ../Source/umfpack_%.c $(INC)
+	$(MKOCT) -DDINT -c $<
+	- $(MV) ../Source/umfpack_$*.o $@
+
+#----------------------------------------
+# Complex double precision, int version, for OCTAVE
+#----------------------------------------
+
+umf_oz_%.o: ../Source/umf_%.c $(INC)
+	$(MKOCT) -DZINT -c $<
+	- $(MV) ../Source/umf_$*.o $@
+
+umf_oz_%hsolve.o: ../Source/umf_%tsolve.c $(INC)
+	$(MKOCT) -DZINT -DCONJUGATE_SOLVE -c $<
+	- $(MV) ../Source/umf_$*tsolve.o $@
+
+umf_oz_triplet_map_x.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DZINT -DDO_MAP -DDO_VALUES -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_oz_triplet_map_nox.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DZINT -DDO_MAP -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_oz_triplet_nomap_x.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DZINT -DDO_VALUES -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_oz_triplet_nomap_nox.o: ../Source/umf_triplet.c $(INC)
+	$(MKOCT) -DZINT -c $<
+	- $(MV) ../Source/umf_triplet.o $@
+
+umf_oz_assemble_fixq.o: ../Source/umf_assemble.c $(INC)
+	$(MKOCT) -DZINT -DFIXQ -c $<
+	- $(MV) ../Source/umf_assemble.o $@
+
+umf_oz_store_lu_drop.o: ../Source/umf_store_lu.c $(INC)
+	$(MKOCT) -DZINT -DDROP -c $<
+	- $(MV) ../Source/umf_store_lu.o $@
+
+umfpack_oz_wsolve.o: ../Source/umfpack_solve.c $(INC)
+	$(MKOCT) -DZINT -DWSOLVE -c $<
+	- $(MV) ../Source/umfpack_solve.o $@
+
+umfpack_oz_%.o: ../Source/umfpack_%.c $(INC)
+	$(MKOCT) -DZINT -c $<
+	- $(MV) ../Source/umfpack_$*.o $@
+
+#----------------------------------------
+# Generic routines for OCTAVE
+#----------------------------------------
+
+umfpack_o_timer.o: ../Source/umfpack_timer.c $(INC)
+	$(MKOCT) -c $<
+	- $(MV) ../Source/umfpack_timer.o $@
+
+umfpack_o_tictoc.o: ../Source/umfpack_tictoc.c $(INC)
+	$(MKOCT) -c $<
+	- $(MV) ../Source/umfpack_tictoc.o $@
+
+#----------------------------------------
+# umfpack oct-files
+#----------------------------------------
+
+umfpack: umfpack.cc $(OCTUMFPACK) $(OCTAMD)
+	$(MKOCT) $(OCT_SPARSE_INC) umfpack.cc $(OCTUMFPACK) $(OCTAMD)  -o umfpack.oct 
+
+luflop: luflop.cc
+	$(MKOCT) $(OCT_SPARSE_INC) luflop.cc -o luflop.oct
+
+#----------------------------------------
+# umfpack library to link with octave
+#----------------------------------------
+
+octave: $(OCTUMFPACK) $(OCTAMD)
+	ld -r $(OCTUMFPACK) $(OCTAMD) -o ../../../$(OCTUMFPACK_LIB)
+
+#-------------------------------------------------------------------------------
+# Remove all but the files in the original distribution
+#-------------------------------------------------------------------------------
+
+purge: clean
+	- $(RM) *.oct *.so
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/luflop.cc UMFPACK/UMFPACK/OCTAVE/luflop.cc
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/luflop.cc	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/luflop.cc	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,223 @@
+/*
+
+Copyright (C) 2004 David Bateman
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+In addition to the terms of the GPL, you are permitted to link
+this program with any Open Source program, as defined by the
+Open Source Initiative (www.opensource.org)
+
+*/
+
+/*
+
+This is the Octave interface to the UMFPACK code, which bore the following
+copyright
+
+  UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+  Davis.  All Rights Reserved.  See ../README for License.
+  email: davis@cise.ufl.edu    CISE Department, Univ. of Florida.
+  web: http://www.cise.ufl.edu/research/sparse/umfpack
+
+*/
+
+
+#include <cstdlib>
+#include <string>
+
+#include <octave/config.h>
+#include <octave/ov.h>
+#include <octave/defun-dld.h>
+#include <octave/pager.h>
+#include <octave/ov-re-mat.h>
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+DEFUN_DLD (luflop, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{f} =} luflup (@var{l}, @var{u})\n\
+\n\
+Given an LU factorization, compute how many flops took to compute it. This\n\
+is the same as (assuming U has a zero-free diagonal):\n\
+\n\
+@example\n\
+@group\n\
+  Lnz = full (sum (spones (L))) - 1 ;\n\
+  Unz = full (sum (spones (U')))' - 1 ;\n\
+  f = 2*Lnz*Unz + sum (Lnz) ;\n\
+@end group\n\
+@end example\n\
+\n\
+except that no extra workspace is allocated for spones (L) and spones (U).\n\
+L and U must be sparse.\n\
+\n\
+Note: the above expression has a subtle undercount when exact numerical\n\
+cancelation occurs.  Try [L,U,P] = lu (sparse (ones (10))) and then\n\
+luflop (L,U).\n\
+@end deftypefn")
+{
+  int nargin = args.length ();
+  octave_value retval;
+
+  // These are here only so that the C++ destructors don't prematurally
+  // remove the underlying data we are interested in
+  SparseMatrix Lmatrix, Umatrix;
+  SparseComplexMatrix CLmatrix, CUmatrix;
+  int *Lp, *Li, *Up, *Ui;
+  int Lm, Ln, Um, Un;
+
+  if (nargin != 2)
+    {
+      usage ("f = luflop (L, U)");
+      return retval;
+    }
+
+  if (args(0).class_name () == "sparse")
+    {
+      if (args(0).is_complex_type ())
+	{
+	  CLmatrix = 
+	    (((const octave_sparse_complex_matrix&) args(0).get_rep ())
+	     .sparse_complex_matrix_value ());
+	  Lp = CLmatrix.cidx ();
+	  Li = CLmatrix.ridx ();
+	  Lm = CLmatrix.rows ();
+	  Ln = CLmatrix.cols ();
+	}
+      else
+	{
+	  Lmatrix = (((const octave_sparse_matrix&) args(0).get_rep ())
+	     .sparse_matrix_value ());
+	  Lp = Lmatrix.cidx ();
+	  Li = Lmatrix.ridx ();
+	  Lm = Lmatrix.rows ();
+	  Ln = Lmatrix.cols ();
+	}
+    }
+  else
+    {
+      if (args(0).is_complex_type ())
+	{
+	  CLmatrix =  SparseComplexMatrix (args(0).complex_matrix_value ());
+	  Lp = CLmatrix.cidx ();
+	  Li = CLmatrix.ridx ();
+	  Lm = CLmatrix.rows ();
+	  Ln = CLmatrix.cols ();
+	}
+      else
+	{
+	  Lmatrix = SparseMatrix (args(0).matrix_value ());
+	  Lp = Lmatrix.cidx ();
+	  Li = Lmatrix.ridx ();
+	  Lm = Lmatrix.rows ();
+	  Ln = Lmatrix.cols ();
+	}
+    }
+
+
+  if (args(0).class_name () == "sparse")
+    {
+      if (args(1).is_complex_type ())
+	{
+	  CUmatrix = 
+	    (((const octave_sparse_complex_matrix&) args(1).get_rep ())
+	     .sparse_complex_matrix_value ());
+	  Up = CUmatrix.cidx ();
+	  Ui = CUmatrix.ridx ();
+	  Um = CUmatrix.rows ();
+	  Un = CUmatrix.cols ();
+	}
+      else
+	{
+	  Umatrix = 
+	    (((const octave_sparse_matrix&) args(1).get_rep ())
+	     .sparse_matrix_value ());
+	  Up = Umatrix.cidx ();
+	  Ui = Umatrix.ridx ();
+	  Um = Umatrix.rows ();
+	  Un = Umatrix.cols ();
+	}
+    }
+  else
+    {
+      if (args(1).is_complex_type ())
+	{
+	  CUmatrix = SparseComplexMatrix (args(1).complex_matrix_value ());
+	  Up = CUmatrix.cidx ();
+	  Ui = CUmatrix.ridx ();
+	  Um = CUmatrix.rows ();
+	  Un = CUmatrix.cols ();
+	}
+      else
+	{
+	  Umatrix = SparseMatrix (args(1).matrix_value ());
+	  Up = Umatrix.cidx ();
+	  Ui = Umatrix.ridx ();
+	  Um = Umatrix.rows ();
+	  Un = Umatrix.cols ();
+	}
+    }
+
+
+  if (error_state)
+    return retval;
+
+      
+  int n = Lm;
+      
+  if (n != Ln || n != Um || n != Un)
+    error ("luflop: L and U must be square");
+  else
+    {
+	
+      OCTAVE_LOCAL_BUFFER (int, Unz, n);
+
+      // count the nonzeros in each row of U
+      for (int row = 0 ; row < n ; row++)
+	Unz [row] = 0 ;
+
+      for (int col = 0 ; col < n ; col++)
+	{
+	  for (int p = Up [col] ; p < Up [col+1] ; p++)
+	    {
+	      int row = Ui [p] ;
+	      Unz [row]++ ;
+	    }
+	}
+
+      // count the flops
+      double flop_count = 0.0 ;
+      for (int k = 0 ; k < n ; k++)
+	{
+	  /* off-diagonal nonzeros in column k of L: */
+	  int Lnz_k = Lp [k+1] - Lp [k] - 1 ;
+	  int Unz_k = Unz [k] - 1 ;
+	  flop_count += (2 * Lnz_k * Unz_k) + Lnz_k ;
+	}
+
+      // return the result
+      retval = flop_count;
+    }
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/lu_normest.m UMFPACK/UMFPACK/OCTAVE/lu_normest.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/lu_normest.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/lu_normest.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,106 @@
+function rho = lu_normest (A, L, U)
+% LU_NORMEST:  estimate the 1-norm of A-L*U without computing L*U
+%
+% Usage:
+%
+%       rho = lu_normest (A, L, U)
+%
+% which estimates the computation of the 1-norm:
+%
+%       rho = norm (A-L*U, 1) 
+%
+% Authors:  William W. Hager, Math Dept., Univ. of Florida
+%       Timothy A. Davis, CISE Dept., Univ. of Florida
+%       Gainesville, FL, 32611, USA.
+%       based on normest1, contributed on November, 1997
+%
+% This code can be quite easily adapted to estimate the 1-norm of any 
+% matrix E, where E itself is dense or not explicitly represented, but the
+% computation of E (and E') times a vector is easy.  In this case, our matrix
+% of interest is:
+%
+%       E = A-L*U
+%
+% That is, L*U is the LU factorization of A, where A, L and U
+% are sparse.  This code works for dense matrices A and L too,
+% but it would not be needed in that case, since E is easy to compute
+% explicitly.  For sparse A, L, and U, computing E explicitly would be quite
+% expensive, and thus normest (A-L*U) would be prohibitive.
+%
+% For a detailed description, see Davis, T. A. and Hager, W. W.,
+% Modifying a sparse Cholesky factorization, SIAM J. Matrix Analysis and
+% Applications, 1999, vol. 20, no. 3, 606-627.
+
+% The three places that the matrix-vector multiply E*x is used are highlighted.
+% Note that E is never formed explicity.
+
+[m n] = size (A) ;
+
+if (m ~= n)
+    % pad A, L, and U with zeros so that they are all square
+    if (m < n)
+        U = [ U ; (sparse (n-m,n)) ] ;
+        L = [ L , (sparse (m,n-m)) ; (sparse (n-m,n)) ] ;
+        A = [ A ; (sparse (n-m,n)) ] ;
+    else
+        U = [ U , (sparse (n,m-n)) ; (sparse (m-n,m)) ] ;
+        L = [ L , (sparse (m,m-n)) ] ;
+        A = [ A , (sparse (m,m-n)) ] ;
+    end
+end
+
+[m n] = size (A) ;
+
+notvisited = ones (m, 1) ;  % nonvisited(j) is zero if j is visited, 1 otherwise
+rho = 0 ;    % the global rho
+
+At = A' ;
+Lt = L' ;
+
+for trial = 1:3 % {
+
+   x = notvisited ./ sum (notvisited) ;
+   rho1 = 0 ;    % the current rho for this trial
+
+   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+   %%% COMPUTE Ex1 = E*x EFFICIENTLY: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+   Ex1 = (A*x) - L*(U*x) ;
+   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+   rho2 = norm (Ex1, 1) ;
+
+   while rho2 > rho1 % {
+
+        rho1 = rho2 ;
+        y = 2*(Ex1 >= 0) - 1 ;
+
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        %%% COMPUTE z = E'*y EFFICIENTLY: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        z = (A'*y) - U'*(L'*y) ;
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+        [zj, j] = max (abs (z .* notvisited)) ;
+        j = j (1) ;
+        if (abs (z (j)) > z'*x) % {
+            x = zeros (m, 1) ;
+            x (j) = 1 ;
+            notvisited (j) = 0 ;
+        else % } {
+            break ;
+        end % }
+
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        %%% COMPUTE Ex1 = E*x EFFICIENTLY: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+        Ex1 = (A*x) - L*(U*x) ;
+        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+        rho2 = norm (Ex1, 1) ;
+
+    end % }
+
+    rho = max (rho, rho1) ;
+
+end % }
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/Makefile UMFPACK/UMFPACK/OCTAVE/Makefile
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/Makefile	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,517 @@
+#-------------------------------------------------------------------------------
+# UMFPACK Makefile for the UMFPACK MATLAB mexFunction (old "make" only)
+#-------------------------------------------------------------------------------
+
+# UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+# Davis.  All Rights Reserved.  See ../README for License.
+
+# This is a very ugly Makefile, and is only provided for those who do not
+# have GNU make.  Note that it is not used if you have GNU make.  It ignores
+# dependency checking and just compiles everything.  It was created
+# automatically, via make -n using the GNUmakefile.  That way, I don't have
+# maintain two Makefiles.
+
+all: umfpack luflop
+
+include ../Make/Make.include
+
+MKOCT = mkoctfile $(CONFIG) -DNRECIPROCAL -I/usr/include/atlas -I../Include -I../Source -I../../AMD/Include -I../../AMD/Source 
+
+OCT_SPARSE_INC = -I../../../
+OCTUMFPACK_LIB = umfpack_octave.o
+
+umfpack:
+	$(MKOCT) -DDINT -c ../Source/umf_analyze.c
+	$(MV) -f ../Source/umf_analyze.o umf_m_analyze.o
+	$(MKOCT) -DDINT -c ../Source/umf_apply_order.c
+	$(MV) -f ../Source/umf_apply_order.o umf_m_apply_order.o
+	$(MKOCT) -DDINT -c ../Source/umf_colamd.c
+	$(MV) -f ../Source/umf_colamd.o umf_m_colamd.o
+	$(MKOCT) -DDINT -c ../Source/umf_free.c
+	$(MV) -f ../Source/umf_free.o umf_m_free.o
+	$(MKOCT) -DDINT -c ../Source/umf_fsize.c
+	$(MV) -f ../Source/umf_fsize.o umf_m_fsize.o
+	$(MKOCT) -DDINT -c ../Source/umf_is_permutation.c
+	$(MV) -f ../Source/umf_is_permutation.o umf_m_is_permutation.o
+	$(MKOCT) -DDINT -c ../Source/umf_malloc.c
+	$(MV) -f ../Source/umf_malloc.o umf_m_malloc.o
+	$(MKOCT) -DDINT -c ../Source/umf_realloc.c
+	$(MV) -f ../Source/umf_realloc.o umf_m_realloc.o
+	$(MKOCT) -DDINT -c ../Source/umf_report_perm.c
+	$(MV) -f ../Source/umf_report_perm.o umf_m_report_perm.o
+	$(MKOCT) -DDINT -c ../Source/umf_singletons.c
+	$(MV) -f ../Source/umf_singletons.o umf_m_singletons.o
+	$(MKOCT) -DDINT -DCONJUGATE_SOLVE -c ../Source/umf_ltsolve.c
+	$(MV) -f ../Source/umf_ltsolve.o umf_od_lhsolve.o
+	$(MKOCT) -DDINT -DCONJUGATE_SOLVE -c ../Source/umf_utsolve.c
+	$(MV) -f ../Source/umf_utsolve.o umf_od_uhsolve.o
+	$(MKOCT) -DDINT -DDO_MAP -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_od_triplet_map_nox.o
+	$(MKOCT) -DDINT -DDO_VALUES -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_od_triplet_nomap_x.o
+	$(MKOCT) -DDINT -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_od_triplet_nomap_nox.o
+	$(MKOCT) -DDINT -DDO_MAP -DDO_VALUES -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_od_triplet_map_x.o
+	$(MKOCT) -DDINT -DFIXQ -c ../Source/umf_assemble.c
+	$(MV) -f ../Source/umf_assemble.o umf_od_assemble_fixq.o
+	$(MKOCT) -DDINT -DDROP -c ../Source/umf_store_lu.c
+	$(MV) -f ../Source/umf_store_lu.o umf_od_store_lu_drop.o
+	$(MKOCT) -DDINT -c ../Source/umf_assemble.c
+	$(MV) -f ../Source/umf_assemble.o umf_od_assemble.o
+	$(MKOCT) -DDINT -c ../Source/umf_blas3_update.c
+	$(MV) -f ../Source/umf_blas3_update.o umf_od_blas3_update.o
+	$(MKOCT) -DDINT -c ../Source/umf_build_tuples.c
+	$(MV) -f ../Source/umf_build_tuples.o umf_od_build_tuples.o
+	$(MKOCT) -DDINT -c ../Source/umf_create_element.c
+	$(MV) -f ../Source/umf_create_element.o umf_od_create_element.o
+	$(MKOCT) -DDINT -c ../Source/umf_dump.c
+	$(MV) -f ../Source/umf_dump.o umf_od_dump.o
+	$(MKOCT) -DDINT -c ../Source/umf_extend_front.c
+	$(MV) -f ../Source/umf_extend_front.o umf_od_extend_front.o
+	$(MKOCT) -DDINT -c ../Source/umf_garbage_collection.c
+	$(MV) -f ../Source/umf_garbage_collection.o umf_od_garbage_collection.o
+	$(MKOCT) -DDINT -c ../Source/umf_get_memory.c
+	$(MV) -f ../Source/umf_get_memory.o umf_od_get_memory.o
+	$(MKOCT) -DDINT -c ../Source/umf_init_front.c
+	$(MV) -f ../Source/umf_init_front.o umf_od_init_front.o
+	$(MKOCT) -DDINT -c ../Source/umf_kernel.c
+	$(MV) -f ../Source/umf_kernel.o umf_od_kernel.o
+	$(MKOCT) -DDINT -c ../Source/umf_kernel_init.c
+	$(MV) -f ../Source/umf_kernel_init.o umf_od_kernel_init.o
+	$(MKOCT) -DDINT -c ../Source/umf_kernel_wrapup.c
+	$(MV) -f ../Source/umf_kernel_wrapup.o umf_od_kernel_wrapup.o
+	$(MKOCT) -DDINT -c ../Source/umf_local_search.c
+	$(MV) -f ../Source/umf_local_search.o umf_od_local_search.o
+	$(MKOCT) -DDINT -c ../Source/umf_lsolve.c
+	$(MV) -f ../Source/umf_lsolve.o umf_od_lsolve.o
+	$(MKOCT) -DDINT -c ../Source/umf_ltsolve.c
+	$(MV) -f ../Source/umf_ltsolve.o umf_od_ltsolve.o
+	$(MKOCT) -DDINT -c ../Source/umf_mem_alloc_element.c
+	$(MV) -f ../Source/umf_mem_alloc_element.o umf_od_mem_alloc_element.o
+	$(MKOCT) -DDINT -c ../Source/umf_mem_alloc_head_block.c
+	$(MV) -f ../Source/umf_mem_alloc_head_block.o umf_od_mem_alloc_head_block.o
+	$(MKOCT) -DDINT -c ../Source/umf_mem_alloc_tail_block.c
+	$(MV) -f ../Source/umf_mem_alloc_tail_block.o umf_od_mem_alloc_tail_block.o
+	$(MKOCT) -DDINT -c ../Source/umf_mem_free_tail_block.c
+	$(MV) -f ../Source/umf_mem_free_tail_block.o umf_od_mem_free_tail_block.o
+	$(MKOCT) -DDINT -c ../Source/umf_mem_init_memoryspace.c
+	$(MV) -f ../Source/umf_mem_init_memoryspace.o umf_od_mem_init_memoryspace.o
+	$(MKOCT) -DDINT -c ../Source/umf_report_vector.c
+	$(MV) -f ../Source/umf_report_vector.o umf_od_report_vector.o
+	$(MKOCT) -DDINT -c ../Source/umf_row_search.c
+	$(MV) -f ../Source/umf_row_search.o umf_od_row_search.o
+	$(MKOCT) -DDINT -c ../Source/umf_scale_column.c
+	$(MV) -f ../Source/umf_scale_column.o umf_od_scale_column.o
+	$(MKOCT) -DDINT -c ../Source/umf_set_stats.c
+	$(MV) -f ../Source/umf_set_stats.o umf_od_set_stats.o
+	$(MKOCT) -DDINT -c ../Source/umf_solve.c
+	$(MV) -f ../Source/umf_solve.o umf_od_solve.o
+	$(MKOCT) -DDINT -c ../Source/umf_symbolic_usage.c
+	$(MV) -f ../Source/umf_symbolic_usage.o umf_od_symbolic_usage.o
+	$(MKOCT) -DDINT -c ../Source/umf_transpose.c
+	$(MV) -f ../Source/umf_transpose.o umf_od_transpose.o
+	$(MKOCT) -DDINT -c ../Source/umf_tuple_lengths.c
+	$(MV) -f ../Source/umf_tuple_lengths.o umf_od_tuple_lengths.o
+	$(MKOCT) -DDINT -c ../Source/umf_usolve.c
+	$(MV) -f ../Source/umf_usolve.o umf_od_usolve.o
+	$(MKOCT) -DDINT -c ../Source/umf_utsolve.c
+	$(MV) -f ../Source/umf_utsolve.o umf_od_utsolve.o
+	$(MKOCT) -DDINT -c ../Source/umf_valid_numeric.c
+	$(MV) -f ../Source/umf_valid_numeric.o umf_od_valid_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umf_valid_symbolic.c
+	$(MV) -f ../Source/umf_valid_symbolic.o umf_od_valid_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umf_grow_front.c
+	$(MV) -f ../Source/umf_grow_front.o umf_od_grow_front.o
+	$(MKOCT) -DDINT -c ../Source/umf_start_front.c
+	$(MV) -f ../Source/umf_start_front.o umf_od_start_front.o
+	$(MKOCT) -DDINT -c ../Source/umf_2by2.c
+	$(MV) -f ../Source/umf_2by2.o umf_od_2by2.o
+	$(MKOCT) -DDINT -c ../Source/umf_store_lu.c
+	$(MV) -f ../Source/umf_store_lu.o umf_od_store_lu.o
+	$(MKOCT) -DDINT -c ../Source/umf_scale.c
+	$(MV) -f ../Source/umf_scale.o umf_od_scale.o
+	$(MKOCT) -DDINT -DWSOLVE -c ../Source/umfpack_solve.c
+	$(MV) -f ../Source/umfpack_solve.o umfpack_od_wsolve.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_col_to_triplet.c
+	$(MV) -f ../Source/umfpack_col_to_triplet.o umfpack_od_col_to_triplet.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_defaults.c
+	$(MV) -f ../Source/umfpack_defaults.o umfpack_od_defaults.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_free_numeric.c
+	$(MV) -f ../Source/umfpack_free_numeric.o umfpack_od_free_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_free_symbolic.c
+	$(MV) -f ../Source/umfpack_free_symbolic.o umfpack_od_free_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_get_numeric.c
+	$(MV) -f ../Source/umfpack_get_numeric.o umfpack_od_get_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_get_lunz.c
+	$(MV) -f ../Source/umfpack_get_lunz.o umfpack_od_get_lunz.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_get_symbolic.c
+	$(MV) -f ../Source/umfpack_get_symbolic.o umfpack_od_get_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_get_determinant.c
+	$(MV) -f ../Source/umfpack_get_determinant.o umfpack_od_get_determinant.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_numeric.c
+	$(MV) -f ../Source/umfpack_numeric.o umfpack_od_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_qsymbolic.c
+	$(MV) -f ../Source/umfpack_qsymbolic.o umfpack_od_qsymbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_control.c
+	$(MV) -f ../Source/umfpack_report_control.o umfpack_od_report_control.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_info.c
+	$(MV) -f ../Source/umfpack_report_info.o umfpack_od_report_info.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_matrix.c
+	$(MV) -f ../Source/umfpack_report_matrix.o umfpack_od_report_matrix.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_numeric.c
+	$(MV) -f ../Source/umfpack_report_numeric.o umfpack_od_report_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_perm.c
+	$(MV) -f ../Source/umfpack_report_perm.o umfpack_od_report_perm.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_status.c
+	$(MV) -f ../Source/umfpack_report_status.o umfpack_od_report_status.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_symbolic.c
+	$(MV) -f ../Source/umfpack_report_symbolic.o umfpack_od_report_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_triplet.c
+	$(MV) -f ../Source/umfpack_report_triplet.o umfpack_od_report_triplet.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_report_vector.c
+	$(MV) -f ../Source/umfpack_report_vector.o umfpack_od_report_vector.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_solve.c
+	$(MV) -f ../Source/umfpack_solve.o umfpack_od_solve.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_symbolic.c
+	$(MV) -f ../Source/umfpack_symbolic.o umfpack_od_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_transpose.c
+	$(MV) -f ../Source/umfpack_transpose.o umfpack_od_transpose.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_triplet_to_col.c
+	$(MV) -f ../Source/umfpack_triplet_to_col.o umfpack_od_triplet_to_col.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_scale.c
+	$(MV) -f ../Source/umfpack_scale.o umfpack_od_scale.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_load_numeric.c
+	$(MV) -f ../Source/umfpack_load_numeric.o umfpack_od_load_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_save_numeric.c
+	$(MV) -f ../Source/umfpack_save_numeric.o umfpack_od_save_numeric.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_load_symbolic.c
+	$(MV) -f ../Source/umfpack_load_symbolic.o umfpack_od_load_symbolic.o
+	$(MKOCT) -DDINT -c ../Source/umfpack_save_symbolic.c
+	$(MV) -f ../Source/umfpack_save_symbolic.o umfpack_od_save_symbolic.o
+	$(MKOCT) -DZINT -DCONJUGATE_SOLVE -c ../Source/umf_ltsolve.c
+	$(MV) -f ../Source/umf_ltsolve.o umf_oz_lhsolve.o
+	$(MKOCT) -DZINT -DCONJUGATE_SOLVE -c ../Source/umf_utsolve.c
+	$(MV) -f ../Source/umf_utsolve.o umf_oz_uhsolve.o
+	$(MKOCT) -DZINT -DDO_MAP -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_oz_triplet_map_nox.o
+	$(MKOCT) -DZINT -DDO_VALUES -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_oz_triplet_nomap_x.o
+	$(MKOCT) -DZINT -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_oz_triplet_nomap_nox.o
+	$(MKOCT) -DZINT -DDO_MAP -DDO_VALUES -c ../Source/umf_triplet.c
+	$(MV) -f ../Source/umf_triplet.o umf_oz_triplet_map_x.o
+	$(MKOCT) -DZINT -DFIXQ -c ../Source/umf_assemble.c
+	$(MV) -f ../Source/umf_assemble.o umf_oz_assemble_fixq.o
+	$(MKOCT) -DZINT -DDROP -c ../Source/umf_store_lu.c
+	$(MV) -f ../Source/umf_store_lu.o umf_oz_store_lu_drop.o
+	$(MKOCT) -DZINT -c ../Source/umf_assemble.c
+	$(MV) -f ../Source/umf_assemble.o umf_oz_assemble.o
+	$(MKOCT) -DZINT -c ../Source/umf_blas3_update.c
+	$(MV) -f ../Source/umf_blas3_update.o umf_oz_blas3_update.o
+	$(MKOCT) -DZINT -c ../Source/umf_build_tuples.c
+	$(MV) -f ../Source/umf_build_tuples.o umf_oz_build_tuples.o
+	$(MKOCT) -DZINT -c ../Source/umf_create_element.c
+	$(MV) -f ../Source/umf_create_element.o umf_oz_create_element.o
+	$(MKOCT) -DZINT -c ../Source/umf_dump.c
+	$(MV) -f ../Source/umf_dump.o umf_oz_dump.o
+	$(MKOCT) -DZINT -c ../Source/umf_extend_front.c
+	$(MV) -f ../Source/umf_extend_front.o umf_oz_extend_front.o
+	$(MKOCT) -DZINT -c ../Source/umf_garbage_collection.c
+	$(MV) -f ../Source/umf_garbage_collection.o umf_oz_garbage_collection.o
+	$(MKOCT) -DZINT -c ../Source/umf_get_memory.c
+	$(MV) -f ../Source/umf_get_memory.o umf_oz_get_memory.o
+	$(MKOCT) -DZINT -c ../Source/umf_init_front.c
+	$(MV) -f ../Source/umf_init_front.o umf_oz_init_front.o
+	$(MKOCT) -DZINT -c ../Source/umf_kernel.c
+	$(MV) -f ../Source/umf_kernel.o umf_oz_kernel.o
+	$(MKOCT) -DZINT -c ../Source/umf_kernel_init.c
+	$(MV) -f ../Source/umf_kernel_init.o umf_oz_kernel_init.o
+	$(MKOCT) -DZINT -c ../Source/umf_kernel_wrapup.c
+	$(MV) -f ../Source/umf_kernel_wrapup.o umf_oz_kernel_wrapup.o
+	$(MKOCT) -DZINT -c ../Source/umf_local_search.c
+	$(MV) -f ../Source/umf_local_search.o umf_oz_local_search.o
+	$(MKOCT) -DZINT -c ../Source/umf_lsolve.c
+	$(MV) -f ../Source/umf_lsolve.o umf_oz_lsolve.o
+	$(MKOCT) -DZINT -c ../Source/umf_ltsolve.c
+	$(MV) -f ../Source/umf_ltsolve.o umf_oz_ltsolve.o
+	$(MKOCT) -DZINT -c ../Source/umf_mem_alloc_element.c
+	$(MV) -f ../Source/umf_mem_alloc_element.o umf_oz_mem_alloc_element.o
+	$(MKOCT) -DZINT -c ../Source/umf_mem_alloc_head_block.c
+	$(MV) -f ../Source/umf_mem_alloc_head_block.o umf_oz_mem_alloc_head_block.o
+	$(MKOCT) -DZINT -c ../Source/umf_mem_alloc_tail_block.c
+	$(MV) -f ../Source/umf_mem_alloc_tail_block.o umf_oz_mem_alloc_tail_block.o
+	$(MKOCT) -DZINT -c ../Source/umf_mem_free_tail_block.c
+	$(MV) -f ../Source/umf_mem_free_tail_block.o umf_oz_mem_free_tail_block.o
+	$(MKOCT) -DZINT -c ../Source/umf_mem_init_memoryspace.c
+	$(MV) -f ../Source/umf_mem_init_memoryspace.o umf_oz_mem_init_memoryspace.o
+	$(MKOCT) -DZINT -c ../Source/umf_report_vector.c
+	$(MV) -f ../Source/umf_report_vector.o umf_oz_report_vector.o
+	$(MKOCT) -DZINT -c ../Source/umf_row_search.c
+	$(MV) -f ../Source/umf_row_search.o umf_oz_row_search.o
+	$(MKOCT) -DZINT -c ../Source/umf_scale_column.c
+	$(MV) -f ../Source/umf_scale_column.o umf_oz_scale_column.o
+	$(MKOCT) -DZINT -c ../Source/umf_set_stats.c
+	$(MV) -f ../Source/umf_set_stats.o umf_oz_set_stats.o
+	$(MKOCT) -DZINT -c ../Source/umf_solve.c
+	$(MV) -f ../Source/umf_solve.o umf_oz_solve.o
+	$(MKOCT) -DZINT -c ../Source/umf_symbolic_usage.c
+	$(MV) -f ../Source/umf_symbolic_usage.o umf_oz_symbolic_usage.o
+	$(MKOCT) -DZINT -c ../Source/umf_transpose.c
+	$(MV) -f ../Source/umf_transpose.o umf_oz_transpose.o
+	$(MKOCT) -DZINT -c ../Source/umf_tuple_lengths.c
+	$(MV) -f ../Source/umf_tuple_lengths.o umf_oz_tuple_lengths.o
+	$(MKOCT) -DZINT -c ../Source/umf_usolve.c
+	$(MV) -f ../Source/umf_usolve.o umf_oz_usolve.o
+	$(MKOCT) -DZINT -c ../Source/umf_utsolve.c
+	$(MV) -f ../Source/umf_utsolve.o umf_oz_utsolve.o
+	$(MKOCT) -DZINT -c ../Source/umf_valid_numeric.c
+	$(MV) -f ../Source/umf_valid_numeric.o umf_oz_valid_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umf_valid_symbolic.c
+	$(MV) -f ../Source/umf_valid_symbolic.o umf_oz_valid_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umf_grow_front.c
+	$(MV) -f ../Source/umf_grow_front.o umf_oz_grow_front.o
+	$(MKOCT) -DZINT -c ../Source/umf_start_front.c
+	$(MV) -f ../Source/umf_start_front.o umf_oz_start_front.o
+	$(MKOCT) -DZINT -c ../Source/umf_2by2.c
+	$(MV) -f ../Source/umf_2by2.o umf_oz_2by2.o
+	$(MKOCT) -DZINT -c ../Source/umf_store_lu.c
+	$(MV) -f ../Source/umf_store_lu.o umf_oz_store_lu.o
+	$(MKOCT) -DZINT -c ../Source/umf_scale.c
+	$(MV) -f ../Source/umf_scale.o umf_oz_scale.o
+	$(MKOCT) -DZINT -DWSOLVE -c ../Source/umfpack_solve.c
+	$(MV) -f ../Source/umfpack_solve.o umfpack_oz_wsolve.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_col_to_triplet.c
+	$(MV) -f ../Source/umfpack_col_to_triplet.o umfpack_oz_col_to_triplet.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_defaults.c
+	$(MV) -f ../Source/umfpack_defaults.o umfpack_oz_defaults.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_free_numeric.c
+	$(MV) -f ../Source/umfpack_free_numeric.o umfpack_oz_free_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_free_symbolic.c
+	$(MV) -f ../Source/umfpack_free_symbolic.o umfpack_oz_free_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_get_numeric.c
+	$(MV) -f ../Source/umfpack_get_numeric.o umfpack_oz_get_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_get_lunz.c
+	$(MV) -f ../Source/umfpack_get_lunz.o umfpack_oz_get_lunz.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_get_symbolic.c
+	$(MV) -f ../Source/umfpack_get_symbolic.o umfpack_oz_get_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_get_determinant.c
+	$(MV) -f ../Source/umfpack_get_determinant.o umfpack_oz_get_determinant.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_numeric.c
+	$(MV) -f ../Source/umfpack_numeric.o umfpack_oz_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_qsymbolic.c
+	$(MV) -f ../Source/umfpack_qsymbolic.o umfpack_oz_qsymbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_control.c
+	$(MV) -f ../Source/umfpack_report_control.o umfpack_oz_report_control.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_info.c
+	$(MV) -f ../Source/umfpack_report_info.o umfpack_oz_report_info.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_matrix.c
+	$(MV) -f ../Source/umfpack_report_matrix.o umfpack_oz_report_matrix.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_numeric.c
+	$(MV) -f ../Source/umfpack_report_numeric.o umfpack_oz_report_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_perm.c
+	$(MV) -f ../Source/umfpack_report_perm.o umfpack_oz_report_perm.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_status.c
+	$(MV) -f ../Source/umfpack_report_status.o umfpack_oz_report_status.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_symbolic.c
+	$(MV) -f ../Source/umfpack_report_symbolic.o umfpack_oz_report_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_triplet.c
+	$(MV) -f ../Source/umfpack_report_triplet.o umfpack_oz_report_triplet.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_report_vector.c
+	$(MV) -f ../Source/umfpack_report_vector.o umfpack_oz_report_vector.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_solve.c
+	$(MV) -f ../Source/umfpack_solve.o umfpack_oz_solve.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_symbolic.c
+	$(MV) -f ../Source/umfpack_symbolic.o umfpack_oz_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_transpose.c
+	$(MV) -f ../Source/umfpack_transpose.o umfpack_oz_transpose.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_triplet_to_col.c
+	$(MV) -f ../Source/umfpack_triplet_to_col.o umfpack_oz_triplet_to_col.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_scale.c
+	$(MV) -f ../Source/umfpack_scale.o umfpack_oz_scale.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_load_numeric.c
+	$(MV) -f ../Source/umfpack_load_numeric.o umfpack_oz_load_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_save_numeric.c
+	$(MV) -f ../Source/umfpack_save_numeric.o umfpack_oz_save_numeric.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_load_symbolic.c
+	$(MV) -f ../Source/umfpack_load_symbolic.o umfpack_oz_load_symbolic.o
+	$(MKOCT) -DZINT -c ../Source/umfpack_save_symbolic.c
+	$(MV) -f ../Source/umfpack_save_symbolic.o umfpack_oz_save_symbolic.o
+	$(MKOCT) -c ../Source/umfpack_timer.c
+	$(MV) -f ../Source/umfpack_timer.o umfpack_m_timer.o
+	$(MKOCT) -c ../Source/umfpack_tictoc.c
+	$(MV) -f ../Source/umfpack_tictoc.o umfpack_m_tictoc.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_aat.c
+	$(MV) -f ../../AMD/Source/amd_aat.o amd_m_aat.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_1.c
+	$(MV) -f ../../AMD/Source/amd_1.o amd_m_1.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_2.c
+	$(MV) -f ../../AMD/Source/amd_2.o amd_m_2.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_dump.c
+	$(MV) -f ../../AMD/Source/amd_dump.o amd_m_dump.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_postorder.c
+	$(MV) -f ../../AMD/Source/amd_postorder.o amd_m_postorder.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_post_tree.c
+	$(MV) -f ../../AMD/Source/amd_post_tree.o amd_m_post_tree.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_defaults.c
+	$(MV) -f ../../AMD/Source/amd_defaults.o amd_m_defaults.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_order.c
+	$(MV) -f ../../AMD/Source/amd_order.o amd_m_order.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_control.c
+	$(MV) -f ../../AMD/Source/amd_control.o amd_m_control.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_info.c
+	$(MV) -f ../../AMD/Source/amd_info.o amd_m_info.o
+	$(MKOCT) -DDINT -c ../../AMD/Source/amd_valid.c
+	$(MV) -f ../../AMD/Source/amd_valid.o amd_m_valid.o
+	$(MKOCT) -o umfpack.oct $(OCT_SPARSE_INC) umfpack.cc \
+	    umf_o_analyze.o umf_o_apply_order.o umf_o_colamd.o umf_o_free.o \
+	    umf_o_fsize.o umf_o_is_permutation.o umf_o_malloc.o \
+	    umf_o_realloc.o umf_o_report_perm.o umf_o_singletons.o \
+	    umf_od_lhsolve.o umf_od_uhsolve.o umf_od_triplet_map_nox.o \
+	    umf_od_triplet_nomap_x.o umf_od_triplet_nomap_nox.o \
+	    umf_od_triplet_map_x.o umf_od_assemble_fixq.o \
+	    umf_od_store_lu_drop.o umf_od_assemble.o umf_od_blas3_update.o \
+	    umf_od_build_tuples.o umf_od_create_element.o umf_od_dump.o \
+	    umf_od_extend_front.o umf_od_garbage_collection.o \
+	    umf_od_get_memory.o umf_od_init_front.o umf_od_kernel.o \
+	    umf_od_kernel_init.o umf_od_kernel_wrapup.o umf_od_local_search.o \
+	    umf_od_lsolve.o umf_od_ltsolve.o umf_od_mem_alloc_element.o \
+	    umf_od_mem_alloc_head_block.o umf_od_mem_alloc_tail_block.o \
+	    umf_od_mem_free_tail_block.o umf_od_mem_init_memoryspace.o \
+	    umf_od_report_vector.o umf_od_row_search.o umf_od_scale_column.o \
+	    umf_od_set_stats.o umf_od_solve.o umf_od_symbolic_usage.o \
+	    umf_od_transpose.o umf_od_tuple_lengths.o umf_od_usolve.o \
+	    umf_od_utsolve.o umf_od_valid_numeric.o umf_od_valid_symbolic.o \
+	    umf_od_grow_front.o umf_od_start_front.o umf_od_2by2.o \
+	    umf_od_store_lu.o umf_od_scale.o umfpack_od_wsolve.o \
+	    umfpack_od_col_to_triplet.o umfpack_od_defaults.o \
+	    umfpack_od_free_numeric.o umfpack_od_free_symbolic.o \
+	    umfpack_od_get_numeric.o umfpack_od_get_lunz.o \
+	    umfpack_od_get_symbolic.o umfpack_od_numeric.o \
+	    umfpack_od_qsymbolic.o umfpack_od_report_control.o \
+	    umfpack_od_report_info.o umfpack_od_report_matrix.o \
+	    umfpack_od_report_numeric.o umfpack_od_report_perm.o \
+	    umfpack_od_report_status.o umfpack_od_report_symbolic.o \
+	    umfpack_od_report_triplet.o umfpack_od_report_vector.o \
+	    umfpack_od_solve.o umfpack_od_symbolic.o umfpack_od_transpose.o \
+	    umfpack_od_triplet_to_col.o umfpack_od_scale.o \
+	    umfpack_od_load_numeric.o umfpack_od_save_numeric.o \
+	    umfpack_od_load_symbolic.o umfpack_od_save_symbolic.o \
+	    umf_oz_lhsolve.o umf_oz_uhsolve.o umf_oz_triplet_map_nox.o \
+	    umf_oz_triplet_nomap_x.o umf_oz_triplet_nomap_nox.o \
+	    umf_oz_triplet_map_x.o umf_oz_assemble_fixq.o \
+	    umf_oz_store_lu_drop.o umf_oz_assemble.o umf_oz_blas3_update.o \
+	    umf_oz_build_tuples.o umf_oz_create_element.o umf_oz_dump.o \
+	    umf_oz_extend_front.o umf_oz_garbage_collection.o \
+	    umf_oz_get_memory.o umf_oz_init_front.o umf_oz_kernel.o \
+	    umf_oz_kernel_init.o umf_oz_kernel_wrapup.o umf_oz_local_search.o \
+	    umf_oz_lsolve.o umf_oz_ltsolve.o umf_oz_mem_alloc_element.o \
+	    umf_oz_mem_alloc_head_block.o umf_oz_mem_alloc_tail_block.o \
+	    umf_oz_mem_free_tail_block.o umf_oz_mem_init_memoryspace.o \
+	    umf_oz_report_vector.o umf_oz_row_search.o umf_oz_scale_column.o \
+	    umf_oz_set_stats.o umf_oz_solve.o umf_oz_symbolic_usage.o \
+	    umf_oz_transpose.o umf_oz_tuple_lengths.o umf_oz_usolve.o \
+	    umf_oz_utsolve.o umf_oz_valid_numeric.o umf_oz_valid_symbolic.o \
+	    umf_oz_grow_front.o umf_oz_start_front.o umf_oz_2by2.o \
+	    umf_oz_store_lu.o umf_oz_scale.o umfpack_oz_wsolve.o \
+	    umfpack_oz_col_to_triplet.o umfpack_oz_defaults.o \
+	    umfpack_oz_free_numeric.o umfpack_oz_free_symbolic.o \
+	    umfpack_oz_get_numeric.o umfpack_oz_get_lunz.o \
+	    umfpack_oz_get_symbolic.o umfpack_oz_numeric.o \
+	    umfpack_oz_qsymbolic.o umfpack_oz_report_control.o \
+	    umfpack_oz_report_info.o umfpack_oz_report_matrix.o \
+	    umfpack_oz_report_numeric.o umfpack_oz_report_perm.o \
+	    umfpack_oz_report_status.o umfpack_oz_report_symbolic.o \
+	    umfpack_oz_report_triplet.o umfpack_oz_report_vector.o \
+	    umfpack_oz_solve.o umfpack_oz_symbolic.o umfpack_oz_transpose.o \
+	    umfpack_oz_triplet_to_col.o umfpack_oz_scale.o \
+	    umfpack_oz_load_numeric.o umfpack_oz_save_numeric.o \
+	    umfpack_oz_load_symbolic.o umfpack_oz_save_symbolic.o \
+	    umfpack_o_timer.o umfpack_o_tictoc.o \
+	    amd_o_aat.o amd_o_1.o amd_o_2.o amd_o_dump.o \
+	    amd_o_postorder.o amd_o_post_tree.o amd_o_defaults.o amd_o_order.o \
+	    amd_o_control.o amd_o_info.o amd_o_valid.o
+
+luflop: luflop.cc
+	$(MKOCT) luflop.cc -I$(OCT_SPARSE_INC) -o luflop.oct
+
+#----------------------------------------
+# umfpack library to link with octave
+#----------------------------------------
+
+octave: umfpack
+	ld -r -o ../../../$(OCTUMFPACK_LIB) \
+	    umf_o_analyze.o umf_o_apply_order.o umf_o_colamd.o umf_o_free.o \
+	    umf_o_fsize.o umf_o_is_permutation.o umf_o_malloc.o \
+	    umf_o_realloc.o umf_o_report_perm.o umf_o_singletons.o \
+	    umf_od_lhsolve.o umf_od_uhsolve.o umf_od_triplet_map_nox.o \
+	    umf_od_triplet_nomap_x.o umf_od_triplet_nomap_nox.o \
+	    umf_od_triplet_map_x.o umf_od_assemble_fixq.o \
+	    umf_od_store_lu_drop.o umf_od_assemble.o umf_od_blas3_update.o \
+	    umf_od_build_tuples.o umf_od_create_element.o umf_od_dump.o \
+	    umf_od_extend_front.o umf_od_garbage_collection.o \
+	    umf_od_get_memory.o umf_od_init_front.o umf_od_kernel.o \
+	    umf_od_kernel_init.o umf_od_kernel_wrapup.o umf_od_local_search.o \
+	    umf_od_lsolve.o umf_od_ltsolve.o umf_od_mem_alloc_element.o \
+	    umf_od_mem_alloc_head_block.o umf_od_mem_alloc_tail_block.o \
+	    umf_od_mem_free_tail_block.o umf_od_mem_init_memoryspace.o \
+	    umf_od_report_vector.o umf_od_row_search.o umf_od_scale_column.o \
+	    umf_od_set_stats.o umf_od_solve.o umf_od_symbolic_usage.o \
+	    umf_od_transpose.o umf_od_tuple_lengths.o umf_od_usolve.o \
+	    umf_od_utsolve.o umf_od_valid_numeric.o umf_od_valid_symbolic.o \
+	    umf_od_grow_front.o umf_od_start_front.o umf_od_2by2.o \
+	    umf_od_store_lu.o umf_od_scale.o umfpack_od_wsolve.o \
+	    umfpack_od_col_to_triplet.o umfpack_od_defaults.o \
+	    umfpack_od_free_numeric.o umfpack_od_free_symbolic.o \
+	    umfpack_od_get_numeric.o umfpack_od_get_lunz.o \
+	    umfpack_od_get_symbolic.o umfpack_od_numeric.o \
+	    umfpack_od_qsymbolic.o umfpack_od_report_control.o \
+	    umfpack_od_report_info.o umfpack_od_report_matrix.o \
+	    umfpack_od_report_numeric.o umfpack_od_report_perm.o \
+	    umfpack_od_report_status.o umfpack_od_report_symbolic.o \
+	    umfpack_od_report_triplet.o umfpack_od_report_vector.o \
+	    umfpack_od_solve.o umfpack_od_symbolic.o umfpack_od_transpose.o \
+	    umfpack_od_triplet_to_col.o umfpack_od_scale.o \
+	    umfpack_od_load_numeric.o umfpack_od_save_numeric.o \
+	    umfpack_od_load_symbolic.o umfpack_od_save_symbolic.o \
+	    umf_oz_lhsolve.o umf_oz_uhsolve.o umf_oz_triplet_map_nox.o \
+	    umf_oz_triplet_nomap_x.o umf_oz_triplet_nomap_nox.o \
+	    umf_oz_triplet_map_x.o umf_oz_assemble_fixq.o \
+	    umf_oz_store_lu_drop.o umf_oz_assemble.o umf_oz_blas3_update.o \
+	    umf_oz_build_tuples.o umf_oz_create_element.o umf_oz_dump.o \
+	    umf_oz_extend_front.o umf_oz_garbage_collection.o \
+	    umf_oz_get_memory.o umf_oz_init_front.o umf_oz_kernel.o \
+	    umf_oz_kernel_init.o umf_oz_kernel_wrapup.o umf_oz_local_search.o \
+	    umf_oz_lsolve.o umf_oz_ltsolve.o umf_oz_mem_alloc_element.o \
+	    umf_oz_mem_alloc_head_block.o umf_oz_mem_alloc_tail_block.o \
+	    umf_oz_mem_free_tail_block.o umf_oz_mem_init_memoryspace.o \
+	    umf_oz_report_vector.o umf_oz_row_search.o umf_oz_scale_column.o \
+	    umf_oz_set_stats.o umf_oz_solve.o umf_oz_symbolic_usage.o \
+	    umf_oz_transpose.o umf_oz_tuple_lengths.o umf_oz_usolve.o \
+	    umf_oz_utsolve.o umf_oz_valid_numeric.o umf_oz_valid_symbolic.o \
+	    umf_oz_grow_front.o umf_oz_start_front.o umf_oz_2by2.o \
+	    umf_oz_store_lu.o umf_oz_scale.o umfpack_oz_wsolve.o \
+	    umfpack_oz_col_to_triplet.o umfpack_oz_defaults.o \
+	    umfpack_oz_free_numeric.o umfpack_oz_free_symbolic.o \
+	    umfpack_oz_get_numeric.o umfpack_oz_get_lunz.o \
+	    umfpack_oz_get_symbolic.o umfpack_oz_numeric.o \
+	    umfpack_oz_qsymbolic.o umfpack_oz_report_control.o \
+	    umfpack_oz_report_info.o umfpack_oz_report_matrix.o \
+	    umfpack_oz_report_numeric.o umfpack_oz_report_perm.o \
+	    umfpack_oz_report_status.o umfpack_oz_report_symbolic.o \
+	    umfpack_oz_report_triplet.o umfpack_oz_report_vector.o \
+	    umfpack_oz_solve.o umfpack_oz_symbolic.o umfpack_oz_transpose.o \
+	    umfpack_oz_triplet_to_col.o umfpack_oz_scale.o \
+	    umfpack_oz_load_numeric.o umfpack_oz_save_numeric.o \
+	    umfpack_oz_load_symbolic.o umfpack_oz_save_symbolic.o \
+	    umfpack_o_timer.o umfpack_o_tictoc.o \
+	    amd_o_aat.o amd_o_1.o amd_o_2.o amd_o_dump.o \
+	    amd_o_postorder.o amd_o_post_tree.o amd_o_defaults.o amd_o_order.o \
+	    amd_o_control.o amd_o_info.o amd_o_valid.o
+
+#-------------------------------------------------------------------------------
+# Remove all but the files in the original distribution
+#-------------------------------------------------------------------------------
+
+purge: clean
+	- $(RM) *.oct* *.dll
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_btf.m UMFPACK/UMFPACK/OCTAVE/umfpack_btf.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_btf.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_btf.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,129 @@
+function x = umfpack_btf (A, b, Control)
+% UMFPACK_BTF
+%
+% x = umfpack_btf (A, b, Control)
+%
+% solve Ax=b by first permuting the matrix A to block triangular form via dmperm
+% and then using UMFPACK to factorize each diagonal block.  Adjacent 1-by-1
+% blocks are merged into a single upper triangular block, and solved via
+% MATLAB's \ operator.  The Control parameter is optional (Type umfpack_details
+% and umfpack_report for details on its use).  A must be square.
+%
+% See also:  umfpack, umfpack_factorize, umfpack_details, dmperm
+
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  Type umfpack_details for License.
+
+if (nargin < 2)
+    help umfpack_btf
+    error ('Usage: x = umfpack_btf (A, b, Control)') ;
+end
+
+[m n] = size (A) ;
+if (m ~= n)
+    help umfpack_btf
+    error ('umfpack_btf:  A must be square') ;
+end
+[m1 n1] = size (b) ;
+if (m1 ~= n)
+    help umfpack_btf
+    error ('umfpack_btf:  b has the wrong dimensions') ;
+end
+
+if (nargin < 3)
+    Control = umfpack ;
+end
+
+%-------------------------------------------------------------------------------
+% find the block triangular form
+%-------------------------------------------------------------------------------
+
+[p,q,r] = dmperm (A) ;
+nblocks = length (r) - 1 ;
+
+%-------------------------------------------------------------------------------
+% solve the system
+%-------------------------------------------------------------------------------
+
+if (nblocks == 1 | sprank (A) < n)
+
+    %---------------------------------------------------------------------------
+    % matrix is irreducible or structurally singular
+    %---------------------------------------------------------------------------
+
+    x = umfpack_solve (A, '\\', b, Control) ;
+
+else
+
+    %---------------------------------------------------------------------------
+    % A (p,q) is in block triangular form
+    %---------------------------------------------------------------------------
+
+    b = b (p,:) ;
+    A = A (p,q) ;
+    x = zeros (size (b)) ;
+
+    %---------------------------------------------------------------------------
+    % merge adjacent singletons into a single upper triangular block
+    %---------------------------------------------------------------------------
+
+    [r, nblocks, is_triangular] = merge_singletons (r) ;
+
+    %---------------------------------------------------------------------------
+    % solve the system: x (q) = A\b
+    %---------------------------------------------------------------------------
+
+    for k = nblocks:-1:1
+
+	% get the kth block
+        k1 = r (k) ;
+        k2 = r (k+1) - 1 ;
+
+	% solve the system
+	x (k1:k2,:) = solver (A (k1:k2, k1:k2), b (k1:k2,:), ...
+	    is_triangular (k), Control) ;
+
+        % off-diagonal block back substitution
+        b (1:k1-1,:) = b (1:k1-1,:) - A (1:k1-1, k1:k2) * x (k1:k2,:) ;
+
+    end
+
+    x (q,:) = x ;
+
+end
+
+%-------------------------------------------------------------------------------
+% merge_singletons
+%-------------------------------------------------------------------------------
+
+function [r, nblocks, is_triangular] = merge_singletons (r)
+%
+% Given r from [p,q,r] = dmperm (A), where A is square, return a modified r that
+% reflects the merger of adjacent singletons into a single upper triangular
+% block.  is_triangular (k) is 1 if the kth block is upper triangular.  nblocks
+% is the number of new blocks.
+
+nblocks = length (r) - 1 ;
+bsize = r (2:nblocks+1) - r (1:nblocks) ;
+t = [0 (bsize == 1)] ;
+z = (t (1:nblocks) == 0 & t (2:nblocks+1) == 1) | t (2:nblocks+1) == 0 ;
+y = [(find (z)) nblocks+1] ;
+r = r (y) ;
+nblocks = length (y) - 1 ;
+is_triangular = y (2:nblocks+1) - y (1:nblocks) > 1 ;
+
+%-------------------------------------------------------------------------------
+% solve Ax=b, but check for small and/or triangular systems
+%-------------------------------------------------------------------------------
+
+function x = solver (A, b, is_triangular, Control)
+if (is_triangular)
+    % back substitution only
+    x = A \ b ;
+elseif (size (A,1) < 4)
+    % a very small matrix, solve it as a dense linear system
+    x = full (A) \ b ;
+else
+    % solve it as a sparse linear system
+    x = umfpack_solve (A, '\\', b, Control) ;
+end
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack.cc UMFPACK/UMFPACK/OCTAVE/umfpack.cc
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack.cc	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack.cc	2005-02-01 21:58:15.885225363 +0100
@@ -0,0 +1,1399 @@
+/*
+
+Copyright (C) 2004 David Bateman
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+In addition to the terms of the GPL, you are permitted to link
+this program with any Open Source program, as defined by the
+Open Source Initiative (www.opensource.org)
+
+*/
+
+/*
+
+This is the Octave interface to the UMFPACK code, which bore the following
+copyright
+
+  UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+  Davis.  All Rights Reserved.  See ../README for License.
+  email: davis@cise.ufl.edu    CISE Department, Univ. of Florida.
+  web: http://www.cise.ufl.edu/research/sparse/umfpack
+
+*/
+
+#include <cfloat>
+#include <cstdlib>
+#include <string>
+
+#include <octave/config.h>
+#include <octave/ov.h>
+#include <octave/defun-dld.h>
+#include <octave/pager.h>
+#include <octave/ov-re-mat.h>
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// External UMFPACK functions in C
+extern "C" {
+#include "umfpack.h"
+}
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+
+// Return an error message
+static 
+void umfpack_error (const char *s, int A_is_complex, int nargout,
+		    octave_value_list retval, NDArray Control, 
+		    NDArray Info, int status, int do_info)
+{
+  if (A_is_complex)
+    {
+      umfpack_zi_report_status (Control.fortran_vec (), status) ;
+      umfpack_zi_report_info (Control.fortran_vec (), Info.fortran_vec ()) ;
+    }
+  else
+    {
+      umfpack_di_report_status (Control.fortran_vec (), status) ;
+      umfpack_di_report_info (Control.fortran_vec (), Info.fortran_vec ()) ;
+    }
+  if (do_info > 0)
+    // return Info
+    retval (do_info) = octave_value (Info);
+
+  error (s);
+}
+
+DEFUN_DLD (umfpack, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{a}, '\\', @var{b})\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{a}, '\\', @var{b}, @var{Control})\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{a}, @var{Qinit}, '\\', @var{b}, @var{Control})\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{a}, @var{Qinit}, '\\', b)\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{b}, '/', A) ;\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{b}, '/', @var{a}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{b}, '/', @var{a}, @var{Qinit}) ;\n\
+@deftypefnx {Loadable Function} {[@var{x}, @var{Info}] =} umfpack (@var{b}, '/', @var{a}, @var{Qinit}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}, @var{Info}] =} umfpack (@var{a}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}, @var{Info}] =} umfpack (@var{a}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}, @var{Info}] =} umfpack (@var{a}, @var{Qinit}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}, @var{Info}] =} umfpack (@var{a}, @var{Qinit}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} umfpack (@var{a}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} umfpack (@var{a}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} umfpack (@var{a}, @var{Qinit}) ;\n\
+@deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{p}, @var{q}] =} umfpack (@var{a}, @var{Qinit}, @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[P1, Q1, Fr, Ch, Info] =} umfpack (@var{a}, 'symbolic') ;\n\
+@deftypefnx {Loadable Function} {[P1, Q1, Fr, Ch, Info] =} umfpack (@var{a}, 'symbolic', @var{Control}) ;\n\
+@deftypefnx {Loadable Function} {[P1, Q1, Fr, Ch, Info] =} umfpack (@var{a}, @var{Qinit}, 'symbolic') ;\n\
+@deftypefnx {Loadable Function} {[P1, Q1, Fr, Ch, Info] =} umfpack (@var{a}, @var{Qinit}, 'symbolic', @var{Control});\n\
+@deftypefnx {Loadable Function} {@var{Control} =} umfpack ;\n\
+\n\
+UMFPACK v4.3 is a Octave oct-file for solving sparse linear systems.\n\
+\n\
+@iftex\n\
+@tex\n\
+\\vskip 2ex\n\
+\\hfil\\vbox{\n\
+\\offinterlineskip\n\
+\\tabskip=0pt\n\
+\\halign{\n\
+\\vrule height1.75ex depth1.25ex width 0.6pt #\\tabskip=1em &\n\
+\\hfil #\\hfil &\\vrule # & \n\
+\\hfil #\\hfil &\\vrule # width 0.6pt \\tabskip=0pt\\cr\n\
+\\noalign{\\hrule height 0.6pt}\n\
+&     UMFPACK v4.3                  && OCTAVE approximate equivalent  &\\cr\n\
+\\noalign{\\hrule} \n\
+& x = umfpack (A, '\\', b) ;        &&  x = A \\ b                    &\\cr\n\
+&                                   &&                                &\\cr\n\
+&x = umfpack (b, '/', A) ;          &&  x = b / A                     &\\cr\n\
+&                                   &&                                &\\cr\n\
+&[L,U,P,Q] = umfpack (A) ;          &&  [m,n] = size (A) ;            &\\cr\n\
+&                                   &&  I = speye (n) ;               &\\cr\n\
+&                                   &&  Q = I (:, colamd (A)) ;       &\\cr\n\
+&                                   &&  [L,U,P] = lu (A*Q) ;          &\\cr\n\
+&                                   &&                                &\\cr\n\
+&[L,U,P,Q,R] = umfpack (A) ;        &&  [m,n] = size (A) ;            &\\cr\n\
+&                                   &&  I = speye (n) ;               &\\cr\n\
+&                                   &&  Q = I (:, colamd (A)) ;       &\\cr\n\
+&                                   &&  r = full (sum (abs (A), 2)) ; &\\cr\n\
+&                                   &&  r (find (r == 0)) = 1 ;       &\\cr\n\
+&                                   &&  R = spdiags (r, 0, m, m) ;    &\\cr\n\
+&                                   &&  [L,U,P] = lu ((R\\A)*Q) ;     &\\cr\n\
+&                                   &&                                &\\cr\n\
+&[P,Q,F,C] = umfpack (A, 'symbolic')&&  [m,n] = size (A) ;            &\\cr\n\
+&                                   &&  I = speye (n) ;               &\\cr\n\
+&                                   &&  Q = I (:, colamd (A)) ;       &\\cr\n\
+&                                   &&  [count,h,parent,post] = ...   &\\cr\n\
+&                                   &&  symbfact (A*Q, 'col') ;       &\\cr\n\
+\\noalign{\\hrule height 0.6pt}\n\
+}}\\hfil\n\
+\\vskip 1ex\n\
+@end tex\n\
+@end iftex\n\
+@ifinfo\n\
+@multitable @columnfractions 0.43 .02 .43\n\
+@item UMFPACK v4.3:                       @tab | \n\
+@tab OCTAVE approx. equivalent\n\
+@item -------------------------------     @tab | \n\
+@tab --------------------------------\n\
+@item x = umfpack (A, '\\', b) ;          @tab | \n\
+@tab x = A \\ b\n\
+@item                                     @tab | \n\
+@tab\n\
+@item x = umfpack (b, '/', A) ;           @tab | \n\
+@tab  x = b / A\n\
+@item                                     @tab | \n\
+@tab\n\
+@item [L,U,P,Q] = umfpack (A) ;           @tab | \n\
+@tab  [m,n] = size (A) ;\n\
+@item                                     @tab | \n\
+@tab  I = speye (n) ;\n\
+@item                                     @tab | \n\
+@tab  Q = I (:, colamd (A)) ;\n\
+@item                                     @tab | \n\
+@tab  [L,U,P] = lu (A*Q) ;\n\
+@item                                     @tab | \n\
+@tab\n\
+@item [L,U,P,Q,R] = umfpack (A) ;         @tab | \n\
+@tab  [m,n] = size (A) ;\n\
+@item                                     @tab | \n\
+@tab  I = speye (n) ;\n\
+@item                                     @tab | \n\
+@tab  Q = I (:, colamd (A)) ;\n\
+@item                                     @tab | \n\
+@tab  r = full (sum (abs (A), 2)) ;\n\
+@item                                     @tab | \n\
+@tab  r (find (r == 0)) = 1 ;\n\
+@item                                     @tab | \n\
+@tab  R = spdiags (r, 0, m, m) ;\n\
+@item                                     @tab | \n\
+@tab  [L,U,P] = lu ((R\\A)*Q) ;\n\
+@item                                     @tab | \n\
+@tab\n\
+@item [P,Q,F,C] = umfpack (A, 'symbolic') @tab | \n\
+@tab  [m,n] = size (A) ; \n\
+@item                                     @tab | \n\
+@tab  I = speye (n) ;\n\
+@item                                     @tab | \n\
+@tab  Q = I (:, colamd (A)) ;\n\
+@item                                     @tab | \n\
+@tab  [count,h,parent,post] = ...\n\
+@item                                     @tab | \n\
+@tab  symbfact (A*Q, 'col') ;\n\
+@end multitable\n\
+@end ifinfo\n\
+\n\
+A must be sparse.  It can be complex, singular, and/or rectangular.\n\
+A must be square for '/' or '\\'.  b must be a full real or complex\n\
+vector.  For @code{[@var{l}, @var{u}, @var{p}, @var{q}, @var{r}] =\n\
+umfpack (@var{a})}, the factorization is @code{@var{l} * @var{u} =\n\
+@var{p} * (@var{r} \\ @var{a}) * @var{q}}. If @var{a} has a mostly\n\
+symmetric nonzero pattern, then replace @dfn{colamd} with @dfn{amd}\n\
+in the OCTAVE-equivalent column in the table above.\n\
+\n\
+Factor or solve a sparse linear system, returning either the solution\n\
+@var{x} to @code{@var{A} * @var{x} = @var{b}} or @code{@var{A}' * @var{x}'\n\
+= @var{b}'}, the factorization LU=PAQ, or LU=P(R\\A)Q.  A must be sparse.\n\
+For the solve, A must be square and b must be a dense n-by-1 vector.  For LU\n\
+factorization, A can be rectangular.  In both cases, A and/or b can be real\n\
+or complex.\n\
+\n\
+UMFPACK analyzes the matrix and selects one of three strategies to factorize\n\
+the matrix. It first finds a set of k initial pivot entries of zero\n\
+Markowitz cost. This forms the first k rows and columns of L and U. The\n\
+remaining submatrix S is then analyzed, based on the symmetry of the nonzero\n\
+pattern of the submatrix and the values on the diagaonal.  The strategies\n\
+include:\n\
+\n\
+@table @asis\n\
+@item unsymmetric\n\
+Use a COLAMD pre-ordering, a column elimination tree\n\
+post-ordering, refine the column ordering during factorization,\n\
+and make no effort at selecting pivots on the diagonal.\n\
+@item 2-by-2\n\
+Like the symmetric strategy (see below), except that local\n\
+row permutations are first made to attempt to place large entries\n\
+on the diagonal.\n\
+@item symmetric\n\
+Use an AMD pre-ordering on the matrix @code{@var{s} + @var{s}'}, an\n\
+elimination tree post-ordering, do not refine the column ordering during\n\
+factorization, and attempt to select pivots on the diagonal.\n\
+@end table\n\
+\n\
+Each of the following uses of umfpack (except for 'Control = umfpack') is\n\
+stand-alone.  That is, no call to umfpack is required for any subsequent\n\
+call. In each usage, the Info output argument is optional.\n\
+\n\
+Usage:\n\
+\n\
+[x, Info] = umfpack (A, '\\', b) ;\n\
+[x, Info] = umfpack (A, '\\', b, Control) ;\n\
+[x, Info] = umfpack (A, Qinit, '\\', b, Control) ;\n\
+[x, Info] = umfpack (A, Qinit, '\\', b) ;\n\
+\n\
+     Solves Ax=b (similar to x = A\\b in OCTAVE).\n\
+\n\
+[x, Info] = umfpack (b, '/', A) ;\n\
+[x, Info] = umfpack (b, '/', A, Control) ;\n\
+[x, Info] = umfpack (b, '/', A, Qinit) ;\n\
+[x, Info] = umfpack (b, '/', A, Qinit, Control) ;\n\
+\n\
+     Solves A'x'=b' (similar to x = b/A in OCTAVE).\n\
+\n\
+[L, U, P, Q, R, Info] = umfpack (A) ;\n\
+[L, U, P, Q, R, Info] = umfpack (A, Control) ;\n\
+[L, U, P, Q, R, Info] = umfpack (A, Qinit) ;\n\
+[L, U, P, Q, R, Info] = umfpack (A, Qinit, Control) ;\n\
+\n\
+     Returns the LU factorization of A.  P and Q are returned as permutation\n\
+     matrices.  R is a diagonal sparse matrix of scale factors for the rows\n\
+     of A, L is lower triangular, and U is upper triangular.  The\n\
+     factorization is L*U = P*(R\\A)*Q.  You can turn off scaling by setting\n\
+     Control (17) to zero (in which case R = speye (m)), or by using the\n\
+     following syntaxes (in which case Control (17) is ignored):\n\
+\n\
+[L, U, P, Q] = umfpack (A) ;\n\
+[L, U, P, Q] = umfpack (A, Control) ;\n\
+[L, U, P, Q] = umfpack (A, Qinit) ;\n\
+[L, U, P, Q] = umfpack (A, Qinit, Control) ;\n\
+\n\
+     Same as above, except that no row scaling is performed.  The Info array\n\
+     is not returned, either.\n\
+\n\
+[P1, Q1, Fr, Ch, Info] = umfpack (A, 'symbolic') ;\n\
+[P1, Q1, Fr, Ch, Info] = umfpack (A, 'symbolic', Control) ;\n\
+[P1, Q1, Fr, Ch, Info] = umfpack (A, Qinit, 'symbolic') ;\n\
+[P1, Q1, Fr, Ch, Info] = umfpack (A, Qinit, 'symbolic', Control);\n\
+\n\
+     Performs only the fill-reducing column pre-ordering (including the\n\
+     elimination tree post-ordering) and symbolic factorization.  Q1 is the\n\
+     initial column permutation (either from colamd, amd, or the input\n\
+     ordering Qinit), possibly followed by a column elimination tree post-\n\
+     ordering or a symmetric elimination tree post-ordering, depending on\n\
+     the strategy used.\n\
+\n\
+     For the unsymmetric strategy, P1 is the row ordering induced by Q1\n\
+     (row-merge order). For the 2-by-2 strategy, P1 is the row ordering that\n\
+     places large entries on the diagonal of P1*A*Q1.  For the symmetric\n\
+     strategy, P1 = Q1.\n\
+\n\
+     Fr is a (nfr+1)-by-4 array containing information about each frontal\n\
+     matrix, where nfr <= n is the number of frontal matrices.  Fr (:,1) is\n\
+     the number of pivot columns in each front, and Fr (:,2) is the parent\n\
+     of each front in the supercolumn elimination tree.  Fr (k,2) is zero if\n\
+     k is a root.  The first Fr (1,1) columns of P1*A*Q1 are the pivot\n\
+     columns for the first front, the next Fr (2,1) columns of P1*A*Q1\n\
+     are the pivot columns for the second front, and so on.\n\
+\n\
+     For the unsymmetric strategy, Fr (:,3) is the row index of the first\n\
+     row in P1*A*Q1 whose leftmost nonzero entry is in a pivot column for\n\
+     the kth front.  Fr (:,4) is the leftmost descendent of the kth front.\n\
+     Rows in the range Fr (Fr (k,4),3) to Fr (k+1,3)-1 form the entire set\n\
+     of candidate pivot rows for the kth front (some of these will typically\n\
+     have been selected as pivot rows of fronts Fr (k,3) to k-1, before the\n\
+     factorization reaches the kth front.  If front k is a leaf node, then\n\
+     Fr (k,4) is k.\n\
+\n\
+     Ch is a (nchains+1)-by-3 array containing information about each\n\
+     'chain' (unifrontal sequence) of frontal matrices, and where\n\
+      nchains <= nfr is the number of chains. The ith chain consists of\n\
+     frontal matrices. Chain (i,1) to Chain (i+1,1)-1, and the largest\n\
+     front in chain i is Chain (i,2)-by-Chain (i,3).\n\
+\n\
+     This use of umfpack is not required to factor or solve a linear system\n\
+     in OCTAVE.  It analyzes the matrix A and provides information only.\n\
+     The OCTAVE statement @code{treeplot (Fr (:,2)')} plots the column\n\
+     elimination tree.\n\
+\n\
+Control = umfpack ;\n\
+\n\
+      Returns a 20-by-1 vector of default parameter settings for umfpack.\n\
+\n\
+umfpack_report (Control, Info) ;\n\
+\n\
+      Prints the current Control settings, and Info\n\
+\n\
+If present, Qinit is a user-supplied 1-by-n permutation vector.  It is an\n\
+initial fill-reducing column pre-ordering for A; if not present, then colamd\n\
+or amd are used instead.  If present, Control is a user-supplied 20-by-1\n\
+array.   Control and Info are optional; if Control is not present, defaults\n\
+are used.  If a Control entry is NaN, then the default is used for that entry.\n\
+\n\
+UMFPACK Version 4.3 (Jan. 16, 2004), Copyright @copyright{} 2004 by\n\
+Timothy A. Davis.  All Rights Reserved.\n\
+\n\
+UMFPACK License:\n\
+\n\
+@example\n\
+Your use or distribution of UMFPACK or any modified version of\n\
+UMFPACK implies that you agree to this License.\n\
+\n\
+THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY\n\
+EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.\n\
+\n\
+Permission is hereby granted to use or copy this program, provided\n\
+that the Copyright, this License, and the Availability of the original\n\
+version is retained on all copies.  User documentation of any code that\n\
+uses UMFPACK or any modified version of UMFPACK code must cite the\n\
+Copyright, this License, the Availability note, and 'Used by permission.'\n\
+Permission to modify the code and to distribute modified code is granted,\n\
+provided the Copyright, this License, and the Availability note are\n\
+retained, and a notice that the code was modified is included.  This\n\
+software was developed with support from the National Science Foundation,\n\
+and is provided to you free of charge.\n\
+@end example\n\
+\n\
+Availability: http://www.cise.ufl.edu/research/sparse/umfpack\n\
+@end deftypefn\n\
+@seealso{lu_normtest, colamd, amd, umfpack_solve}")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  int op = 0;
+  std::string operation;
+  bool do_solve = false;
+  int do_info = 0;
+
+  ColumnVector User_Qinit;
+  SparseComplexMatrix CAmatrix;
+  ComplexMatrix CBmatrix;
+  SparseMatrix Amatrix;
+  Matrix Bmatrix;
+  NDArray User_Control_matrix;
+
+  bool A_is_complex = false;
+  bool B_is_complex = false;
+  bool X_is_complex = false;
+  bool transpose = false;
+  bool have_User_Qinit  = false;
+  bool have_User_Control_matrix = false;
+  bool do_numeric = true;
+  bool no_scale = false;
+
+  // find the operator
+  for (int i = 0 ; i < nargin ; i++)
+    {
+      if (args(i).is_string ())
+	{
+	  op = i;
+	  break;
+	}
+    }
+
+  if (op > 0)
+    {
+      std::string op_type = args (op).string_value ();
+
+      if (op_type == "\\")
+	{
+
+	  // matrix left divide, x = A\b 
+	  
+	  //  [x, Info] = umfpack (A, '\', b) ;
+	  //  [x, Info] = umfpack (A, '\', b, Control) ;
+	  //  [x, Info] = umfpack (A, Qinit, '\', b, Control) ;
+	  //  [x, Info] = umfpack (A, Qinit, '\', b) ;
+
+	  do_solve = true;
+	  operation = "x = A\\b";
+
+	  if (args(0).class_name () != "sparse")
+	    {
+	      error ("umfpack: input matrix A must be sparse");
+	      return retval;
+	    }
+	  
+	  if (args(0).is_complex_type ())
+	    {
+	      CAmatrix = args(0).sparse_complex_matrix_value ();
+	      A_is_complex = true;
+	    }
+	  else
+	    Amatrix = args(0).sparse_matrix_value ();
+
+
+	  if (args(op+1).is_complex_type ())
+	    {
+	      CBmatrix = args(op+1).complex_matrix_value ();
+	      B_is_complex = true;
+	    }
+	  else
+	    Bmatrix = args(op+1).matrix_value ();
+
+	  if (nargout == 2)
+	    do_info = 1;
+
+	  if (op == 2)
+	    {
+	      User_Qinit = args(1).column_vector_value ();
+	      have_User_Qinit = true;
+	    }
+
+	  if ((op == 1 && nargin == 4) || (op == 2 && nargin == 5))
+	    {
+	      User_Control_matrix = args(nargin-1).array_value ();
+	      have_User_Control_matrix = true;
+	    }
+
+	  if (error_state)
+	    {
+	      error ("umfpack: incorrect argument type");
+	      return retval;
+	    }
+
+	  if (nargin < 3 || nargin > 5 || nargout > 2)
+	    {
+	      error ("umfpack: wrong number of arguments");
+	      return retval;
+	    }
+
+	}
+      else if (op_type == "/")
+	{
+	  // matrix right divide, x = b/A
+
+	  // [x, Info] = umfpack (b, '/', A) ;
+	  // [x, Info] = umfpack (b, '/', A, Control) ;
+	  // [x, Info] = umfpack (b, '/', A, Qinit) ;
+	  // [x, Info] = umfpack (b, '/', A, Qinit, Control) ;
+
+	  do_solve = true;
+	  operation = "x = b/A" ;
+
+	  transpose = true;
+
+	  if (args(2).class_name () != "sparse")
+	    {
+	      error ("umfpack: input matrix A must be sparse");
+	      return retval;
+	    }
+
+	  if (args(2).is_complex_type ())
+	    {
+	      CAmatrix = args(2).sparse_complex_matrix_value ();
+	      A_is_complex = true;
+	    }
+	  else
+	    Amatrix = args(2).sparse_matrix_value ();
+
+	  if (args(0).is_complex_type ())
+	    {
+	      CBmatrix = args(0).complex_matrix_value ();
+	      B_is_complex = true;
+	    }
+	  else
+	    Bmatrix = args(0).matrix_value ();
+
+	  if (nargout == 2)
+	    do_info = 1;
+
+	  if (nargin == 5)
+	    {
+	      User_Qinit = args(3).column_vector_value ();
+	      User_Control_matrix = args(4).array_value ();
+	      have_User_Qinit = true;
+	      have_User_Control_matrix = true;
+	    }
+	  else if (nargin == 4)
+	    {
+	      User_Control_matrix = args(3).array_value ();
+
+	      if (User_Control_matrix.rows () == 1)
+		{
+		  User_Qinit = args(3).column_vector_value ();
+		  have_User_Qinit = true;
+		}
+	      else
+		have_User_Control_matrix = true;
+	    }
+	  else if (nargin < 3 || nargin > 5 || nargout > 2)
+	    {
+	      error ("umfpack: wrong number of arguments");
+	      return retval;
+	    }
+
+	  if (error_state)
+	    {
+	      error ("umfpack: incorrect argument type");
+	      return retval;
+	    }
+	}
+      else if (op_type == "symbolic")
+	{
+	  // symbolic factorization only
+
+	  // [P Q Fr Ch Info] = umfpack (A, 'symbolic') ;
+	  // [P Q Fr Ch Info] = umfpack (A, 'symbolic', Control) ;
+	  // [P Q Fr Ch Info] = umfpack (A, Qinit, 'symbolic') ;
+	  // [P Q Fr Ch Info] = umfpack (A, Qinit, 'symbolic', Control) ;
+
+	  operation = "symbolic factorization";
+	  do_numeric = false;
+
+	  if (args(0).class_name () != "sparse")
+	    {
+	      error ("umfpack: input matrix A must be sparse");
+	      return retval;
+	    }
+
+	  if (args(0).is_complex_type ())
+	    {
+	      CAmatrix = args(0).sparse_complex_matrix_value ();
+	      A_is_complex = true;
+	    }
+	  else
+	    Amatrix = args(0).sparse_matrix_value ();
+
+	  if (nargout == 5)
+	    do_info = 4 ;
+	  
+	  if (op == 2)
+	    {
+	      User_Qinit = args(1).column_vector_value ();
+	      have_User_Qinit = true;
+	    }
+	  if ((op == 1 && nargin == 3) || (op == 2 && nargin == 4))
+	    {
+	      User_Control_matrix = args(nargin-1).array_value ();
+	      have_User_Control_matrix = true;
+	    }
+
+	  if (error_state)
+	    {
+	      error ("umfpack: incorrect argument type");
+	      return retval;
+	    }
+
+	  if (nargin < 2 || nargin > 4 || nargout > 5 || nargout < 4)
+	    {
+	      error ("umfpack: wrong number of arguments") ;
+	      return retval;
+	    }
+	}
+      else
+	{
+	  error ("operator must be '/', '\\', or 'symbolic'") ;
+	  return retval;
+	}
+    }
+  else if (nargin > 0)
+    {
+      // LU factorization
+
+      // with scaling:
+      //   [L, U, P, Q, R, Info] = umfpack (A) ;
+      //   [L, U, P, Q, R, Info] = umfpack (A, Qinit) ;
+      //
+      // scaling determined by Control settings:
+      //   [L, U, P, Q, R, Info] = umfpack (A, Control) ;
+      //   [L, U, P, Q, R, Info] = umfpack (A, Qinit, Control) ;
+      //
+      // with no scaling:
+      //   [L, U, P, Q] = umfpack (A) ;
+      //   [L, U, P, Q] = umfpack (A, Control) ;
+      //   [L, U, P, Q] = umfpack (A, Qinit) ;
+      //   [L, U, P, Q] = umfpack (A, Qinit, Control) ;
+
+      operation = "numeric factorization" ;
+
+      if (args(0).is_complex_type ())
+	{
+	  CAmatrix = args(0).sparse_complex_matrix_value ();
+	  A_is_complex = true;
+	}
+      else
+	Amatrix = args(0).sparse_matrix_value ();
+
+      no_scale = nargout <= 4 ;
+
+      if (nargout == 6)
+	    do_info = 5 ;
+
+      if (nargin == 3)
+	{
+	  User_Qinit = args(1).column_vector_value ();
+	  User_Control_matrix = args(2).array_value ();
+	  have_User_Qinit = true;
+	  have_User_Control_matrix = true;
+	}
+      else if (nargin == 2)
+	{
+	  User_Control_matrix = args(1).array_value ();
+	  
+	  if (User_Control_matrix.rows () == 1)
+	    {
+	      User_Qinit = args(1).column_vector_value ();
+	      have_User_Qinit = true;
+	    }
+	  else
+	    have_User_Control_matrix = true;
+	}
+      else if (nargin > 3 || nargout > 6 || nargout < 4)
+	{
+	  error ("umfpack: wrong number of arguments") ;
+	  return retval;
+	}
+    }
+  else
+    {
+      // return default control settings
+
+      // Control = umfpack ;
+      // umfpack ;
+
+      if (nargout > 1)
+	{
+	  error ("umfpack: wrong number of arguments") ;
+	  return retval;
+	}
+      
+      NDArray user_control (dim_vector (UMFPACK_CONTROL, 1));
+      double *user_control_ptr = user_control.fortran_vec ();
+      umfpack_di_defaults (user_control_ptr);
+      retval(0) = user_control;
+      return retval;
+    }
+
+  // check inputs
+  
+  int n_row = Amatrix.rows ();
+  int n_col = Amatrix.cols ();
+  int nn = MAX (n_row, n_col) ;
+  int n_inner = MIN (n_row, n_col) ;
+  if (do_solve && n_row != n_col)
+    {
+      error ("umfpack: input matrix A must square for '\\' or '/'") ;
+      return retval;
+    }
+  if (n_row == 0 || n_col == 0)
+    {
+      error ("umfpack: input matrix A cannot have zero rows or zero columns") ;
+      return retval;
+    }
+
+  /* The real/complex status of A determines which version to use, */
+  /* (umfpack_di_* or umfpack_zi_*). */
+  const int *Ap;
+  const int *Ai;
+  const double *Ax;
+  const double *Bx;
+  
+  if (A_is_complex)
+    {
+      Ap = CAmatrix.cidx ();
+      Ai = CAmatrix.ridx ();
+      Ax = X_CAST (const double *, CAmatrix.data ());
+    }
+  else
+    {
+      Ap = Amatrix.cidx ();
+      Ai = Amatrix.ridx ();
+      Ax = Amatrix.data ();
+    }
+
+  if (B_is_complex)
+    Bx = X_CAST (const double *, CBmatrix.fortran_vec ());
+  else
+    Bx = Bmatrix.fortran_vec ();
+
+  if (do_solve)
+    {
+      int b_row = Bmatrix.rows ();
+      int b_col = Bmatrix.cols ();
+
+      if (!((transpose && b_row == 1 && b_col == nn) ||  
+	     (!transpose && b_row == nn && b_col == 1)))  
+	{
+	  error ("umfpack: b has the wrong dimensions") ;
+	  return retval;
+	}
+
+      X_is_complex = A_is_complex || B_is_complex ;
+    }
+
+  // set the Control parameters
+  NDArray Control (dim_vector (UMFPACK_CONTROL, 1));
+  double *Control_ptr = Control.fortran_vec ();
+  if (A_is_complex)
+    umfpack_zi_defaults (Control_ptr) ;
+  else
+    umfpack_di_defaults (Control_ptr) ;
+
+  if (have_User_Control_matrix)
+    {
+      int size = MIN (UMFPACK_CONTROL, User_Control_matrix.length ());
+      for (int i = 0 ; i < size ; i++)
+	Control (i) = User_Control_matrix (i) ;
+    }
+  
+  if (no_scale)
+    {
+      // turn off scaling for [L, U, P, Q] = umfpack (A) ;
+      // ignoring the input value of Control (24) for the usage
+      // [L, U, P, Q] = umfpack (A, Control) ;
+      Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE ;
+    }
+
+  int print_level;
+  if (xisnan (Control (UMFPACK_PRL)))
+    print_level = UMFPACK_DEFAULT_PRL ;
+  else
+    print_level = int (Control (UMFPACK_PRL)) ;
+
+  Control (UMFPACK_PRL) = print_level ;
+
+  // check Qinit, if present
+  int *Qinit = NULL;
+  if (have_User_Qinit)
+    {
+      if(User_Qinit.rows () != 1 || User_Qinit.cols () != n_col)
+	{
+	  error ("umfpack: Qinit must be 1-by-n_col") ;
+	  return retval;
+	}
+
+      Qinit = new int [n_col];
+      for (int i = 0; i < n_col; i++)
+	Qinit[i] = static_cast<int> (User_Qinit (i));
+    }
+
+  // report the inputs A and Qinit
+
+  if (print_level >= 2)
+    // print the operation
+    octave_stdout << "\numfpack: " << operation;
+
+  if (A_is_complex)
+    {
+      umfpack_zi_report_control (Control_ptr) ;
+
+      if (print_level >= 3) 
+	octave_stdout << "\nA: " ;
+
+      umfpack_zi_report_matrix (n_row, n_col, Ap, Ai, Ax, NULL,
+				1, Control_ptr) ;
+      if (have_User_Qinit)
+	{
+	  if (print_level >= 3) 
+	    octave_stdout << "\nQinit: " ;
+
+	  umfpack_zi_report_perm (n_col, Qinit, Control_ptr) ;
+	}
+    }
+  else
+    {
+      umfpack_di_report_control (Control_ptr) ;
+
+      if (print_level >= 3) 
+	octave_stdout << "\nA: " ;
+
+       umfpack_di_report_matrix (n_row, n_col, Ap, Ai, Ax,
+				 1, Control_ptr) ;
+       if (have_User_Qinit)
+	 {
+	   if (print_level >= 3) 
+	     octave_stdout << "\nQinit: " ;
+
+	   umfpack_di_report_perm (n_col, Qinit, Control_ptr) ;
+	 }
+    }
+
+#ifndef NO_TRANSPOSE_FORWARD_SLASH
+  // create the array transpose for x = b/A
+  if (transpose)
+    if (A_is_complex)
+      {
+	CAmatrix = CAmatrix.transpose ();
+	Ap = Amatrix.cidx ();
+	Ai = Amatrix.ridx ();
+	Ax = X_CAST (const double *, CAmatrix.data ());
+      }
+    else
+      {
+	Amatrix = Amatrix.transpose ();
+	Ap = Amatrix.cidx ();
+	Ai = Amatrix.ridx ();
+	Ax = Amatrix.data ();
+      }
+#endif
+
+  // perform the symbolic factorization
+  
+  NDArray InfoOut (dim_vector (1, UMFPACK_INFO));
+  double * Info = InfoOut.fortran_vec ();
+  void *Symbolic;
+  int status, status2;
+  if (A_is_complex)
+    status = umfpack_zi_qsymbolic (n_row, n_col, Ap, Ai, Ax, NULL,
+				   Qinit, &Symbolic, Control_ptr, 
+				   Info);
+  else
+    status = umfpack_di_qsymbolic (n_row, n_col, Ap, Ai, Ax,
+				   Qinit, &Symbolic, Control_ptr, 
+				   Info);
+  
+  if (status < 0)
+    {
+      umfpack_error ("symbolic factorization failed", A_is_complex, 
+		     nargout, retval, Control, InfoOut, status, do_info) ;
+      return retval;
+    }
+
+  if (have_User_Qinit)
+    delete [] Qinit;
+
+  // report the Symbolic object
+
+  if (A_is_complex)
+    umfpack_zi_report_symbolic (Symbolic, Control_ptr) ;
+  else
+    umfpack_di_report_symbolic (Symbolic, Control_ptr) ;
+
+  // perform numeric factorization, or just return symbolic factorization
+
+  if (do_numeric)
+    {
+      // perform the numeric factorization
+      void *Numeric;
+
+      if (A_is_complex)
+	status = umfpack_zi_numeric (Ap, Ai, Ax, NULL, Symbolic, &Numeric,
+				     Control_ptr, Info) ;
+      else
+	status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric,
+				     Control_ptr, Info) ;
+
+      // free the symbolic factorization
+      if (A_is_complex)
+	umfpack_zi_free_symbolic (&Symbolic) ;
+      else
+	umfpack_di_free_symbolic (&Symbolic) ;
+
+      // report the Numeric object
+      if (status < 0)
+	{
+	  umfpack_error ("numeric factorization failed", A_is_complex, 
+			 nargout, retval, Control, InfoOut, status, do_info);
+	  return retval;
+	}
+
+      if (A_is_complex)
+	(void) umfpack_zi_report_numeric (Numeric, Control_ptr) ;
+      else
+	(void) umfpack_di_report_numeric (Numeric, Control_ptr) ;
+
+      // return the solution or the factorization
+
+      if (do_solve)
+	{
+	  int sys;
+	  ComplexNDArray Xcmplx;
+	  NDArray Xreal;
+
+	  // solve Ax=b or A'x'=b', and return just the solution x
+
+#ifndef NO_TRANSPOSE_FORWARD_SLASH
+	  if (transpose)
+	    {
+	      // A.'x.'=b.' gives the same x=b/A as solving A'x'=b'
+	      // since C=A.' was factorized, solve with sys = UMFPACK_A 
+	      // since x and b are vectors, x.' and b.' are implicit 
+	      if (X_is_complex)
+		Xcmplx.resize (dim_vector (1, nn));
+	      else
+		Xreal.resize (dim_vector (1, nn));
+	    }
+	  else
+	    {
+	      if (X_is_complex)
+		Xcmplx.resize (dim_vector (nn, 1));
+	      else
+		Xreal.resize (dim_vector (nn, 1));
+	    }
+
+	  sys = UMFPACK_A ;
+#else
+	  if (transpose)
+	    {
+	      // If A is real, A'x=b is the same as A.'x=b. 
+	      // x and b are vectors, so x and b are the same as x' and b'. 
+	      // If A is complex, then A.'x.'=b.' gives the same solution x 
+	      // as the complex conjugate transpose.  If we used the A'x=b 
+	      // option in umfpack_*_solve, we would have to form b' on 
+	      // input and x' on output (negating the imaginary part). 
+	      // We can save this work by just using the A.'x=b option in 
+	      // umfpack_*_solve.  Then, forming x.' and b.' is implicit, 
+	      // since x and b are just vectors anyway. 
+	      // In both cases, the system to solve is A.'x=b
+	      if (X_is_complex)
+		Xcmplx.resize (dim_vector (1, nn));
+	      else
+		Xreal.resize (dim_vector (1, nn));
+
+	      sys = UMFPACK_Aat ;
+	    }
+	  else
+	    {
+	      if (X_is_complex)
+		Xcmplx.resize (dim_vector (nn, 1));
+	      else
+		Xreal.resize (dim_vector (nn, 1));
+	      sys = UMFPACK_A ;
+	    }
+#endif
+
+	  // print the right-hand-side, B
+	  if (print_level >= 3) 
+	    octave_stdout << "\nright-hand side, b: ";
+
+	  if (B_is_complex)
+	    (void) umfpack_zi_report_vector (nn, Bx, NULL, Control_ptr) ;
+	  else
+	    (void) umfpack_di_report_vector (nn, Bx, Control_ptr) ;
+
+	  // solve the system
+	  double * Xx;
+	  if (X_is_complex)
+	    Xx = X_CAST (double *, Xcmplx.fortran_vec ());
+	  else
+	    Xx = Xreal.fortran_vec ();
+	  status2 = UMFPACK_OK ;
+
+	  if (A_is_complex)
+	    {
+	      if (!B_is_complex)
+		{
+		  OCTAVE_LOCAL_BUFFER (double, Bz, nn);
+		  for (int i = 0; i < nn; i++)
+		    Bz[i] = 0.;
+
+		  status = umfpack_zi_solve (sys, Ap, Ai, Ax, NULL, Xx, NULL, 
+					     Bx, Bz, Numeric, Control_ptr, 
+					     Info);
+		}
+	      else
+		status = umfpack_zi_solve (sys, Ap, Ai, Ax, NULL, Xx, NULL, 
+					   Bx, NULL, Numeric, Control_ptr, 
+					   Info);
+	    }
+	  else
+	    {
+	      if (B_is_complex)
+		{
+		  // Ax=b when b is complex and A is sparse can be split
+		  // into two systems, A*xr=br and A*xi=bi, where r denotes
+		  // the real part and i the imaginary part of x and b.
+		  OCTAVE_LOCAL_BUFFER (double, Tx, nn);
+		  OCTAVE_LOCAL_BUFFER (double, Tz, nn);
+
+		  status = umfpack_di_solve (sys, Ap, Ai, Ax, Tx, Bx,
+					     Numeric, Control_ptr, Info);
+		  status2 = umfpack_di_solve (sys, Ap, Ai, Ax, Tz, Bx,
+					      Numeric, Control_ptr, Info) ;
+
+		  for (int i = 0; i < nn; i++)
+		    Xcmplx (i) = Complex (Tx[i], Tz[i]);
+		}
+	      else
+		status = umfpack_di_solve (sys, Ap, Ai, Ax, Xx, Bx,
+					   Numeric, Control_ptr, Info);
+	    }
+	  
+	  // free the Numeric object
+	  if (A_is_complex)
+	    umfpack_zi_free_numeric (&Numeric) ;
+	  else
+	    umfpack_di_free_numeric (&Numeric) ;
+	  
+	  // check error status
+	  if (status < 0 || status2 < 0)
+	    {
+	      umfpack_error ("solve failed", A_is_complex, nargout, 
+			     retval, Control, InfoOut, status, do_info) ;
+	      return retval;
+	    }
+
+	  // print the solution, X
+	  if (print_level >= 3) 
+	    octave_stdout << "\nsolution, x: ";
+
+	  if (X_is_complex)
+	    (void) umfpack_zi_report_vector (nn, Xx, NULL, Control_ptr);
+	  else
+	    (void) umfpack_di_report_vector (nn, Xx, Control_ptr);
+
+	  // warn about singular or near-singular matrices
+	  // no warning is given if Control (1) is zero
+	  if (Control (UMFPACK_PRL) >= 1)
+	    {
+	      if (status == UMFPACK_WARNING_singular_matrix)
+		{
+		  warning ("matrix is singular");
+		  warning ("Try increasing Control (%d) and Control (%d).",
+			   1+UMFPACK_PIVOT_TOLERANCE, 
+			   1+UMFPACK_SYM_PIVOT_TOLERANCE);
+		  warning ("(Suppress this warning with Control (%d) = 0.)",
+			   1+UMFPACK_PRL);
+		}
+	      else if (InfoOut (UMFPACK_RCOND) < DBL_EPSILON)
+		{
+		  warning ("matrix is nearly singular, rcond = %g",
+			   InfoOut (UMFPACK_RCOND));
+		  warning ("Try increasing Control (%d) and Control (%d).",
+			   1+UMFPACK_PIVOT_TOLERANCE,
+			   1+UMFPACK_SYM_PIVOT_TOLERANCE);
+		  warning ("(Suppress this warning with Control (%d) = 0.)",
+			   1+UMFPACK_PRL);
+		}
+	    }
+
+	  // Setup the return value
+	  if (X_is_complex)
+	    retval (0) = octave_value (Xcmplx);
+	  else
+	    retval (0) = octave_value (Xreal);
+	}
+      else
+	{
+	  // get L, U, P, Q, and r
+	  int lnz, unz, ignore1, ignore2, ignore3;
+
+	  if (A_is_complex)
+	    status = umfpack_zi_get_lunz (&lnz, &unz, &ignore1, &ignore2,
+					  &ignore3, Numeric) ;
+	  else
+	    status = umfpack_di_get_lunz (&lnz, &unz, &ignore1, &ignore2,
+					  &ignore3, Numeric) ;
+
+	  if (status < 0)
+	    {
+	      if (A_is_complex)
+		umfpack_zi_free_numeric (&Numeric) ;
+	      else
+		umfpack_di_free_numeric (&Numeric) ;
+
+	      umfpack_error ("extracting LU factors failed", A_is_complex, 
+			     nargout, retval, Control, InfoOut, status, 
+			     do_info);
+	      return retval;
+	    }
+
+	  // avoid malloc of zero-sized arrays
+	  lnz = MAX (lnz, 1) ;
+	  unz = MAX (unz, 1) ;
+
+	  // get space for the *** ROW *** form of L
+	  SparseMatrix Lreal;
+	  SparseComplexMatrix Limag;
+	  int *Ltp, *Ltj;
+	  double *Ltx;
+	  if (A_is_complex)
+	    {
+	      Limag = SparseComplexMatrix (n_inner, n_row, lnz);
+	      Ltp = Limag.cidx ();
+	      Ltj = Limag.ridx ();
+	      Ltx = X_CAST (double *, Limag.data ());
+	    }
+	  else
+	    {
+	      Lreal = SparseMatrix (n_inner, n_row, lnz);
+	      Ltp = Lreal.cidx ();
+	      Ltj = Lreal.ridx ();
+	      Ltx = Lreal.data ();
+	    }
+
+	  // create permanent copy of the output matrix U
+	  int *Up, *Ui;
+	  double *Ux;
+	  SparseMatrix Ureal;
+	  SparseComplexMatrix Uimag;
+
+	  if (A_is_complex)
+	    {
+	      Uimag = SparseComplexMatrix (n_inner, n_col, unz);
+	      Up = Uimag.cidx ();
+	      Ui = Uimag.ridx ();
+	      Ux = X_CAST (double *, Uimag.data ());
+	    }
+	  else
+	    {
+	      Ureal = SparseMatrix (n_inner, n_col, unz);
+	      Up = Ureal.cidx ();
+	      Ui = Ureal.ridx ();
+	      Ux = Ureal.data ();
+	    }
+
+	  // temporary space for the integer permutation vectors
+	  OCTAVE_LOCAL_BUFFER (int, P, n_row);
+	  OCTAVE_LOCAL_BUFFER (int, Q, n_col);
+
+	  // get scale factors, if requested 
+	  status2 = UMFPACK_OK ;
+	  SparseMatrix Rsout;
+	  double * Rs;
+	  if (!no_scale)
+	    {
+	      // create a diagonal sparse matrix for the scale factors 
+	      Rsout = SparseMatrix (n_row, n_row, n_row);
+	      for (int i = 0 ; i < n_row ; i++)
+		{
+		  Rsout.cidx (i) = i;
+		  Rsout.ridx (i) = i;
+		}
+	      Rsout.cidx (n_row) = n_row;
+	      Rs = Rsout.data ();
+	    }
+	  else
+	    Rs = (double *) NULL ;
+
+	  // get Lt, U, P, Q, and Rs from the numeric object
+	  int do_recip;
+	  if (A_is_complex)
+	    {
+	      status = umfpack_zi_get_numeric (Ltp, Ltj, Ltx, NULL, Up, Ui, 
+					       Ux, NULL, P, Q, 
+					       (double *) NULL, 
+					       (double *) NULL,
+					       &do_recip, Rs, Numeric) ;
+	      umfpack_zi_free_numeric (&Numeric) ;
+	    }
+	  else
+	    {
+	      status = umfpack_di_get_numeric (Ltp, Ltj, Ltx, Up, Ui,
+					       Ux, P, Q, (double *) NULL,
+					       &do_recip, Rs, Numeric) ;
+	      umfpack_di_free_numeric (&Numeric) ;
+	    }
+
+	  if (!no_scale)
+	    retval (4) = octave_vale (Rsout);
+
+	  // for the oct-file, -DNRECIPROCAL must be set,
+	  // so do_recip must be FALSE
+
+	  if (status < 0 || status2 < 0 || do_recip)
+	    {
+	      umfpack_error ("extracting LU factors failed", A_is_complex, 
+			     nargout, retval, Control, InfoOut, status, 
+			     do_info);
+	      return retval;
+	    }
+
+	  if (A_is_complex)
+	    retval (1) = octave_value (Uimag);
+	  else
+	    retval (1) = octave_valye (Ureal);
+	  
+	  // create sparse permutation matrix for P 
+	  SparseMatrix Pout (n_row, n_row, n_row);
+	  for (int k = 0 ; k < n_row ; k++)
+	    {
+	      Pout.cidx (k) = k ;
+	      Pout.ridx (P [k]) = k;
+	      Pout.data (k) = 1;
+	    }
+	  Pout.cidx (n_row) = n_row;
+	  retval (2) = octave_value (Pout);
+
+	  // create sparse permutation matrix for Q 
+	  SparseMatrix Qout (n_col, n_col, n_col);
+	  for (int k = 0 ; k < n_col ; k++)
+	    {
+	      Qout.cidx (k) = k ;
+	      Qout.ridx (k) = Q[k];
+	      Qout.data (k) = 1;
+	    }
+	  Qout.cidx (n_col) = n_col;
+	  retval (3) = octave_value (Qout);
+	  
+	  // permanent copy of L 
+	  if (A_is_complex)
+	    retval (0) = octave_value (Limag.transpose());
+	  else
+	    retval (0) = octave_value (Lreal.transpose());
+
+	  if (status < 0)
+	    {
+	      umfpack_error ("constructing L failed", A_is_complex, 
+			     nargout, retval, Control, InfoOut, status, 
+			     do_info) ;
+	      return octave_value ();
+	    }
+
+	  // print L, U, P, and Q
+	  if (A_is_complex)
+	    {
+	      if (print_level >= 3) 
+		{
+		  octave_stdout << "\nL: ";
+		  int *Lp = Limag.cidx ();
+		  int *Li = Limag.ridx ();
+		  double *Lx = X_CAST (double *, Limag.data ());
+
+		  (void) umfpack_zi_report_matrix (n_row, n_inner, Lp, Li,
+						   Lx, NULL, 1, Control_ptr) ;
+		}
+
+	      if (print_level >= 3) 
+		octave_stdout << "\nU: ";
+	      (void) umfpack_zi_report_matrix (n_inner, n_col, Up, Ui,
+					       Ux, NULL, 1, Control_ptr) ;
+	      if (print_level >= 3)
+		octave_stdout << "\nP: ";
+	      (void) umfpack_zi_report_perm (n_row, P, Control_ptr);
+	      if (print_level >= 3) 
+		octave_stdout << "\nQ: ";
+	      (void) umfpack_zi_report_perm (n_col, Q, Control_ptr);
+	    }
+	  else
+	    {
+	      if (print_level >= 3) 
+		{
+		  int *Lp = Lreal.cidx ();
+		  int *Li = Lreal.ridx ();
+		  double *Lx = Lreal.data ();
+		  octave_stdout << "\nL: ";
+		  (void) umfpack_di_report_matrix (n_row, n_inner, Lp, Li,
+						   Lx, 1, Control_ptr);
+		}
+
+	      if (print_level >= 3) 
+		octave_stdout << "\nU: ";
+	      (void) umfpack_di_report_matrix (n_inner, n_col, Up, Ui,
+					       Ux, 1, Control_ptr);
+	      if (print_level >= 3) 
+		octave_stdout << "\nP: ";
+	      (void) umfpack_di_report_perm (n_row, P, Control_ptr);
+	      if (print_level >= 3) 
+		octave_stdout << "\nQ: ";
+	      (void) umfpack_di_report_perm (n_col, Q, Control_ptr);
+	    }
+	}
+    }
+  else
+    {
+      // return the symbolic factorization
+      int ignore1, ignore2, ignore3;
+      OCTAVE_LOCAL_BUFFER (int, Q, n_col);
+      OCTAVE_LOCAL_BUFFER (int, P, n_row);
+      OCTAVE_LOCAL_BUFFER (int, Front_npivcol, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Front_parent, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Front_1strow, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Front_leftmostdesc, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Chain_start, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Chain_maxrows, nn + 1);
+      OCTAVE_LOCAL_BUFFER (int, Chain_maxcols, nn + 1);
+
+      int nz, nfronts, nchains;
+
+      if (A_is_complex)
+	{
+	  status = umfpack_zi_get_symbolic (&ignore1, &ignore2, &ignore3,
+					    &nz, &nfronts, &nchains, P, Q, 
+					    Front_npivcol, Front_parent, 
+					    Front_1strow, 
+					    Front_leftmostdesc,
+					    Chain_start, Chain_maxrows, 
+					    Chain_maxcols, Symbolic) ;
+	  umfpack_zi_free_symbolic (&Symbolic) ;
+	}
+      else
+	{
+	  status = umfpack_di_get_symbolic (&ignore1, &ignore2, &ignore3,
+					    &nz, &nfronts, &nchains, P, Q, 
+					    Front_npivcol, Front_parent, 
+					    Front_1strow, 
+					    Front_leftmostdesc,
+					    Chain_start, Chain_maxrows, 
+					    Chain_maxcols, Symbolic) ;
+	  umfpack_di_free_symbolic (&Symbolic) ;
+	}
+
+      if (status < 0)
+	{
+	  umfpack_error ("extracting symbolic factors failed", 
+			 A_is_complex, nargout, retval, Control, 
+			 InfoOut, status, do_info) ;
+	  return retval;
+	}
+      
+      // create sparse permutation matrix for P
+      SparseMatrix Pout (n_row, n_row, n_row);
+      for (int k = 0 ; k < n_row ; k++)
+	{
+	  Pout.cidx (k) = k;
+	  Pout.ridx (P [k]) = k;
+	  Pout.data (k) = 1;
+	}
+      Pout.cidx (n_row) = n_row;
+      retval (0) = octave_value (Pout);
+
+      // create sparse permutation matrix for Q 
+      SparseMatrix Qout (n_col, n_col, n_col);
+      for (int k = 0 ; k < n_col ; k++)
+	{
+	  Qout.cidx (k) = k;
+	  Qout.ridx (k) = Q[k];
+	  Qout.data (k) = 1;
+	}
+      Qout.cidx (n_col) = n_col;
+      retval (1) = octave_value (Qout);
+      
+      // create Fr 
+      Matrix Frout (nfronts + 1, 4);
+      for (int i = 0 ; i <= nfronts ; i++)
+	{
+	  // convert parent, 1strow, and leftmostdesc to 1-based 
+	  Frout (i, 0) = (double) (Front_npivcol [i]) ;
+	  Frout (i, 1) = (double) (Front_parent [i] + 1) ;
+	  Frout (i, 2) = (double) (Front_1strow [i] + 1) ;
+	  Frout (i, 3) = (double) (Front_leftmostdesc [i] + 1) ;
+	}
+      retval (2) = octave_value (Frout);
+      
+      // create Ch 
+      Matrix Chout (nchains + 1, 3);
+      for (int i = 0 ; i <= nchains ; i++)
+	{
+	  // convert to 1-based 
+	  Chout (i, 0) = (double) (Chain_start [i] + 1) ;
+	  Chout (i, 1) = (double) (Chain_maxrows [i]) ;
+	  Chout (i, 2) = (double) (Chain_maxcols [i]) ;
+	}
+      Chout (0, nchains) = (double) Chain_start [nchains] + 1 ;
+      Chout (1, nchains) = 0.;
+      Chout (2, nchains) = 0.;
+      retval (3) = octave_value (Chout);
+    }
+
+  // report Info
+  if (A_is_complex)
+    umfpack_zi_report_info (Control_ptr, Info);
+  else
+    umfpack_di_report_info (Control_ptr, Info);
+
+  if (do_info > 0)
+    retval (do_info) = InfoOut;
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_demo.m UMFPACK/UMFPACK/OCTAVE/umfpack_demo.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_demo.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_demo.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,191 @@
+function umfpack_demo
+% UMFPACK DEMO
+%
+% A demo of UMFPACK for OCTAVE.
+%
+% See also umfpack, umfpack_make, umfpack_details, umfpack_report,
+% and umfpack_simple.
+
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  Type umfpack_details for License.
+
+%-------------------------------------------------------------------------------
+% get default control parameters
+%-------------------------------------------------------------------------------
+
+control = umfpack ;
+fprintf ('\nEnter the printing level for UMFPACK''s output statistics:\n') ;
+fprintf ('0: none, 1: errors only, 2: statistics, 4: print some of outputs\n') ;
+c = input ('5: print all output [default is 1]: ') ;
+if (isempty (c))
+    c = 1 ;
+end
+control (1) = c ;
+
+%-------------------------------------------------------------------------------
+% solve a simple system
+%-------------------------------------------------------------------------------
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('Factor and solve a small system, Ax=b, using default parameters\n') ;
+if (control (1) > 1)
+    fprintf ('(except for verbose printing enabled)\n') ;
+end
+
+load west0067 ;
+A = Problem.A ;
+n = size (A, 1) ;
+b = rand (n, 1) ;
+
+fprintf ('Solving Ax=b via UMFPACK:\n') ;
+[xu, info] = umfpack (A, '\\', b, control) ;
+x = xu ;
+
+fprintf ('Solving Ax=b via OCTAVE:\n') ;
+xm = A\b ;
+x = xm ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (xu - xm, Inf)) ;
+
+%-------------------------------------------------------------------------------
+% spy the results
+%-------------------------------------------------------------------------------
+
+figure (1) ;
+clf
+
+subplot (2,3,1)
+title ('The matrix A') ;
+spy (A)
+
+subplot (2,3,2)
+[P1, Q1, Fr, Ch, Info] = umfpack (A, 'symbolic') ;
+title ('Supernodal column elimination tree') ;
+%% Disable for now !!
+%% treeplot (Fr (1:end-1,2)') ;
+
+subplot (2,3,3)
+title ('A, with initial row and column order') ;
+spy (P1 * A * Q1)
+
+subplot (2,3,4)
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('\nFactorizing [L, U, P, Q, R] = umfpack (A)\n') ;
+[L, U, P, Q, R] = umfpack (A) ;
+title ('A, with final row/column order') ;
+spy (P*A*Q)
+
+fprintf ('\nP * (R\\A) * Q - L*U should be zero:\n') ;
+fprintf ('norm (P*(R\\A)*Q - L*U, 1) = %g (exact) %g (estimated)\n', ...
+    norm (P * (R\A) * Q - L*U, 1), lu_normest (P * (R\A) * Q,  L, U)) ;
+
+fprintf ('\nSolution to Ax=b via UMFPACK factorization:\n') ;
+fprintf ('x = Q * (U \\ (L \\ (P * (R \\ b))))\n') ;
+xu = Q * (U \ (L \ (P * (R \ b)))) ;
+x = xu ;
+
+fprintf ('\nUMFPACK flop count: %d\n', luflop (L, U)) ;
+
+subplot (2,3,5)
+title ('UMFPACK LU factors') ;
+spy (spones (L) + spones (U))
+
+subplot (2,3,6)
+fprintf ('\nFactorizing [L, U, P] = lu (A (:, q))\n') ;
+try
+    q = colamd (A) ;
+catch
+    fprintf ('\n *** colamd not found, using colmmd instead *** \n') ;
+    q = colmmd (A) ;
+end
+[L, U, P] = lu (A (:,q)) ;
+title ('OCTAVE LU factors') ;
+spy (spones (L) + spones (U))
+
+fprintf ('\nSolution to Ax=b via OCTAVE factorization:\n') ;
+fprintf ('x = U \\ (L \\ (P * b)) ; x (q) = x ;\n') ;
+xm = U \ (L \ (P * b)) ;
+xm (q) = xm ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (xu - xm, Inf)) ;
+
+fprintf ('\nOCTAVE LU flop count: %d\n', luflop (L, U)) ;
+
+%-------------------------------------------------------------------------------
+% solve A'x=b
+%-------------------------------------------------------------------------------
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('Solve A''x=b:\n') ;
+
+fprintf ('Solving A''x=b via UMFPACK:\n') ;
+[xu, info] = umfpack (b', '/', A, control) ;
+xu = xu' ;
+
+fprintf ('Solving A''x=b via OCTAVE:\n') ;
+xm = (b'/A)' ;
+x = xm ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (xu - xm, Inf)) ;
+
+%-------------------------------------------------------------------------------
+% factor A' and then solve Ax=b using the factors of A'
+%-------------------------------------------------------------------------------
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('Compute C = A'', and compute the LU factorization of C.\n') ;
+fprintf ('Factorizing A'' can sometimes be better than factorizing A itself\n');
+fprintf ('(less work and memory usage).  Solve C''x=b; the solution is the\n') ;
+fprintf ('same as the solution to Ax=b for the original A.\n');
+
+C = A' ;
+
+% factorize C (P,Q) = L*U
+[L, U, P, Q, R, info] = umfpack (C, control) ;
+
+fprintf ('\nP * (R\\C) * Q - L*U should be zero:\n') ;
+fprintf ('norm (P*(R\\C)*Q - L*U, 1) = %g (exact) %g (estimated)\n', ...
+    norm (P * (R\C) * Q - L*U, 1), lu_normest (P * (R\C) * Q,  L, U)) ;
+
+fprintf ('\nSolution to Ax=b via UMFPACK, using the factors of C:\n') ;
+fprintf ('x = R \\ (P'' * (L'' \\ (U'' \\ (Q'' * b)))) ;\n') ;
+xu = R \ (P' * (L' \ (U' \ (Q' * b)))) ;
+x = xu ;
+
+fprintf ('Solution to Ax=b via OCTAVE:\n') ;
+xm = A\b ;
+x = xm ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (xu - xm, Inf)) ;
+
+%-------------------------------------------------------------------------------
+% solve Ax=B
+%-------------------------------------------------------------------------------
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('\nSolve AX=B, where B is n-by-10, and sparse\n') ;
+B = sprandn (n, 10, 0.05) ;
+XU = umfpack_solve (A, '\\', B, control) ;
+XM = A\B ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (XU - XM, Inf)) ;
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('\nSolve AX=B, where B is n-by-10, and sparse, using umfpack_btf\n') ;
+XU = umfpack_btf (A, B, control) ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (XU - XM, Inf)) ;
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('\nSolve A''X=B, where B is n-by-10, and sparse\n') ;
+XU = umfpack_solve (B', '/', A, control) ;
+XM = B'/A ;
+
+fprintf ('Difference between UMFPACK and OCTAVE solution: %g\n', ...
+    norm (XU - XM, Inf)) ;
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_demo.m.out UMFPACK/UMFPACK/OCTAVE/umfpack_demo.m.out
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_demo.m.out	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_demo.m.out	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,72 @@
+>> umfpack_demo
+
+Enter the printing level for UMFPACK's output statistics:
+0: none, 1: errors only, 2: statistics, 4: print some of outputs
+5: print all output [default is 1]: 
+
+--------------------------------------------------------------
+Factor and solve a small system, Ax=b, using default parameters
+Solving Ax=b via UMFPACK:
+Solving Ax=b via MATLAB:
+Difference between UMFPACK and MATLAB solution: 1.24345e-14
+
+--------------------------------------------------------------
+
+Factorizing [L, U, P, Q, R] = umfpack (A)
+
+P * (R\A) * Q - L*U should be zero:
+norm (P*(R\A)*Q - L*U, 1) = 4.2068e-16 (exact) 3.74627e-16 (estimated)
+
+Solution to Ax=b via UMFPACK factorization:
+x = Q * (U \ (L \ (P * (R \ b))))
+
+UMFPACK flop count: 2362
+
+Factorizing [L, U, P] = lu (A (:, q))
+If you are using a version of MATLAB prior to V6.0, then the
+following statement (q = colamd (A)) may fail.  Either download
+colamd from http://www.cise.ufl.edu/research/sparse, upgrade to
+MATLAB V6.0 or later, or replace the statement with
+q = colmmd (A) ;
+
+Solution to Ax=b via MATLAB factorization:
+x = U \ (L \ (P * b)) ; x (q) = x ;
+Difference between UMFPACK and MATLAB solution: 1.37668e-14
+
+MATLAB LU flop count: 3164
+
+--------------------------------------------------------------
+Solve A'x=b:
+Solving A'x=b via UMFPACK:
+Solving A'x=b via MATLAB:
+Difference between UMFPACK and MATLAB solution: 3.10862e-15
+
+--------------------------------------------------------------
+Compute C = A', and compute the LU factorization of C.
+Factorizing A' can sometimes be better than factorizing A itself
+(less work and memory usage).  Solve C'x=b; the solution is the
+same as the solution to Ax=b for the original A.
+
+P * (R\C) * Q - L*U should be zero:
+norm (P*(R\C)*Q - L*U, 1) = 1.31839e-16 (exact) 6.41848e-17 (estimated)
+
+Solution to Ax=b via UMFPACK, using the factors of C:
+x = R \ (P' * (L' \ (U' \ (Q' * b)))) ;
+Solution to Ax=b via MATLAB:
+Difference between UMFPACK and MATLAB solution: 1.77636e-14
+
+--------------------------------------------------------------
+
+Solve AX=B, where B is n-by-10, and sparse
+Difference between UMFPACK and MATLAB solution: 2.88198e-14
+
+--------------------------------------------------------------
+
+Solve AX=B, where B is n-by-10, and sparse, using umfpack_btf
+Difference between UMFPACK and MATLAB solution: 9.79736e-14
+
+--------------------------------------------------------------
+
+Solve A'X=B, where B is n-by-10, and sparse
+Difference between UMFPACK and MATLAB solution: 1.05244e-13
+>> diary off
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_make.m UMFPACK/UMFPACK/OCTAVE/umfpack_make.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_make.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_make.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,356 @@
+function umfpack_make
+% UMFPACK_MAKE
+%
+% Compiles the UMFPACK mexFunction and then runs a simple demo.
+%
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  Type umfpack_details for License.
+%
+% See also: umfpack, umfpack_details, umfpack_report, umfpack_demo, and
+% umfpack_simple.
+
+help umfpack_make
+
+fprintf ('\n--------------------------------------------------------------\n') ;
+fprintf ('Now compiling the UMFPACK and AMD mexFunctions.\n') ;
+fprintf ('--------------------------------------------------------------\n') ;
+
+try
+    % ispc does not appear in MATLAB 5.3
+    pc = ispc ;
+catch
+    % if ispc fails, assume we aren't on a Windows PC.
+    pc = 0 ;
+end
+
+obj = 'o' ;
+blas_lib = '' ;
+if (pc)
+    obj = 'obj' ;
+end
+
+%-------------------------------------------------------------------------------
+% BLAS option
+%-------------------------------------------------------------------------------
+
+msg = [ ...
+    '\nUsing the BLAS is faster, but might not compile correctly.\n', ...
+    'If you get an error stating that dgemm, dgemv, dger, zgemm,\n', ...
+    'zgemv, and/or zger are not defined, then recompile without the\n', ...
+    'BLAS.  You can ignore warnings that these routines are implicitly\n', ...
+    'declared.\n\nPlease select one of the following options: \n', ...
+    '   1:  attempt to compile with the BLAS (default)\n', ...
+    '   2:  do not use the BLAS\n'] ;
+fprintf (msg) ;
+blas = input (': ') ;
+if (isempty (blas))
+    blas = 1 ;
+end
+if (blas == 1)
+    % try to link to MATLAB's built-in BLAS
+    blas = '' ;
+    if (pc)
+        % the default lcc compiler needs this library to access the BLAS
+        blas_lib = ' libmwlapack.lib' ;
+        msg = [ ...
+        '\nCheck to see if you have a file called libmwlapack.lib in the\n', ...
+        '<matlab>\\extern\\lib\\win32\\lcc\\ directory, where <matlab> is ', ...
+        'the\ndirectory where MATLAB is installed.  If a file of that ', ...
+        'name is already\nthere, then you don''t have to do anything.  ', ...
+        'Otherwise, you must first\ncopy the libmwlapack.lib file from ', ...
+        'the umfpack\\lcc_lib\\ directory to the\n', ...
+        '<matlab>\\extern\\lib\\win32\\lcc\\ directory.  Next, type\n\n', ...
+        '    mex -setup\n\n', ...
+        'at the MATLAB prompt, and ask MATLAB to select the lcc compiler.  ',...
+        'You can skip\nall of this if you have already done it, or have ', ...
+        'configured mex to use\na different compiler.  If you are using ', ...
+        'Norton anti-virus software on Windows\n98SE, then you need to ', ...
+        'exit MATLAB, turn off virus checking, and restart MATLAB\n', ...
+        'before you can use the mex command or compile UMFPACK.\n', ...
+        'You may also need to turn off virus checking in other cases.\n', ...
+        '\nHit enter to continue, or type control-C if you do not wish to '] ;
+        fprintf (msg) ;
+        input ('proceed: ') ;
+    end
+    fprintf ('\nUsing the BLAS (recommended).\n') ;
+else
+    % No BLAS
+    fprintf ('\nNot using the BLAS.  UMFPACK will be slow.\n') ;
+    blas = ' -DNBLAS' ;
+end
+
+%-------------------------------------------------------------------------------
+% -DNUTIL option (using utMalloc or mxMalloc)
+%-------------------------------------------------------------------------------
+
+utils = '' ;
+
+if (~pc)
+    msg = [ ...
+    '--------------------------------------------------------------\n', ...
+    '\nUMFPACK uses MATLAB''s memory allocation routines.  The internal', ...
+    '\nutMalloc, utFree, and utRealloc allow for better use of memory,', ...
+    '\nbut they are internal utility routines that are not documented.\n', ...
+    'Thus, they might not always work.  Using mxMalloc, mxFree, and\n', ...
+    'mxRealloc works, but UMFPACK might run out of memory when solving\n', ...
+    'problems that it could otherwise solve.  Try using the default.\n', ...
+    'If you get an error stating that utMalloc, utFree, and/or\n', ...
+    'utRealloc are not defined, then recompile with the mx* routines.\n', ...
+    '\nPlease select one of the following options:\n', ...
+    '    1:  attempt to use the ut* routines (default)\n', ...
+    '    2:  use the standard mx* routines\n'] ;
+    fprintf (msg) ;
+    utils = input (': ') ;
+    if (isempty (utils))
+	utils = 1 ;
+    end
+    if (utils == 2)
+        fprintf ('\nNot using utMalloc, utFree, or utRealloc\n') ;
+        utils = ' -DNUTIL' ;
+    else
+        fprintf ('\nUsing utMalloc, utFree, and utRealloc\n') ;
+        utils = '' ;
+    end
+end
+
+%-------------------------------------------------------------------------------
+% -DNPOSIX option (for sysconf and times timer routines)
+%-------------------------------------------------------------------------------
+
+posix = '' ;
+
+if (~pc)
+    msg = [ ...
+    '--------------------------------------------------------------\n', ...
+    '\nUMFPACK can use the POSIX routines sysconf () and times ()\n', ...
+    'to provide CPU time and wallclock time statistics.  If you do not\n', ...
+    'have a POSIX-compliant operating system, then UMFPACK won''t\n', ...
+    'compile.  If you don''t know which option to pick, try the\n', ...
+    'default.  If you get an error saying that sysconf and/or times\n', ...
+    'are not defined, then recompile with the non-POSIX option.\n', ...
+    '\nPlease select one of the following options:\n', ...
+    '    1:  use POSIX sysconf and times routines (default)\n', ...
+    '    2:  do not use POSIX routines\n'] ;
+    fprintf (msg) ;
+    posix = input (': ') ;
+    if (isempty (posix))
+	posix = 1 ;
+    end
+    if (posix == 2)
+        fprintf ('\nNot using POSIX sysconf and times routines.\n') ;
+        posix = ' -DNPOSIX' ;
+    else
+        fprintf ('\nUsing POSIX sysconf and times routines.\n') ;
+        posix = '' ;
+    end
+end
+
+%-------------------------------------------------------------------------------
+% mex command
+%-------------------------------------------------------------------------------
+
+umfdir = sprintf ('..%sSource%s', filesep, filesep) ;
+amddir = sprintf ('..%s..%sAMD%sSource%s', filesep, filesep, filesep, filesep) ;
+incdir = sprintf ( ...
+' -I..%sInclude -I..%sSource -I..%s..%sAMD%sInclude -I..%s..%sAMD%sSource', ...
+filesep,filesep,  filesep, filesep, filesep, filesep, filesep, filesep) ;
+
+mx = sprintf ('mex -inline -O%s%s%s%s', blas, utils, posix, incdir) ;
+msg = [ ...
+    '--------------------------------------------------------------\n', ...
+    '\nCompile options:\n%s\nNow compiling.  Please wait.\n'] ;
+fprintf (msg, mx) ;
+
+% The following is adapted from GNUmakefile
+
+%-------------------------------------------------------------------------------
+% source files
+%-------------------------------------------------------------------------------
+
+% non-user-callable umf_*.[ch] files:
+umfch = { 'assemble', 'blas3_update', ...
+        'build_tuples', 'create_element', ...
+        'dump', 'extend_front', 'garbage_collection', ...
+        'get_memory', 'init_front', 'kernel', ...
+        'kernel_init', 'kernel_wrapup', ...
+        'local_search', 'lsolve', 'ltsolve', ...
+        'mem_alloc_element', 'mem_alloc_head_block', ...
+        'mem_alloc_tail_block', 'mem_free_tail_block', ...
+        'mem_init_memoryspace', ...
+        'report_vector', 'row_search', 'scale_column', ...
+        'set_stats', 'solve', 'symbolic_usage', 'transpose', ...
+        'tuple_lengths', 'usolve', 'utsolve', 'valid_numeric', ...
+        'valid_symbolic', 'grow_front', 'start_front', '2by2', ...
+	'store_lu', 'scale' } ;
+
+% non-user-callable umf_*.[ch] files, int versions only (no real/complex):
+umfint = { 'analyze', 'apply_order', 'colamd', 'free', 'fsize', ...
+        'is_permutation', 'malloc', 'realloc', 'report_perm', ...
+	'singletons' } ;
+
+% non-user-callable and user-callable amd_*.[ch] files (int versions only):
+amd = { 'aat', '1', '2', 'dump', 'postorder', 'post_tree', 'defaults', ...
+        'order', 'control', 'info', 'valid' } ;
+
+% user-callable umfpack_*.[ch] files (real/complex):
+user = { 'col_to_triplet', 'defaults', 'free_numeric', ...
+        'free_symbolic', 'get_numeric', 'get_lunz', ...
+        'get_symbolic', 'numeric', 'qsymbolic', ...
+        'report_control', 'report_info', 'report_matrix', ...
+        'report_numeric', 'report_perm', 'report_status', ...
+        'report_symbolic', 'report_triplet', ...
+        'report_vector', 'solve', 'symbolic', ...
+        'transpose', 'triplet_to_col', 'scale' ...
+	'load_numeric', 'save_numeric', 'load_symbolic', 'save_symbolic' } ;
+
+% user-callable umfpack_*.[ch], only one version
+generic = { 'timer', 'tictoc' } ;
+
+M = cell (0) ;
+
+%-------------------------------------------------------------------------------
+% Create the umfpack and amd mexFunctions for MATLAB (int versions only)
+%-------------------------------------------------------------------------------
+
+for k = 1:length(umfint)
+    M = make (M, '%s -DDINT -c %sumf_%s.c', 'umf_%s.%s', 'umf_%s_%s.%s', ...
+        mx, umfint {k}, umfint {k}, 'm', obj, umfdir) ;
+end
+
+rules = { [mx ' -DDINT'] , [mx ' -DZINT'] } ;
+kinds = { 'md', 'mz' } ;
+
+for what = 1:2 
+
+    rule = rules {what} ;
+    kind = kinds {what} ;
+
+    M = make (M, '%s -DCONJUGATE_SOLVE -c %sumf_%s.c', 'umf_%s.%s', ...
+        'umf_%s_%s.%s', rule, 'ltsolve', 'lhsolve', kind, obj, umfdir) ;
+
+    M = make (M, '%s -DCONJUGATE_SOLVE -c %sumf_%s.c', 'umf_%s.%s', ...
+        'umf_%s_%s.%s', rule, 'utsolve', 'uhsolve', kind, obj, umfdir) ;
+
+    M = make (M, '%s -DDO_MAP -c %sumf_%s.c', 'umf_%s.%s', ...
+        'umf_%s_%s_map_nox.%s', rule, 'triplet', 'triplet', kind, obj, umfdir) ;
+
+    M = make (M, '%s -DDO_VALUES -c %sumf_%s.c', 'umf_%s.%s', ...
+        'umf_%s_%s_nomap_x.%s', rule, 'triplet', 'triplet', kind, obj, umfdir) ;
+
+    M = make (M, '%s -c %sumf_%s.c', 'umf_%s.%s',  ...
+        'umf_%s_%s_nomap_nox.%s', rule, 'triplet', 'triplet', kind, obj, ...
+	umfdir) ;
+
+    M = make (M, '%s -DDO_MAP -DDO_VALUES -c %sumf_%s.c', 'umf_%s.%s', ...
+        'umf_%s_%s_map_x.%s', rule, 'triplet', 'triplet', kind, obj, umfdir) ;
+
+    M = make (M, '%s -DFIXQ -c %sumf_%s.c', 'umf_%s.%s', ...
+	'umf_%s_%s_fixq.%s', rule, 'assemble', 'assemble', kind, obj, umfdir) ;
+
+    M = make (M, '%s -DDROP -c %sumf_%s.c', 'umf_%s.%s', ...
+	'umf_%s_%s_drop.%s', rule, 'store_lu', 'store_lu', kind, obj, umfdir) ;
+
+    for k = 1:length(umfch)
+        M = make (M, '%s -c %sumf_%s.c', 'umf_%s.%s', 'umf_%s_%s.%s', ...
+            rule, umfch {k}, umfch {k}, kind, obj, umfdir) ;
+    end
+
+    M = make (M, '%s -DWSOLVE -c %sumfpack_%s.c', 'umfpack_%s.%s', ...
+        'umfpack_%s_w%s.%s', rule, 'solve', 'solve', kind, obj, umfdir) ;
+
+    for k = 1:length(user)
+        M = make (M, '%s -c %sumfpack_%s.c', 'umfpack_%s.%s', ...
+            'umfpack_%s_%s.%s', rule, user {k}, user {k}, kind, obj, umfdir) ;
+    end
+end
+
+for k = 1:length(generic)
+    M = make (M, '%s -c %sumfpack_%s.c', 'umfpack_%s.%s', ...
+	'umfpack_%s_%s.%s', mx, generic {k}, generic {k}, 'm', obj, umfdir) ;
+end
+
+%----------------------------------------
+% AMD routines (int only)
+%----------------------------------------
+
+for k = 1:length(amd)
+    M = make (M, '%s -DDINT -c %samd_%s.c', 'amd_%s.%s', 'amd_%s_%s.%s', ...
+        mx, amd {k}, amd {k}, 'm', obj, amddir) ;
+end
+
+%----------------------------------------
+% compile the umfpack mexFunction
+%----------------------------------------
+
+C = sprintf ('%s -output umfpack umfpackmex.c', mx) ;
+for i = 1:length (M)
+    C = [C ' ' (M {i})] ;
+end
+C = [C ' ' blas_lib] ;
+cmd (C) ;
+
+%----------------------------------------
+% delete the object files
+%----------------------------------------
+
+for i = 1:length (M)
+    rmfile (M {i}) ;
+end
+
+%----------------------------------------
+% compile the luflop mexFunction
+%----------------------------------------
+
+cmd (sprintf ('%s -output luflop luflopmex.c', mx)) ;
+
+fprintf ('\n\nCompilation has completed.  Now trying the umfpack_simple demo.\n');
+umfpack_simple
+
+%-------------------------------------------------------------------------------
+% rmfile:  delete a file, but only if it exists
+%-------------------------------------------------------------------------------
+
+function rmfile (file)
+if (length (dir (file)) > 0)
+    delete (file) ;
+end
+
+%-------------------------------------------------------------------------------
+% cpfile:  copy the src file to the filename dst, overwriting dst if it exists
+%-------------------------------------------------------------------------------
+
+function cpfile (src, dst)
+rmfile (dst)
+if (length (dir (src)) == 0)
+    help umfpack_make
+    error (sprintf ('File does not exist: %s\n', src)) ;
+end
+copyfile (src, dst) ;
+
+%-------------------------------------------------------------------------------
+% mvfile:  move the src file to the filename dst, overwriting dst if it exists
+%-------------------------------------------------------------------------------
+
+function mvfile (src, dst)
+cpfile (src, dst) ;
+rmfile (src) ;
+
+%-------------------------------------------------------------------------------
+% cmd:  display and execute a command
+%-------------------------------------------------------------------------------
+
+function cmd (s)
+fprintf ('.') ;
+eval (s) ;
+
+%-------------------------------------------------------------------------------
+% make:  execute a "make" command for a source file
+%-------------------------------------------------------------------------------
+
+function M = make (M, s, src, dst, rule, file1, file2, kind, obj, srcdir)
+cmd (sprintf (s, rule, srcdir, file1)) ;
+src = sprintf (src, file1, obj) ;
+dst = sprintf (dst, kind, file2, obj) ;
+mvfile (src, dst) ;
+M {end + 1} = dst ;
+
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_report.m UMFPACK/UMFPACK/OCTAVE/umfpack_report.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_report.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_report.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,346 @@
+function umfpack_report (Control, Info)
+% UMFPACK_REPORT
+%
+%       umfpack_report (Control, Info) ;
+%
+% Prints the current Control settings for umfpack, and the statistical
+% information returned by umfpack in the Info array.  If Control is
+% an empty matrix, then the default control settings are printed.
+%
+% Control is 20-by-1, and Info is 90-by-1.  Not all entries are used.
+%
+% Alternative usages:
+%
+%       umfpack_report ([ ], Info) ;    print the default control parameters
+%                                       and the Info array.
+%       umfpack_report (Control) ;      print the control parameters only.
+%       umfpack_report ;                print the default control parameters
+%                                       and an empty Info array.
+%
+% See also umfpack, umfpack_make, umfpack_details,
+% umfpack_demo, and umfpack_simple.
+
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  See ../README for License.
+
+%-------------------------------------------------------------------------------
+% get inputs, use defaults if input arguments not present
+%-------------------------------------------------------------------------------
+
+% The contents of Control and Info are defined in umfpack.h
+if (nargin < 1)
+    Control = [] ;
+end
+if (nargin < 2)
+    Info = [] ;
+end
+if (isempty (Control))
+    Control = umfpack ;
+end
+if (isempty (Info))
+    Info = [ 0 (-ones (1, 89)) ] ;
+end
+
+%-------------------------------------------------------------------------------
+% control settings
+%-------------------------------------------------------------------------------
+
+fprintf ('\nUMFPACK Version 4.3:  Control settings:\n\n') ;
+fprintf ('    Control (1): print level: %d\n', Control (1)) ;
+fprintf ('    Control (2): dense row parameter:    %g\n', Control (2)) ;
+fprintf ('       "dense" rows have    > max (16, (%g)*16*sqrt(n_col)) entries\n', Control (2)) ;
+fprintf ('    Control (3): dense column parameter: %g\n', Control (3)) ;
+fprintf ('       "dense" columns have > max (16, (%g)*16*sqrt(n_row)) entries\n', Control (3)) ;
+fprintf ('    Control (4): pivot tolerance: %g\n', Control (4)) ;
+fprintf ('    Control (5): max block size for dense matrix kernels: %d\n', Control (5)) ;
+prstrat ('    Control (6): strategy: %g ', Control (6)) ;
+fprintf ('    Control (7): initial allocation ratio: %g\n', Control (7)) ;
+fprintf ('    Control (8): max iterative refinement steps: %d\n', Control (8)) ;
+fprintf ('    Control (13): 2-by-2 pivot tolerance: %g\n', Control (13)) ;
+fprintf ('    Control (14): Q fixed during numeric factorization: %g ', Control (14)) ;
+if (Control (14) > 0)
+    fprintf ('(yes)\n') ;
+elseif (Control (14) < 0)
+    fprintf ('(no)\n') ;
+else
+    fprintf ('(auto)\n') ;
+end
+fprintf ('    Control (15): AMD dense row/column parameter: %g\n', Control (15)) ;
+fprintf ('       "dense" rows/columns in A+A'' have > max (16, (%g)*sqrt(n)) entries.\n', Control (15)) ;
+fprintf ('        Only used if the AMD ordering is used.\n') ;
+fprintf ('    Control (16): diagonal pivot tolerance: %g\n', Control (16)) ;
+fprintf ('        Only used if diagonal pivoting is attempted.\n') ;
+
+fprintf ('    Control (17): scaling option: %g ', Control (17)) ;
+if (Control (17) == 0)
+    fprintf ('(none)\n') ;
+elseif (Control (17) == 2)
+    fprintf ('(scale the matrix by\n') ;
+    fprintf ('        dividing each row by max. abs. value in each row)\n') ;
+else
+    fprintf ('(scale the matrix by\n') ;
+    fprintf ('        dividing each row by sum of abs. values in each row)\n') ;
+end
+
+fprintf ('    Control (18): frontal matrix allocation ratio: %g\n', Control (18)) ;
+fprintf ('    Control (19): drop tolerance: %g\n', Control (19)) ;
+fprintf ('    Control (20): AMD and COLAMD aggressive absorption: %g ', Control (20)) ;
+yes_no (Control (20)) ;
+
+% compile-time options:
+
+fprintf ('\n  The following options can only be changed at compile-time:\n') ;
+
+if (Control (9) == 1)
+    fprintf ('    Control (9): compiled to use the BLAS\n') ;
+else
+    fprintf ('    Control (9): compiled without the BLAS\n') ;
+    fprintf ('        (you will not get the best possible performance)\n') ;
+end
+
+if (Control (10) == 1)
+    fprintf ('    Control (10): compiled for MATLAB\n') ;
+elseif (Control (10) == 2)
+    fprintf ('    Control (10): compiled for MATLAB\n') ;
+    fprintf ('        Uses internal utMalloc, utFree, utRealloc, utPrintf\n') ;
+    fprintf ('        utDivideComplex, and utFdlibm_hypot routines.\n') ;
+else
+    fprintf ('    Control (10): not compiled for MATLAB\n') ;
+    fprintf ('        Uses ANSI C malloc, free, realloc, and printf\n') ;
+    fprintf ('        instead of mxMalloc, mxFree, mxRealloc, and mexPrintf.\n') ;
+    fprintf ('        Printing will be in terms of 0-based matrix indexing,\n') ;
+    fprintf ('        not 1-based as is expected in MATLAB.  Diary output may\n') ;
+    fprintf ('        not be properly recorded.\n') ;
+end
+
+if (Control (11) == 2)
+    fprintf ('    Control (11): uses POSIX times ( ) to get CPU time and wallclock time.\n') ;
+elseif (Control (11) == 1)
+    fprintf ('    Control (11): uses getrusage to get CPU time.\n') ;
+else
+    fprintf ('    Control (11): uses ANSI C clock to get CPU time.\n') ;
+    fprintf ('        The CPU time may wrap around, type "help cputime".\n') ;
+end
+
+if (Control (12) == 1)
+    fprintf ('    Control (12): compiled with debugging enabled\n') ;
+    fprintf ('        ###########################################\n') ;
+    fprintf ('        ### This will be exceedingly slow! ########\n') ;
+    fprintf ('        ###########################################\n') ;
+    if (Control (10) == 1)
+        fprintf ('        Uses mxAssert.\n') ;
+    elseif (Control (10) == 2)
+        fprintf ('        Uses utAssert.\n') ;
+    else
+        fprintf ('        Uses ANSI C assert instead of mxAssert.\n') ;
+    end
+else
+    fprintf ('    Control (12): compiled for normal operation (no debugging)\n') ;
+end
+
+%-------------------------------------------------------------------------------
+% Info:
+%-------------------------------------------------------------------------------
+
+if (nargin == 1)
+    return
+end
+
+status = Info (1) ;
+fprintf ('\nUMFPACK status:  Info (1): %d, ', status) ;
+
+if (status == 0)
+    fprintf ('OK\n') ;
+elseif (status == 1)
+    fprintf ('WARNING  matrix is singular\n') ;
+elseif (status == -1)
+    fprintf ('ERROR    out of memory\n') ;
+elseif (status == -3)
+    fprintf ('ERROR    numeric LU factorization is invalid\n') ;
+elseif (status == -4)
+    fprintf ('ERROR    symbolic LU factorization is invalid\n') ;
+elseif (status == -5)
+    fprintf ('ERROR    required argument is missing\n') ;
+elseif (status == -6)
+    fprintf ('ERROR    n <= 0\n') ;
+elseif (status <= -7 & status >= -12 | status == -14)
+    fprintf ('ERROR    matrix A is corrupted\n') ;
+elseif (status == -13)
+    fprintf ('ERROR    invalid system\n') ;
+elseif (status == -15)
+    fprintf ('ERROR    invalid permutation\n') ;
+elseif (status == -911)
+    fprintf ('ERROR    internal error!\n') ;
+    fprintf ('Please report this error to Tim Davis (davis@cise.ufl.edu)\n') ;
+else
+    fprintf ('ERROR    unrecognized error.  Info array corrupted\n') ;
+end
+
+fprintf ('    (a -1 means the entry has not been computed):\n') ;
+
+fprintf ('\n  Basic statistics:\n') ;
+fprintf ('    Info (2):  %d, # of rows of A\n', Info (2)) ;
+fprintf ('    Info (17): %d, # of columns of A\n', Info (17)) ;
+fprintf ('    Info (3): %d, nnz (A)\n', Info (3)) ;
+fprintf ('    Info (4): %d, Unit size, in bytes, for memory usage reported below\n', Info (4)) ;
+fprintf ('    Info (5): %d, size of int (in bytes)\n', Info (5)) ;
+fprintf ('    Info (6): %d, size of long (in bytes)\n', Info (6)) ;
+fprintf ('    Info (7): %d, size of pointer (in bytes)\n', Info (7)) ;
+fprintf ('    Info (8): %d, size of numerical entry (in bytes)\n', Info (8)) ;
+
+fprintf ('\n  Pivots with zero Markowitz cost removed to obtain submatrix S:\n') ;
+fprintf ('    Info (57): %d, # of pivots with one entry in pivot column\n', Info (57)) ;
+fprintf ('    Info (58): %d, # of pivots with one entry in pivot row\n', Info (58)) ;
+fprintf ('    Info (59): %d, # of rows/columns in submatrix S (if square)\n', Info (59)) ;
+fprintf ('    Info (60): %d ') ;
+if (Info (60) > 0)
+    fprintf ('submatrix S square and diagonal preserved\n') ;
+elseif (Info  (60) == 0)
+    fprintf ('submatrix S not square or diagonal not preserved\n') ;
+else
+    fprintf ('\n') ;
+end
+fprintf ('    Info (9):  %d, # of "dense" rows in S\n', Info (9)) ;
+fprintf ('    Info (10): %d, # of empty rows in S\n', Info (10)) ;
+fprintf ('    Info (11): %d, # of "dense" columns in S\n', Info (11)) ;
+fprintf ('    Info (12): %d, # of empty columns in S\n', Info (12)) ;
+fprintf ('    Info (34): %g, symmetry of pattern of S\n', Info (34)) ;
+fprintf ('    Info (35): %d, # of off-diagonal nonzeros in S+S''\n', Info (35)) ;
+fprintf ('    Info (36): %d, nnz (diag (S))\n', Info (36)) ;
+
+fprintf ('\n  2-by-2 pivoting to place large entries on diagonal:\n') ;
+fprintf ('    Info (52): %d, # of small diagonal entries of S\n', Info (52)) ;
+fprintf ('    Info (53): %d, # of unmatched small diagonal entries\n', Info (53)) ;
+fprintf ('    Info (54): %g, symmetry of P2*S\n', Info (54)) ;
+fprintf ('    Info (55): %d, # of off-diagonal entries in (P2*S)+(P2*S)''\n', Info (55)) ;
+fprintf ('    Info (56): %d, nnz (diag (P2*S))\n', Info (56)) ;
+
+fprintf ('\n  AMD results, for strict diagonal pivoting:\n') ;
+fprintf ('    Info (37): %d, est. nz in L and U\n', Info (37)) ;
+fprintf ('    Info (38): %g, est. flop count\n', Info (38)) ;
+fprintf ('    Info (39): %g, # of "dense" rows in S+S''\n', Info (39)) ;
+fprintf ('    Info (40): %g, est. max. nz in any column of L\n', Info (40)) ;
+
+fprintf ('\n  Final strategy selection, based on the analysis above:\n') ;
+prstrat ('    Info (19): %d, strategy used ', Info (19)) ;
+fprintf ('    Info (20): %d, ordering used ', Info (20)) ;
+if (Info (20) == 0)
+    fprintf ('(COLAMD on A)\n') ;
+elseif (Info (20) == 1)
+    fprintf ('(AMD on A+A'')\n') ;
+elseif (Info (20) == 2)
+    fprintf ('(provided by user)\n') ;
+else
+    fprintf ('(undefined ordering option)\n') ;
+end
+fprintf ('    Info (32): %d, Q fixed during numeric factorization: ', Info (32)) ;
+yes_no (Info (32)) ;
+fprintf ('    Info (33): %d, prefer diagonal pivoting: ', Info (33)) ;
+yes_no (Info (33)) ;
+
+fprintf ('\n  symbolic analysis time and memory usage:\n') ;
+fprintf ('    Info (13): %d, defragmentations during symbolic analysis\n', Info (13)) ;
+fprintf ('    Info (14): %d, memory used during symbolic analysis (Units)\n', Info (14)) ;
+fprintf ('    Info (15): %d, final size of symbolic factors (Units)\n', Info (15)) ;
+fprintf ('    Info (16): %.2f, symbolic analysis CPU time (seconds)\n', Info (16)) ;
+fprintf ('    Info (18): %.2f, symbolic analysis wall clock time (seconds)\n', Info (18)) ;
+
+fprintf ('\n  Estimates computed in the symbolic analysis:\n') ;
+fprintf ('    Info (21): %d, est. size of LU factors (Units)\n', Info (21)) ;
+fprintf ('    Info (22): %d, est. total peak memory usage (Units)\n', Info (22)) ;
+fprintf ('    Info (23): %d, est. factorization flop count\n', Info (23)) ;
+fprintf ('    Info (24): %d, est. nnz (L)\n', Info (24)) ;
+fprintf ('    Info (25): %d, est. nnz (U)\n', Info (25)) ;
+fprintf ('    Info (26): %d, est. initial size, variable-part of LU (Units)\n', Info (26)) ;
+fprintf ('    Info (27): %d, est. peak size, of variable-part of LU (Units)\n', Info (27)) ;
+fprintf ('    Info (28): %d, est. final size, of variable-part of LU (Units)\n', Info (28)) ;
+fprintf ('    Info (29): %d, est. max frontal matrix size (# of entries)\n', Info (29)) ;
+fprintf ('    Info (30): %d, est. max # of rows in frontal matrix\n', Info (30)) ;
+fprintf ('    Info (31): %d, est. max # of columns in frontal matrix\n', Info (31)) ;
+
+fprintf ('\n  Computed in the numeric factorization (estimates shown above):\n') ;
+fprintf ('    Info (41): %d, size of LU factors (Units)\n', Info (41)) ;
+fprintf ('    Info (42): %d, total peak memory usage (Units)\n', Info (42)) ;
+fprintf ('    Info (43): %d, factorization flop count\n', Info (43)) ;
+fprintf ('    Info (44): %d, nnz (L)\n', Info (44)) ;
+fprintf ('    Info (45): %d, nnz (U)\n', Info (45)) ;
+fprintf ('    Info (46): %d, initial size of variable-part of LU (Units)\n', Info (46)) ;
+fprintf ('    Info (47): %d, peak size of variable-part of LU (Units)\n', Info (47)) ;
+fprintf ('    Info (48): %d, final size of variable-part of LU (Units)\n', Info (48)) ;
+fprintf ('    Info (49): %d, max frontal matrix size (# of numerical entries)\n', Info (49)) ;
+fprintf ('    Info (50): %d, max # of rows in frontal matrix\n', Info (50)) ;
+fprintf ('    Info (51): %d, max # of columns in frontal matrix\n', Info (51)) ;
+
+fprintf ('\n  Computed in the numeric factorization (no estimates computed a priori):\n') ;
+fprintf ('    Info (61): %d, defragmentations during numeric factorization\n', Info (61)) ;
+fprintf ('    Info (62): %d, reallocations during numeric factorization\n', Info (62)) ;
+fprintf ('    Info (63): %d, costly reallocations during numeric factorization\n', Info (63)) ;
+fprintf ('    Info (64): %d, integer indices in compressed pattern of L and U\n', Info (64)) ;
+fprintf ('    Info (65): %d, numerical values stored in L and U\n', Info (65)) ;
+fprintf ('    Info (66): %.2f, numeric factorization CPU time (seconds)\n', Info (66)) ;
+fprintf ('    Info (76): %.2f, numeric factorization wall clock time (seconds)\n', Info (76)) ;
+if (Info (66) > 0.05 & Info (43) > 0)
+fprintf ('    mflops in numeric factorization phase: %.2f\n', 1e-6 * Info (43) / Info (66)) ;
+end
+fprintf ('    Info (67): %d, nnz (diag (U))\n', Info (67)) ;
+fprintf ('    Info (68): %g, reciprocal condition number estimate\n', Info (68)) ;
+fprintf ('    Info (69): %g, matrix was ', Info (69)) ;
+if (Info (69) == 0)
+    fprintf ('not scaled\n') ;
+elseif (Info (69) == 2)
+    fprintf ('scaled (row max)\n') ;
+else
+    fprintf ('scaled (row sum)\n') ;
+end
+fprintf ('    Info (70): %g, min. scale factor of rows of A\n', Info (70)) ;
+fprintf ('    Info (71): %g, max. scale factor of rows of A\n', Info (71)) ;
+fprintf ('    Info (72): %g, min. abs. on diagonal of U\n', Info (72)) ;
+fprintf ('    Info (73): %g, max. abs. on diagonal of U\n', Info (73)) ;
+fprintf ('    Info (74): %g, initial allocation parameter used\n', Info (74)) ;
+fprintf ('    Info (75): %g, # of forced updates due to frontal growth\n', Info (75)) ;
+fprintf ('    Info (77): %d, # of off-diaogonal pivots\n', Info (77)) ;
+fprintf ('    Info (78): %d, nnz (L), if no small entries dropped\n', Info (78)) ;
+fprintf ('    Info (79): %d, nnz (U), if no small entries dropped\n', Info (79)) ;
+fprintf ('    Info (80): %d, # of small entries dropped\n', Info (80)) ;
+
+fprintf ('\n  Computed in the solve step:\n') ;
+fprintf ('    Info (81): %d, iterative refinement steps taken\n', Info (81)) ;
+fprintf ('    Info (82): %d, iterative refinement steps attempted\n', Info (82)) ;
+fprintf ('    Info (83): %g, omega(1), sparse-backward error estimate\n', Info (83)) ;
+fprintf ('    Info (84): %g, omega(2), sparse-backward error estimate\n', Info (84)) ;
+fprintf ('    Info (85): %d, solve flop count\n', Info (85)) ;
+fprintf ('    Info (86): %.2f, solve CPU time (seconds)\n', Info (86)) ;
+fprintf ('    Info (87): %.2f, solve wall clock time (seconds)\n', Info (87)) ;
+
+fprintf ('\n    Info (88:90): unused\n\n') ;
+
+%-------------------------------------------------------------------------------
+
+function prstrat (fmt, strategy)
+fprintf (fmt, strategy) ;
+if (strategy == 1)
+    fprintf ('(unsymmetric)\n') ;
+    fprintf ('        Q = COLAMD (A), Q refined during numerical\n') ;
+    fprintf ('        factorization, and no attempt at diagonal pivoting.\n') ;
+elseif (strategy == 2)
+    fprintf ('(symmetric, with 2-by-2 pivoting)\n') ;
+    fprintf ('        P2 = row permutation to place large values on the diagonal\n') ;
+    fprintf ('        Q = AMD (P2*A+(P2*A)''), Q not refined during numeric factorization,\n') ;
+    fprintf ('        and diagonal pivoting attempted.\n') ;
+elseif (strategy == 3)
+    fprintf ('(symmetric)\n') ;
+    fprintf ('        Q = AMD (A+A''), Q not refined during numeric factorization,\n') ;
+    fprintf ('        and diagonal pivoting (P=Q'') attempted.\n') ;
+else
+    strategy = 0 ;
+    fprintf ('(auto)\n') ;
+end
+
+%-------------------------------------------------------------------------------
+
+function yes_no (s)
+if (s == 0)
+    fprintf ('(no)\n') ;
+else
+    fprintf ('(yes)\n') ;
+end
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_simple.m UMFPACK/UMFPACK/OCTAVE/umfpack_simple.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_simple.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_simple.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,61 @@
+% umfpack_simple:  a simple demo of UMFPACK
+%
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.
+% 
+% UMFPACK License:
+% 
+%     Your use or distribution of UMFPACK or any modified version of
+%     UMFPACK implies that you agree to this License.
+% 
+%     THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+%     EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+% 
+%     Permission is hereby granted to use or copy this program, provided
+%     that the Copyright, this License, and the Availability of the original
+%     version is retained on all copies.  User documentation of any code that
+%     uses UMFPACK or any modified version of UMFPACK code must cite the
+%     Copyright, this License, the Availability note, and "Used by permission."
+%     Permission to modify the code and to distribute modified code is granted,
+%     provided the Copyright, this License, and the Availability note are
+%     retained, and a notice that the code was modified is included.  This
+%     software was developed with support from the National Science Foundation,
+%     and is provided to you free of charge.
+% 
+% Availability: http://www.cise.ufl.edu/research/sparse/umfpack
+%
+% See also: umfpack, umfpack_details
+
+help umfpack_simple
+i = input ('Hit enter to agree to the above License: ', 's') ;
+if (~isempty (i))
+    error ('terminating') ;
+end
+
+format short
+
+A = [
+ 2  3  0  0  0
+ 3  0  4  0  6
+ 0 -1 -3  2  0
+ 0  0  1  0  0
+ 0  4  2  0  1
+]
+
+A = sparse (A) ;
+
+b = [8 45 -3 3 19]'
+
+fprintf ('Solution to Ax=b via UMFPACK:\n') ;
+fprintf ('x1 = umfpack (A, ''\\'', b)\n') ;
+
+x1 = umfpack (A, '\\', b)
+
+fprintf ('Solution to Ax=b via OCTAVE:\n') ;
+fprintf ('x2 = A\\b\n') ;
+
+x2 = A\b
+
+fprintf ('norm (x1-x2) should be small: %g\n', norm (x1-x2)) ;
+
+fprintf ('Type ''umfpack_demo'' for a full demo of UMFPACK\n') ;
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_simple.m.out UMFPACK/UMFPACK/OCTAVE/umfpack_simple.m.out
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_simple.m.out	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_simple.m.out	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,79 @@
+octave:4> umfpack_simple
+umfpack_simple is the file: /home/dbateman/octave/devel/octave-sparse/UMFPACKv4.3/UMFPACK/OCTAVE/umfpack_simple.m
+
+umfpack_simple:  a simple demo of UMFPACK
+
+UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+Davis.  All Rights Reserved.
+
+UMFPACK License:
+
+    Your use or distribution of UMFPACK or any modified version of
+    UMFPACK implies that you agree to this License.
+
+    THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+    EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+
+    Permission is hereby granted to use or copy this program, provided
+    that the Copyright, this License, and the Availability of the original
+    version is retained on all copies.  User documentation of any code that
+    uses UMFPACK or any modified version of UMFPACK code must cite the
+    Copyright, this License, the Availability note, and "Used by permission."
+    Permission to modify the code and to distribute modified code is granted,
+    provided the Copyright, this License, and the Availability note are
+    retained, and a notice that the code was modified is included.  This
+    software was developed with support from the National Science Foundation,
+    and is provided to you free of charge.
+
+Availability: http://www.cise.ufl.edu/research/sparse/umfpack
+
+See also: umfpack, umfpack_details
+
+
+Additional help for built-in functions, operators, and variables
+is available in the on-line version of the manual.  Use the command
+`help -i <topic>' to search the manual index.
+
+Help and information about Octave is also available on the WWW
+at http://www.octave.org and via the help@octave.org
+mailing list.
+Hit enter to agree to the above License: 
+A =
+
+   2   3   0   0   0
+   3   0   4   0   6
+   0  -1  -3   2   0
+   0   0   1   0   0
+   0   4   2   0   1
+
+b =
+
+    8
+   45
+   -3
+    3
+   19
+
+Solution to Ax=b via UMFPACK:
+x1 = umfpack (A, '\', b)
+x1 =
+
+  1.00000
+  2.00000
+  3.00000
+  4.00000
+  5.00000
+
+Solution to Ax=b via OCTAVE:
+x2 = A\b
+x2 =
+
+  1.00000
+  2.00000
+  3.00000
+  4.00000
+  5.00000
+
+norm (x1-x2) should be small: 0
+Type 'umfpack_demo' for a full demo of UMFPACK
+octave:5> diary off
diff -uNr UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_solve.m UMFPACK/UMFPACK/OCTAVE/umfpack_solve.m
--- UMFPACKv4.4.orig/UMFPACK/OCTAVE/umfpack_solve.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/UMFPACK/OCTAVE/umfpack_solve.m	2004-12-30 01:58:46.000000000 +0100
@@ -0,0 +1,97 @@
+function x = umfpack_solve (arg1, op, arg2, Control)
+% UMFPACK_SOLVE
+%
+% x = umfpack_solve (A, '\', b, Control)
+% x = umfpack_solve (b, '/', A, Control)
+%
+% Computes x = A\b, or b/A, where A is square.  Uses UMFPACK if A is sparse.
+% The Control argument is optional.
+%
+% See also umfpack, umfpack_make, umfpack_details, umfpack_report,
+% and umfpack_simple.
+
+% UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A.
+% Davis.  All Rights Reserved.  Type umfpack_details for License.
+
+%-------------------------------------------------------------------------------
+% check inputs and get default control parameters
+%-------------------------------------------------------------------------------
+
+if (op == '\\')
+    A = arg1 ;
+    b = arg2 ;
+elseif (op == '/')
+    A = arg2 ;
+    b = arg1 ;
+else
+    help umfack_solve
+    error ('umfpack_solve:  unrecognized operator') ;
+end
+
+[m n] = size (A) ;
+if (m ~= n)
+    help umfpack_solve
+    error ('umfpack_solve:  A must be square') ;
+end
+
+[m1 n1] = size (b) ;
+if ((op == '\\' & n ~= m1) | (op == '/' & n1 ~= m))
+    help umfpack_solve
+    error ('umfpack_solve:  b has the wrong dimensions') ;
+end
+
+if (nargin < 4)
+    Control = umfpack ;
+end
+
+%-------------------------------------------------------------------------------
+% solve the system
+%-------------------------------------------------------------------------------
+
+if (op == '\\')
+
+    if (~issparse (A))
+
+	% A is not sparse, so just use MATLAB
+	x = A\b ;
+
+    elseif (n1 == 1 & ~issparse (b))
+
+	% the UMFPACK '\' requires b to be a dense column vector
+	x = umfpack (A, '\\', b, Control) ;
+
+    else
+
+	% factorize with UMFPACK and do the forward/back solves in MATLAB 
+	[L, U, P, Q, R] = umfpack (A, Control) ;
+	keyboard
+	x = Q * (U \ (L \ (P * (R \ b)))) ;
+
+    end
+
+else
+
+    if (~issparse (A))
+
+	% A is not sparse, so just use MATLAB
+	x = b/A ;
+
+    elseif (m1 == 1 & ~issparse (b))
+
+	% the UMFPACK '/' requires b to be a dense column vector
+	x = umfpack (b, '/', A, Control) ;
+
+    else
+
+	% factorize with UMFPACK and do the forward/back solves in MATLAB
+	% this mimics the behavior of x = b/A, except for the row scaling
+	[L, U, P, Q, R] = umfpack (A.', Control) ;
+	x = (Q * (U \ (L \ (P * (R \ (b.')))))).' ;
+
+	% an alternative method:
+	% [L, U, P, Q, r] = umfpack (A, Control) ;
+	% x = (R \ (P' * (L.' \ (U.' \ (Q' * b.'))))).' ;
+
+    end
+
+end
diff -uNr UMFPACKv4.4.orig/AMD/OCTAVE/amd.cc UMFPACK/AMD/OCTAVE/amd.cc
--- UMFPACKv4.4.orig/AMD/OCTAVE/amd.cc	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/AMD/OCTAVE/amd.cc	2005-02-01 21:51:23.944874478 +0100
@@ -0,0 +1,299 @@
+/*
+
+Copyright (C) 2004 David Bateman
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+In addition to the terms of the GPL, you are permitted to link
+this program with any Open Source program, as defined by the
+Open Source Initiative (www.opensource.org)
+
+*/
+
+/*
+
+This is the Octave interface to the UMFPACK AMD code, which bore the following
+copyright
+
+ AMD Version 1.1 (Jan. 21, 2004), Copyright (c) 2004 by Timothy A. Davis,
+ Patrick R. Amestoy, and Iain S. Duff.  See ../README for License.
+ email: davis@cise.ufl.edu    CISE Department, Univ. of Florida.
+ web: http://www.cise.ufl.edu/research/sparse/amd
+ --------------------------------------------------------------------------
+
+    Acknowledgements: This work was supported by the National Science
+       Foundation, under grants ASC-9111263, DMS-9223088, and CCR-0203270.
+
+*/
+
+#include <cstdlib>
+#include <string>
+
+#include <octave/config.h>
+#include <octave/ov.h>
+#include <octave/defun-dld.h>
+#include <octave/pager.h>
+#include <octave/ov-re-mat.h>
+
+#include "ov-re-sparse.h"
+#include "ov-cx-sparse.h"
+
+// External AMD functions in C
+extern "C" {
+#include "amd.h"
+}
+
+DEFUN_DLD (amd, args, nargout,
+    "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{p} =} amd (@var{s})\n\
+@deftypefnx {Loadable Function} {@var{Control} =} amd ()\n\
+@deftypefnx {Loadable Function} {[@var{p}, @var{info}] =} amd (@var{s})\n\
+\n\
+AMD Approximate minimum degree permutation. Returns the approximate\n\
+minimum degree permutation vector for the sparse matrix\n\
+@code{@var{c} = @var{S} + @var{S}'}. The Cholesky factorization of\n\
+@code{@var{c} (@var{p}, @var{p})}, or @code{@var{s} (@var{p}, @var{p})},\n\
+tends to be sparser than that of @var{c} or @var{s}.\n\
+@var{s} must be square. If @var{s} is full, @code{amd (@var{S})} is\n\
+equivalent to  @code{amd (sparse (@var{s}))}.\n\
+\n\
+@table @asis\n\
+@item @var{Control} (1)\n\
+If S is n-by-n, then rows/columns with more than\n\
+@code{@dfn{max} (16, (@var{Control} (1)) * @dfn{sqrt} (@var{n}))} entries\n\
+in @code{@var{s} + @var{S}'} are considered @emph{dense}, and ignored during\n\
+ordering.  They are placed last in the output permutation.  The default is\n\
+10.0 if @var{Control} is not present.\n\
+@item @var{Control} (2)\n\
+If nonzero, then aggressive absorption is performed. This is the default if\n\
+@var{Control} is not present.\n\
+@item @var{Control} (3)\n\
+If nonzero, print statistics about the ordering.\n\
+@end table\n\
+\n\
+@table @asis\n\
+@item @var{Info} (1)\n\
+status (0: ok, -1: out of memory, -2: matrix invalid)\n\
+@item @var{Info} (2)\n\
+@code{@var{n} = size (@var{a}, 1)}\n\
+@item @var{Info} (3)\n\
+@code{nnz (A)}\n\
+@item @var{Info} (4)\n\
+The symmetry of the matrix @var{s} (0.0 means purely unsymmetric, 1.0 means\n\
+purely symmetric).  Computed as: @code{@var{b} = tril (@var{s}, -1) +\n\
+triu (@var{s}, 1); @var{symmetry} = nnz (@var{b} & @var{b}')\n\
+/ nnz (@var{b});}\n\
+@item @var{Info} (5)\n\
+@code{nnz (diag (@var{s}))}\n\
+@item @var{Info} (6)\n\
+@dfn{nnz} in @code{@var{s} + @var{s}'}, excluding the diagonal\n\
+(= @code{nnz (@var{b} + @var{b}')})\n\
+@item @var{Info} (7)\n\
+Number of @emph{dense} rows/columns in @code{@var{s} + @var{s}'}\n\
+@item @var{Info} (8)\n\
+The amount of memory used by AMD, in bytes\n\
+@item @var{Info} (9)\n\
+The number of memory compactions performed by AMD\n\
+@end table\n\
+\n\
+The following statistics are slight upper bounds because of the\n\
+approximate degree in AMD. The bounds are looser if @emph{dense}\n\
+rows/columns are ignored during ordering @code{(@var{Info} (7) > 0)}.\n\
+The statistics are for a subsequent factorization of the matrix\n\
+@code{@var{c} (@var{p},@var{p})}.  The LU factorization statistics assume\n \
+no pivoting.\n\
+\n\
+@table @asis\n\
+@item @var{Info} (10)\n\
+The number of nonzeros in L, excluding the diagonal\n\
+@item @var{Info} (11)\n\
+The number of divide operations for LL', LDL', or LU\n\
+@item @var{Info (12)}\n\
+The number of multiply-subtract pairs for LL' or LDL'\n\
+@item @var{Info} (13)\n\
+The number of multiply-subtract pairs for LU\n\
+@item @var{Info} (14)\n\
+The max number of nonzeros in any column of L (incl. diagonal)\n\
+@item @var{Info} (15:20)\n\
+unused, reserved for future use\n\
+@end table\n\
+\n\
+An assembly tree post-ordering is performed, which is typically the same\n\
+as an elimination tree post-ordering.  It is not always identical because\n\
+of the approximate degree update used, and because @emph{dense} rows/columns\n\
+do not take part in the post-order.  It well-suited for a subsequent\n\
+@dfn{chol}, however.  If you require a precise elimination tree\n\
+post-ordering, then do:\n\
+\n\
+@group\n\
+   @var{p} = @dfn{amd} (@var{s});\n\
+   % skip this if S already symmetric\n\
+   @var{c} = spones (@var{s}) + spones (@var{s}');\n\
+   [@var{ignore}, @var{q}] = sparsfun ('symetree', @var{c} (@var{p}, @var{p}));\n\
+   @var{p} = @var{p} (@var{q});\n\
+@end group\n\
+\n\
+AMD Version 1.1 (Jan. 21, 2004), Copyright @copyright{} 2004 by\n\
+Timothy A. Davis, Patrick R. Amestoy, and Iain S. Duff.\n\
+\n\
+email: davis@@cise.ufl.edu  (CISE Department, Univ. of Florida).\n\
+\n\
+web: http://www.cise.ufl.edu/research/sparse/amd\n\
+\n\
+Acknowledgements: This work was supported by the National Science\n\
+Foundation, under grants ASC-9111263, DMS-9223088, and CCR-0203270.\n\
+@end deftypefn")
+{
+  int nargin = args.length (); 
+  octave_value_list retval; 
+  int spumoni = 0;
+
+  if (nargin > 2 || nargout > 2)
+    usage ("p = amd (A) or [p, Info] = amd (A, Control)");
+  else if (nargin == 0)
+    {
+      // Get the default control parameter, and return
+      NDArray control (dim_vector (AMD_CONTROL, 1));
+      double *control_ptr = control.fortran_vec ();
+      amd_defaults (control_ptr);
+      if (nargout == 0)
+	amd_control (control_ptr);
+      else
+	retval(0) = control;
+    }
+  else
+    {
+      NDArray control (dim_vector (AMD_CONTROL, 1));
+      double *control_ptr = control.fortran_vec ();
+      amd_defaults (control_ptr);
+
+      if (nargin > 1)
+	{
+	  NDArray control_in = args(1).array_value();
+
+	  if (error_state)
+	    {	  
+	      error ("amd: could not read control vector");
+	      return retval;
+	    }
+
+	  dim_vector dv = control_in.dims ();
+	  if (dv.length() > 2 || (dv(0) != 1 && dv(1) != 1))
+	    {
+	      error ("amd: control vector isn't a vector");
+	      return retval;
+	    }
+	  
+	  int nc = dv.numel ();
+	  control (AMD_DENSE) = (nc > 0 ? control_in (AMD_DENSE) :
+				 AMD_DEFAULT_DENSE);
+	  control (AMD_AGGRESSIVE) = (nc > 1 ? control_in (AMD_AGGRESSIVE) :
+				      AMD_DEFAULT_AGGRESSIVE);
+	  spumoni = (nc > 2 ? (control_in (2) != 0) : 0);
+	}
+
+      if (spumoni > 0)
+	amd_control (control_ptr);
+
+      int *Ap, *Ai;
+      int n, m, nz;
+
+      // These are here only so that the C++ destructors don't prematurally
+      // remove the underlying data we are interested in
+      SparseMatrix sm;
+      SparseComplexMatrix scm;
+      Matrix mm;
+      ComplexMatrix cm;
+
+      if (args(0).class_name () != "sparse" && spumoni > 0)
+	octave_stdout << "    input matrix A is full (sparse copy"
+		      << " of A will be created)" << std::endl;
+
+      if (args(0).is_complex_type ())
+	{
+	  scm = args(0).sparse_complex_matrix_value ();
+	  Ai = scm.ridx ();
+	  Ap = scm.cidx ();
+	  m = scm.rows ();
+	  n = scm.cols ();
+	  nz = scm.nnz ();
+	}
+      else
+	{
+	  sm = args(0).sparse_matrix_value ();
+	  Ai = sm.ridx ();
+	  Ap = sm.cidx ();
+	  m = sm.rows ();
+	  n = sm.cols ();
+	  nz = sm.nnz ();
+	}
+
+      if (spumoni > 0)
+	octave_stdout << "    input matrix A is " << m << "-by-" << n 
+		      << std::endl;
+
+      if (m != n)
+	{
+	  error ("amd: A must be square");
+	  return retval;
+	}
+
+      if (spumoni > 0)
+	octave_stdout << "    input matrix A has " << nz << 
+	  " nonzero entries" << std::endl;
+
+      // allocate workspace for output permutation 
+      Array<int> P(n+1);
+      int *P_ptr = P.fortran_vec ();
+      NDArray info (dim_vector (AMD_INFO, 1));
+      double *info_ptr = info.fortran_vec ();
+      int result;
+
+      // order the matrix
+      result = amd_order (n, Ap, Ai, P_ptr, control_ptr, info_ptr);
+
+      // print results (including return value)
+      if (spumoni > 0)
+	amd_info (info_ptr);
+
+      // check error conditions
+      if (result == AMD_OUT_OF_MEMORY)
+	error ("amd: out of memory");
+      else if (result == AMD_INVALID)
+	error ("amd: input matrix A is corrupted");
+      else
+	{
+	  // copy the outputs to Octave
+
+	  // output permutation, P
+	  NDArray perm (dim_vector (1, n));
+	  for (int i = 0; i < n; i++)
+	    perm (i) = double (P(i) + 1);  // 1-based indexing for Octave
+
+	  retval (0) = perm;
+
+	  // Info
+	  if (nargout > 1)
+	    retval (1) = info;
+	}
+    }
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff -uNr UMFPACKv4.4.orig/AMD/OCTAVE/amd_demo.m UMFPACK/AMD/OCTAVE/amd_demo.m
--- UMFPACKv4.4.orig/AMD/OCTAVE/amd_demo.m	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/AMD/OCTAVE/amd_demo.m	2004-12-30 01:58:45.000000000 +0100
@@ -0,0 +1,61 @@
+function amd_demo
+% AMD DEMO
+%
+% A demo of AMD for OCTAVE.
+%
+% --------------------------------------------------------------------------
+% AMD Version 1.1 (Jan. 21, 2004), Copyright (c) 2004 by Timothy A. Davis,
+% Patrick R. Amestoy, and Iain S. Duff.  See ../README for License.
+% email: davis@cise.ufl.edu    CISE Department, Univ. of Florida.
+% web: http://www.cise.ufl.edu/research/sparse/amd
+% --------------------------------------------------------------------------
+%
+% See also: amd
+
+% Get the Harwell/Boeing can_24 matrix.  This is an example matrix from the
+% MATLAB-accessible UF sparse matrix collection, and can be loaded into
+% MATLAB with the statment "Problem = UFget ('HB/can_24')", after obtaining
+% the UFget function and its supporting routines at
+% http://www.cise.ufl.edu/sparse/mat .
+
+load can_24.mat
+A = Problem.A ;
+n = size (A,1) ;
+
+figure (1)
+clf
+hold off
+subplot (2,1,1) ;
+% remove the "_" from the name before printing it in the plot title
+title (sprintf ('%s', strrep (Problem.name, '_', '-'))) ;
+fprintf ('Matrix name:  %s\n', Problem.name) ;
+fprintf ('Matrix title: %s\n', Problem.title) ;
+spy (A)
+
+% print the details during AMD ordering and SYMBFACT
+control = amd ();
+control (3) = 1;
+
+% order the matrix.  Note that the Info argument is optional.
+fprintf ('\nIf the next step fails, then you have\n') ;
+fprintf ('not yet compiled the AMD mexFunction.\n') ;
+[p, Info] = amd (A, control) ;
+
+% order again, but this time print some statistics
+[p, Info] = amd (A, [10 1 1]) ;
+
+fprintf ('Permutation vector:\n') ;
+fprintf (' %2d', p) ;
+fprintf ('\n\n') ;
+
+subplot (2,1,2) ;
+title ('Permuted matrix') ;
+spy (A (p,p))
+
+% approximations from amd:
+lnz2 = n + Info (10) ;
+fl2 = n + Info (11) + 2 * Info (12) ;
+fprintf ('\nResults from AMD''s approximate analysis:\n') ;
+fprintf ('number of nonzeros in L (including diagonal):      %d\n', lnz2) ;
+fprintf ('floating point operation count for chol (A (p,p)): %d\n\n', fl2) ;
+
diff -uNr UMFPACKv4.4.orig/AMD/OCTAVE/amd_demo.m.out UMFPACK/AMD/OCTAVE/amd_demo.m.out
--- UMFPACKv4.4.orig/AMD/OCTAVE/amd_demo.m.out	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/AMD/OCTAVE/amd_demo.m.out	2004-12-30 01:58:45.000000000 +0100
@@ -0,1 +1,21 @@
+octave:3> amd_demo
+ans = 1
+Matrix name:  HB/can_24
+Matrix title: 1SYMMETRIC PATTERN FROM CANNES,LUCIEN MARRO,JUNE 1981.
+
+If the next step fails, then you have
+not yet compiled the AMD mexFunction.
+    input matrix A is 24-by-24
+    input matrix A has 160 nonzero entries
+    input matrix A is 24-by-24
+    input matrix A has 160 nonzero entries
+Permutation vector:
+ 23 21 11 24 13  6 17  9 15  5 16  8  2 10 14 18  1  3  4  7 12 19 22 20
+
+
+Results from AMD's approximate analysis:
+number of nonzeros in L (including diagonal):      121
+floating point operation count for chol (A (p,p)): 671
+
+octave:4> quit
--- UMFPACKv4.4.orig/AMD/OCTAVE/GNUmakefile	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/AMD/OCTAVE/GNUmakefile	2004-12-30 01:58:45.000000000 +0100
@@ -0,0 +1,33 @@
+#------------------------------------------------------------------------------
+# GNUmakefile for the AMD MATLAB mexFunction
+#------------------------------------------------------------------------------
+
+all: amd
+
+include ../Make/Make.include
+
+MKOCT = mkoctfile -I../Include
+
+OCT_SPARSE_INC = -I../../../
+
+AMD = amd_aat amd_1 amd_2 amd_dump amd_postorder amd_post_tree amd_defaults \
+	amd_order amd_control amd_info amd_valid
+
+INC = ../Include/amd.h ../Source/amd_internal.h 
+
+OCTAMD = $(addsuffix .o, $(subst amd_,amd_o_,$(AMD)))
+
+amd_o_%.o: ../Source/amd_%.c $(INC)
+	$(MKOCT) -DDINT -c $< -o $@
+	- $(MV) ../Source/amd_$*.o
+
+# Note temporary addition of octave sparse path
+amd: amd.cc $(OCTAMD) $(INC)
+	$(MKOCT) amd.cc $(OCTAMD) $(OCT_SPARSE_INC) -o amd.oct
+
+#------------------------------------------------------------------------------
+# Remove all but the files in the original distribution
+#------------------------------------------------------------------------------
+
+purge: clean
+	- $(RM) amd.oct
diff -uNr UMFPACKv4.4.orig/AMD/OCTAVE/Makefile UMFPACK/AMD/OCTAVE/Makefile
--- UMFPACKv4.4.orig/AMD/OCTAVE/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ UMFPACK/AMD/OCTAVE/Makefile	2004-12-30 01:58:45.000000000 +0100
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------
+# compile the AMD mexFunction for MATLAB (original make only)
+#------------------------------------------------------------------------------
+
+# This is a very ugly Makefile, and is only provided for those who do not
+# have GNU make.  Note that it is not used if you have GNU make.  It ignores
+# dependency checking and just compiles everything.  It was created
+# automatically, via make -n using the GNUmakefile.  That way, I don't have
+# maintain two Makefiles.
+
+all: amd
+
+include ../Make/Make.include
+
+MKOCT = mkoctfile -I../Include
+
+OCT_SPARSE_INC = ../../../
+
+amd:
+	$(MKOCT) -DDINT -o amd_o_aat.o -c ../Source/amd_aat.c
+	$(MKOCT) -DDINT -o amd_o_1.o -c ../Source/amd_1.c
+	$(MKOCT) -DDINT -o amd_o_2.o -c ../Source/amd_2.c
+	$(MKOCT) -DDINT -o amd_o_dump.o -c ../Source/amd_dump.c
+	$(MKOCT) -DDINT -o amd_o_postorder.o -c ../Source/amd_postorder.c
+	$(MKOCT) -DDINT -o amd_o_post_tree.o -c ../Source/amd_post_tree.c
+	$(MKOCT) -DDINT -o amd_o_defaults.o -c ../Source/amd_defaults.c
+	$(MKOCT) -DDINT -o amd_o_order.o -c ../Source/amd_order.c
+	$(MKOCT) -DDINT -o amd_o_control.o -c ../Source/amd_control.c
+	$(MKOCT) -DDINT -o amd_o_info.o -c ../Source/amd_info.c
+	$(MKOCT) -DDINT -o amd_o_valid.o -c ../Source/amd_valid.c
+	$(MKOCT) -output amd.oct amd_mex.c amd_o_aat.o \
+	    amd_o_1.o amd_o_2.o amd_o_dump.o amd_o_postorder.o \
+	    amd_o_post_tree.o amd_o_defaults.o amd_o_order.o amd_o_control.o \
+	    amd_o_info.o amd_o_valid.o $(OCT_SPARSE_INC) -o amd.oct
+
+#------------------------------------------------------------------------------
+# Remove all but the files in the original distribution
+#------------------------------------------------------------------------------
+
+purge: clean
+	- $(RM) amd.oct
--- UMFPACKv4.4.orig/UMFPACK/Source/umf_solve.c	2005-01-17 17:21:29.000000000 +0100
+++ UMFPACK/UMFPACK/Source/umf_solve.c	2005-02-02 00:01:22.904346651 +0100
@@ -79,7 +79,8 @@
     double *Z2, *Y, *B2, *Rs ;
     Int *Rperm, *Cperm, i, n, p, step, j, nz, status, p2, do_scale ;
 #ifdef COMPLEX
-    Int split ;
+    Int AXsplit ;
+    Int Bsplit ;
 #endif
 #ifndef NRECIPROCAL
     Int do_recip = Numeric->do_recip ;
@@ -141,7 +142,7 @@
 	    return (UMFPACK_ERROR_argument_missing) ;
 	}
 	/* A, B, and X in split format if Az, Bz, and Xz present */
-	split = SPLIT (Az) && SPLIT (Bz) && SPLIT (Xz) ;
+	AXsplit = SPLIT (Az) || SPLIT(Xz);
 	Z = (Entry *) (SolveWork + 4*n) ;	/* Entry Z [0..n-1] */
 	S = (Entry *) (SolveWork + 6*n) ;	/* Entry S [0..n-1] */
 	Y = (double *) (SolveWork + 8*n) ;	/* double Y [0..n-1] */
@@ -150,10 +151,12 @@
     }
     else
     {
-	/* A is ignored, only  look at X and B for split/packed cases */
-	split = SPLIT (Bz) && SPLIT (Xz) ;
+      /* A is ignored, only  look at X for split/packed cases */
+      AXsplit = SPLIT(Xz);
     }
-    if (split)
+    Bsplit = SPLIT (Bz);
+
+    if (AXsplit)
     {
 	X = (Entry *) (SolveWork + 2*n) ;	/* Entry X [0..n-1] */
     }
@@ -209,7 +212,7 @@
 	    for (p = 0 ; p < p2 ; p++)
 	    {
 		/* Y [Ai [p]] += ABS (Ax [p]) ; */
-	        ASSIGN (aij, Ax, Az, p, split) ;
+	        ASSIGN (aij, Ax, Az, p, AXsplit) ;
 		ABS (d, aij) ;
 		Y [Ai [p]] += d ;
 	    }
@@ -219,7 +222,7 @@
 	    for (i = 0 ; i < n ; i++)
 	    {
 		/* B2 [i] = ABS (B [i]) ; */
-		ASSIGN (bi, Bx, Bz, i, split) ;
+		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
 		ABS (B2 [i], bi) ;
 	    }
 
@@ -276,7 +279,7 @@
 			/* multiply by the scale factors */
 			for (i = 0 ; i < n ; i++)
 			{
-			    ASSIGN (X [i], Bx, Bz, i, split) ;
+			    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 			    SCALE (X [i], Rs [i]) ;
 			}
 		    }
@@ -286,7 +289,7 @@
 			/* divide by the scale factors */
 			for (i = 0 ; i < n ; i++)
 			{
-			    ASSIGN (X [i], Bx, Bz, i, split) ;
+			    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 			    SCALE_DIV (X [i], Rs [i]) ;
 			}
 		    }
@@ -302,7 +305,7 @@
 		    for (i = 0 ; i < n ; i++)
 		    {
 			/* W [i] = B [Rperm [i]] ; */
-			ASSIGN (W [i], Bx, Bz, Rperm [i], split) ;
+			ASSIGN (W [i], Bx, Bz, Rperm [i], Bsplit) ;
 		    }
 		}
 	    }
@@ -311,7 +314,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* Z [i] = B [i] ; */
-		    ASSIGN (Z [i], Bx, Bz, i, split) ;
+		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
 		}
 		flops += MULTSUB_FLOPS * nz ;
 		for (i = 0 ; i < n ; i++)
@@ -321,7 +324,7 @@
 		    for (p = Ap [i] ; p < p2 ; p++)
 		    {
 			/* Z [Ai [p]] -= Ax [p] * xi ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			MULT_SUB (Z [Ai [p]], aij, xi) ;
 		    }
 		}
@@ -390,7 +393,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* W [i] = B [i] ; */
-		    ASSIGN (W [i], Bx, Bz, i, split) ;
+		    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
 		    Z2 [i] = 0. ;
 		}
 		flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ;
@@ -403,7 +406,7 @@
 			i = Ai [p] ;
 
 			/* axx = Ax [p] * xj ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			MULT (axx, aij, xj) ;
 
 			/* W [i] -= axx ; */
@@ -493,7 +496,7 @@
 			    /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */
 			    /* note that abs (aij) is the same as
 			     * abs (conj (aij)) */
-			    ASSIGN (aij, Ax, Az, p, split) ;
+			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			    ABS (d, aij) ;
 			    yi += (d * Rs [Ai [p]]) ;
 			}
@@ -513,7 +516,7 @@
 			    /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */
 			    /* note that abs (aij) is the same as
 			     * abs (conj (aij)) */
-			    ASSIGN (aij, Ax, Az, p, split) ;
+			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			    ABS (d, aij) ;
 			    yi += (d / Rs [Ai [p]]) ;
 			}
@@ -534,7 +537,7 @@
 			/* yi += ABS (Ax [p]) ; */
 			/* note that abs (aij) is the same as
 			 * abs (conj (aij)) */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			ABS (d, aij) ;
 			yi += d ;
 		    }
@@ -546,7 +549,7 @@
 	    for (i = 0 ; i < n ; i++)
 	    {
 		/* B2 [i] = ABS (B [i]) ; */
-		ASSIGN (bi, Bx, Bz, i, split) ;
+		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
 		ABS (B2 [i], bi) ;
 	    }
 
@@ -568,7 +571,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* W [i] = B [Cperm [i]] ; */
-		    ASSIGN (W [i], Bx, Bz, Cperm [i], split) ;
+		    ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ;
 		}
 	    }
 	    else
@@ -577,7 +580,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* Z [i] = B [i] ; */
-		    ASSIGN (Z [i], Bx, Bz, i, split) ;
+		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
 		}
 		flops += MULTSUB_FLOPS * nz ;
 		for (i = 0 ; i < n ; i++)
@@ -587,7 +590,7 @@
 		    for (p = Ap [i] ; p < p2 ; p++)
 		    {
 			/* zi -= conjugate (Ax [p]) * X [Ai [p]] ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, Bsplit) ;
 			MULT_SUB_CONJ (zi, X [Ai [p]], aij) ;
 		    }
 		    Z [i] = zi ;
@@ -696,13 +699,13 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* wi = B [i] ; */
-		    ASSIGN (wi, Bx, Bz, i, split) ;
+		    ASSIGN (wi, Bx, Bz, i, Bsplit) ;
 		    z2i = 0. ;
 		    p2 = Ap [i+1] ;
 		    for (p = Ap [i] ; p < p2 ; p++)
 		    {
 			/* axx = conjugate (Ax [p]) * X [Ai [p]] ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			MULT_CONJ (axx, X [Ai [p]], aij) ;
 
 			/* wi -= axx ; */
@@ -766,7 +769,7 @@
 			    /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */
 			    /* note that A.' is the array transpose,
 			     * so no conjugate */
-			    ASSIGN (aij, Ax, Az, p, split) ;
+			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			    ABS (d, aij) ;
 			    yi += (d * Rs [Ai [p]]) ;
 			}
@@ -786,7 +789,7 @@
 			    /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */
 			    /* note that A.' is the array transpose,
 			     * so no conjugate */
-			    ASSIGN (aij, Ax, Az, p, split) ;
+			    ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			    ABS (d, aij) ;
 			    yi += (d / Rs [Ai [p]]) ;
 			}
@@ -807,7 +810,7 @@
 			/* yi += ABS (Ax [p]) */
 			/* note that A.' is the array transpose,
 			 * so no conjugate */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			ABS (d, aij) ;
 			yi += d ;
 		    }
@@ -819,7 +822,7 @@
 	    for (i = 0 ; i < n ; i++)
 	    {
 		/* B2 [i] = ABS (B [i]) ; */
-		ASSIGN (bi, Bx, Bz, i, split) ;
+		ASSIGN (bi, Bx, Bz, i, Bsplit) ;
 		ABS (B2 [i], bi) ;
 	    }
 
@@ -841,7 +844,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* W [i] = B [Cperm [i]] ; */
-		    ASSIGN (W [i], Bx, Bz, Cperm [i], split) ;
+		    ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ;
 		}
 	    }
 	    else
@@ -850,7 +853,7 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* Z [i] = B [i] ; */
-		    ASSIGN (Z [i], Bx, Bz, i, split) ;
+		    ASSIGN (Z [i], Bx, Bz, i, Bsplit) ;
 		}
 		flops += MULTSUB_FLOPS * nz ;
 		for (i = 0 ; i < n ; i++)
@@ -860,7 +863,7 @@
 		    for (p = Ap [i] ; p < p2 ; p++)
 		    {
 			/* zi -= Ax [p] * X [Ai [p]] ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			MULT_SUB (zi, aij, X [Ai [p]]) ;
 		    }
 		    Z [i] = zi ;
@@ -969,13 +972,13 @@
 		for (i = 0 ; i < n ; i++)
 		{
 		    /* wi = B [i] ; */
-		    ASSIGN (wi, Bx, Bz, i, split) ;
+		    ASSIGN (wi, Bx, Bz, i, Bsplit) ;
 		    z2i = 0. ;
 		    p2 = Ap [i+1] ;
 		    for (p = Ap [i] ; p < p2 ; p++)
 		    {
 			/* axx = Ax [p] * X [Ai [p]] ; */
-			ASSIGN (aij, Ax, Az, p, split) ;
+			ASSIGN (aij, Ax, Az, p, AXsplit) ;
 			MULT (axx, aij, X [Ai [p]]) ;
 
 			/* wi -= axx ; */
@@ -1011,7 +1014,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [Rperm [i]] ; */
-	    ASSIGN (X [i], Bx, Bz, Rperm [i], split) ;
+	    ASSIGN (X [i], Bx, Bz, Rperm [i], Bsplit) ;
 	}
 	flops = UMF_lsolve (Numeric, X, Pattern) ;
 	status = UMFPACK_OK ;
@@ -1027,7 +1030,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	    ASSIGN (X [i], Bx, Bz, i, split) ;
+	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_lsolve (Numeric, X, Pattern) ;
 	status = UMFPACK_OK ;
@@ -1043,7 +1046,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* W [i] = B [i] ; */
-	    ASSIGN (W [i], Bx, Bz, i, split) ;
+	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_lhsolve (Numeric, W, Pattern) ;
 	for (i = 0 ; i < n ; i++)
@@ -1063,7 +1066,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* W [i] = B [i] ; */
-	    ASSIGN (W [i], Bx, Bz, i, split) ;
+	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_ltsolve (Numeric, W, Pattern) ;
 	for (i = 0 ; i < n ; i++)
@@ -1083,7 +1086,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	    ASSIGN (X [i], Bx, Bz, i, split) ;
+	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_lhsolve (Numeric, X, Pattern) ;
 	status = UMFPACK_OK ;
@@ -1099,7 +1102,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	    ASSIGN (X [i], Bx, Bz, i, split) ;
+	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_ltsolve (Numeric, X, Pattern) ;
 	status = UMFPACK_OK ;
@@ -1115,7 +1118,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* W [i] = B [i] ; */
-	    ASSIGN (W [i], Bx, Bz, i, split) ;
+	    ASSIGN (W [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_usolve (Numeric, W, Pattern) ;
 	for (i = 0 ; i < n ; i++)
@@ -1134,7 +1137,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	    ASSIGN (X [i], Bx, Bz, i, split) ;
+	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_usolve (Numeric, X, Pattern) ;
 
@@ -1149,7 +1152,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [Cperm [i]] ; */
-	    ASSIGN (X [i], Bx, Bz, Cperm [i], split) ;
+	    ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ;
 	}
 	flops = UMF_uhsolve (Numeric, X, Pattern) ;
 
@@ -1164,7 +1167,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [Cperm [i]] ; */
-	    ASSIGN (X [i], Bx, Bz, Cperm [i], split) ;
+	    ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ;
 	}
 	flops = UMF_utsolve (Numeric, X, Pattern) ;
 
@@ -1179,7 +1182,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	  ASSIGN (X [i], Bx, Bz, i, split) ;
+	  ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_uhsolve (Numeric, X, Pattern) ;
 
@@ -1194,7 +1197,7 @@
 	for (i = 0 ; i < n ; i++)
 	{
 	    /* X [i] = B [i] ; */
-	    ASSIGN (X [i], Bx, Bz, i, split) ;
+	    ASSIGN (X [i], Bx, Bz, i, Bsplit) ;
 	}
 	flops = UMF_utsolve (Numeric, X, Pattern) ;
 
@@ -1206,7 +1209,7 @@
 
 #ifdef COMPLEX
     /* copy the solution back, from Entry X [ ] to double Xx [ ] and Xz [ ] */
-    if (split)
+    if (AXsplit)
     {
 	for (i = 0 ; i < n ; i++)
 	{