UMFPACK
Sylvestre Ledru [Mon, 17 Mar 2008 11:47:14 +0000 (11:47 +0000)]
57 files changed:
scilab/modules/Makefile.am
scilab/modules/Makefile.in
scilab/modules/umfpack/Makefile.am
scilab/modules/umfpack/Makefile.in
scilab/modules/umfpack/TAUCS_license.txt [new file with mode: 0644]
scilab/modules/umfpack/UMFPACK_license.txt [new file with mode: 0644]
scilab/modules/umfpack/builder.sce [new file with mode: 0644]
scilab/modules/umfpack/changelog.txt [new file with mode: 0644]
scilab/modules/umfpack/etc/umfpack.quit [new file with mode: 0644]
scilab/modules/umfpack/etc/umfpack.start [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/PlotSparse.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/ReadHBSparse.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/addchapter.sce [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/cond2sp.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/condestsp.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/rafiter.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/res_with_prec.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_chdel.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_chfact.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_chget.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_chinfo.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_chsolve.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/taucs_license.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_license.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_ludel.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_lufact.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_luget.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_luinfo.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umf_lusolve.xml [new file with mode: 0644]
scilab/modules/umfpack/help/en_US/umfpack.xml [new file with mode: 0644]
scilab/modules/umfpack/includes/gw_umfpack.h [new file with mode: 0644]
scilab/modules/umfpack/license.txt [new file with mode: 0644]
scilab/modules/umfpack/loader.sce [new file with mode: 0644]
scilab/modules/umfpack/macros/buildmacros.bat [new file with mode: 0644]
scilab/modules/umfpack/macros/buildmacros.sce [new file with mode: 0644]
scilab/modules/umfpack/macros/cleanmacros.bat [new file with mode: 0644]
scilab/modules/umfpack/macros/sparse_util.sci [new file with mode: 0644]
scilab/modules/umfpack/readme.txt [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/gw_umfpack.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_res_with_prec.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_taucs_chdel.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_taucs_chfact.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_taucs_chget.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_taucs_chinfo.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_taucs_chsolve.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umf_ludel.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umf_lufact.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umf_luget.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umf_luinfo.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umf_lusolve.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/c/sci_umfpack.c [new file with mode: 0644]
scilab/modules/umfpack/sci_gateway/umfpack_gateway.xml [new file with mode: 0644]
scilab/modules/umfpack/src/c/common_umfpack.c [new file with mode: 0644]
scilab/modules/umfpack/src/c/sciumfpack.h [new file with mode: 0644]
scilab/modules/umfpack/src/c/taucs_scilab.c [new file with mode: 0644]
scilab/modules/umfpack/src/c/taucs_scilab.h [new file with mode: 0644]
scilab/modules/umfpack/version.xml [new file with mode: 0644]

index f89ba5d..e619e71 100644 (file)
@@ -68,6 +68,7 @@ development_tools \
 compatibility_functions \
 helptools \
 fftw \
+umfpack \
 demo_tools
 
 #umfpack
@@ -164,6 +165,10 @@ if FFTW
 libscilab_la_LIBADD += $(top_builddir)/modules/fftw/libscifftw.la
 endif
 
+if UMFPACK
+libscilab_la_LIBADD += $(top_builddir)/modules/umfpack/libsciumfpack.la
+endif
+
 libscilab_la_LIBADD += $(top_builddir)/modules/jvm/libscijvm.la
 
 libscilab_la_LIBADD += $(top_builddir)/modules/scicos/libsciscicos.la
index 87f7e78..f183115 100644 (file)
@@ -57,9 +57,10 @@ host_triplet = @host@
 #libscilab_la_LIBADD += $(top_builddir)/modules/mpi/libscimpi.la
 #endif
 @FFTW_TRUE@am__append_5 = $(top_builddir)/modules/fftw/libscifftw.la
-@SCICOS_TRUE@am__append_6 = $(top_builddir)/modules/scicos_blocks/libsciscicos_blocks.la
-@USE_EMBEDDED_BLAS_TRUE@am__append_7 = $(top_builddir)/libs/blas/libsciblas.la
-@USE_EMBEDDED_LAPACK_TRUE@am__append_8 = \
+@UMFPACK_TRUE@am__append_6 = $(top_builddir)/modules/umfpack/libsciumfpack.la
+@SCICOS_TRUE@am__append_7 = $(top_builddir)/modules/scicos_blocks/libsciscicos_blocks.la
+@USE_EMBEDDED_BLAS_TRUE@am__append_8 = $(top_builddir)/libs/blas/libsciblas.la
+@USE_EMBEDDED_LAPACK_TRUE@am__append_9 = \
 @USE_EMBEDDED_LAPACK_TRUE@$(top_builddir)/libs/lapack/libscilapack.la
 
 subdir = modules
@@ -134,13 +135,13 @@ libscilab_la_DEPENDENCIES = $(top_builddir)/modules/mexlib/libmex.la \
        $(top_builddir)/modules/dynamic_link/libscidynamic_link.la \
        $(top_builddir)/modules/output_stream/libscioutput_stream.la \
        $(top_builddir)/modules/string/libscistring.la $(am__append_5) \
-       $(top_builddir)/modules/jvm/libscijvm.la \
-       $(top_builddir)/modules/scicos/libsciscicos.la $(am__append_6) \
+       $(am__append_6) $(top_builddir)/modules/jvm/libscijvm.la \
+       $(top_builddir)/modules/scicos/libsciscicos.la $(am__append_7) \
        $(top_builddir)/libs/hashtable/libscihashtable.la \
        $(top_builddir)/libs/MALLOC/libscimalloc.la \
        $(top_builddir)/libs/doublylinkedlist/libscidoublylinkedlist.la \
-       $(top_builddir)/libs/libst/libscilibst.la $(am__append_7) \
-       $(am__append_8)
+       $(top_builddir)/libs/libst/libscilibst.la $(am__append_8) \
+       $(am__append_9)
 am_libscilab_la_OBJECTS =
 libscilab_la_OBJECTS = $(am_libscilab_la_OBJECTS)
 libscilab_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -179,7 +180,8 @@ DIST_SUBDIRS = core output_stream action_binding arnoldi \
        metanet signal_processing sound time sparse windows_tools \
        functions others overloading maple2scilab m2sci texmacs scipad \
        scilab2fortran development_tools compatibility_functions \
-       helptools fftw demo_tools scicos_blocks scicos . javasci
+       helptools fftw umfpack demo_tools scicos_blocks scicos . \
+       javasci
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LINGUAS = @ALL_LINGUAS@
@@ -374,7 +376,7 @@ SUBDIRS = core output_stream action_binding arnoldi \
        randlib sparse windows_tools functions others overloading \
        maple2scilab m2sci texmacs scipad scilab2fortran \
        development_tools compatibility_functions helptools fftw \
-       demo_tools $(am__append_1) scicos . $(am__append_2)
+       umfpack demo_tools $(am__append_1) scicos . $(am__append_2)
 
 #### Basic files ####
 libscilab_la_rootdir = $(mydatadir)
@@ -431,13 +433,13 @@ libscilab_la_LIBADD = $(top_builddir)/modules/mexlib/libmex.la \
        $(top_builddir)/modules/dynamic_link/libscidynamic_link.la \
        $(top_builddir)/modules/output_stream/libscioutput_stream.la \
        $(top_builddir)/modules/string/libscistring.la $(am__append_5) \
-       $(top_builddir)/modules/jvm/libscijvm.la \
-       $(top_builddir)/modules/scicos/libsciscicos.la $(am__append_6) \
+       $(am__append_6) $(top_builddir)/modules/jvm/libscijvm.la \
+       $(top_builddir)/modules/scicos/libsciscicos.la $(am__append_7) \
        $(top_builddir)/libs/hashtable/libscihashtable.la \
        $(top_builddir)/libs/MALLOC/libscimalloc.la \
        $(top_builddir)/libs/doublylinkedlist/libscidoublylinkedlist.la \
-       $(top_builddir)/libs/libst/libscilibst.la $(am__append_7) \
-       $(am__append_8)
+       $(top_builddir)/libs/libst/libscilibst.la $(am__append_8) \
+       $(am__append_9)
 all: all-recursive
 
 .SUFFIXES:
index decf096..acd12e5 100644 (file)
@@ -8,7 +8,7 @@ modulename=umfpack
 
 pkglib_LTLIBRARIES = libsciumfpack.la
 
-libsciumfpack_la_LDFLAGS = -version-info $(SCILAB_LIBRARY_VERSION) $(UMFPACK3_LIB)
+libsciumfpack_la_LDFLAGS = -version-info $(SCILAB_LIBRARY_VERSION) $(UMFPACK3_LIB) -lumfpack -lamd
 
 #### umfpack : Conf files ####
 libsciumfpack_la_rootdir = $(mydatadir)
@@ -19,10 +19,23 @@ libsciumfpack_la_etc_DATA = etc/umfpack.quit etc/umfpack.start
 
 #if UMFPACK
 
-UMFPACK_C_SOURCES = src/c/intscispt.c \
-src/c/taucs_scilab.c 
+UMFPACK_C_SOURCES = src/c/taucs_scilab.c \
+src/c/common_umfpack.c
+
+GATEWAY_C_SOURCES =  sci_gateway/c/gw_umfpack.c \
+sci_gateway/c/sci_res_with_prec.c \
+sci_gateway/c/sci_taucs_chdel.c \
+sci_gateway/c/sci_taucs_chfact.c \
+sci_gateway/c/sci_taucs_chget.c \
+sci_gateway/c/sci_taucs_chinfo.c \
+sci_gateway/c/sci_taucs_chsolve.c \
+sci_gateway/c/sci_umf_ludel.c \
+sci_gateway/c/sci_umf_lufact.c \
+sci_gateway/c/sci_umf_luget.c \
+sci_gateway/c/sci_umf_luinfo.c \
+sci_gateway/c/sci_umf_lusolve.c \
+sci_gateway/c/sci_umfpack.c
 
-#GATEWAY_C_SOURCES = 
 
 
 #### umfpack : Conf files ####
@@ -32,10 +45,10 @@ libsciumfpack_la_root_DATA = changelog.txt license.txt readme.txt version.xml
 libsciumfpack_la_sci_gatewaydir = $(mydatadir)/sci_gateway
 libsciumfpack_la_sci_gateway_DATA = sci_gateway/umfpack_gateway.xml
 
-libsciumfpack_la_SOURCES = $(UMFPACK_C_SOURCES) 
+libsciumfpack_la_SOURCES = $(UMFPACK_C_SOURCES)  $(GATEWAY_C_SOURCES)
 #$(GATEWAY_C_SOURCES)
 
-libsciumfpack_la_LIBADD =  $(top_builddir)/modules/libmx/libmx.la $(top_builddir)/modules/libmat/libmat.la $(top_builddir)/modules/sparse/libscisparse.la $(top_builddir)/modules/libmex/libmex.la $(top_builddir)/modules/core/libscicore.la $(top_builddir)/modules/output_stream/libscioutput_stream.la 
+libsciumfpack_la_LIBADD =  $(top_builddir)/modules/mexlib/libmx.la $(top_builddir)/modules/mexlib/libmat.la $(top_builddir)/modules/sparse/libscisparse.la $(top_builddir)/modules/mexlib/libmex.la $(top_builddir)/modules/core/libscicore.la $(top_builddir)/modules/output_stream/libscioutput_stream.la 
 
 if USE_EMBEDDED_LAPACK
 libsciumfpack_la_LIBADD += $(top_builddir)/libs/lapack/libscilapack.la
index 5122185..830f341 100644 (file)
@@ -60,7 +60,7 @@ host_triplet = @host@
 @USE_EMBEDDED_BLAS_TRUE@am__append_2 = $(top_builddir)/libs/blas/libsciblas.la 
 DIST_COMMON = $(libsciumfpack_la_include_HEADERS) \
        $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-       $(top_srcdir)/Makefile.incl.am
+       $(top_srcdir)/Makefile.incl.am INSTALL
 @GUI_TRUE@am__append_3 = java
 @SWIG_TRUE@am__append_4 = swig
 @GIWS_TRUE@am__append_5 = giws
@@ -96,16 +96,29 @@ am__installdirs = "$(DESTDIR)$(pkglibdir)" \
 pkglibLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(pkglib_LTLIBRARIES)
 libsciumfpack_la_DEPENDENCIES =  \
-       $(top_builddir)/modules/libmx/libmx.la \
-       $(top_builddir)/modules/libmat/libmat.la \
+       $(top_builddir)/modules/mexlib/libmx.la \
+       $(top_builddir)/modules/mexlib/libmat.la \
        $(top_builddir)/modules/sparse/libscisparse.la \
-       $(top_builddir)/modules/libmex/libmex.la \
+       $(top_builddir)/modules/mexlib/libmex.la \
        $(top_builddir)/modules/core/libscicore.la \
        $(top_builddir)/modules/output_stream/libscioutput_stream.la \
        $(am__append_1) $(am__append_2)
-am__objects_1 = libsciumfpack_la-intscispt.lo \
-       libsciumfpack_la-taucs_scilab.lo
-am_libsciumfpack_la_OBJECTS = $(am__objects_1)
+am__objects_1 = libsciumfpack_la-taucs_scilab.lo \
+       libsciumfpack_la-common_umfpack.lo
+am__objects_2 = libsciumfpack_la-gw_umfpack.lo \
+       libsciumfpack_la-sci_res_with_prec.lo \
+       libsciumfpack_la-sci_taucs_chdel.lo \
+       libsciumfpack_la-sci_taucs_chfact.lo \
+       libsciumfpack_la-sci_taucs_chget.lo \
+       libsciumfpack_la-sci_taucs_chinfo.lo \
+       libsciumfpack_la-sci_taucs_chsolve.lo \
+       libsciumfpack_la-sci_umf_ludel.lo \
+       libsciumfpack_la-sci_umf_lufact.lo \
+       libsciumfpack_la-sci_umf_luget.lo \
+       libsciumfpack_la-sci_umf_luinfo.lo \
+       libsciumfpack_la-sci_umf_lusolve.lo \
+       libsciumfpack_la-sci_umfpack.lo
+am_libsciumfpack_la_OBJECTS = $(am__objects_1) $(am__objects_2)
 libsciumfpack_la_OBJECTS = $(am_libsciumfpack_la_OBJECTS)
 libsciumfpack_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libsciumfpack_la_CFLAGS) \
@@ -315,7 +328,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 modulename = umfpack
 pkglib_LTLIBRARIES = libsciumfpack.la
-libsciumfpack_la_LDFLAGS = -version-info $(SCILAB_LIBRARY_VERSION) $(UMFPACK3_LIB)
+libsciumfpack_la_LDFLAGS = -version-info $(SCILAB_LIBRARY_VERSION) $(UMFPACK3_LIB) -lumfpack -lamd
 
 #### umfpack : Conf files ####
 libsciumfpack_la_rootdir = $(mydatadir)
@@ -325,24 +338,36 @@ libsciumfpack_la_etcdir = $(mydatadir)/etc
 libsciumfpack_la_etc_DATA = etc/umfpack.quit etc/umfpack.start
 
 #if UMFPACK
-UMFPACK_C_SOURCES = src/c/intscispt.c \
-src/c/taucs_scilab.c 
+UMFPACK_C_SOURCES = src/c/taucs_scilab.c \
+src/c/common_umfpack.c
+
+GATEWAY_C_SOURCES = sci_gateway/c/gw_umfpack.c \
+sci_gateway/c/sci_res_with_prec.c \
+sci_gateway/c/sci_taucs_chdel.c \
+sci_gateway/c/sci_taucs_chfact.c \
+sci_gateway/c/sci_taucs_chget.c \
+sci_gateway/c/sci_taucs_chinfo.c \
+sci_gateway/c/sci_taucs_chsolve.c \
+sci_gateway/c/sci_umf_ludel.c \
+sci_gateway/c/sci_umf_lufact.c \
+sci_gateway/c/sci_umf_luget.c \
+sci_gateway/c/sci_umf_luinfo.c \
+sci_gateway/c/sci_umf_lusolve.c \
+sci_gateway/c/sci_umfpack.c
 
 
-#GATEWAY_C_SOURCES = 
-
 #### umfpack : Conf files ####
 libsciumfpack_la_root_DATA = changelog.txt license.txt readme.txt version.xml
 
 #### umfpack : gateway declaration ####
 libsciumfpack_la_sci_gatewaydir = $(mydatadir)/sci_gateway
 libsciumfpack_la_sci_gateway_DATA = sci_gateway/umfpack_gateway.xml
-libsciumfpack_la_SOURCES = $(UMFPACK_C_SOURCES) 
+libsciumfpack_la_SOURCES = $(UMFPACK_C_SOURCES)  $(GATEWAY_C_SOURCES)
 #$(GATEWAY_C_SOURCES)
-libsciumfpack_la_LIBADD = $(top_builddir)/modules/libmx/libmx.la \
-       $(top_builddir)/modules/libmat/libmat.la \
+libsciumfpack_la_LIBADD = $(top_builddir)/modules/mexlib/libmx.la \
+       $(top_builddir)/modules/mexlib/libmat.la \
        $(top_builddir)/modules/sparse/libscisparse.la \
-       $(top_builddir)/modules/libmex/libmex.la \
+       $(top_builddir)/modules/mexlib/libmex.la \
        $(top_builddir)/modules/core/libscicore.la \
        $(top_builddir)/modules/output_stream/libscioutput_stream.la \
        $(am__append_1) $(am__append_2)
@@ -486,7 +511,20 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-intscispt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-common_umfpack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-gw_umfpack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_res_with_prec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_taucs_chdel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_taucs_chfact.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_taucs_chget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_taucs_chinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_taucs_chsolve.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umf_ludel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umf_lufact.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umf_luget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umf_luinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umf_lusolve.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-sci_umfpack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsciumfpack_la-taucs_scilab.Plo@am__quote@
 
 .c.o:
@@ -510,13 +548,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
 
-libsciumfpack_la-intscispt.lo: src/c/intscispt.c
-@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-intscispt.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-intscispt.Tpo -c -o libsciumfpack_la-intscispt.lo `test -f 'src/c/intscispt.c' || echo '$(srcdir)/'`src/c/intscispt.c
-@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-intscispt.Tpo $(DEPDIR)/libsciumfpack_la-intscispt.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/intscispt.c' object='libsciumfpack_la-intscispt.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-intscispt.lo `test -f 'src/c/intscispt.c' || echo '$(srcdir)/'`src/c/intscispt.c
-
 libsciumfpack_la-taucs_scilab.lo: src/c/taucs_scilab.c
 @am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-taucs_scilab.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-taucs_scilab.Tpo -c -o libsciumfpack_la-taucs_scilab.lo `test -f 'src/c/taucs_scilab.c' || echo '$(srcdir)/'`src/c/taucs_scilab.c
 @am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-taucs_scilab.Tpo $(DEPDIR)/libsciumfpack_la-taucs_scilab.Plo
@@ -524,6 +555,104 @@ libsciumfpack_la-taucs_scilab.lo: src/c/taucs_scilab.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-taucs_scilab.lo `test -f 'src/c/taucs_scilab.c' || echo '$(srcdir)/'`src/c/taucs_scilab.c
 
+libsciumfpack_la-common_umfpack.lo: src/c/common_umfpack.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-common_umfpack.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-common_umfpack.Tpo -c -o libsciumfpack_la-common_umfpack.lo `test -f 'src/c/common_umfpack.c' || echo '$(srcdir)/'`src/c/common_umfpack.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-common_umfpack.Tpo $(DEPDIR)/libsciumfpack_la-common_umfpack.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/c/common_umfpack.c' object='libsciumfpack_la-common_umfpack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-common_umfpack.lo `test -f 'src/c/common_umfpack.c' || echo '$(srcdir)/'`src/c/common_umfpack.c
+
+libsciumfpack_la-gw_umfpack.lo: sci_gateway/c/gw_umfpack.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-gw_umfpack.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-gw_umfpack.Tpo -c -o libsciumfpack_la-gw_umfpack.lo `test -f 'sci_gateway/c/gw_umfpack.c' || echo '$(srcdir)/'`sci_gateway/c/gw_umfpack.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-gw_umfpack.Tpo $(DEPDIR)/libsciumfpack_la-gw_umfpack.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/gw_umfpack.c' object='libsciumfpack_la-gw_umfpack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-gw_umfpack.lo `test -f 'sci_gateway/c/gw_umfpack.c' || echo '$(srcdir)/'`sci_gateway/c/gw_umfpack.c
+
+libsciumfpack_la-sci_res_with_prec.lo: sci_gateway/c/sci_res_with_prec.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_res_with_prec.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_res_with_prec.Tpo -c -o libsciumfpack_la-sci_res_with_prec.lo `test -f 'sci_gateway/c/sci_res_with_prec.c' || echo '$(srcdir)/'`sci_gateway/c/sci_res_with_prec.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_res_with_prec.Tpo $(DEPDIR)/libsciumfpack_la-sci_res_with_prec.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_res_with_prec.c' object='libsciumfpack_la-sci_res_with_prec.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_res_with_prec.lo `test -f 'sci_gateway/c/sci_res_with_prec.c' || echo '$(srcdir)/'`sci_gateway/c/sci_res_with_prec.c
+
+libsciumfpack_la-sci_taucs_chdel.lo: sci_gateway/c/sci_taucs_chdel.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_taucs_chdel.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_taucs_chdel.Tpo -c -o libsciumfpack_la-sci_taucs_chdel.lo `test -f 'sci_gateway/c/sci_taucs_chdel.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chdel.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_taucs_chdel.Tpo $(DEPDIR)/libsciumfpack_la-sci_taucs_chdel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_taucs_chdel.c' object='libsciumfpack_la-sci_taucs_chdel.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_taucs_chdel.lo `test -f 'sci_gateway/c/sci_taucs_chdel.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chdel.c
+
+libsciumfpack_la-sci_taucs_chfact.lo: sci_gateway/c/sci_taucs_chfact.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_taucs_chfact.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_taucs_chfact.Tpo -c -o libsciumfpack_la-sci_taucs_chfact.lo `test -f 'sci_gateway/c/sci_taucs_chfact.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chfact.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_taucs_chfact.Tpo $(DEPDIR)/libsciumfpack_la-sci_taucs_chfact.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_taucs_chfact.c' object='libsciumfpack_la-sci_taucs_chfact.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_taucs_chfact.lo `test -f 'sci_gateway/c/sci_taucs_chfact.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chfact.c
+
+libsciumfpack_la-sci_taucs_chget.lo: sci_gateway/c/sci_taucs_chget.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_taucs_chget.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_taucs_chget.Tpo -c -o libsciumfpack_la-sci_taucs_chget.lo `test -f 'sci_gateway/c/sci_taucs_chget.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chget.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_taucs_chget.Tpo $(DEPDIR)/libsciumfpack_la-sci_taucs_chget.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_taucs_chget.c' object='libsciumfpack_la-sci_taucs_chget.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_taucs_chget.lo `test -f 'sci_gateway/c/sci_taucs_chget.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chget.c
+
+libsciumfpack_la-sci_taucs_chinfo.lo: sci_gateway/c/sci_taucs_chinfo.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_taucs_chinfo.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_taucs_chinfo.Tpo -c -o libsciumfpack_la-sci_taucs_chinfo.lo `test -f 'sci_gateway/c/sci_taucs_chinfo.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chinfo.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_taucs_chinfo.Tpo $(DEPDIR)/libsciumfpack_la-sci_taucs_chinfo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_taucs_chinfo.c' object='libsciumfpack_la-sci_taucs_chinfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_taucs_chinfo.lo `test -f 'sci_gateway/c/sci_taucs_chinfo.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chinfo.c
+
+libsciumfpack_la-sci_taucs_chsolve.lo: sci_gateway/c/sci_taucs_chsolve.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_taucs_chsolve.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_taucs_chsolve.Tpo -c -o libsciumfpack_la-sci_taucs_chsolve.lo `test -f 'sci_gateway/c/sci_taucs_chsolve.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chsolve.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_taucs_chsolve.Tpo $(DEPDIR)/libsciumfpack_la-sci_taucs_chsolve.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_taucs_chsolve.c' object='libsciumfpack_la-sci_taucs_chsolve.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_taucs_chsolve.lo `test -f 'sci_gateway/c/sci_taucs_chsolve.c' || echo '$(srcdir)/'`sci_gateway/c/sci_taucs_chsolve.c
+
+libsciumfpack_la-sci_umf_ludel.lo: sci_gateway/c/sci_umf_ludel.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umf_ludel.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umf_ludel.Tpo -c -o libsciumfpack_la-sci_umf_ludel.lo `test -f 'sci_gateway/c/sci_umf_ludel.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_ludel.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umf_ludel.Tpo $(DEPDIR)/libsciumfpack_la-sci_umf_ludel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umf_ludel.c' object='libsciumfpack_la-sci_umf_ludel.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umf_ludel.lo `test -f 'sci_gateway/c/sci_umf_ludel.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_ludel.c
+
+libsciumfpack_la-sci_umf_lufact.lo: sci_gateway/c/sci_umf_lufact.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umf_lufact.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umf_lufact.Tpo -c -o libsciumfpack_la-sci_umf_lufact.lo `test -f 'sci_gateway/c/sci_umf_lufact.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_lufact.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umf_lufact.Tpo $(DEPDIR)/libsciumfpack_la-sci_umf_lufact.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umf_lufact.c' object='libsciumfpack_la-sci_umf_lufact.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umf_lufact.lo `test -f 'sci_gateway/c/sci_umf_lufact.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_lufact.c
+
+libsciumfpack_la-sci_umf_luget.lo: sci_gateway/c/sci_umf_luget.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umf_luget.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umf_luget.Tpo -c -o libsciumfpack_la-sci_umf_luget.lo `test -f 'sci_gateway/c/sci_umf_luget.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_luget.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umf_luget.Tpo $(DEPDIR)/libsciumfpack_la-sci_umf_luget.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umf_luget.c' object='libsciumfpack_la-sci_umf_luget.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umf_luget.lo `test -f 'sci_gateway/c/sci_umf_luget.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_luget.c
+
+libsciumfpack_la-sci_umf_luinfo.lo: sci_gateway/c/sci_umf_luinfo.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umf_luinfo.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umf_luinfo.Tpo -c -o libsciumfpack_la-sci_umf_luinfo.lo `test -f 'sci_gateway/c/sci_umf_luinfo.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_luinfo.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umf_luinfo.Tpo $(DEPDIR)/libsciumfpack_la-sci_umf_luinfo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umf_luinfo.c' object='libsciumfpack_la-sci_umf_luinfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umf_luinfo.lo `test -f 'sci_gateway/c/sci_umf_luinfo.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_luinfo.c
+
+libsciumfpack_la-sci_umf_lusolve.lo: sci_gateway/c/sci_umf_lusolve.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umf_lusolve.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umf_lusolve.Tpo -c -o libsciumfpack_la-sci_umf_lusolve.lo `test -f 'sci_gateway/c/sci_umf_lusolve.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_lusolve.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umf_lusolve.Tpo $(DEPDIR)/libsciumfpack_la-sci_umf_lusolve.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umf_lusolve.c' object='libsciumfpack_la-sci_umf_lusolve.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umf_lusolve.lo `test -f 'sci_gateway/c/sci_umf_lusolve.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umf_lusolve.c
+
+libsciumfpack_la-sci_umfpack.lo: sci_gateway/c/sci_umfpack.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -MT libsciumfpack_la-sci_umfpack.lo -MD -MP -MF $(DEPDIR)/libsciumfpack_la-sci_umfpack.Tpo -c -o libsciumfpack_la-sci_umfpack.lo `test -f 'sci_gateway/c/sci_umfpack.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umfpack.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/libsciumfpack_la-sci_umfpack.Tpo $(DEPDIR)/libsciumfpack_la-sci_umfpack.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sci_gateway/c/sci_umfpack.c' object='libsciumfpack_la-sci_umfpack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsciumfpack_la_CFLAGS) $(CFLAGS) -c -o libsciumfpack_la-sci_umfpack.lo `test -f 'sci_gateway/c/sci_umfpack.c' || echo '$(srcdir)/'`sci_gateway/c/sci_umfpack.c
+
 mostlyclean-libtool:
        -rm -f *.lo
 
diff --git a/scilab/modules/umfpack/TAUCS_license.txt b/scilab/modules/umfpack/TAUCS_license.txt
new file mode 100644 (file)
index 0000000..a1dca10
--- /dev/null
@@ -0,0 +1,30 @@
+Copyright
+       TAUCS  Version  1.0, November 29, 2001. Copyright (c) 2001
+       by Sivan Toledo,  Tel-Aviv  Univesity,  stoledo@tau.ac.il.
+       All Rights Reserved.
+TAUCS License
+       Your  use  or distribution of TAUCS or any derivative code
+       implies that you agree to this License.
+       THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY  NO  WAR-
+       RANTY 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  Avail-
+       ability of the original version is retained on all copies.
+       User documentation of any code that uses this code or  any
+       derivative code must cite the Copyright, this License, the
+       Availability note, and "Used by permission." If this  code
+       or  any  derivative code is accessible from within MATLAB,
+       then typing "help taucs"  must  cite  the  Copyright,  and
+       "type  taucs"  must  also cite this License and the Avail-
+       ability note.  Permission to modify the code and  to  dis-
+       tribute  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 is provided to you free of charge.
+Availability
+       http://www.tau.ac.il/~stoledo/taucs/
diff --git a/scilab/modules/umfpack/UMFPACK_license.txt b/scilab/modules/umfpack/UMFPACK_license.txt
new file mode 100644 (file)
index 0000000..81eb1a3
--- /dev/null
@@ -0,0 +1,38 @@
+
+UMFPACK, Copyright (c) 1995-2006 by Timothy A.  Davis.  All Rights Reserved.
+UMFPACK is available under alternate licences; contact T. Davis for details.
+
+UMFPACK License:
+
+    Your use or distribution of UMFPACK or any modified version of
+    UMFPACK implies that you agree to this License.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+    USA
+
+    Permission is hereby granted to use or copy this program under the
+    terms of the GNU LGPL, provided that the Copyright, this License,
+    and the Availability of the original version is retained on all copies.
+    User documentation of any code that uses this code or any modified
+    version of this code must cite the Copyright, this License, the
+    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.
+
+Availability:
+
+    http://www.cise.ufl.edu/research/sparse/umfpack
+
diff --git a/scilab/modules/umfpack/builder.sce b/scilab/modules/umfpack/builder.sce
new file mode 100644 (file)
index 0000000..98bff8d
--- /dev/null
@@ -0,0 +1,71 @@
+//  
+//  builder.sce file to build the scispt toolbox
+//  Bruno Pincon (some modifs from Antonio Frasson)
+//
+
+//---variable part to customize---------------------//
+
+UMF_INC_DIR = "/usr/local/include/ufsparse/";  // the path until umfpack.h
+UMF_LIB_DIR = "/usr/local/lib/";  // the path until libumfpack.a
+AMD_LIB_DIR = "/usr/local/lib/"  // the path until libamd.a 
+
+COMPILER_PLUS_FLAG_1 = "gcc -c -O";  // interface routines
+COMPILER_PLUS_FLAG_2 = "gcc -c -O3"; // for the taucs snmf stuff   
+
+SCILAB_ATLAS = %t ; // %t if scilab compiled with atlas
+                    // %f if scilab classic
+UMF_WITH_CBLAS = %f; // %t if umfpack compiled with the C blas interface            
+                     // %f if not
+
+// set the following only if UMF_WITH_CBLAS = %t;
+ATLAS_BLAS_LIB_DIR = "/usr/local/lib/"; 
+
+
+//---don't edit below (normally !)------------------//
+
+// blas lib files involved (used only when CASE22 == %t)
+BLAS_LIB = [ "libcblas.a"  ;...  // C blas interface
+             "libatlas.a" ];     // atlas core
+
+// build makefile
+fd=mopen("Makefile","w");
+  mfprintf(fd,"SCIDIRINC = %s\n",SCI+"/routines");
+  mfprintf(fd,"UMFDIRINC = %s\n",UMF_INC_DIR);
+  mfprintf(fd,"CC1 = %s\n",COMPILER_PLUS_FLAG_1);
+  mfprintf(fd,"CC2 = %s\n",COMPILER_PLUS_FLAG_2);
+  mfprintf(fd,"all: intscispt.o taucs_scilab.o\n");
+  mfprintf(fd,"intscispt.o: intscispt.c \n");
+  mfprintf(fd,"\t$(CC1) intscispt.c  -I${UMFDIRINC} -I${SCIDIRINC}\n");
+  mfprintf(fd,"taucs_scilab.o: taucs_scilab.c \n");
+  mfprintf(fd,"\t$(CC2) taucs_scilab.c -I${SCIDIRINC}\n");
+  mfprintf(fd,"clean:\n");
+  mfprintf(fd,"\trm *.o loader_inc.sce\n");
+mclose(fd);
+
+// compile the interface
+unix("make");
+
+// build loader_inc.sce
+fd=mopen("loader_inc.sce","w");
+if UMF_WITH_CBLAS then
+   if SCILAB_ATLAS then
+      mfprintf(fd,"objects = [ path+\""intscispt.o\"" ; \n")
+      mfprintf(fd,"            path+\""taucs_scilab.o\"" ; \n")
+      mfprintf(fd,"            \""%s\"" ;\n",UMF_LIB_DIR+"libumfpack.a")
+      mfprintf(fd,"            \""%s\"" ;\n",AMD_LIB_DIR+"libamd.a")      
+      mfprintf(fd,"            \""%s\"" ];\n", ATLAS_BLAS_LIB_DIR+BLAS_LIB(1))
+   else
+      mfprintf(fd,"objects = [ path+\""intscispt.o\"" ; \n")
+      mfprintf(fd,"            path+\""taucs_scilab.o\"" ; \n")
+      mfprintf(fd,"            \""%s\"" ;\n",UMF_LIB_DIR+"libumfpack.a")
+      mfprintf(fd,"            \""%s\"" ;\n",AMD_LIB_DIR+"libamd.a")            
+      mfprintf(fd,"            \""%s\"" ;\n", ATLAS_BLAS_LIB_DIR+BLAS_LIB(1))
+      mfprintf(fd,"            \""%s\"" ];\n",ATLAS_BLAS_LIB_DIR+BLAS_LIB(2))
+   end
+else
+   mfprintf(fd,"objects = [ path+\""intscispt.o\"" ; \n")
+   mfprintf(fd,"            path+\""taucs_scilab.o\"" ; \n")
+   mfprintf(fd,"            \""%s\"" ;\n",UMF_LIB_DIR+"libumfpack.a")
+   mfprintf(fd,"            \""%s\"" ];\n",AMD_LIB_DIR+"libamd.a")
+end
+mclose(fd);
diff --git a/scilab/modules/umfpack/changelog.txt b/scilab/modules/umfpack/changelog.txt
new file mode 100644 (file)
index 0000000..226d113
--- /dev/null
@@ -0,0 +1,102 @@
+from version 1.3 beta to version 1.4:
+       choose CeCILL-A licence
+       adapt PlotSparse for newgraphics
+       adapt the interface with minor changes in scilab (lstk->Lstk)
+       remove obsolete umfpack_cmplx function.
+
+from version 1.3 alpha to 1.3 beta:
+       From a suggestion of Eduardo Lenz
+       the functions taucs_chfact and taucs_chsolve work
+       also if one provides only the upper triangle of 
+       the matrix.
+
+from version 1.2 alpha to 1.3 alpha:
+
+       This new version was motivated by several things:
+          * Antonio Manoel Ferreria Frasson sent me some month
+            ago a first version adapted for complex matrices
+            (concerning the umfpack interface).
+          * I am also working currently with complex systems
+            (from Helmholtz equation).
+          * The likely incorporation of umfpack (with this interface)
+            in the future scilab version (3.1 ?); a very good news !
+          * update the interface to support umfpack v4.3.
+
+       So many changes occured but most are not visibles from
+       the scilab functions provided by this toolbox. For the user
+       the main changes are that: x=umfpack(A,"\",b), LUp=umf_lufact(A);
+       x = umf_lusolve(LUp,b) can be used with A or b real or
+       complex.
+
+        (i)   adapt the Antonio 's modifs (to treat complex linear
+              systems) => umfpack_cmplx is obsolete. I have 
+              added a field "it" in the cell type of the ListNumeric 
+              linked list. It gives the type (real it=0 or complex it=1)
+              of the factorisation: this was necessary to choose which
+              routines umfpack calling (the xxx_di_xxxxx family (real)
+              or the xxxxx_zi_xxxxx family (complex)). Also
+              rectangular matrices may be factorised.
+    
+        (ii)  finally I take the decision to
+              change the format (scilab sparse -> CCS) before 
+              calling the umfpack routines: this is clearer than 
+              the tricks I have done before (one got a factorisation of A' 
+              while the interface provides now a factorisation of A).
+              This extra work is compensed by the fact that the
+              interface is now passed by reference.
+
+        (iii) many changes in the interface C file:
+               - I use more heavily the scilab stack in place 
+                 of malloc (this simplifies a little all the error 
+                 treatment). 
+               - Also Francois (Delebecque) tells me about sci_gateway 
+                 which avoid the use of PutLhsVar(). 
+
+        (iv)  remove some bugs, in particular in umf_lusolve without 
+              refinement.
+
+        (v)   taucs_chsolve with an optional arg (A) do one
+              refinement step (=> rafiter is obsolete).
+
+        (vi)  better builder.sce and loader.sce (thanks to Antonio
+              Frasson) so that the toolbox is "loadable" from any
+              directory.
+
+
+from version 1.1 alpha to 1.2 alpha:
+        (i)   adapt the stuff to umfpack v4.0 
+
+        (ii)  correct a bug in  ReadHBSparse
+
+        (iii) help pages are provided also in html
+
+        (iv)  install explanations may be a little
+              clearer than before !   
+
+from version 1.0 alpha to 1.1 alpha :
+       (i)   add the taucs snmf stuff interface
+
+       (ii)  add a trick in ReadHBSparse so as to
+              read some HB matrices which doesn't respect
+              exactly the Harwell-Boeing format !
+
+        (iii) add the 2 macros cond2sp and rafiter and a
+              new func res_with_prec
+
+        (iv)  add a trick in PlotSparse to minimize memory
+              usage
+
+        (v)   add some tricks in the interface to avoid
+              memory leak when CreateVarFromPtr fails
+              (see test_size_for_sparse and test_size_for_mat
+              in scispt.c).
+
+        (vi)  correct bad path in the .cat files
+
+        (vii) correct a scilab bug (you have to download the
+              latest cvs version (begin of December) or to correct 
+              yourself, see NOTES 2 in the README file). You must 
+              correct it if you want to use umf_luget or taucs_chget 
+              with to small sparse matrices.
+
+
diff --git a/scilab/modules/umfpack/etc/umfpack.quit b/scilab/modules/umfpack/etc/umfpack.quit
new file mode 100644 (file)
index 0000000..859062a
--- /dev/null
@@ -0,0 +1,8 @@
+// ====================================================================
+// This file contains command to be executed at the end 
+// of a scilab session for umfpack module
+// Copyright INRIA 2008
+// ====================================================================
+// delete help chapter
+del_help_chapter('umfpack',%T);
+// ====================================================================
diff --git a/scilab/modules/umfpack/etc/umfpack.start b/scilab/modules/umfpack/etc/umfpack.start
new file mode 100644 (file)
index 0000000..45a6a88
--- /dev/null
@@ -0,0 +1,10 @@
+// ====================================================================
+// umfpack module initialisation file 
+// Copyright INRIA 2006
+// ====================================================================
+//Load  functions librarie
+load('SCI/modules/umfpack/macros/lib');
+// ====================================================================
+//add help chapter
+add_module_help_chapter('umfpack');
+// ====================================================================
diff --git a/scilab/modules/umfpack/help/en_US/PlotSparse.xml b/scilab/modules/umfpack/help/en_US/PlotSparse.xml
new file mode 100644 (file)
index 0000000..22d79f9
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>PlotSparse  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="PlotSparse"> plot the pattern of non nul elements of a sparse matrix  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>PlotSparse(A [,style])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+    <PARAM_INDENT>
+    <PARAM_ITEM>
+    <PARAM_NAME>A  </PARAM_NAME>
+      <PARAM_DESCRIPTION>
+    : a sparse matrix
+      </PARAM_DESCRIPTION> 
+   </PARAM_ITEM>
+   <PARAM_ITEM>
+   <PARAM_NAME>style  </PARAM_NAME>
+   <PARAM_DESCRIPTION>
+    : (optional) a string given the color and/or the marker type of the form &quot;[color][mark]&quot; 
+      where color may be a number referring the color you want to use (in the current colormap). 
+      If you use the std colormap then color may be one of the following letters :
+  <VERBATIM><![CDATA[
+    k  for black       b  for blue
+    r  for red         g  for green
+    c  for cyan        m  for magenta
+    y  for yellow      t  for turquoise
+    G  a dark green
+   ]]></VERBATIM>
+  <P>
+    mark must be one of the following :
+  </P>
+  <VERBATIM><![CDATA[
+    .  point           +  plus 
+    x  cross           *  circled plus 
+    D  filled diamond  d  diamond
+    ^  upper triangle  v  down triangle
+    o  circle
+   ]]></VERBATIM>
+  <P>
+    by default you have &quot;b.&quot; (in fact the 2d color) and this is also forced in case of error. 
+  </P>
+
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    plot the pattern of non nul elements of a sparse matrix :
+    each non nul element is drawn with a marker. For &quot;big&quot; 
+    matrix use essentially the point . as marker
+  </P>
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+[A,description,ref,mtype] = ReadHBSparse(DIR_SCISPT_DEM+"arc130.rua");
+set figure_style old
+PlotSparse(A,"y+")
+xtitle(ref + "." + mtype + " : " + description)
+ ]]></EXAMPLE>
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>ReadHBSparse</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+  <AUTHOR>Bruno Pincon  &lt;Bruno.Pincon@iecn.u-nancy.fr&gt;  </AUTHOR>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/ReadHBSparse.xml b/scilab/modules/umfpack/help/en_US/ReadHBSparse.xml
new file mode 100644 (file)
index 0000000..0f366a4
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>ReadHBSparse  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+  <SHORT_DESCRIPTION name="ReadHBSparse"> read a Harwell-Boeing sparse format file  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[A, description, ref, mtype] = ReadHBSparse([filename])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>filename  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) a string given the filename (eventually preceeding by the path), if filename is not given then the function use <LINK>xgetfile</LINK> to get filename interactively
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : the sparse matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>description  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a string given some information about the matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>ref  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a string given the reference of the matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>mtype  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a string given the type of the matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    An utility to read the Harwell-Boeing sparse matrix 
+    format. Currently don&apos;t work for unassembled matrix.
+    Also the eventual rhs vectors of the file are not returned.
+    Generally the file name is of the form ref.mtype  
+    where mtype is a 3 letters word abc given some 
+    informations (already inside the file) on the matrix : 
+  </P>
+  <VERBATIM><![CDATA[
+   a = R|C|P   for real|complex|pattern (no values given)
+   b = S|H|Z|U for symetric|hermitian|skew symetric|unsymetric
+   c = A|E     for assembled|unassembled matrix 
+               (case E is not treated by this func)
+   ]]></VERBATIM>
+  </DESCRIPTION>
+  <SECTION label='References'>
+  <P>
+    Users&apos; Guide for the Harwell-Boeing Sparse Matrix Collection Iain S. Duff, Roger G. Grimes, John G. Lewis. 
+    You may found  this guide and numerous sparse matrices (in the Harwell-Boeing  format) at the University of 
+    Florida Sparse Matrix Collection web site :
+  </P>
+     <A href="http://www.cise.ufl.edu/research/sparse/matrices/">http://www.cise.ufl.edu/research/sparse/matrices/</A>
+  <P>
+    maintained by Tim Davis (<A href="http://www.cise.ufl.edu/~davis/">http://www.cise.ufl.edu/~davis/</A>);
+  </P>
+  </SECTION>
+  <EXAMPLE><![CDATA[
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"arc130.rua");
+ ]]></EXAMPLE>
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>PlotSparse</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+  <AUTHOR>Bruno Pincon &lt;Bruno.Pincon@iecn.u-nancy.fr&gt;  </AUTHOR>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/addchapter.sce b/scilab/modules/umfpack/help/en_US/addchapter.sce
new file mode 100644 (file)
index 0000000..4737a12
--- /dev/null
@@ -0,0 +1,18 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2007-2008 - INRIA - Allan CORNET
+// 
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution.  The terms
+// are also available at    
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+
+
+// ====================================================================
+// help umfpack module
+// Add chapter
+// ====================================================================
+path = SCI+'/modules/umfpack/help/'+getdefaultlanguage();
+add_help_chapter("UMFPACK Interface",path,%T);
+clear path add_help_chapter;
+// ====================================================================
diff --git a/scilab/modules/umfpack/help/en_US/cond2sp.xml b/scilab/modules/umfpack/help/en_US/cond2sp.xml
new file mode 100644 (file)
index 0000000..38f46b7
--- /dev/null
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>cond2sp  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+  <SHORT_DESCRIPTION name="cond2sp"> computes an approximation of the 2-norm condition number of a s.p.d. sparse matrix  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[K2, lm, vm, lM, vM] = cond2sp(A, C_ptr [, rtol, itermax, verb])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a real symetric positive definite sparse matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to a Cholesky factorization (got with taucs_chfact)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>rtol  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) relative tolerance (default 1.e-3) (see details in DESCRIPTION)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>itermax  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) maximum number of iterations in the underlying algorithms (default 30)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>verb  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) boolean, must be %t for displaying the intermediary results, and %f (default) if you don&apos;t want.
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>K2  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : estimated 2-norm condition number <TT>K2 = ||A||_2 ||A^(-1)||_2 = lM/lm</TT>
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>lm  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (real positive scalar) minimum eigenvalue
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>vm  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : associated eigenvector
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>lM  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (real positive scalar) maximum eigenvalue
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>vM  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : associated eigenvector
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This quick and dirty function computes <TT>(lM,vM)</TT> using the iterative 
+    power method and <TT>(lm,vm)</TT> with the inverse iterative power method, then 
+    <TT>K2 = lM/lm</TT>. For each method the iterations are stopped until the following
+    condition is met :
+  </P>
+  <VERBATIM><![CDATA[
+     | (l_new - l_old)/l_new | < rtol
+   ]]></VERBATIM>
+  <P>
+    but 4 iterations are nevertheless required and also the iterations are stopped
+    if itermax is reached (and a warning message is issued). As the matrix is symetric
+    this is the rayleigh quotient which gives the estimated eigenvalue at each step
+    (<TT>lambda = v&apos;*A*v</TT>). You may called this function with named parameter, for 
+    instance if you want to see the intermediary result without setting yourself the 
+    rtol and itermax parameters you may called this function with the syntax :
+  </P>
+  <VERBATIM><![CDATA[
+    [K2, lm, vm, lM, vM] = cond2sp(A , C_ptr, verb=%t )
+   ]]></VERBATIM>
+  </DESCRIPTION>
+  <SECTION label='Caution'>
+  <P>
+    Currently there is no verification for the input parameters !
+  </P>
+  </SECTION>
+  <SECTION label='Remark'>
+  <P>
+    This function is intended to get an approximation of the 2-norm condition number (K2) and 
+    with the methods used, the precision on the obtained eigenvectors (vM and vm) are generally 
+    not very good. If you look for a smaller residual <TT>||Av - l*v||</TT>, you may apply some inverse 
+    power iterations  from v0 with the matrix :
+  </P>
+  <VERBATIM><![CDATA[
+   B = A - l0*speye(A)
+   ]]></VERBATIM>
+  <P>
+    For instance, applied 5 such iterations for <TT>(lm,vm)</TT> is done with :
+  </P>
+  <VERBATIM><![CDATA[
+l0 = lm ; v0 = vm;  // or l0 = lM ; v0 = vM;  // to polish (lM,vM)
+B = A - l0*speye(A);
+LUp = umf_lufact(B);
+vr = v0; nstep = 5;
+for i=1:nstep, vr = umf_lusolve(LUp, vr, "Ax=b", B); vr = vr/norm(vr) ; end
+umf_ludel(LUp); // if you don't use anymore this factorization
+lr = vr'*A*vr;
+norm_r0 = norm(A*v0 - l0*v0);
+norm_rr = norm(A*vr - lr*vr);
+// Bauer-Fike error bound...
+mprintf(" first estimated eigenvalue : l0 = %e \n\t", l0) 
+mprintf(" |l-l0| <= ||Av0-l0v0|| = %e , |l-l0|/l0 <= %e \n\r", norm_r0, norm_r0/l0)
+mprintf(" raffined estimated eigenvalue : lr = %e \n\t", lr) 
+mprintf(" |l-lr| <= ||Avr-lrvr|| = %e , |l-lr|/lr <= %e \n\r", norm_rr, norm_rr/lr)
+   ]]></VERBATIM>
+  </SECTION>
+
+  <EXAMPLE><![CDATA[
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"bcsstk24.rsa");
+C_ptr = taucs_chfact(A);
+[K2, lm, vm, lM, vM] = cond2sp(A , C_ptr, 1.e-5, 50, %t );
+taucs_chdel(C_ptr)
+ ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>condestsp</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>rcond</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+  <AUTHOR>Bruno Pincon  &lt;Bruno.Pincon@iecn.u-nancy.fr&gt;  </AUTHOR>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/condestsp.xml b/scilab/modules/umfpack/help/en_US/condestsp.xml
new file mode 100644 (file)
index 0000000..cabbdab
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>condestsp  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+
+  <SHORT_DESCRIPTION name="condestsp"> estimate the condition number of a sparse matrix  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+     <CALLING_SEQUENCE_ITEM>[K1] = condestsp(A, LUp, t)</CALLING_SEQUENCE_ITEM>
+     <CALLING_SEQUENCE_ITEM>[K1] = condestsp(A, LUp)</CALLING_SEQUENCE_ITEM>
+     <CALLING_SEQUENCE_ITEM>[K1] = condestsp(A, t)</CALLING_SEQUENCE_ITEM>
+     <CALLING_SEQUENCE_ITEM>[K1] = condestsp(A)</CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+     <PARAM_INDENT>
+     <PARAM_ITEM>
+        <PARAM_NAME>A  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+          : a real or complex square sparse matrix
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>LUp  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : (optional) a pointer to (umf) LU factors of A obtained by a call to umf_lufact ; 
+             if you have already computed the LU (= PAQ) factors it is recommanded to give 
+             this optional parameter (as the factorization may be time consuming)
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>t  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : (optional) a positive integer (default value 2) by increasing this one 
+             you may hope to get a better (even exact) estimate
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>K1  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : estimated 1-norm condition number of A 
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    Give an estimate of the 1-norm condition number of 
+    the sparse matrix A by Algorithm 2.4 appearing in :
+  </P>
+  <VERBATIM><![CDATA[
+  "A block algorithm for matrix 1-norm estimation
+   with an application to 1-norm pseudospectra"
+   Nicholas J. Higham and Francoise Tisseur
+   Siam J. Matrix Anal. Appl., vol 21, No 4, pp 1185-1201
+   ]]></VERBATIM>
+  <P> Noting the exact condition number <TT>K1e = ||A||_1 ||A^(-1)||_1</TT>, 
+    we have allways <TT>K1 &lt;= K1e</TT> and this estimate gives in most case 
+    something superior to <TT>1/2 K1e</TT>
+  </P>
+
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+A = sparse( [ 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] );
+K1 = condestsp(A)
+// verif by direct computation
+K1e = norm(A,1)*norm(inv(full(A)),1)
+
+// another example
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"arc130.rua");
+K1 = condestsp(A)
+// this example is not so big so that we can do the verif
+K1e = norm(A,1)*norm(inv(full(A)),1)
+
+// if you have already the lu factors condestsp(A,Lup) is faster
+// because lu factors are then not computed inside condestsp
+Lup = umf_lufact(A);   
+K1 = condestsp(A,Lup)
+umf_ludel(Lup)         // clear memory
+   ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>rcond</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHOR>Bruno Pincon &lt;Bruno.Pincon@iecn.u-nancy.fr&gt; </AUTHOR>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/rafiter.xml b/scilab/modules/umfpack/help/en_US/rafiter.xml
new file mode 100644 (file)
index 0000000..b2f1a2f
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>rafiter  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+
+  <SHORT_DESCRIPTION name="rafiter"> (obsolete) iterative refinement for a s.p.d. linear system  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[xn, rn] = rafiter(A, C_ptr, b, x0, [, nb_iter, verb])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a real symetric positive definite sparse matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to a Cholesky factorization (got with taucs_chfact)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>b  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : column vector (r.h.s of the linear system) but &quot;matrix&quot; (multiple r.h.s.) are allowed.
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>x0  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : first solution obtained with taucs_chsolve(C_ptr, b)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>nb_iter  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) number of raffinement iterations (default 2)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>verb  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) boolean, must be %t for displaying the intermediary results, 
+      and %f (default) if you don&apos;t want.
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>xn  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : new refined solution
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>rn  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : residual (<TT>A*xn - b</TT>)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function is somewhat obsolete, use <TT>x = taucs_chsolve(C_ptr,b,A)</TT>
+    (see <LINK>taucs_chsolve</LINK>) which do one iterative refinement step.
+  </P>
+  <P>
+    To use if you want to improve a little the solution got with taucs_chsolve.
+    Note that with verb=%t the displayed internal steps are essentially meaningful 
+    in the case where b is a column vector.
+  </P>
+  </DESCRIPTION>
+  <SECTION label='Caution'>
+  <P>
+    Currently there is no verification for the input parameters !
+  </P>
+  </SECTION>
+  <EXAMPLE><![CDATA[
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"bcsstk24.rsa");
+C_ptr = taucs_chfact(A);
+b = rand(size(A,1),1);
+x0 = taucs_chsolve(C_ptr, b);
+norm(A*x0 - b)
+[xn, rn] = rafiter(A, C_ptr, b, x0, verb=%t);
+norm(A*xn - b)
+taucs_chdel(C_ptr)
+ ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chsolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHOR>Bruno Pincon &lt;Bruno.Pincon@iecn.u-nancy.fr&gt; </AUTHOR>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/res_with_prec.xml b/scilab/modules/umfpack/help/en_US/res_with_prec.xml
new file mode 100644 (file)
index 0000000..12c50e8
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>res_with_prec  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+
+  <SHORT_DESCRIPTION name="res_with_prec"> computes the residual r = Ax-b with precision  </SHORT_DESCRIPTION>
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[r,norm2_r] = res_with_prec(A, x, b)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : real or complex sparse matrix (m x n)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>x  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : column vector (n x 1) or matrix (n x p) 
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>b  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : column vector (m x 1) or matrix (m x p)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>r  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : column vector (m x 1) or matrix (m x p)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>norm2_r  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : scalar or vector (1 x p) when b is a m x p matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function computes the residual of a linear system <TT>r = Ax - b</TT> (together
+    with its 2-norm) with the additionnal precision provided on &quot;Intel like&quot; 
+    FPU (80 bits in place of 64) if the compiler translate &quot;long double&quot; to 
+    use it. Else one must get the same than using <TT>A*x - b</TT> at the scilab level. 
+    In both cases using <VERB>[r, nr] = res_with_prec(A,x,b)</VERB> is 
+    faster than  <VERB>r = A*x - b</VERB> (and faster than <TT>r = A*x - b; nr = norm(r)</TT>).
+  </P>
+  <P>
+    When <TT>p &gt; 1</TT>, <TT>norm2_r(i)</TT> is the 2-norm of the vector <TT>r(:,i)</TT>.
+  </P>
+
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"bcsstk24.rsa");
+C_ptr = taucs_chfact(A);
+b = rand(size(A,1),1);
+x0 = taucs_chsolve(C_ptr, b);
+norm(A*x0 - b)
+norm(res_with_prec(A, x0, b))
+ ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>rafiter</LINK> </SEE_ALSO_ITEM>
+
+  </SEE_ALSO>
+
+  <AUTHOR>Bruno Pincon &lt;Bruno.Pincon@iecn.u-nancy.fr&gt; </AUTHOR>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_chdel.xml b/scilab/modules/umfpack/help/en_US/taucs_chdel.xml
new file mode 100644 (file)
index 0000000..101bd32
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+ <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_chdel  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+  <SHORT_DESCRIPTION name="taucs_chdel"> utility function used with taucs_chfact  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>taucs_chdel(C_ptr) or taucs_chdel()  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to a Cholesky factorization
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function is used in conjunction with <LINK>taucs_chfact</LINK> and
+    <LINK>taucs_chsolve</LINK>. It clears the internal memory space used to store 
+    the Cholesky factorization (got with taucs_chfact). Use without argument 
+    it frees the memory for all the current scilab (taucs) Cholesky factorizations. 
+  </P>
+  </DESCRIPTION>
+
+  <SECTION label='Examples'>
+  <P>
+    see the example section of <LINK>taucs_chfact</LINK>
+  </P>
+  </SECTION>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chsolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chget</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>taucs</EM> by Sivan Toledo (see <LINK>taucs_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_chfact.xml b/scilab/modules/umfpack/help/en_US/taucs_chfact.xml
new file mode 100644 (file)
index 0000000..c80f20e
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_chfact  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="taucs_chfact"> cholesky factorisation of a sparse s.p.d. matrix  </SHORT_DESCRIPTION>
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>C_ptr = taucs_chfact(A)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a sparse real symetric positive definite (s.p.d.)  matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to the Cholesky factors (C,p : A(p,p)=CC&apos;)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    This function computes a Cholesky factorization of the sparse 
+    symetric positive definite (s.p.d.) matrix A and retrieves at the scilab 
+    level, a pointer (C_ptr) to an handle of the Cholesky 
+    factors (C,p) (the memory used for them is &quot;outside&quot; scilab
+    space).
+  </P>
+  <P>
+    If your matrix is s.p.d. this function must be used in 
+    place of <LINK>umf_lufact</LINK> or in place of the scilab function 
+    <LINK>chfact</LINK> for
+    a gain in speed (also as chfact uses the scilab memory for the factors
+    the user must set the stacksize with a large value because of the
+    fill-in occuring in computing the factor C which then may take more
+    memory than the initial matrix A).
+  </P>
+  <P>
+    When such a factorisation have 
+    been computed, a linear system  must be solved with <LINK>taucs_chsolve</LINK>. 
+    To free the memory used by the Cholesky factors, use <LINK>taucs_chdel</LINK>(C_ptr) ; 
+    to retrieve the Cholesky factors at the scilab level (for example to 
+    display their sparse patterns), use <LINK>taucs_chget</LINK> ; to get some informations 
+    (number of non zeros in C), use <LINK>taucs_chinfo</LINK>. To compute an approximation
+    of the condition number in norm 2 use <LINK>cond2sp</LINK>.
+  </P>
+  </DESCRIPTION>
+  <SECTION label='Remarks'>
+  <ITEMIZE>
+  <ITEM label='1.'>
+      taucs_chfact works only with the upper triangle of A, and the matrix A must
+      be provided either in its complete form (that is with the lower triangle also) or
+      only with its upper triangle ;
+  </ITEM>
+  <ITEM label='2.'>
+      currently taucs_chfact uses the genmmd (generalized minimum degree) algorithm of 
+      Liu to find in a first step the permutation p (so as to minimize the fill-in in 
+      the factorization) ; future versions will let the user choose his/her own reordering 
+      by providing a supplementary argument p.
+  </ITEM>
+  </ITEMIZE>
+  </SECTION>
+
+  <EXAMPLE><![CDATA[
+// Example #1 : a small linear test system 
+// whom solution must be [1;2;3;4;5]
+A = sparse( [ 2 -1  0  0  0;
+             -1  2 -1  0  0; 
+              0 -1  2 -1  0; 
+              0  0 -1  2 -1; 
+              0  0  0 -1  2] );
+b = [0 ; 0; 0; 0; 6];
+Cp = taucs_chfact(A);
+x = taucs_chsolve(Cp,b)
+// don't forget to clear memory with
+taucs_chdel(Cp)
+
+// Example #2 a real example
+// first load a sparse matrix
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"bcsstk24.rsa");
+// compute the factorisation
+Cp = taucs_chfact(A); 
+b = rand(size(A,1),1); // a random rhs
+// use taucs_chsolve for solving Ax=b
+x = taucs_chsolve(Cp,b);
+norm(A*x - b)
+// the same with one iterative refinement step
+x = taucs_chsolve(Cp,b,A);
+norm(A*x - b)
+// don't forget to clear memory
+taucs_chdel(Cp)
+   ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chsolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chdel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>cond2sp</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>taucs</EM> by Sivan Toledo (see <LINK>taucs_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_chget.xml b/scilab/modules/umfpack/help/en_US/taucs_chget.xml
new file mode 100644 (file)
index 0000000..fbd1393
--- /dev/null
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_chget  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+
+  <SHORT_DESCRIPTION name="taucs_chget"> retrieve the Cholesky factorization at the scilab level  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[Ct,p] = taucs_chget(C_ptr)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to the Cholesky factorization (C,p : A(p,p)=CC&apos;)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>Ct  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a scilab sparse matrix (you get the upper triangle i.e. Ct is equal to C&apos;) 
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>p  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : column vector storing the permutation
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function  may be used if you want  to plot  the sparse
+    pattern  of the Cholesky factorization (or if you  code something which
+    use the factors). Traditionnaly, the factorization is written :
+  </P>
+  <VERBATIM><![CDATA[
+    P A P' = C C'
+   ]]></VERBATIM>
+  <P>
+    with P&apos; the permutation matrix associated to the permutation p.
+    As we get the upper triangle Ct (= C&apos;), in scilab syntax we
+    can write :
+  </P>
+  <VERBATIM><![CDATA[
+    A(p,p) = Ct' * Ct
+   ]]></VERBATIM>
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+// Example #1 : a small linear test system 
+A = sparse( [ 2 -1  0  0  0;
+             -1  2 -1  0  0; 
+              0 -1  2 -1  0; 
+              0  0 -1  2 -1; 
+              0  0  0 -1  2] );
+Cp = taucs_chfact(A);
+[Ct, p] = taucs_chget(Cp);
+full(A(p,p) - Ct'*Ct)  // this must be near the null matrix
+taucs_chdel(Cp)
+
+// Example #2 a real example
+stacksize(3000000)  // the last PlotSparse need memory
+// first load a sparse matrix
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"bcsstk24.rsa");
+// compute the factorisation
+Cptr = taucs_chfact(A); 
+// retrieve the factor at scilab level
+[Ct, p] = taucs_chget(Cptr);
+// plot the initial matrix
+xset("window",0) ; xbasc()
+PlotSparse(A) ; xtitle("Initial matrix A (bcsstk24.rsa)")
+// plot the permuted matrix
+B = A(p,p);
+xset("window",1) ; xbasc()
+PlotSparse(B) ; xtitle("Permuted matrix B = A(p,p)")
+// plot the upper triangle Ct
+xset("window",2) ; xbasc()
+PlotSparse(Ct) ; xtitle("The pattern of Ct (A(p,p) = C*Ct)")
+// retrieve cnz
+[OK, n, cnz] = taucs_chinfo(Cptr)
+// cnz is superior to the realnumber of non zeros elements of C :
+cnz_exact = nnz(Ct)
+// don't forget to clear memory
+taucs_chdel(Cptr)
+ ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chsolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chdel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>cond2sp</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>taucs</EM> by Sivan Toledo (see <LINK>taucs_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_chinfo.xml b/scilab/modules/umfpack/help/en_US/taucs_chinfo.xml
new file mode 100644 (file)
index 0000000..47ef49c
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_chinfo  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>scispt  </DATE>
+  <SHORT_DESCRIPTION name="taucs_chinfo ">  get information on Cholesky factors  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[OK, n, cnz] = taucs_chinfo(C_ptr)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to a Cholesky factorization
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>OK  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a scalar boolean
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>n  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a scalar integer
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>cnz  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a scalar integer
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function may be used to know basic information about 
+    the Cholesky factor created with taucs_chfact :
+  </P>
+
+  <DESCRIPTION_ITEM> 
+    first <VERB>OK</VERB> is <TT>%t</TT> if <VERB>C_ptr</VERB> is a valid pointer to an Cholesky 
+    factorization (and <TT>%f</TT> else)
+  </DESCRIPTION_ITEM>
+
+  <DESCRIPTION_ITEM> 
+    if <VERB>OK</VERB> is <TT>%t</TT> then <VERB>n</VERB> and <VERB>cnz</VERB> are respectively the 
+    matrix order and the number of non zeros elements in the supernodal structure storing 
+    <VERB>C</VERB> ; if <VERB>OK</VERB> is <TT>%f</TT>, <VERB>n</VERB> and <VERB>cnz</VERB> are set 
+    to the void matrix [].
+  </DESCRIPTION_ITEM>
+  </DESCRIPTION>
+
+  <SECTION label='Details'>
+  <P>
+    Due to the supernodal structure used for <VERB>C</VERB>, <VERB>cnz</VERB> is larger 
+    than the exact number of non-zeros elements in <VERB>C</VERB> (and so this <VERB>cnz</VERB>
+    is a mesure of the memory used internally). To get the exact <VERB>cnz</VERB> you may retrieve 
+    the Cholesky factor with <LINK>taucs_chget</LINK> then apply 
+    the <LINK>nnz</LINK> scilab function (see the 2d example in <LINK>taucs_chget</LINK>).
+  </P>
+  </SECTION>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chsolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chdel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chget</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>taucs</EM> by Sivan Toledo (see <LINK>taucs_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_chsolve.xml b/scilab/modules/umfpack/help/en_US/taucs_chsolve.xml
new file mode 100644 (file)
index 0000000..aa5ee4c
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_chsolve  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+  <SHORT_DESCRIPTION name="taucs_chsolve"> solve a linear sparse (s.p.d.) system given the Cholesky factors  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[x] = taucs_chsolve(C_ptr, b [, A])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>C_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to a handle of the Cholesky factors (C,p with A(p,p)=CC&apos;)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>b  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a real column vector or a matrix (multiple rhs)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>x  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a real column vector or a matrix in case of multiple rhs ( x(:,i) is solution of A x(:,i) = b(:,i))
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) the real s.p.d. matrix A (to use for iterative refinement step)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function must be used in conjonction with <LINK>taucs_chfact</LINK> which
+    computes the Cholesky factorization of a sparse real s.p.d. matrix.
+    When the matrix <VERB>A</VERB> is provided, one iterative refinement
+    step is done (the refined solution is accepted if it improves the
+    2-norm of the residual <VERB>Ax-b</VERB>).
+  </P>
+  <P>
+    Like in <LINK>taucs_chfact</LINK> the matrix A may be provided either
+    in its complete form (that is with the lower triangle also) or
+    only with its upper triangle.
+   </P>
+   </DESCRIPTION>
+  <SECTION label='Examples'>
+  <P>
+    see the example section of <LINK>taucs_chfact</LINK>
+  </P>
+  </SECTION>
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>taucs_chfact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chdel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>taucs_chget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>cond2sp</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>taucs</EM> by Sivan Toledo (see <LINK>taucs_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/taucs_license.xml b/scilab/modules/umfpack/help/en_US/taucs_license.xml
new file mode 100644 (file)
index 0000000..e8ff424
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>taucs_license  </TITLE>
+  <TYPE>  </TYPE>
+  <DATE>scispt toolbox  </DATE>
+  <SHORT_DESCRIPTION name="taucs_license"> display the taucs license   </SHORT_DESCRIPTION>
+  <SECTION label='Copyright'>
+  <P>
+    TAUCS Version 1.0, November 29, 2001. Copyright (c) 2001 by Sivan Toledo, Tel-Aviv Univesity,
+    stoledo@tau.ac.il. All Rights Reserved. 
+  </P>
+  </SECTION>
+  <SECTION label='TAUCS License'>
+  <P>
+    Your use or distribution of TAUCS or any derivative code 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 this code or any derivative
+    code must cite the Copyright, this License, the Availability note, and &quot;Used by permission.&quot; 
+    If this code or any derivative code is accessible from within MATLAB, then typing 
+    &quot;help taucs&quot; must cite the Copyright, and &quot;type taucs&quot; must also cite this 
+    License and the Availability note. 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 is provided to you free of charge. 
+  </P>
+  </SECTION>
+  <SECTION label='Availability'>
+  <P>
+    <A href="http://www.tau.ac.il/~stoledo/taucs/">http://www.tau.ac.il/~stoledo/taucs/</A>
+  </P>
+  </SECTION>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_license.xml b/scilab/modules/umfpack/help/en_US/umf_license.xml
new file mode 100644 (file)
index 0000000..bed2943
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_license  </TITLE>
+  <TYPE>  </TYPE>
+  <DATE>scispt toolbox  </DATE>
+  <SHORT_DESCRIPTION name="umf_license"> display the umfpack license   </SHORT_DESCRIPTION>
+
+  <SECTION label='Copyright'>
+  <P>
+UMFPACK, Copyright (c) 1995-2006 by Timothy A.  Davis.  All Rights Reserved.
+UMFPACK is available under alternate licences; contact T. Davis for details.
+  </P>
+  </SECTION>
+
+  <SECTION label='UMFPACK License'>
+  <P>
+    Your use or distribution of UMFPACK or any modified version of
+    UMFPACK implies that you agree to this License.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+    USA
+
+    Permission is hereby granted to use or copy this program under the
+    terms of the GNU LGPL, provided that the Copyright, this License,
+    and the Availability of the original version is retained on all copies.
+    User documentation of any code that uses this code or any modified
+    version of this code must cite the Copyright, this License, the
+    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.
+  </P>
+  </SECTION>
+  <SECTION label='Availability'>
+  <P>
+    <A href="http://www.cise.ufl.edu/research/sparse">http://www.cise.ufl.edu/research/sparse</A>
+  </P>
+  </SECTION>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_ludel.xml b/scilab/modules/umfpack/help/en_US/umf_ludel.xml
new file mode 100644 (file)
index 0000000..44db271
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_ludel  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>scispt toolbox  </DATE>
+  <SHORT_DESCRIPTION name="umf_ludel"> utility function used with umf_lufact  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+     <CALLING_SEQUENCE_ITEM>umf_ludel(LU_ptr) or umf_ludel()  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+     <PARAM_INDENT>
+     <PARAM_ITEM>
+         <PARAM_NAME>LU_ptr  </PARAM_NAME>
+         <PARAM_DESCRIPTION>
+            : a pointer to an handle of umf lu factors (L,U,p,q,R)
+         </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function must be used in conjunction with <LINK>umf_lufact</LINK> and
+    <LINK>umf_lusolve</LINK>. It clears the internal memory space used to store 
+    the LU factors (got with umf_lufact). Use without argument 
+    it frees the memory for all the current scilab umfpack LU factors. 
+  </P>
+  </DESCRIPTION>
+
+  <SECTION label='Examples'>
+  <P>
+    see the example section of <LINK>umf_lufact</LINK> 
+  </P>
+  </SECTION>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umfpack</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lusolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luinfo</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_lufact.xml b/scilab/modules/umfpack/help/en_US/umf_lufact.xml
new file mode 100644 (file)
index 0000000..dda82bf
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_lufact  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="umf_lufact"> lu factorisation of a sparse matrix  </SHORT_DESCRIPTION>
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>LU_ptr = umf_lufact(A)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a sparse, real or complex, square or rectangular, matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>LU_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to umf lu factors (L,U,p,q,R)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    This function computes a LU factorisation of the sparse matrix A 
+    (<tt> P R^(-1) A Q = LU </tt>) and return at the scilab level, 
+    a pointer (LU_ptr) to an handle of the LU factors (L,U,p,q,R) 
+    (the memory used for them is &quot;outside&quot; scilab stack). 
+  </P>
+  <P>
+    This function must be used in place of <LINK>umfpack</LINK> if you
+    have multiple linear systems with the same matrix to solve when
+    the rhs are not known at the same time (for instance A x1 = b1
+    and A x2 = b2 but b2 depends on x1, etc...). 
+  </P>
+  <P>
+    When such a 
+    factorisation have been computed, a linear system must be solved
+    with umf_lusolve (in general x = umf_lusolve(LU_ptr, b) but others
+    options are possible, see <LINK>umf_lusolve</LINK>). To free the memory used
+    by the LU factors, use umf_ludel(LU_ptr) (<LINK>umf_ludel</LINK>); to retrieve the LU 
+    factors at the scilab level (for example to display their sparse 
+    patterns), use <LINK>umf_luget</LINK> ; to get some informations (number of
+    non zeros in L and U), use <LINK>umf_luinfo</LINK>. To compute an approximation
+    of the condition number use <LINK>condestsp</LINK>.
+  </P>
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+// this is the small linear test system from UMFPACK
+// whom solution must be [1;2;3;4;5]
+A = sparse( [ 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];
+Lup = umf_lufact(A);
+x = umf_lusolve(Lup,b)
+
+// solve now A'x=b
+x = umf_lusolve(Lup,b,"A''x=b")
+norm(A'*x - b)
+
+// don't forget to clear memory with
+umf_ludel(Lup)
+
+// a real (but small)  example
+// first load a sparse matrix
+[A] = ReadHBSparse(DIR_SCISPT_DEM+"arc130.rua");
+// compute the factorisation
+Lup = umf_lufact(A); 
+b = rand(size(A,1),1); // a random rhs
+// use umf_lusolve for solving Ax=b
+x = umf_lusolve(Lup,b);
+norm(A*x - b)
+
+// now the same thing with iterative refiment
+x = umf_lusolve(Lup,b,"Ax=b",A);
+norm(A*x - b)
+
+// solve now the system A'x=b
+x = umf_lusolve(Lup,b,"A''x=b");  // without refinement
+norm(A'*x - b)
+x = umf_lusolve(Lup,b,"A''x=b",A);  // with refinement
+norm(A'*x - b)
+
+// don't forget to clear memory
+umf_ludel(Lup)
+   ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umfpack</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lusolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_ludel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>condestsp</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon with contributions from Antonio Frasson</AUTHORS_ITEM>
+  </AUTHORS>
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_luget.xml b/scilab/modules/umfpack/help/en_US/umf_luget.xml
new file mode 100644 (file)
index 0000000..9fb1eaa
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_luget  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="umf_luget"> retrieve lu factors at the scilab level  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+      <CALLING_SEQUENCE_ITEM>[L,U,p,q,Rd] = umf_luget(LU_ptr)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+  
+  <PARAM>
+     <PARAM_INDENT>
+     <PARAM_ITEM>
+        <PARAM_NAME>LU_ptr  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : a pointer to umf lu factors (L,U,p,q,R)
+       </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>L,U  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : scilab sparse matrix
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>p,q  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : column vectors storing the permutations
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>Rd </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : vector storing the (row) scaling factors
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function  may be used if you want  to plot  the sparse
+    pattern  of the lu factors (or if you  code something which
+    use the lu factors). The factorization provided by umfpack is
+    of the form:
+  </P> 
+  <P>
+       P R^(-1) A Q = LU
+  </P> 
+  <P>
+    where P and Q are permutation matrices, R is a diagonal matrix (row scaling), L
+    a lower triangular matrix with a diagonal of 1, and U an upper triangular matrix.
+    The function provides the matrices L and U as Sparse scilab matrices but
+    P and Q are given as permutation vectors p and q (in fact p is the permutation 
+    associated to P&apos;) and Rd is the vector corresponding to the diagonal
+    of R.
+  </P>
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+// this is the test matrix from UMFPACK
+A = sparse( [ 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] );
+Lup = umf_lufact(A);
+[L,U,p,q,R] = umf_luget(Lup);
+B = A;
+for i=1:5, B(i,:) = B(i,:)/R(i); end // apply the row scaling
+B(p,q) - L*U  // must be a (quasi) nul matrix
+
+umf_ludel(Lup) // clear memory
+
+// the same with a complex matrix
+A = sparse( [ 2+%i  3+2*%i  0      0    0;
+              3-%i  0       4+%i   0    6-3*%i; 
+              0    -1+%i   -3+6*%i 2-%i 0; 
+              0     0       1-5*%i 0    0; 
+              0     4       2-%i   0    1] );
+Lup = umf_lufact(A);
+[L,U,p,q,R] = umf_luget(Lup);
+B = A;
+for i=1:5, B(i,:) = B(i,:)/R(i); end // apply the row scaling
+B(p,q) - L*U  // must be a (quasi) nul matrix
+
+umf_ludel(Lup) // clear memory
+
+ ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umfpack</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lusolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_ludel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luinfo</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_luinfo.xml b/scilab/modules/umfpack/help/en_US/umf_luinfo.xml
new file mode 100644 (file)
index 0000000..941ca41
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+
+<MAN>
+
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_luinfo  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE>  </DATE>
+  <SHORT_DESCRIPTION name="  umf_luinfo ">  get information on LU factors  </SHORT_DESCRIPTION>
+
+  <CALLING_SEQUENCE>
+     <CALLING_SEQUENCE_ITEM>[OK, nrow, ncol, lnz, unz, udiag_nz, it] = umf_luinfo(LU_ptr)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+
+  <PARAM>
+     <PARAM_INDENT>
+     <PARAM_ITEM>
+        <PARAM_NAME>LU_ptr  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : a pointer to umf lu factors (L,U,p,q, R)
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>OK  </PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : a scalar boolean
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     <PARAM_ITEM>
+        <PARAM_NAME>nrow, ncol, lnz, unz, udiag_nz, it</PARAM_NAME>
+        <PARAM_DESCRIPTION>
+           : scalars (integers)
+        </PARAM_DESCRIPTION> 
+     </PARAM_ITEM>
+     </PARAM_INDENT>
+  </PARAM>
+
+  <DESCRIPTION>
+  <P>
+    This function may be used to know basic information about 
+    LU factors created with umf_lufact :
+  </P>
+  <P>
+    first <VERB>OK</VERB> is %t if <VERB>LU_ptr</VERB> is a valid pointer to an umfpack 
+    LU numeric handle (and %f else)
+  </P>
+  <P>
+    if <VERB>OK</VERB> is %t then: 
+  </P>
+    <ITEMIZE>
+      <ITEM label="nrow, ncol">
+        <SP>: are the matrix size (L is <TT>nrow x n</TT> and U is  <TT>n x ncol</TT>
+              where <TT>n = min(nrow,ncol)</TT>
+        </SP>
+      </ITEM>
+      <ITEM label="lnz, unz">
+        <SP>: are the number of non zeros elements in L and in U;
+        </SP>
+      </ITEM>
+      <ITEM label="udiag_nz">
+        <SP>: are the number of non zeros elements on the diagonal of U; if the matrix
+              is square (<TT>nrow = ncol = n)</TT> then it is not inversible if 
+              udiag_nz &lt; n (more precisely it appears to be numericaly not
+              inversible through the LU factorization).
+        </SP>
+      </ITEM>
+      <ITEM label="it">
+        <SP>: 0 if the factors are real and 1 if they are complex.
+        </SP>
+      </ITEM>
+    </ITEMIZE>
+    <P>
+    if OK is %f then all the others outputs are set to the empty matrix [].
+    </P>
+  </DESCRIPTION>
+
+  <EXAMPLE><![CDATA[
+// this is the test matrix from UMFPACK
+A = sparse( [ 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] );
+Lup = umf_lufact(A);
+[OK, nrow, ncol, lnz, unz, udiag_nz, it] = umf_luinfo(Lup)  // OK must be %t, nrow=ncol = 5, 
+[L,U,p,q,R] = umf_luget(Lup);
+nnz(L)  // must be equal to lnz
+nnz(U)  // must be equal to unz
+umf_ludel(Lup) // clear memory
+   ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umfpack</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lusolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_ludel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luget</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umf_lusolve.xml b/scilab/modules/umfpack/help/en_US/umf_lusolve.xml
new file mode 100644 (file)
index 0000000..c9cfc82
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umf_lusolve  </TITLE>
+  <TYPE>Scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="umf_lusolve"> solve a linear sparse system given the LU factors  </SHORT_DESCRIPTION>
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>[x] = umf_lusolve(LU_ptr, b [, st, A])  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>LU_ptr  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a pointer to umf lu factors (L,U,p,q,R) 
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>b  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a real or complex column vector or a matrix (multiple rhs)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>st  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) a string &quot;Ax=b&quot; (default) or &quot;Ax&apos;=b&quot; 
+      (to be written &quot;Ax&apos;&apos;=b&quot;  in scilab langage: a quote in a string
+       must be doubled !)
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : (optional) the sparse square matrix corresponding to the LU factors (LU_ptr must be got with LU_ptr = umf_lufact(A))
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>x  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a column vector or a matrix in case of multiple rhs ( x(:,i) is solution of A x(:,i) = b(:,i) or A&apos;x(:,i) = b(:,i) )
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    This function must be used in conjonction with <LINK>umf_lufact</LINK> which
+    computes the LU factors of a sparse matrix. The optional
+    <VERB>st</VERB> argument lets us choose between the solving of Ax=b (general case)
+    or of A&apos;x=b (sometimes useful). If you give the 4th argument then
+    iterative refinement will be also proceceed (as in umfpack) to
+    give a better numerical solution. 
+  </P>
+  </DESCRIPTION>
+  <SECTION label='Examples'>
+  <P>
+    see the example section of <LINK>umf_lufact</LINK>
+  </P>
+  </SECTION>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umfpack</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luget</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_ludel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luinfo</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon with contributions from Antonio Frasson</AUTHORS_ITEM>
+  </AUTHORS>
+
+</MAN>
diff --git a/scilab/modules/umfpack/help/en_US/umfpack.xml b/scilab/modules/umfpack/help/en_US/umfpack.xml
new file mode 100644 (file)
index 0000000..4f671d0
--- /dev/null
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> 
+<!DOCTYPE MAN SYSTEM "manrev.dtd">
+<MAN>
+  <LANGUAGE>eng</LANGUAGE>
+  <TITLE>umfpack  </TITLE>
+  <TYPE>scilab function - scispt toolbox</TYPE>
+  <DATE></DATE>
+  <SHORT_DESCRIPTION name="umfpack"> solve sparse linear system  </SHORT_DESCRIPTION>
+  <CALLING_SEQUENCE>
+  <CALLING_SEQUENCE_ITEM>x = umfpack(A,&quot;\&quot;,b)  </CALLING_SEQUENCE_ITEM>
+  <CALLING_SEQUENCE_ITEM>x = umfpack(b,&quot;/&quot;,A)  </CALLING_SEQUENCE_ITEM>
+  </CALLING_SEQUENCE>
+  <PARAM>
+ <PARAM_INDENT>
+  <PARAM_ITEM>
+  <PARAM_NAME>A  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : a sparse (real or complex) square matrix n x n
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>b  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : in the first case, a column vector (n x 1) or a n x m matrix ;    
+      in the second case, a row vector (1 x n) or a m x n matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>x  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : in the first case , a column vector (n x 1) or a n x m matrix ;    
+      in the second case, a row vector (1 x n) or a m x n matrix
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+  <PARAM_ITEM>
+  <PARAM_NAME>2d arg  </PARAM_NAME>
+  <PARAM_DESCRIPTION>
+    : string specifier &quot;\&quot; or &quot;/&quot;
+  </PARAM_DESCRIPTION> 
+  </PARAM_ITEM>
+ </PARAM_INDENT>
+  </PARAM>
+  <DESCRIPTION>
+  <P>
+    This function is intended to work like the classic operators \ and / 
+    x = A\b  and x = b/A) i.e. it solves a linear system Ax = b or xA = b 
+    with a sparse square (says n x n) real or complex matrix and with a compatible
+    rhs b : n x m in the first case and m x n in the second. 
+  </P>
+  </DESCRIPTION>
+  <SECTION label='Details'>
+  <P>
+    First an LU factorisation of the matrix is computed (<TT> P R^(-1) A Q = LU </TT>
+    where P and Q are permutation matrices, R is a diagonal matrix (row scaling), L
+    a lower triangular matrix with a diagonal of 1, and U an upper triangular matrix) 
+    then a first solution is computed with forward/backward subtitutions ; 
+    finaly the solution is improved  by iterative refinement.
+  </P>
+  </SECTION>
+
+  <EXAMPLE><![CDATA[
+// this is the small linear test system from UMFPACK
+// whom solution must be [1;2;3;4;5]
+A = sparse( [ 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];
+x = umfpack(A,"\",b)
+
+// test the other form x A = b
+b = [8  20  13  6  17];
+x = umfpack(b,"/",A)   // solution must be [1 2 3 4 5]
+
+// test multiple rhs
+b = rand(5,3);
+x = umfpack(A,"\",b)
+norm(A*x - b)
+
+// test multiple rhs for x A = b
+b = rand(3,5);
+x = umfpack(b,"/",A)
+norm(x*A - b)
+
+// solve a complex system
+A = sparse( [ 2+%i  3+2*%i  0      0    0;
+              3-%i  0       4+%i   0    6-3*%i; 
+              0    -1+%i   -3+6*%i 2-%i 0; 
+              0     0       1-5*%i 0    0; 
+              0     4       2-%i   0    1] );
+b = [ 3+13*%i ; 58+32*%i ; -19+13*%i ; 18-12*%i ; 22+16*%i ];
+x = umfpack(A,"\",b)  // x must be [1+i; 2+2i; 3+3i; 4 + 4i; 5+5i]
+   ]]></EXAMPLE>
+
+  <SEE_ALSO>
+    <SEE_ALSO_ITEM> <LINK>umf_lufact</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_lusolve</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_ludel</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luinfo</LINK> </SEE_ALSO_ITEM>     
+    <SEE_ALSO_ITEM> <LINK>umf_luget</LINK> </SEE_ALSO_ITEM>
+  </SEE_ALSO>
+
+  <AUTHORS>
+      <AUTHORS_ITEM><EM>umfpack</EM> by Timothy A. Davis (see <LINK>umf_license</LINK>)</AUTHORS_ITEM>
+      <AUTHORS_ITEM><EM>scilab interface</EM> by Bruno Pincon with contributions from Antonio Frasson</AUTHORS_ITEM>
+  </AUTHORS>
+</MAN>
diff --git a/scilab/modules/umfpack/includes/gw_umfpack.h b/scilab/modules/umfpack/includes/gw_umfpack.h
new file mode 100644 (file)
index 0000000..cccb389
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2006 - INRIA - Allan CORNET
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef __GW_UMFPACK__
+#define __GW_UMFPACK__
+/*--------------------------------------------------------------------------*/
+#include "machine.h"
+/*--------------------------------------------------------------------------*/
+int gw_umfpack(void);
+int sci_umfpack(char* fname, unsigned long l);
+int sci_umf_lufact(char* fname, unsigned long l);
+int sci_umf_lusolve(char* fname, unsigned long l);
+int sci_umf_ludel(char* fname, unsigned long l);
+int sci_umf_luinfo(char* fname, unsigned long l);
+int sci_umf_luget(char* fname, unsigned long l);
+int sci_taucs_chfact(char* fname, unsigned long l);
+int sci_taucs_chsolve(char* fname, unsigned long l);
+int sci_taucs_chdel(char* fname, unsigned long l);
+int sci_taucs_chinfo(char* fname, unsigned long l);
+int sci_taucs_chget(char* fname, unsigned long l);
+int sci_res_with_prec(char* fname, unsigned long l);
+/*--------------------------------------------------------------------------*/
+#endif /*  __GW_UMFPACK__ */
+/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/umfpack/license.txt b/scilab/modules/umfpack/license.txt
new file mode 100644 (file)
index 0000000..7fb87fa
--- /dev/null
@@ -0,0 +1,41 @@
+
+ Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ <bruno.pincon@iecn.u-nancy.fr>
+ some contributions from Antonio Manoel Ferreria Frasson, 
+ Universidade Federal do Espírito Santo, Brazil. 
+ <frasson@ele.ufes.br> (file intscispt.c)
+
+ PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ plus some sparse utility scilab macros.
+
+ This software is governed by the CeCILL license under French law and
+ abiding by the rules of distribution of free software.  You can  use,
+ modify and/or redistribute the software under the terms of the CeCILL
+ license as circulated by CEA, CNRS and INRIA at the following URL
+ "http://www.cecill.info".
+
+ As a counterpart to the access to the source code and  rights to copy,
+ modify and redistribute granted by the license, users are provided only
+ with a limited warranty  and the software's author,  the holder of the
+ economic rights,  and the successive licensors  have only  limited
+ liability.
+
+ In this respect, the user's attention is drawn to the risks associated
+ with loading,  using,  modifying and/or developing or reproducing the
+ software by the user in light of its specific status of free software,
+ that may mean  that it is complicated to manipulate,  and  that  also
+ therefore means  that it is reserved for developers  and  experienced
+ professionals having in-depth computer knowledge. Users are therefore
+ encouraged to load and test the software's suitability as regards their
+ requirements in conditions enabling the security of their systems and/or
+ data to be ensured and,  more generally, to use and operate it in the
+ same conditions as regards security.
+
+ The fact that you are presently reading this means that you have had
+ knowledge of the CeCILL license and that you accept its terms.
+
+Availability:
+
+    http://www.iecn.u-nancy.fr/~pincon/scilab/scilab.html
diff --git a/scilab/modules/umfpack/loader.sce b/scilab/modules/umfpack/loader.sce
new file mode 100644 (file)
index 0000000..51e3236
--- /dev/null
@@ -0,0 +1,46 @@
+path=get_absolute_file_path('loader.sce');
+
+exec(path+"/loader_inc.sce");
+
+functions = [ "umfpack"      ;
+              "umf_lufact"   ;
+              "umf_lusolve"  ;
+              "umf_ludel"    ;
+              "umf_luinfo"   ;
+              "umf_luget"    ;
+              "taucs_chfact" ;
+              "taucs_chsolve";
+              "taucs_chdel"  ;
+              "taucs_chinfo" ;
+              "taucs_chget"  ;
+              "res_with_prec"] ;
+
+
+
+entrypoint = "scispt" ;
+
+addinter( objects , entrypoint , functions )
+num_interface = floor(funptr("umfpack")/100);
+intppty(num_interface)
+
+
+[units,typs,nams]=file();
+for k=size(nams,'*'):-1:1 
+  l=strindex(nams(k),'loader.sce');
+  if l<>[] then
+    DIR_SCISPT = part(nams(k),1:l($)-1);
+    break
+  end
+end
+
+DIR_SCISPT_DEM = DIR_SCISPT + "examples/";
+
+add_help_chapter("scispt : Interface on umfpack & taucs snmf plus sparse utilities",...
+                 path+"manxml");
+
+clear units typs k l entrypoint num_interface nams path
+
+getf(DIR_SCISPT+"sparse_util.sci")
+
+write(%io(2),[" scispt toolbox loaded : enter scisptdemo() for a demo ";...
+              "                         (stacksize must be >= 3000000)"]);
diff --git a/scilab/modules/umfpack/macros/buildmacros.bat b/scilab/modules/umfpack/macros/buildmacros.bat
new file mode 100644 (file)
index 0000000..c4e35ec
--- /dev/null
@@ -0,0 +1 @@
+@..\..\..\bin\scilex -nwni -ns -e exec('buildmacros.sce');quit;
\ No newline at end of file
diff --git a/scilab/modules/umfpack/macros/buildmacros.sce b/scilab/modules/umfpack/macros/buildmacros.sce
new file mode 100644 (file)
index 0000000..002a0a5
--- /dev/null
@@ -0,0 +1,15 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2005 - INRIA - Allan CORNET
+// 
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution.  The terms
+// are also available at    
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+
+if (isdef('genlib') == %f) then
+  exec(SCI+'/modules/functions/scripts/buildmacros/loadgenlib.sce');
+end
+//------------------------------------
+genlib('umfpacklib','SCI/modules/umfpack/macros',%f,%t);
+//------------------------------------
diff --git a/scilab/modules/umfpack/macros/cleanmacros.bat b/scilab/modules/umfpack/macros/cleanmacros.bat
new file mode 100644 (file)
index 0000000..5079dfd
--- /dev/null
@@ -0,0 +1,3 @@
+@del *.bin 2>NUL
+@del lib 2>NUL
+@del names 2>NUL
\ No newline at end of file
diff --git a/scilab/modules/umfpack/macros/sparse_util.sci b/scilab/modules/umfpack/macros/sparse_util.sci
new file mode 100644 (file)
index 0000000..70508ea
--- /dev/null
@@ -0,0 +1,716 @@
+//   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+//   <bruno.pincon@iecn.u-nancy.fr>
+// 
+// This set of scilab 's macros provide a few sparse utilities.
+// 
+// This software is governed by the CeCILL license under French law and
+// abiding by the rules of distribution of free software.  You can  use, 
+// modify and/ or redistribute the software under the terms of the CeCILL
+// license as circulated by CEA, CNRS and INRIA at the following URL
+// "http://www.cecill.info". 
+// 
+// As a counterpart to the access to the source code and  rights to copy,
+// modify and redistribute granted by the license, users are provided only
+// with a limited warranty  and the software's author,  the holder of the
+// economic rights,  and the successive licensors  have only  limited
+// liability. 
+// 
+// In this respect, the user's attention is drawn to the risks associated
+// with loading,  using,  modifying and/or developing or reproducing the
+// software by the user in light of its specific status of free software,
+// that may mean  that it is complicated to manipulate,  and  that  also
+// therefore means  that it is reserved for developers  and  experienced
+// professionals having in-depth computer knowledge. Users are therefore
+// encouraged to load and test the software's suitability as regards their
+// requirements in conditions enabling the security of their systems and/or 
+// data to be ensured and,  more generally, to use and operate it in the 
+// same conditions as regards security. 
+// 
+// The fact that you are presently reading this means that you have had
+// knowledge of the CeCILL license and that you accept its terms.
+
+function [K1] = condestsp(A, arg2, arg3)
+  //                     (A, LUp  , t)
+  //  PURPOSE
+  //     Give an estimate of the 1-norm condition number of 
+  //     the sparse matrix A by Algorithm 2.4 appearing in :
+  //
+  //      "A block algorithm for matrix 1-norm estimation
+  //       with an application to 1-norm pseudospectra"
+  //       Nicholas J. Higham and Francoise Tisseur
+  //       Siam J. Matrix Anal. Appl., vol 21, No 4, pp 1185-1201
+  //
+  //  PARAMETERS
+  //     A   : a square sparse matrix
+  //  
+  //     LUp : (optional) a pointer to (umf) LU factors of A
+  //           gotten by a call to umf_lufact ; if you
+  //           have already computed the LU (= PAQ) factors
+  //           it is recommanded to give this optional
+  //           parameter (as the factorization may be time
+  //           consuming)
+  //
+  //     t   : (optional) a positive integer
+  //
+  //     K1  : estimated 1-norm condition number of A
+  //
+  //  POSSIBLE CALLING SEQUENCES
+  //     [K1, [x]] = condestsp(A, LUp, t)
+  //     [K1, [x]] = condestsp(A, LUp)
+  //     [K1, [x]] = condestsp(A, t)
+  //     [K1, [x]] = condestsp(A)
+  //
+  //  AUTHOR
+  //     Bruno Pincon <Bruno.Pincon@iecn.u-nancy.fr> but nearly
+  //     close to the given algorithm as this one is written in
+  //     a "matlab-like" language
+  //
+  [lhs, rhs] = argn()
+
+  if rhs<1 | rhs>3 | lhs > 2 then
+     error(msprintf(gettext("%s: Wrong number of input arguments.\n"),"condestsp"))
+  end
+  
+  if typeof(A) ~= "sparse"  then
+     error(msprintf(gettext("%s: Wrong type for first input argument: Square sparse matrix expected.\n"),"condestsp"))
+  else
+     [n,m] = size(A)
+     if n~=m  then
+        error(msprintf(gettext("%s: Wrong size for first input argument: Square sparse matrix expected.\n"),"condestsp"))
+     end
+  end
+    
+  factor_inside = %f  // when LUp is given (after the following tests
+                      // this var is set to %t if the factorisation 
+                     // is computed inside this function)
+  if rhs == 1 then
+     LUp = umf_lufact(A) ; factor_inside = %t ; t = 2
+  elseif rhs == 2 then
+     if typeof(arg2) == "pointer" then
+       LUp = arg2 ; t = 2
+     else
+       t = arg2 ; LUp = umf_lufact(A) ; factor_inside = %t
+     end
+  elseif rhs == 3 then
+     LUp = arg2 ; t = arg3
+  end
+
+  // verify if LUp and T are valid !
+  [OK, nrow, ncol] = umf_luinfo(LUp)
+  if ~OK then
+     error(" the LU pointer is not valid")
+  elseif n ~= nrow | nrow ~= ncol
+     error(" the matrix and the LU factors have not the same dimension !")
+  end
+     
+  if int(t)~=t | length(t)~=1 | or(t < 1) then
+     error(" invalid type and/or size and/or value for the second arg")
+  end   
+
+  // go on
+  
+  // the algo need a fortran-like sign function (with sign(0) = 1
+  // and not with sign(0)=0 as the scilab native 's one)
+  deff("s = fsign(x)", "s = sign(x) ; s(find(s == 0)) = 1")
+  
+  
+  // Part 1 : computes ||A||_1
+  norm1_A = norm(A,1)
+  
+  // Part 2 : computes (estimates) || A^(-1) ||_1
+  
+  // 1/ choose starting matrix X (n,t)
+  X = ones(n,t)
+  X(:,2:t) = fsign(rand(n,t-1)-0.5)
+  X = test_on_columns(X) / n
+  Y = zeros(X) ; Z = zeros(X)
+  ind_hist = []
+  est_old = 0
+  ind = zeros(n,1)
+  S = zeros(n,t)
+  k = 1 ; itmax = 5
+  
+  while %t
+     // solve Y = A^(-1) X <=> A Y = X
+     for j=1:t
+       Y(:,j) = umf_lusolve(LUp, X(:,j))
+     end
+     [est, ind_est] = max( sum(abs(Y),"r") )
+     if est > est_old  |  k==2 then
+       ind_best = ind_est
+       w = Y(:,ind_best)
+     end
+     
+     if k >= 2  &  est <= est_old then, est = est_old, break, end
+     est_old = est ; S_old = S
+     
+     if k > itmax then , break , end
+     
+     S = fsign(Y)
+     
+     // if every column of S is // to a column of S_old then it is finish
+     if and( abs(S_old'*S) == n ) then , break , end
+
+     if t > 1 then
+       // s'assurer qu'aucune colonne de S n'est // a une autre
+       // ou a une colonne de S_old en remplacant des colonnes par rand{-1,1}
+       S = test_on_columns(S,S_old)
+     end
+     
+     // calcul de Z = A' S
+     for j=1:t
+       Z(:,j) = umf_lusolve(LUp, S(:,j),"A''x=b")
+     end
+
+     [h,ind] = sort(max(abs(Z),"c"))
+     if k >= 2  then
+       if h(1) == h(ind_best) then , break , end
+     end
+
+     if (t > 1) & (k > 1) then
+       j = 1
+       for l=1:t
+          while %t
+             if find(ind_hist == ind(j)) == [] then  
+                ind(l) = ind(j)
+                j = j + 1
+                break
+             else
+                j = j + 1
+             end
+          end
+        end
+     end
+     X = zeros(n,t)
+     for l = 1:t
+        X(ind(l),l) = 1
+     end
+     ind_hist = [ind_hist ; ind(1:t)]
+     k = k + 1
+  end
+
+  K1 = est * norm1_A
+  if factor_inside then
+     umf_ludel(LUp)
+  end
+  
+endfunction
+
+
+function [X] = test_on_columns(X,Xold)
+   // 
+   //  X and Xold are (n,t) matrix , Xold being an optional argument
+   //  verify and force all columns of the new X to be non paralleles
+   //  and also to be non paralleles to the columns of Xold if Xold
+   //  is given
+   //  2 columns j1 and j2 are // if  | Cj1'*Cj2 | = n because
+   //  all elements are in {+1,-1} 
+   //
+   [lhs,rhs] = argn()
+   [n,t] = size(X)
+   if rhs == 1 then
+      for j=2:t
+        while %t
+           res_test = abs(X(:,j)'*X(:,1:j-1))
+           if or(res_test == n) then
+              X(:,j) = fsign(rand(n,1)-0.5)
+           else
+              break
+           end
+        end
+      end
+   else   // rhs = 2
+      for j=1:t
+        while %t
+           res_test = abs([X(:,j)'*Xold  X(:,j)'*X(:,1:j-1)])
+           if or(res_test == n) then
+              X(:,j) = fsign(rand(n,1)-0.5)
+           else
+              break
+           end
+        end
+      end
+   end  
+endfunction
+
+function [A,description,ref,mtype] = ReadHBSparse(filename)
+   //
+   //  PURPOSE
+   //     An utility to read the Harwell-Boeing sparse matrix 
+   //     format. Currently don't work for unassembled matrix.
+   //     Also possible rhs presents in the file are not red.
+   //
+   //  ARGUMENTS
+   //     filename   : (optional) a string given the filename 
+   //                  (eventually preceeding by the path), if 
+   //                  filename is not given then the function 
+   //                  use xgetfile to get filename
+   //     A          : the sparse matrix
+   //     description: a string given some information about the
+   //                  matrix
+   //     ref        : a string given the reference of the matrix
+   //     mtype      : a string given the "type" of the matrix
+   //                  
+   //  COMMENTS 
+   //     Generally the file name is of the form ref.matrixtype  
+   //     where mtype is a 3 letters word given some 
+   //     informations (already inside the file) on the matrix : 
+   //        1st letter : R|C|P   for real|complex|pattern (no values given)
+   //        2d  letter : S|H|Z|U for symetric|hermitian|skew symetric|unsymetric
+   //        3d  letter : A|E     for assembled|unassembled matrix
+   //                             (case E is not treated by this func)
+   //  REFERENCES
+   //     Users' Guide for the Harwell-Boeing Sparse Matrix Collection
+   //     Iain S. Duff, Roger G. Grimes, John G. Lewis
+   //
+   //     You may found this guide and numerous sparse
+   //     matrices (in the Harwell-Boeing format) at the
+   //     University of Florida Sparse Matrix Collection
+   //     web site :
+   //
+   //        http://www.cise.ufl.edu/research/sparse/matrices/
+   //
+   //     maintained by Tim Davis <http://www.cise.ufl.edu/~davis/>
+   //
+   //  AUTHOR
+   //     Bruno Pincon <Bruno.Pincon@iecn.u-nancy.fr>
+   //
+   [lhs, rhs] = argn()
+
+   if rhs == 0 then
+      filename = xgetfile("*.[rc][shzu]a", title=["Choose a sparse matrix"; ...
+                                                 "   then click on OK   "])
+   elseif rhs == 1 then
+      if typeof(filename) ~= "string" then
+        error(" the argument must be a string")
+      end
+   else
+      error(" bad number of arguments")
+   end
+   
+   unit = file("open", filename, "old")
+
+   // 1)  read the 4 or 5 header lines
+   
+   line1 = read(unit,1,1,"(A)")
+   ref = stripblanks(part(line1,73:80))
+   ref = convstr(ref)
+   description = stripblanks(part(line1,1:72))
+   description = convstr(description)
+
+   // normaly the line2 contains 5 numbers and if the last is zero
+   // the file contains no rhs but in this case in some HB file
+   // we have only 4 numbers. So the following is a trick to take
+   // into account this pb
+   line2 = read(unit,1,1,"(A)") // read the line 2 as a string
+   line2 = evstr(line2)         // this string is then transform is a row vector
+   if length(line2) < 5 then
+      Rhs_in_file = %f
+   else
+      if line2(5) == 0 then
+        Rhs_in_file = %f
+      else
+        Rhs_in_file = %t
+        warning(" The file contains a rhs but it will not be read !")
+      end
+   end
+   
+   line3 = read(unit,1,1,"(A)")
+   mtype = convstr(part(line3,1:3))
+   
+   Dimensions = evstr(part(line3,4:80))
+   if part(mtype,3)=="e" then
+      error("currently don''t read unassembled (elemental) sparse matrix")
+   end
+   TypeValues = part(mtype,1) // r for real, c for complex, p for pattern
+                                  
+   m     = Dimensions(1)   // number of rows
+   n     = Dimensions(2)   // number of columns 
+   nb_nz = Dimensions(3)   // number of non zeros
+   
+   
+   line4 = read(unit,1,1,"(A)")  // these are the formats
+   form1 = stripblanks(part(line4,1:16))
+   form2 = stripblanks(part(line4,17:32))
+   form3 = stripblanks(part(line4,33:52))
+   // for the 2 first replace Ix by Fx.0 : the read func uses only float formats
+   form1 = replace_Ix_by_Fx(form1)
+   form2 = replace_Ix_by_Fx(form2)
+   
+   if Rhs_in_file then  // a 5 header line to read (but ignored)
+      line5 = read(unit,1,1,"(A)")  
+   end
+   
+   
+   // 2) read the datas
+   
+   col_ptr = read(unit,1,n+1,form1)
+   ind_row = read(unit,1,nb_nz,form2)
+   select TypeValues
+   case "p" // values given 
+      warning(" No values for this matrix (only non zero pattern) : put some 1")
+      val = ones(1,nb_nz)
+   case "r" // values are real
+      val = read(unit,1,nb_nz,form3)
+   case "c" // values are complex
+      valc = matrix( read(unit,1,2*nb_nz,form3) , 2, nb_nz )
+      val = valc(1,:) + %i*(valc(2,:))
+      clear valc
+   end
+
+   file("close", unit)
+   
+   // 3) form the sparse scilab matrix
+
+   // 3-1/ form the basic matrix
+   ind_col = ones(1,nb_nz)
+   for i = 2:n
+      ind_col(col_ptr(i):col_ptr(i+1)-1) = i
+   end
+   
+   A = sparse([ind_row' ind_col'], val, [m n])
+   clear ind_row ind_col col_ptr val  // to regain some memory
+   
+   // 3-2/ complete the matrix depending the symetry property
+   MatrixSymetry = part(mtype,2)
+   select MatrixSymetry
+   case "s"  // (real or complex) symmetric matrix 
+      A = A - diag(diag(A)) + A.'
+   case "h"  // complex hermitian matrix
+      A = A - diag(diag(A)) + A'
+   case "z"  // skew symmetric matrix
+      A = A - A'
+   end
+   
+endfunction
+
+function [form_out] = replace_Ix_by_Fx(form_in)
+   //
+   //  replace Ix by Fx.0 (assuming that x is 1 char max)
+   //  (utility function used by ReadHBSparse)
+   //
+   n = length(form_in)
+   indI = strindex(form_in,"I")
+   if indI== [] then
+      indI = strindex(form_in,"i")
+   end 
+   form_out = part(form_in,1:indI-1)+"F"+part(form_in,indI+1) ...
+             +".0"+part(form_in,indI+2:n)
+endfunction
+
+function [] = scisptdemo()
+   // demo pour l'interface umf
+   mode(-1)
+   st = stacksize();
+   if st(1) < 3000000 then
+      x_message([" For this demo the current stack size is not enought ";
+                " enter the following at the scilab prompt :          ";
+                "                                                     ";
+                "              stacksize(3000000);                    ";
+                "                                                     ";
+                 "           then re enter scisptdemo()                ";
+                "                                                     ";
+                "               CLICK TO  CONTINUE                    "]);
+      return
+   end
+
+   oldln = lines();
+   lines(0)
+
+   deff('[]=demoex(num)','exec(scisptdemolist(num,2),-1)')
+   a = gda();
+   a.title.font_size = 3;
+   a;title.font_style = 6;
+   
+
+   scisptdemolist = ["how to use this stuff"           , DIR_SCISPT_DEM+"scisptdem1.dem";
+                     "display a speed comparison test" , DIR_SCISPT_DEM+"scisptdem2.dem";
+                    "small tests for condestsp"       , DIR_SCISPT_DEM+"scisptdem3.dem"];
+   while %t
+      num=x_choose(scisptdemolist(:,1), "Click to choose a demo");
+      if num==0 then 
+        lines(oldln(1)) , break
+      else
+        demoex(num)
+      end
+   end
+   
+   sda()
+endfunction
+
+function [] = PlotSparse(A, style)
+   //
+   //  PURPOSE
+   //     plot the pattern of non nul elements of a sparse matrix
+   //
+   //  ARGUMENTS
+   //     A     : a sparse matrix
+   //     style : (optional) a string given the color and/or the
+   //             marker type of the form "[color][mark]" where
+   //             color may be a number referring the color you
+   //             want to use (in the current colormap). If you
+   //             use the std colormap then color may be one of 
+   //             the following letters :
+   //               k  for black       b  for blue
+   //               r  for red         g  for green
+   //               c  for cyan        m  for magenta
+   //               y  for yellow      t  for turquoise
+   //               G  a dark green
+   //
+   //             mark must be one of the following :
+   //               .  point             +  plus 
+   //               x  cross             *  circled plus 
+   //               D  filled diamond    d  diamond
+   //               ^  upper triangle    v  down triangle
+   //               o  circle
+   //
+   //             by default you have "b." (in fact the 2d color) and 
+   //             this is also forced in case of error. 
+   //
+   //  COMMENTS
+   //     for "big" matrix use essentially point (.) as marker
+   //     
+   //
+   //  AUTHOR
+   //     Bruno Pincon <Bruno.Pincon@iecn.u-nancy.fr>
+   //
+   default_markColor = 2  // blue in std colormap
+   default_markId    = 0  // a point .
+   
+   [lhs, rhs] = argn()
+   
+   if ( rhs<1 | rhs>2 ) then
+      error(" Bad number of arguments")
+   end
+   
+   if (typeof(A) == "sparse") then
+      [m, n] = size(A)
+      nel = nnz(A)
+   else   
+      error(" Arg #1 must be a sparse matrix")
+   end
+   
+   if rhs == 1 then
+      markColor = default_markColor
+      markId = default_markId
+   elseif typeof(style) ~= "string" then
+      error(" Arg #2 must be a string")
+   else
+      [ markColor , markId ] = ana_style(style)
+   end
+   
+   drawlater()
+   plot2d(%inf, %inf, strf="030", rect=[-1,-1,n+1,m+1])
+   
+   // the tics
+   x = [0 n/2 n]
+   dx = -0.02*n ; dy = -0.05*m 
+   xstring(x(1)+dx, dy, "1")
+   h1 = gce();
+   xstring(x(2)+dx, dy, string(floor(x(2))))
+   h2 = gce();
+   xstring(x(3)+dx, dy, string(x(3)))
+   h3 = gce();
+   
+   y = [0 m/2 m]
+   dx = 0.02*m ; dy = 0
+   xstring(m+dx, y(1), string(y(3)))
+   h4 = gce();
+   xstring(m+dx, y(2), string(floor(y(2))))
+   h5 = gce();
+   xstring(m+dx, y(3), "1")
+   h6 = gce();
+
+   // information about nnz
+   xstring(0, -0.1*m, "nnz = "+string(nnz(A)))
+   h7 = gce();
+     
+   glue([h1,h2,h3,h4,h5,h6,h7])
+   
+   // display
+   ij = spget(A)
+   xp = ij(:,2) - 0.5
+   yp = m+0.5 - ij(:,1)
+   plot2d(xp,yp,-markId,strf="000")
+   e = gce();
+   e.children(1).mark_foreground = markColor;
+
+   // the rectangle
+   xrect(0,m,n,m)
+   drawnow()
+   
+endfunction
+
+function [col, mark] = ana_style(style)
+  //
+  //  an utility for PlotSparse
+  //
+  tab_col  = ["k" "b" "r" "g" "c" "m" "y" "t" "G"]
+  num_col  = [ 1   2   5   3   4   6  32  16  13 ]
+  tab_mark = ["." "+" "x" "*" "D" "d" "^" "v" "o"]
+  num_mark = [ 0   1   2   3   4   5   6   7   9 ]
+
+  deff("[b] = is_digit(c)",[ "code = str2code(c)";...
+                            "b = 0 <= code & code <= 9" ])
+  n = length(style)
+  if n >= 1 then
+     c = part(style,1) ; ic = 1
+     ind = grep(tab_col, c)
+     if ind == [] then
+       if is_digit(c) then
+          while %t
+             ic = ic+1
+             if ic <= n then
+                c = part(style,ic)
+                if ~is_digit(c) then , break, end
+             else
+                break
+             end
+          end
+          col = evstr(part(style,1:ic-1))
+          nb_col = xget("lastpattern")
+          if col < 1  |  col > nb_col then
+             col = default_markColor
+          end
+       else
+          col = default_markColor
+       end
+     else
+       ic = 2
+       col = num_col(ind)
+     end
+     reste = part(style,ic:n)
+     if reste == "" then
+       mark = default_markId
+     else
+       ind = grep(tab_mark, part(style,ic:n))
+       if ind == [] then
+          mark = default_markId
+       else
+          mark = num_mark(ind)
+       end
+     end
+  else
+     col = default_markColor ; mark = default_markId
+  end
+
+endfunction
+
+function [K2, lm, vm, lM, vM] = cond2sp(A, C, rtol, itermax, verb)
+   //
+   //  PURPOSE
+   //     for a s.p.d. matrix computes the maximum and minimum
+   //     eigen element (value and vector) with the power and
+   //     inverse power method then the 2-norm condition number
+   //     K2 = lM / lm
+   //
+   //  PARAMETERS
+   //    inputs
+   //    ------
+   //     A       : a sparse s.p.d. matrix
+   //     C       : pointer onto a Cholesky factorization (gotten with 
+   //               taucs_chfact)
+   //     rtol     : (optional) relative precision for the output test 
+   //                   (l_new - l_old)/l_new < rtol 
+   //     itermax : (optional) maximum number of iteration in each step
+   //     verb    : (optional) a boolean must be %t for display result 
+   //               for each iteration
+   //
+   //   outputs
+   //   -------
+   //     K2      : 2-norm condition number
+   //     lm      : min eigenvalue
+   //     vm      : associated eigenvector
+   //     lM      : max eigenvalue
+   //     vM      : associated eigenvector
+      
+   //
+   [lhs, rhs] = argn()
+   // no verif
+   if ~exists("verb", "local") then , verb = %f , end
+   if ~exists("rtol", "local") then , rtol = 1.e-3, end
+   if ~exists("itermax","local") then , itermax = 30 , end
+   itermax = max(4,itermax)  // 4 iterations are forced 
+   
+   // 1) computes (with "direct Rayleigh power method") lM, vM 
+   n = size(A,1)
+   x = rand(n,1) ; x = x / norm(x)
+   y = A*x
+   lM_old = x'*y
+   iter = 0
+   if verb then
+      mprintf("\n\r approximate (lM,vM) with the iterative power method \n")
+      mprintf(" ----------------------------------------------------\n")
+   end   
+   while %t
+      iter = iter + 1
+      x = y / norm(y)
+      y = A*x
+      lM = x'*y
+      if verb then , mprintf(" iteration %3d : lM = %e  \n", iter, lM) , end
+      crit = abs((lM - lM_old)/lM) 
+      if crit < rtol  &  iter > 3 then 
+        break
+      else
+        lM_old = lM
+      end
+      if iter >= itermax then
+        mprintf(" Warning : for lM ""convergence"" at rtol = %e \n", rtol)
+        mprintf("           don''t reached after %d iterations (got only %e) \n", ...
+                itermax, crit)
+        break
+      end
+   end
+   vM = x
+
+   // 2) computes (with "inverse Rayleigh power method") lm, vm 
+   x = rand(n,1) ; x = x / norm(x)
+   y = taucs_chsolve(C,x)
+   lm_old = x'*y
+   iter = 0
+   if verb then
+      mprintf("\n\r approximate (lm,vm) with the inverse iterative power method \n")
+      mprintf(" ------------------------------------------------------------\n")
+   end   
+   while %t
+      iter = iter + 1
+      x = y / norm(y)
+      y = taucs_chsolve(C,x)
+      lm = x'*y
+      if verb then , mprintf(" iteration %3d : lm = %e  \n", iter, 1/lm) , end
+      crit = abs((lm - lm_old)/lm)
+      if crit < rtol  &  iter > 3 then 
+        break
+      else
+        lm_old = lm
+      end
+      if iter >= itermax then
+        mprintf(" Warning : for lm ""convergence"" at rtol = %e \n", rtol)
+        mprintf("           don''t reached after %d iterations (got only %e) \n", ...
+                itermax, crit)
+        break
+      end
+    end
+   vm = x
+   lm = 1/lm;
+   K2 = lM/lm;
+   
+endfunction
+
+function [xn, rn] = rafiter(A, C, b, x0, nb_iter, verb)
+   // raffinement iteratif
+   //
+   if ~exists("verb", "local") then , verb = %f , end
+   if ~exists("nb_iter", "local") then , nb_iter = 2, end
+
+   xn = x0
+   for i=1:nb_iter
+      rn = res_with_prec(A, xn, b)
+      dx = taucs_chsolve(C, rn)
+      if verb then
+        crit1 = norm(rn) ; crit2 = norm(dx)
+        mprintf(" it %2d : ||r|| = %e , ||dx|| = %e \n", i, crit1, crit2)
+      end
+      xn = xn - dx
+   end
+endfunction
diff --git a/scilab/modules/umfpack/readme.txt b/scilab/modules/umfpack/readme.txt
new file mode 100644 (file)
index 0000000..fec9a6b
--- /dev/null
@@ -0,0 +1,219 @@
+       Interface for UMFPACK and TAUCS snmf and others sparse
+       ======================================================
+                    utilities Toolbox for Scilab
+                    ============================
+              the  scispt toolbox (version 1.4)
+              =======================================
+              (scispt stands for scilab sparse tools)
+
+                 The scispt toolbox can be found at
+       http://www.iecn.u-nancy.fr/~pincon/scilab/scilab.html
+
+           This toolbox has been written by Bruno Pincon
+           iecn, Universite Henri Poincare, Nancy, France
+                   <Bruno.Pincon@iecn.u-nancy.fr>
+
+                    with some contributions from:
+          Antonio Manoel Ferreria Frasson <frasson@ele.ufes.br>
+          Universidade Federal do Espírito Santo, Brazil. 
+                    <frasson@ele.ufes.br>.
+      (Antonio Manoel Ferreria Frasson have made the first 
+       add-on to treat complex linear systems within the
+      interface on the UMFPACK solver).   
+  
+       scispt is a Scilab interface onto the UMFPACK package
+      of Tim Davis and onto the snmf (super nodal multi-frontal)
+      Cholesky solver of Sivan Toledo plus some sparse utility 
+                        scilab macros.
+
+           Information about UMFPACK can be found at
+              http://www.cise.ufl.edu/research/sparse
+         UMFPACK has been written by  Timothy A. Davis
+       Copyright (c) 2003 by Timothy A. Davis, University of
+        Florida, <davis@cise.ufl.edu>.  All Rights Reserved.
+
+            Information about TAUCS v1.0 can be found at
+                http://www.tau.ac.il/~stoledo/taucs/
+      TAUCS  Version  1.0, November 29, 2001. Copyright (c) 2001
+      by Sivan Toledo,  Tel-Aviv  Univesity,  stoledo@tau.ac.il.
+                        All Rights Reserved.
+
+              scispt Version 1.4, November, 2007.
+           Copyright (c) 2001-2007 by Bruno Pincon .
+            Cecill licence
+
+
+README CONTENTS :   A/ Introduction
+                    B/ Installation
+                    C/ File Contents
+                    D/ To Do list
+                    E/ Notes
+
+A/ Introduction
+   ============
+
+This  toolbox  contains a Scilab interface  onto  the UMFPACK v4.x or v5.x  package of Tim
+Davis to solve sparse linear systems, says A x = b and also an
+interface onto the TAUCS snmf Cholesky solver of Sivan Toledo to do the
+same thing with a s.p.d. (symetrix positive definite) matrix A (if your matrix
+is s.p.d. then using this last one will be faster). 
+
+First I would thanks Tim Davis and Sivan Toledo to distribute their respective
+packages  under a "free software like license" (*).   Previus UMFPACK versions 
+(UMFPACK   2.x) by Ian Duff &  Tim Davis,  written  in fortran, have  a  more 
+restrictive license  than this  new C version due to Tim Davis. This toolbox 
+is distributed under the Cecill licence, see the scispt_License.txt  file.  
+Also I have  much appreciated the very  clear UMFPACK  User  Guide,  and 
+I find UMFPACK very well  written.
+
+I would also thank Sivan Toledo for his interest in this interface : he provides 
+me the very last snmf version (before TAUCS 1.0 was realesed) and corrects very 
+quickly a minor problem. We had also nice e-mail exchanges. Thanks Sivan !  
+
+(*) see the UMFPACK_License.txt and TAUCS_License.txt file
+
+UMFPACK seems to be the fastest free sparse solver for non // computer (there is
+currently no // UMFPACK version  while SuperLU have  scalar  and // one's).  The
+same seems also true for the TAUCS snmf routines (for symetric positive matrices). 
+The toolbox contains also the following utility scilab macros :
+
+ PlotSparse   -> to plot the sparse pattern of a matrix
+ ReadHBSparse -> to read an Harwell Boeing sparse matrix file
+ condestsp    -> to compute the condition number of a sparse matrix
+                 (algorithm from N. Higham & F. Tisseur)
+ cond2sp      -> to compute the 2-norm condition number of a s.p.d. matrix
+                 (basic algo : K2 = lM/lm with lM and lm the max and min 
+                 eigenvalues computed with power and inverse power iterations).
+
+The UMFPACK interface is made of several routines to replace the
+scilab 's native ones (which  interface the Sparse  1.3 package) :
+
+ scilab sparse lu stuff  |      new stuff 
+ ------------------------+-----------------------------               
+   x = A\b               |    x = umfpack(A,"\",b) 
+   x = b/A               |    x = umfpack(b,"/",A)
+ lup = lufact(A)         |  lup = umf_lufact(A)
+   x = lusolve(lup,b)    |    x = umf_lusolve(lup,b) (umf_lusolve offers others things)
+       ludel(lup)        |        umf_ludel(lup)
+[L,U,P,Q]==luget(lup)    | [L,U,p,q,R] = umf_luget(lup)
+                         | [OK,n,lnz,unz,udiag_nz,it] = umf_luinfo(lup)  (no direct equivalent)
+
+ Some differences :
+
+  1/ in umf_luget p and q are permutation vectors and not (sparse) permutation
+     matrices as in luget
+
+From the  speed point of  view, UMFPACK is actually very  superior to the Sparse
+1.3 package (at least throw is  its scilab interface).  A small bench is exposed
+in the file <PATH>/examples/bench.txt (*) (this file may be open with the demo).
+A more serious bench (UMFPACK v3 versus SuperLU, UMFPACK 2.2.1 and the sparse lu
+matlab stuff) is available at the UMFPACK home page (see after).
+  
+
+The TAUCS snmf interface routines replace the  scilab 's native ones (which  
+interface the Ng Peyton sparse cholesky V0.3 solver) :
+
+ scilab sparse chol stuff  |      new stuff 
+ --------------------------+-----------------------------               
+ spcho = chfact(A)         |  Cp = taucs_chfact(A)
+     x = chsolve(spcho,b)  |   x = taucs_chsolve(Cp,b)
+                           |       taucs_chdel(Cp)
+ [C,p] = spchol(A) ?       | [Ct,p] = taucs_chget(Cp)
+                           | [OK,n,cnz] = taucs_chinfo(Cp)
+
+ Here the main difference is that chfact use the scilab stack to store 
+ the factorization (spcho) while with taucs_chfact the factorization is
+ outside : I think that this is more practical. From the speed point of
+ view the taucs_snmf doesn't bring the same speed up over chfact than 
+ umfpack versus Sparse 1.3. I note a gain about 5. Furthemore this gain
+ is mainly due to the fact that chfact uses a scilab macro (sp2adj) which
+ is far from optimal. By rewriting sp2adj the gain may be only about 1.5 (and
+ it is not clear if this is true if we compile the Ng Peyton stuff with
+ another fortran compiler than g77) but :
+
+  - as chfact uses the scilab memory the user may set the stacksize with
+    a large value (naturally if the user want to retrieve the Cholesky
+    factorization at the scilab level (taucs_chget) the same amount of 
+    memory for the scilab stack is needed... but generally this is not useful).
+
+  - the taucs snmf solver has a free software status and it is currently
+    in development (so we may hope new versions/corrections, etc..) while
+    the status of the Ng peyton is not so clear...
+    
+
+(*) HERE AND IN THE FOLLOWING <PATH> STANDS FOR  THE PATH OF THE DIRECTORY 
+    CONTAINING THIS README FILE
+
+B/ Installation  for scilab-4.x
+   ============
+   see the INSTALL file
+
+
+C/ Files Contents
+   ==============
+
+README             : this file
+INSTALL            : installation instructions
+UMFPACK_License.txt: UMFPACK License
+TAUCS_License.txt  : TAUCS License
+scispt_License.txt : scispt toolbox license
+CHANGES            : changes log file
+builder.sce        : scilab script which builds the (very simple)
+                     Makefile then compile intscispt.c and taucs_scilab.c then
+                     build loader_inc.sce the variable part of loader.sce
+                     (loader.sce do an "exec loader_inc.sce")
+buildhtml.sce      : scilab script to use if you want to rebuild the html
+                     help pages from the xml one's (unnecessary)
+Makefile           : generated
+loader_inc.sce     : generated
+intscispt.c        : C interface file (to umfpack and taucs snmf)
+intscispt.o        : generated
+taucs_scilab.c     : taucs snmf routines
+taucs_scilab.h     : public interface for taucs_scilab.c
+taucs_scilab.o     : generated
+loader.sce         : installation script (load the interface with addinter,
+                     the macros with a simple getf and the help pages)
+sparse_util.sci    : file which contains all the scilab 's macro
+
+manxml             : directory for xml and html help pages.
+
+examples           : directory containing the demo stuff
+     umfdem*.dem   : files used by the demo function
+     arc130.rua    : sparse matrix file (in Harwell Boeing format)
+     ex14.rua      : sparse matrix file (in Harwell Boeing format)
+     bcsstk24.rsa  : sparse matrix file (in Harwell Boeing format)
+     young1c.csa   : sparse matrix file (in Harwell Boeing format)
+     bench.txt     : file containing the results of a comparison
+
+
+D/ To Do List
+   ==========
+
+  After bugs corrections, here is a list of possible new features 
+  (in no special order) that I (or you) may write :
+
+  (i)    a better automatic installation (at least add an install for win) 
+  (ii)   a macro to write an Harwell-Boeing sparse format file
+  (iii)  provide replacement of %sp_l_s (A\b),  %s_r_sp (b/A), etc...  which 
+         use umfpack in place of Sparse1.3 
+  (iv)   add fine tuning in several places by using the Control
+         arg of the UMFPACK routines (for instance when iterative
+         raffinement is done 2 iterations are processed but we can
+         choose what we want, also we can set the tolerance for the
+         partial pivot strategy)
+  (v)    add the possibility of choosing the column re-ordering
+         (by a user choice) and the same for taucs_chfact
+  (vi)   some macros to solve ultra classic p.d.e. on the unit square
+         (elliptic, parabolic and wave) : to do a beautiful demo ! 
+
+                  
+E/ NOTES
+   =====
+        1) currently the macros are not organised as a scilab lib (loader.sce
+           do a simple getf of the file sparse_util.sci which contains all
+           the scilab macros).  
+
+                           -------------
+                            That 's all
\ No newline at end of file
diff --git a/scilab/modules/umfpack/sci_gateway/c/gw_umfpack.c b/scilab/modules/umfpack/sci_gateway/c/gw_umfpack.c
new file mode 100644 (file)
index 0000000..2379a4d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2005-2008 - INRIA - Allan CORNET
+ *  Copyright (C) 2007-2008 - INRIA - Vincent COUVERT
+ *  Copyright (C) 2007-2008 - INRIA - Bruno JOFRET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+/*--------------------------------------------------------------------------*/
+
+/*
+ *  SCILAB INTERFACES FEATURES (Scilab )
+ *     
+ *               [x] = umfpack(A,"\",b)     : solve directly A x =b
+ *               [x] = umfpack(b,"/",A)     : solve directly x A = b (<=> A'x'=b')
+ *          [LU_ptr] = umf_lufact(A)        : factorize A
+ *               [x] = umf_lusolve(LU_ptr,b [,flag, A])
+ *                                          : solve Ax=b or A'x=b with or without iterative 
+ *                                            raffinement given the factorization
+ *                     umf_ludel(LU_ptr)    : free the memory used by the factorization
+ * [OK,nrow,ncol,lnz,unz,udiag_nz,it] = ...
+ *                     umf_luinfo(LU_ptr)   : info on the LU factors
+ *       [L,U,p,q,R] = umf_luget(LU_ptr)    : getting L,U,p,q  (PA'Q = LU)
+ *
+ *         [C_ptr] = taucs_chfact(A)        : factorize A (C_ptr is a pointer to the cholesky factors)
+ *             [x] = taucs_chsolve(C_ptr,b) : solve Ax=b
+ *                   taucs_chdel(C_ptr)     : free the memory used by the factorization
+ *    [OK, n, cnz] = taucs_chinfo(C_ptr)    : info on the cholesky factorisation
+ *           [C,p] = taucs_chget(C_ptr)     : getting C and p  (P'AP = C'C)
+ *
+ *
+ *     The corresponding C interfaces names are sci_<scilab_name>  
+ *
+ ******************************************************************************
+ */
+
+#include <string.h>
+#include "sciprint.h"
+#include "Scierror.h"
+#include "localization.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "callFunctionFromGateway.h"
+#include "taucs_scilab.h"
+/*--------------------------------------------------------------------------*/
+
+static gw_generic_table Tab[]={
+  {sci_umfpack, "umfpack"      },
+  {sci_umf_lufact, "umf_lufact"   },
+  {sci_umf_lusolve, "umf_lusolve"  },
+  {sci_umf_ludel, "umf_ludel"    },
+  {sci_umf_luinfo, "umf_luinfo"   },
+  {sci_umf_luget, "umf_luget"    },
+  {sci_taucs_chfact, "taucs_chfact" },
+  {sci_taucs_chsolve, "taucs_chsolve"},
+  {sci_taucs_chdel, "taucs_chdel"  },
+  {sci_taucs_chinfo, "taucs_chinfo" },
+  {sci_taucs_chget, "taucs_chget"  },
+  {sci_res_with_prec, "res_with_prec"}
+};
+
+/*--------------------------------------------------------------------------*/
+int gw_umfpack(void)
+{
+       callFunctionFromGateway(Tab);
+       return 0;
+}
+/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_res_with_prec.c b/scilab/modules/umfpack/sci_gateway/c/sci_res_with_prec.c
new file mode 100644 (file)
index 0000000..da8e605
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+
+int sci_res_with_prec(char* fname, unsigned long l)
+{
+       int mA, nA, mx, nx, lxr, lxi, itx, mb, nb, lbr, lbi, itb, lrr, lri, itr, ln, lni;
+       int i, one=1, LastNum;
+       SciSparse A;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(3,3);  CheckLhs(1,2);
+
+       /* get A the sparse matrix */ 
+       GetRhsVar(1, "s", &mA, &nA, &A);
+
+       /* get x and b */
+       GetRhsCVar(2, "d", &itx, &mx, &nx, &lxr, &lxi);
+       GetRhsCVar(3, "d", &itb, &mb, &nb, &lbr, &lbi);
+       if ( nx < 1 || nb != nx || mx != nA || mb != mA )
+               {
+                       Scierror(999,"%s: bad dimensions for x and or b",fname);
+                       return 0;
+               };
+
+       if ( A.it == 1  ||  itx == 1  ||  itb == 1 )
+               itr = 1;
+       else
+               itr = 0;
+
+       CreateCVar(4, "d", &itr, &mb, &nb, &lrr, &lri);
+
+       CreateVar(5, "d", &one, &nb, &ln);
+       LastNum = 5;
+
+       if ( itr == 0 )
+               for ( i = 0 ; i < nb ; i++ )
+                       residu_with_prec(&A, stk(lxr+i*mx), stk(lbr+i*mb), stk(lrr+i*mb), stk(ln+i));
+       else
+               {
+                       if ( itx == 0 ) 
+                               {
+                                       CreateVar(LastNum+1, "d", &mx, &nx, &lxi);
+                                       for ( i = 0 ; i < mx*nx ; i++ ) *stk(lxi+i) = 0.0;
+                                       LastNum++;
+                               }
+                       if ( itb == 0 ) 
+                               {
+                                       CreateVar(LastNum+1, "d", &mb, &nb, &lbi);
+                                       for ( i = 0 ; i < mb*nb ; i++ ) *stk(lbi+i) = 0.0;
+                                       LastNum++;
+                               }
+                       if ( A.it == 0 ) 
+                               {
+                                       CreateVar(LastNum+1, "d", &one, &nb, &lni);
+                                       for ( i = 0 ; i < nb ; i++ )
+                                               residu_with_prec(&A, stk(lxr+i*mx), stk(lbr+i*mb), stk(lrr+i*mb), stk(ln+i));
+                                       for ( i = 0 ; i < nb ; i++ )
+                                               residu_with_prec(&A, stk(lxi+i*mx), stk(lbi+i*mb), stk(lri+i*mb), stk(lni+i));
+                                       for ( i = 0 ; i < nb ; i++ )
+                                               *stk(ln+i) = sqrt( *stk(ln+i)**stk(ln+i) +  *stk(lni+i)**stk(lni+i) );
+                               }
+                       else
+                               for ( i = 0 ; i < nb ; i++ )
+                                       cmplx_residu_with_prec(&A, stk(lxr+i*mx), stk(lxi+i*mx),
+                                                                                  stk(lbr+i*mb), stk(lbi+i*mb), 
+                                                                                  stk(lrr+i*mb), stk(lri+i*mb), stk(ln+i));
+               }
+
+       LhsVar(1) = 4;
+       LhsVar(2) = 5;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chdel.c b/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chdel.c
new file mode 100644 (file)
index 0000000..62be24b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+ /*------------------------------------------------------------+
+ |   9) Interface code to free the memory                      |
+ |      used by the Cholesky factors (C + permutation)         |
+ |                                                             |
+ |   Scilab call                                               |
+ |   -----------                                               |
+ |   taucs_chdel(LU_ptr)  or taucs_chdel() for freed all fact. |
+ |                                                             |
+ +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+extern CellAdr *ListCholFactors;
+
+int sci_taucs_chdel(char* fname, unsigned long l)
+{
+
+       int mC_ptr, nC_ptr, lC_ptr, it_flag;
+       taucs_handle_factors * pC;
+       CellAdr * Cell;
+       int NbRhsVar;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(0,1); CheckLhs(1,1);
+
+       NbRhsVar = Rhs;
+
+       if (NbRhsVar == 0)      /* destroy all */ 
+               while ( ListCholFactors )
+                       {
+                               Cell = ListCholFactors;
+                               ListCholFactors = ListCholFactors->next;
+                               pC = (taucs_handle_factors *) Cell->adr;
+                               taucs_supernodal_factor_free(pC->C);  /* free the super nodal struct */
+                               free(pC->p);                          /* free the permutation vector */
+                               free(pC);                             /* free the handle             */
+                               free(Cell);                           
+                       }
+       else
+               {
+                       /* get the pointer to the Cholesky factors */
+                       GetRhsVar(1,"p", &mC_ptr, &nC_ptr, &lC_ptr);
+                       pC = (taucs_handle_factors *) ((unsigned long int) *stk(lC_ptr));
+      
+                       /* Check if the pointer is a valid ref to ... */
+                       if (RetrieveAdrFromList(pC, &ListCholFactors, &it_flag)) 
+                               /* free the memory of the objects */
+                               {
+                                       taucs_supernodal_factor_free(pC->C);
+                                       free(pC->p);
+                                       free(pC);
+                               }
+                       else
+                               Scierror(999,"%s: the argument is not a valid reference to Cholesky factors",fname);
+               }
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chfact.c b/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chfact.c
new file mode 100644 (file)
index 0000000..db32daa
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  | 7) Interface code for the Cholesky factorization of A       |
+  |                                                             |
+  |    Scilab call                                              |
+  |    -----------                                              |
+  |        [C_ptr] = taucs_chfact(A)                            |
+  |                                                             |
+  |             A : a real symetric definite pos. sparse matrix |
+  |         C_ptr : a pointer to the Cholesky fact              |
+  |                                                             |
+  |   Var description (to complete...)                          |
+  |   ---------------                                           |
+  |      mA : number of rows of the matrix A                    |
+  |      nA : number of columns of A                            |
+  |       A : pointer to a sparse matrix struct                 |
+  |                                                             |
+  |      Require mA == nA (matrix must be square), mA > 0       |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+extern CellAdr *ListCholFactors;
+
+int sci_taucs_chfact(char* fname, unsigned long l)
+{
+       int mA, nA, i, stat;
+       int *perm, *invperm;
+       int mC_ptr = 1, nC_ptr = 1; 
+       SciSparse A;
+       taucs_ccs_matrix B, * PAPT;
+       void *C;
+       taucs_handle_factors *pC;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1);  CheckLhs(1,1);
+
+       /* get A the sparse matrix to factorize */ 
+       GetRhsVar(1, "s", &mA, &nA, &A);
+
+       stat = spd_sci_sparse_to_taucs_sparse(2, &A, &B);
+       if ( stat != A_PRIORI_OK )  
+               {
+                       if ( stat == MAT_IS_NOT_SPD )
+                               Scierror(999,"%s: the matrix don't seems to be symetric positive definite",fname);
+                       /* the message for the other problem (not enought memory in stk) is treated automaticaly */
+                       return 0;
+               };
+
+       /* find the permutation */
+       taucs_ccs_genmmd(&B,&perm,&invperm);
+       if ( !perm )
+               {
+                       Scierror(999,"%s: not enough memory for the reordering",fname);
+                       return 0;
+               };
+  
+       /* apply permutation */
+       PAPT = taucs_ccs_permute_symmetrically(&B, perm, invperm);
+       free(invperm);
+
+       /* factor */
+       C = taucs_ccs_factor_llt_mf(PAPT);
+       taucs_ccs_free(PAPT);
+
+       if (! C) 
+               {
+                       /*   Note : an error indicator is given in the main scilab window
+                        *          (out of memory, no positive definite matrix , etc ...)
+                        */
+                       Scierror(999,"%s: failure in the factorization",fname);
+                       return 0;
+               };
+      
+       /* put in an handle (Chol fact + perm + size) */
+       pC = malloc( sizeof(taucs_handle_factors) );
+       pC->p = perm;
+       pC->C = C;
+       pC->n = A.n;
+  
+       /* add in the list of Chol Factors  */
+       AddAdrToList((Adr) pC, 0, &ListCholFactors);  /* FIXME add a test here .. */
+
+       /* create the scilab object to store the pointer onto the Chol handle */
+       CreateVarFromPtr(3,"p",&mC_ptr,&nC_ptr, (void *)pC );
+
+       /* return the pointer */
+       LhsVar(1) = 3;
+       C2F(putlhsvar)();
+       return 0;
+}
+
+   
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chget.c b/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chget.c
new file mode 100644 (file)
index 0000000..a6b9f88
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  |   11) Interface code for getting the Choleky factorisation  |
+  |       p and C                                               |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [C,p] = taucs_chget(C_ptr)                                |
+  |                                                             |
+  |    C  : the upper triangle                                  |
+  |    p  : the permutation                                     |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+extern CellAdr *ListCholFactors;
+
+int sci_taucs_chget(char* fname, unsigned long l)
+{
+
+       int mC_ptr, nC_ptr, lC_ptr;
+       taucs_handle_factors * pC;
+       taucs_ccs_matrix * C;
+       SciSparse S;
+       int one = 1, nnz, old_nnz, k, lp, i, pl_miss, it_flag;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1); CheckLhs(1,3);
+
+       /* get the pointer to the Choleski factorisation handle */
+       GetRhsVar(1,"p", &mC_ptr, &nC_ptr, &lC_ptr);
+       pC = (taucs_handle_factors *) ((unsigned long int) *stk(lC_ptr));
+
+       /* Check if the pointer is a valid ref to ... */
+       if (! IsAdrInList( (Adr)pC, ListCholFactors, &it_flag) )
+               {
+                       Scierror(999,"%s: arg #1 is not a valid reference to a Cholesky factorisation",fname);
+                       return 0;
+               };
+
+       C = taucs_supernodal_factor_to_ccs(pC->C);
+       if (! C) 
+               {
+                       Scierror(999,"%s: not enough memory",fname);
+                       return 0;
+               };
+
+
+       /* set up S fields */
+       nnz = 0;
+       for (i = 0 ; i < C->m ; i++)
+               {
+                       C->colptr[i] = C->colptr[i+1] - C->colptr[i];
+                       nnz += C->colptr[i];
+               }
+       for ( i = 0 ; i < nnz ; i++ )
+               C->rowind[i]++;
+  
+       S.m = C->m ; S.n = C->n; S.it = 0; S.nel = nnz;
+       S.R = C->values; S.I = NULL; 
+       S.icol = C->rowind; S.mnel = C->colptr;
+  
+       if (! test_size_for_sparse(2 , S.m, S.it, S.nel, &pl_miss))
+               {
+                       taucs_ccs_free(C); 
+                       Scierror(999,"%s: not enough place in stk (at least %d supplementary words needed)",
+                                        fname, pl_miss);
+                       return 0;
+               }
+       CreateVarFromPtr(2,"s",&S.m,&S.n,&S);  
+       taucs_ccs_free(C); 
+  
+       /* now p */
+       CreateVar(3,"i", &(S.m), &one, &lp); 
+       for  (i = 0 ; i < S.m ; i++)
+               *istk(lp+i) = pC->p[i]+1;
+
+       LhsVar(1) = 2;
+       LhsVar(2) = 3;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chinfo.c b/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chinfo.c
new file mode 100644 (file)
index 0000000..8104300
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  |   10) Interface code for getting some informations          |
+  |       about the Cholesky factor                             |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [OK, n, cnz] = taucs_chinfo(C_ptr)                        |
+  |                                                             |
+  |    OK  : a boolean true if C_ptr is a valid pointer to an   |
+  |          taucs Choleski numeric handle                      |
+  |    n   : size of the matrix (n,n)                           |
+  |    cnz : number of non zero elements in C                   |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+extern CellAdr *ListCholFactors;
+
+int sci_taucs_chinfo(char* fname, unsigned long l)
+{
+       int mC_ptr, nC_ptr, lC_ptr;
+       taucs_handle_factors * pC;
+       int OK, cnz, n;
+       int one = 1, ind_OK, ind_n, ind_cnz, it_flag;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1); CheckLhs(1,3);
+
+       /* get the pointer to the Choleski handle factor */
+       GetRhsVar(1,"p", &mC_ptr, &nC_ptr, &lC_ptr);
+       pC = (taucs_handle_factors *) ((unsigned long int) *stk(lC_ptr));
+
+       /* Check if the pointer is a valid ref to ... */
+       if ( IsAdrInList( (Adr)pC, ListCholFactors, &it_flag) )
+               {
+                       n = pC->n;
+                       cnz = taucs_get_nnz_from_supernodal_factor(pC->C);
+                       OK = 1;
+               }
+       else
+               {
+                       OK = 0; cnz = 0; n = 0;
+               }
+  
+       CreateVar(2,"b", &one, &one, &ind_OK);   *istk(ind_OK) = OK;
+       CreateVar(3,"d", &one, &one, &ind_n);    *stk(ind_n)   = (double) n;
+       CreateVar(4,"d", &one, &one, &ind_cnz);  *stk(ind_cnz) = (double) cnz;
+
+       LhsVar(1) = 2;
+       LhsVar(2) = 3;
+       LhsVar(3) = 4;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chsolve.c b/scilab/modules/umfpack/sci_gateway/c/sci_taucs_chsolve.c
new file mode 100644 (file)
index 0000000..4c02791
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+
+/*------------------------------------------------------------+
+  |   8) Interface code for solving Ax=b  when the Cholesky     |
+  |      factors of A are known                                 |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [x] = taucs_chsolve(C_ptr,b [,A])                         |
+  |                                                             |
+  |      mb : number of rows of the vector b                    |
+  |      nb : number of columns of the vector b (>= 1)          |
+  |      lb : index of the first element of b in the stack      |
+  |       b : pointer to the vector b (gotten with b = stk(lb)) |
+  |       A : (optional) if provided a refiment step if taken   |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+extern CellAdr *ListCholFactors;
+
+
+int sci_taucs_chsolve(char* fname, unsigned long l)
+{
+       int mb, nb, lb, lx, one=1, lv, lres;
+       int mC_ptr, nC_ptr, lC_ptr;
+       int mA, nA, i, stat, j, n, it_flag, Refinement;
+       double *b, *x, *v, *res, norm_res, norm_res_bis;
+       long double *wk = NULL;
+       int A_is_upper_triangular;
+       taucs_handle_factors * pC;
+       SciSparse A;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(2,3); CheckLhs(1,1);
+
+       /* First get arg #1 : the pointer to the Cholesky factors */
+       GetRhsVar(1,"p", &mC_ptr, &nC_ptr, &lC_ptr);
+       pC = (taucs_handle_factors *) ((unsigned long int) *stk(lC_ptr));
+
+       /* Check if this pointer is a valid ref to a Cholesky factor object */
+       if ( ! IsAdrInList( (Adr)pC, ListCholFactors, &it_flag) )
+               {
+                       Scierror(999,"%s: arg #1 is not a valid reference to Cholesky factor",fname);
+                       return 0;
+               };
+
+       /*  the number of rows/lines of the matrix  */
+       n = pC->n;
+
+       /* Get now arg #2 : the vector b */
+       GetRhsVar(2,"d",&mb,&nb,&lb);
+
+       /* test if the right hand side is compatible */
+       if (mb != n || nb < 1)  
+               {
+                       Scierror(999,"%s: bad dimensions for the rhs (arg #2)",fname);
+                       return 0;
+               };
+
+       /* get the pointer for b */
+       b = stk(lb);
+
+       if ( Rhs == 3 )
+               {
+                       GetRhsVar(3, "s", &mA, &nA, &A);
+                       if ( mA != nA  ||  mA != n  ||  A.it == 1 )
+                               {
+                                       Scierror(999,"%s: the matrix (arg #3) is not compatible with the Choleski factorisation",fname);
+                                       return 0;
+                               };
+                       Refinement = 1;
+                       A_is_upper_triangular = is_sparse_upper_triangular(&A);
+               }
+       else
+               Refinement = 0;
+
+       /* allocate memory for the solution x */
+       CreateVar(Rhs+1, "d", &mb, &nb, &lx);
+       x = stk(lx);
+
+       /* allocate memory for a temporary vector v */
+       CreateVar(Rhs+2, "d", &mb, &one, &lv); v = stk(lv);
+
+       if ( Refinement )
+               {
+                       CreateVar(Rhs+3, "d", &mb, &one, &lres); res = stk(lres);
+                       if ( A_is_upper_triangular )
+                               if ( (wk = malloc( n * sizeof(long double))) == NULL )
+                                       {
+                                               Scierror(999,"%s: not enough memory",fname);
+                                               return 0;
+                                       };
+               }
+
+       for ( j = 0; j < nb ; j++ )
+               {
+                       taucs_vec_permute(n, &b[j*mb], &x[j*mb], pC->p);
+                       taucs_supernodal_solve_llt(pC->C, v, &x[j*mb]);  /* FIXME : add a test here */
+                       taucs_vec_ipermute(n, v, &x[j*mb], pC->p);
+                       if ( Refinement )
+                               {
+                                       /* do one iterative refinement */
+                                       residu_with_prec_for_chol(&A, &x[j*mb], &b[j*mb], res, &norm_res, A_is_upper_triangular, wk);
+                                       /*  FIXME: do a test if the norm_res has an anormal value and send a warning
+                                        *         (the user has certainly not give the good matrix A 
+                                        */
+                                       taucs_vec_permute(n, res, v, pC->p);
+                                       taucs_supernodal_solve_llt(pC->C, res, v);  /* FIXME : add a test here */
+                                       taucs_vec_ipermute(n, res, v, pC->p);
+                                       for ( i = 0 ; i < n ; i++ )
+                                               v[i] = x[j*mb+i] - v[i];    /* v is the refined solution */
+                                       residu_with_prec_for_chol(&A, v, &b[j*mb], res, &norm_res_bis, A_is_upper_triangular, wk);
+                                       /* accept it if the 2 norm of the residual is improved */
+                                       if ( norm_res_bis < norm_res )
+                                               for ( i = 0 ; i < n ; i++ )
+                                                       x[j*mb+i] = v[i];
+                               }
+               }
+  
+       free(wk);
+       LhsVar(1) = Rhs+1;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umf_ludel.c b/scilab/modules/umfpack/sci_gateway/c/sci_umf_ludel.c
new file mode 100644 (file)
index 0000000..a6c2025
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+ /*------------------------------------------------------------+
+ |   4) Interface code to free the memory                      |
+ |      used by the LU factors                                 |
+ |                                                             |
+ |   Scilab call                                               |
+ |   -----------                                               |
+ |   umf_ludel(LU_ptr)  or umf_ludel() for freed all fact.     |
+ |                                                             |
+ +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+
+extern CellAdr *ListNumeric;
+
+int sci_umf_ludel(char* fname, unsigned long l)
+{
+
+  int mLU_ptr, nLU_ptr, lLU_ptr, it_flag;
+  void * Numeric;
+  CellAdr *Cell;
+  
+  /* Check numbers of input/output arguments */
+  CheckRhs(0,1); CheckLhs(1,1);
+
+  if (Rhs == 0)      /* destroy all */ 
+    while ( ListNumeric )
+      {
+       Cell = ListNumeric;
+       ListNumeric = ListNumeric->next;
+       if (Cell->it == 0) 
+         umfpack_di_free_numeric(&(Cell->adr));
+       else
+         umfpack_zi_free_numeric(&(Cell->adr));
+       free(Cell);
+      }
+  else
+    {
+      /* get the pointer to the LU factors */
+      GetRhsVar(1,"p", &mLU_ptr, &nLU_ptr, &lLU_ptr);
+      Numeric = (void *) ((unsigned long int) *stk(lLU_ptr));
+      
+      /* Check if the pointer is a valid ref to ... */
+      if (RetrieveAdrFromList(Numeric, &ListNumeric, &it_flag)) 
+       /* free the memory of the numeric object */
+       if ( it_flag == 0 )
+         umfpack_di_free_numeric(&Numeric);
+        else
+         umfpack_zi_free_numeric(&Numeric);
+      else
+       Scierror(999,"%s: the argument is not a valid reference to (umf) LU factors",fname);
+    }
+  
+  return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umf_lufact.c b/scilab/modules/umfpack/sci_gateway/c/sci_umf_lufact.c
new file mode 100644 (file)
index 0000000..c7804f0
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  | 2) Interface code for the  LU factorization of A            |
+  |                                                             |
+  |    Scilab call                                              |
+  |    -----------                                              |
+  |        [LU_ptr] = umf_lufact(A)                             |
+  |                                                             |
+  |             A : a square real sparse matrix                 |
+  |        LU_ptr : a pointer to the LU fact                    |
+  |                                                             |
+  |   Var description (to complete...)                          |
+  |   ---------------                                           |
+  |      mA : number of rows of the matrix A                    |
+  |      nA : number of columns of A                            |
+  |       A : pointer to a sparse matrix struct                 |
+  |                                                             |
+  |      Require mA, nA  > 0                                    |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "gw_umfpack.h"
+#include "sciumfpack.h"
+#include "stack-c.h"
+
+CellAdr *ListNumeric = NULL;
+CellAdr *ListCholFactors = NULL;
+
+/* RAJOUTER un controle sur la taille du pivot */
+
+int sci_umf_lufact(char* fname,unsigned long l)
+{
+       int mA, nA, stat, one=1;
+       SciSparse AA;
+       CcsSparse A;
+
+       /* umfpack stuff */
+       double *Control = (double *) NULL, *Info = (double *) NULL;
+       void *Symbolic, *Numeric;
+  
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1);  CheckLhs(1,1);
+
+       /* get A the sparse matrix to factorize */ 
+       GetRhsVar(1, "s", &mA, &nA, &AA);
+       if (nA <= 0 || mA <= 0 )  
+               {
+                       Scierror(999,"%s: bad dimensions for the matrix",fname);
+                       return 0;
+               };
+   
+       SciSparseToCcsSparse(2, &AA, &A);
+
+       /* symbolic factorisation */
+       if (A.it == 1)
+               stat = umfpack_zi_symbolic(nA, mA, A.p, A.irow, A.R, A.I, &Symbolic, Control, Info);
+       else
+               stat = umfpack_di_symbolic(nA, mA, A.p, A.irow, A.R, &Symbolic, Control, Info);
+
+       if ( stat != UMFPACK_OK ) 
+               {
+                       Scierror(999,"%s: failure in the symbolic factorization : %s",fname,UmfErrorMes(stat));
+                       return 0;
+               };
+  
+       /* numeric factorisation */
+       if (A.it == 1)
+               stat = umfpack_zi_numeric(A.p, A.irow, A.R, A.I, Symbolic, &Numeric, Control, Info);
+       else
+               stat = umfpack_di_numeric(A.p, A.irow, A.R, Symbolic, &Numeric, Control, Info);
+
+       if (A.it == 1) 
+               umfpack_zi_free_symbolic(&Symbolic); 
+       else
+               umfpack_di_free_symbolic(&Symbolic);
+
+       if ( stat != UMFPACK_OK  &&  stat != UMFPACK_WARNING_singular_matrix ) 
+               {
+                       Scierror(999,"%s: failure in the numeric factorization : %s",fname,UmfErrorMes(stat));
+                       return 0;
+               };
+
+       if ( stat == UMFPACK_WARNING_singular_matrix  &&  mA == nA ) 
+               sciprint("\n\r warning: the (square) matrix appears to be singular");
+
+       /*  add the pointer in the list ListNumeric  */
+       if (! AddAdrToList(Numeric, A.it, &ListNumeric))
+               { 
+                       /* AddAdrToList return 0 if malloc have failed : as it is just
+                          for storing 2 pointers this is unlikely to occurs but ... */
+                       if (A.it == 1) 
+                               umfpack_zi_free_numeric(&Numeric);
+                       else
+                               umfpack_di_free_numeric(&Numeric);
+                       Scierror(999,"%s: no place to store the LU pointer in ListNumeric : %s",fname);
+                       return 0;
+               };
+
+       /* create the scilab object to store the pointer onto the LU factors */
+       CreateVarFromPtr(3,"p",&one,&one, Numeric);
+
+       /* return the pointer */
+       LhsVar(1) = 3;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umf_luget.c b/scilab/modules/umfpack/sci_gateway/c/sci_umf_luget.c
new file mode 100644 (file)
index 0000000..46aad2d
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  |   6) Interface code for getting the LU factors              |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [L,U,p,q,R] = umf_luget(LU_ptr)                           |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+extern CellAdr *ListNumeric;
+
+int sci_umf_luget(char* fname, unsigned long l)
+{
+       /* 
+        *  LU_ptr is (a pointer to) a factorisation of A, we have:
+        *             -1
+        *          P R  A Q = L U
+        *
+        *      A is n_row x n_col
+        *      L is n_row x n
+        *      U is n     x n_col     n = min(n_row, n_col)
+        */
+
+       int mLU_ptr, nLU_ptr, lLU_ptr;
+       void * Numeric;
+       int lnz, unz, n_row, n_col, n, nz_udiag, i, stat, do_recip, it_flag;
+       int *L_mnel, *L_icol, *L_ptrow, *U_mnel, *U_icol, *U_ptrow, *V_irow, *V_ptcol;
+       double *L_R, *L_I, *U_R, *U_I, *V_R, *V_I, *Rs;
+       int *p, *q, one=1, pl_miss, error_flag = 0 ;
+
+       SciSparse L, U;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1); CheckLhs(1,5);
+
+       /* get the pointer to the LU factors */
+       GetRhsVar(1,"p", &mLU_ptr, &nLU_ptr, &lLU_ptr);
+       Numeric = (void *) ((unsigned long int) *stk(lLU_ptr));
+
+       /* Check if the pointer is a valid ref to ... */
+       if ( IsAdrInList(Numeric, ListNumeric, &it_flag) )
+               {
+                       if (it_flag == 0 )
+                               umfpack_di_get_lunz(&lnz, &unz, &n_row, &n_col, &nz_udiag, Numeric);
+                       else
+                               umfpack_zi_get_lunz(&lnz, &unz, &n_row, &n_col, &nz_udiag, Numeric);
+               }
+       else
+               {
+                       Scierror(999,"%s: arg #1 is not a valid reference to (umf) LU factors",fname);
+                       return 0;
+               }
+
+       if (n_row <= n_col) n = n_row; else n = n_col;
+       L_mnel  = malloc( n_row   * sizeof(int));
+       L_icol  = malloc( lnz     * sizeof(int));
+       L_ptrow = malloc((n_row+1)* sizeof(int));
+       L_R     = malloc( lnz     * sizeof(double));
+       U_mnel  = malloc( n       * sizeof(int));
+       U_icol  = malloc( unz     * sizeof(int));
+       U_ptrow = malloc((n+1)    * sizeof(int));
+       U_R     = malloc( unz     * sizeof(double));
+       V_irow  = malloc( unz     * sizeof(int));
+       V_ptcol = malloc((n_col+1)* sizeof(int));
+       V_R     = malloc( unz     * sizeof(double));
+       p       = malloc( n_row   * sizeof(int));
+       q       = malloc( n_col   * sizeof(int));
+       Rs      = malloc( n_row   * sizeof(double)); 
+       if ( it_flag == 1 )
+               {
+                       L_I = malloc( lnz     * sizeof(double));
+                       U_I = malloc( unz     * sizeof(double));
+                       V_I = malloc( unz     * sizeof(double));
+               }
+       else
+               { L_I = U_I = V_I = NULL; }
+
+       if (    !(L_mnel && L_icol && L_R && L_ptrow  && p &&
+                         U_mnel && U_icol && U_R && U_ptrow  && q &&
+                         V_irow && V_R && V_ptcol  && Rs)
+                       || (it_flag && !(L_I && U_I && V_I))   )
+               {
+                       error_flag = 1;
+                       goto the_end;
+               }
+
+       if ( it_flag == 0 )
+               stat = umfpack_di_get_numeric(L_ptrow, L_icol, L_R, V_ptcol, V_irow, V_R, 
+                                                                         p, q, (double *)NULL, &do_recip, Rs, Numeric);
+       else
+               stat = umfpack_zi_get_numeric(L_ptrow, L_icol, L_R, L_I, V_ptcol, V_irow, V_R, V_I, 
+                                                                         p, q, (double *)NULL, (double *)NULL, &do_recip, Rs, Numeric);
+
+       if ( stat != UMFPACK_OK ) { error_flag = 2; goto the_end; };
+
+       if ( do_recip )
+               for ( i = 0 ; i < n_row ; i++ )
+                       Rs[i] = 1.0 / Rs[i];
+
+       if ( it_flag == 0 )
+               stat = umfpack_di_transpose(n, n_col, V_ptcol, V_irow, V_R, (int *) NULL, 
+                                                                       (int*) NULL, U_ptrow, U_icol, U_R);  
+       else
+               stat = umfpack_zi_transpose(n, n_col, V_ptcol, V_irow, V_R, V_I, (int *) NULL, 
+                                                                       (int*) NULL, U_ptrow, U_icol, U_R, U_I, 0);  
+
+       if ( stat != UMFPACK_OK ) { error_flag = 2; goto the_end; };
+
+       for ( i = 0 ; i < n_row ; i++ ) 
+               L_mnel[i] = L_ptrow[i+1] - L_ptrow[i];
+       for ( i = 0 ; i < n ; i++ ) 
+               U_mnel[i] = U_ptrow[i+1] - U_ptrow[i];
+
+       for ( i = 0 ; i < lnz ; i++ ) L_icol[i]++;
+       for ( i = 0 ; i < unz ; i++ ) U_icol[i]++;
+      
+       for ( i = 0 ; i < n_row ; i++ ) p[i]++; 
+       for ( i = 0 ; i < n_col ; i++ ) q[i]++; 
+  
+       L.m = n_row; L.n = n; L.it = it_flag; L.nel = lnz; L.mnel = L_mnel; L.icol = L_icol; L.R = L_R; L.I = L_I; 
+       U.m = n; U.n = n_col; U.it = it_flag; U.nel = unz; U.mnel = U_mnel; U.icol = U_icol; U.R = U_R; U.I = U_I; 
+     
+       if (! test_size_for_sparse(2 , L.m, L.it, L.nel, &pl_miss)) { error_flag = 3; goto the_end; }; 
+       CreateVarFromPtr(2,"s",&n_row ,&n  , &L);
+       if (! test_size_for_sparse(3 , U.m, U.it, U.nel, &pl_miss)) { error_flag = 3; goto the_end; };
+       CreateVarFromPtr(3,"s",&n ,&n_col  , &U);
+       if (! test_size_for_mat(4 , n_row, 1, 0, &pl_miss)) { error_flag = 3; goto the_end; };
+       CreateVarFromPtr(4,"i",&n_row ,&one, &p);
+       if (! test_size_for_mat(5 , n_col, 1, 0, &pl_miss)) { error_flag = 3; goto the_end; };
+       CreateVarFromPtr(5,"i",&n_col ,&one, &q);
+       if (! test_size_for_mat(6 , n_row, 1, 0, &pl_miss)) { error_flag = 3; goto the_end; };
+       CreateVarFromPtr(6,"d",&n_row ,&one, &Rs);
+
+ the_end:
+       free(L_mnel); free(L_icol); free(L_R); free(L_ptrow); free(p);
+       free(U_mnel); free(U_icol); free(U_R); free(U_ptrow); free(q);
+       free(V_irow); free(V_R); free(V_ptcol); free(Rs);
+       if ( it_flag == 1 )
+               { free(L_I); free(V_I); free(U_I); }
+
+       switch (error_flag)
+               {
+                       case 0:   /* no error */
+                               LhsVar(1) = 2;
+                               LhsVar(2) = 3;
+                               LhsVar(3) = 4;
+                               LhsVar(4) = 5;
+                               LhsVar(5) = 6;
+                               break;
+
+                       case 1:   /* enough memory (with malloc) */
+                               Scierror(999,"%s: not enough memory",fname);
+                               break;
+
+                       case 2:   /* a problem with one umfpack routine */
+                               Scierror(999,"%s: %s",fname,UmfErrorMes(stat));
+                               break;
+
+                       case 3:  /* not enough place in the scilab stack */
+                               Scierror(999,"%s: not enough place in stk (at least %d supplementary words needed)",
+                                                fname,pl_miss);
+                               break;
+               }
+       C2F(putlhsvar)();
+       return 0;
+}
+
+
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umf_luinfo.c b/scilab/modules/umfpack/sci_gateway/c/sci_umf_luinfo.c
new file mode 100644 (file)
index 0000000..696e334
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  |   5) Interface code for getting some informations           |
+  |      about the LU factors                                   |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [OK, n, lnz, unz, it] = umf_luinfo(LU_ptr)                |
+  |                                                             |
+  |    OK  : a boolean true if LU_ptr is a valid pointer to an  |
+  |          umfpack LU numeric handle                          |
+  |    n   : size of the matrix (n,n)                           |
+  |    lnz : number of non zero elements in L                   |
+  |    unz : number of non zero elements in U                   |
+  |    it  : 0 the factors are real, 1 the factors are complex  |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+
+extern CellAdr *ListNumeric;
+
+int sci_umf_luinfo(char* fname, unsigned long l)
+{
+       int mLU_ptr, nLU_ptr, lLU_ptr;
+       void * Numeric;
+       int OK, lnz, unz, nrow, ncol, nz_udiag, it_flag;
+       int zero = 0, one = 1, ind_OK, ind_nrow, ind_ncol, ind_lnz, ind_unz, ind_nzu, ind_it ;
+
+       /* Check numbers of input/output arguments */
+       CheckRhs(1,1); CheckLhs(1,7);
+
+       /* get the pointer to the LU factors */
+       GetRhsVar(1,"p", &mLU_ptr, &nLU_ptr, &lLU_ptr);
+       Numeric = (void *) ((unsigned long int) *stk(lLU_ptr));
+
+       /* Check if the pointer is a valid ref to ... */
+       if ( IsAdrInList(Numeric, ListNumeric, &it_flag) )
+               {
+                       if ( it_flag == 0 )
+                               umfpack_di_get_lunz(&lnz, &unz, &nrow, &ncol, &nz_udiag, Numeric);
+                       else
+                               umfpack_zi_get_lunz(&lnz, &unz, &nrow, &ncol, &nz_udiag, Numeric);
+                       OK = 1;
+                       CreateVar(2,"b", &one, &one, &ind_OK);   *istk(ind_OK) = OK;
+                       CreateVar(3,"d", &one, &one, &ind_nrow); *stk(ind_nrow)= (double) nrow;
+                       CreateVar(4,"d", &one, &one, &ind_ncol); *stk(ind_ncol)= (double) ncol;
+                       CreateVar(5,"d", &one, &one, &ind_lnz);  *stk(ind_lnz) = (double) lnz;
+                       CreateVar(6,"d", &one, &one, &ind_unz);  *stk(ind_unz) = (double) unz;
+                       CreateVar(7,"d", &one, &one, &ind_nzu);  *stk(ind_nzu) = (double) nz_udiag;
+                       CreateVar(8,"d", &one, &one, &ind_it);   *stk(ind_it)  = (double) it_flag;
+               }
+       else
+               {
+                       OK = 0;
+                       CreateVar(2,"b", &one, &one, &ind_OK);   *istk(ind_OK) = OK;
+                       CreateVar(3,"d", &zero, &zero, &ind_nrow);
+                       CreateVar(4,"d", &zero, &zero, &ind_ncol);
+                       CreateVar(5,"d", &zero, &zero, &ind_lnz);
+                       CreateVar(6,"d", &zero, &zero, &ind_unz);
+                       CreateVar(7,"d", &zero, &zero, &ind_nzu); 
+                       CreateVar(8,"d", &zero, &zero, &ind_it);
+               }
+       LhsVar(1) = 2;
+       LhsVar(2) = 3;
+       LhsVar(3) = 4;
+       LhsVar(4) = 5;
+       LhsVar(5) = 6;
+       LhsVar(6) = 7;
+       LhsVar(7) = 8;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umf_lusolve.c b/scilab/modules/umfpack/sci_gateway/c/sci_umf_lusolve.c
new file mode 100644 (file)
index 0000000..b077de9
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  |   3) Interface code for solving Ax=b or A'x=b when          |
+  |      the LU factors of A are known                          |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   [x] = umf_lusolve(LU_ptr,b [,flag, A])                    |
+  |         flag = "Ax=b" or "A'x=b" ("Ax=b" default)           |
+  |         if A is given => raffinement is done                |
+  |                                                             |
+  |      mb : number of rows of the vector b                    |
+  |      nb : number of columns of the vector b (>= 1)          |
+  |      lb : index of the first element of b in the stack      |
+  |       b : pointer to the vector b (gotten with b = stk(lb)) |
+  |                                                             |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "gw_umfpack.h"
+#include "sciumfpack.h"
+#include "stack-c.h"
+
+extern CellAdr *ListNumeric;
+
+int sci_umf_lusolve(char* fname,unsigned long l)
+{
+       int mb, nb, lrb, lib, itb, mflag, nflag, lflag, lrx, lix, itx;
+       int mLU_ptr, nLU_ptr, lLU_ptr, it_flag, i;
+       int mA, nA, stat, j, one=1, LastNum;
+       SciSparse AA;
+       CcsSparse A;
+       int NoTranspose, NoRaffinement;
+       double *br, *bi, *xr, *xi;
+
+       /* umfpack stuff */
+       double Info[UMFPACK_INFO]; // double *Info = (double *) NULL;
+       double Control[UMFPACK_CONTROL];
+       void * Numeric;
+       int lnz, unz, n, n_col, nz_udiag, status, umf_flag;
+       int *Wi, lWi, lW, mW;
+       double *W;
+  
+       /* Check numbers of input/output arguments */
+       CheckRhs(2,4); CheckLhs(1,1);
+
+       /* First get arg #1 : the pointer to the LU factors */
+       GetRhsVar(1,"p", &mLU_ptr, &nLU_ptr, &lLU_ptr);
+       Numeric = (void *) ((unsigned long int) *stk(lLU_ptr));
+
+       /* Check if this pointer is a valid ref to a umfpack LU numeric object */
+       if ( ! IsAdrInList(Numeric, ListNumeric, &it_flag) )
+               {
+                       Scierror(999,"%s: arg #1 is not a valid reference to (umf) LU factors",fname);
+                       return 0;
+               };
+
+       /*  get some parameters of the factorisation (for some checking) */
+       if ( it_flag == 0 )
+               umfpack_di_get_lunz(&lnz, &unz, &n, &n_col, &nz_udiag, Numeric);
+       else
+               umfpack_zi_get_lunz(&lnz, &unz, &n, &n_col, &nz_udiag, Numeric);
+       if ( n != n_col ) 
+               {
+                       Scierror(999,"%s: this is not a factorisation of a square matrix",fname);
+                       return 0;
+               };
+       if ( nz_udiag < n ) 
+               {
+                       Scierror(999,"%s: this is a factorisation of a singular matrix",fname);
+                       return 0;
+               };
+
+       /* Get now arg #2 : the vector b */
+       GetRhsCVar(2,"d", &itb, &mb, &nb, &lrb, &lib);
+       if (mb != n || nb < 1)    /* test if the right hand side is compatible */
+               {
+                       Scierror(999,"%s: bad dimensions for the rhs (arg #2)",fname);
+                       return 0;
+               };
+
+       /* allocate memory for the solution x */
+       if ( it_flag == 1  ||  itb == 1 ) itx = 1; else itx = 0;     
+       CreateCVar(Rhs+1,"d", &itx, &mb, &nb, &lrx, &lix);
+       xr = stk(lrx); xi = stk(lix);
+
+       /*  selection between the different options :
+        *   -- solving Ax=b or A'x=b (Note: we could add  A.'x=b)
+        *   -- with or without raffinement
+        */
+
+       if ( Rhs == 2 )
+               {
+                       NoTranspose = 1;
+                       NoRaffinement = 1;
+               }
+       else  /* 3 or 4 input arguments but the third must be a string */
+               {
+                       GetRhsVar(3,"c",&mflag,&nflag,&lflag);
+                       if ( strcmp(cstk(lflag),"Ax=b") == 0 )
+                               NoTranspose = 1;
+                       else if ( strcmp(cstk(lflag),"A'x=b") == 0 )
+                               NoTranspose = 0;
+                       else
+                               {
+                                       Scierror(999,"%s: arg #3 is an unknown string specifier",fname);
+                                       return 0;
+                               };
+                       if ( Rhs == 4 ) 
+                               {
+                                       GetRhsVar(4, "s", &mA, &nA, &AA);
+                                       /*  some check... but we can't be sure that the matrix corresponds to the LU factors */
+                                       if ( mA != nA || mA != n || AA.it != it_flag )  
+                                               {
+                                                       Scierror(999,"%s: the matrix (arg #4) is not compatible with the given LU factors",fname);
+                                                       return 0;
+                                               };
+                                       NoRaffinement = 0;
+                               }
+                       else
+                               NoRaffinement = 1;   /* only 3 input var => no raffinement */
+               }
+
+       /* allocate memory for umfpack_di_wsolve usage or umfpack_zi_wsolve usage*/
+       CreateVar(Rhs+2, "i", &n, &one, &lWi); Wi = istk(lWi);
+       if (it_flag == 1) 
+               if (NoRaffinement) mW = 4*n; else mW = 10*n;
+       else
+               if (NoRaffinement) mW = n; else mW = 5*n;
+       CreateVar(Rhs+3, "d", &mW, &one, &lW); W  = stk(lW);
+
+
+       if (! NoRaffinement)
+               {
+                       SciSparseToCcsSparse(Rhs+4, &AA, &A);
+                       LastNum = Rhs+4;
+               }
+       else
+               {
+                       A.p = NULL; A.irow = NULL; A.R = NULL; A.I = NULL;
+                       LastNum = Rhs+3;
+               }
+
+       /* get the pointer for b */
+       br = stk(lrb); bi = stk(lib);
+       if ( it_flag == 1  &&  itb == 0 )
+               {
+                       CreateVar(LastNum+1,"d", &mb, &nb, &lib);
+                       bi = stk(lib);
+                       for ( i = 0 ; i < mb*nb ; i++ ) bi[i] = 0.0;
+               }
+
+       /* init Control */
+       if (it_flag == 0) 
+               umfpack_di_defaults(Control);
+       else
+               umfpack_zi_defaults(Control);
+       if (NoRaffinement)
+               Control[UMFPACK_IRSTEP] = 0;
+
+       if (NoTranspose) 
+               umf_flag = UMFPACK_A;
+       else
+               umf_flag = UMFPACK_At;
+
+       if (it_flag == 0)
+               {
+                       for ( j = 0; j < nb ; j++ ) 
+                               {
+                                       umfpack_di_wsolve(umf_flag, A.p, A.irow, A.R, &xr[j*mb], &br[j*mb], Numeric, Control, Info, Wi, W);
+                               }
+                       if (itx == 1)
+                               {
+                                       for ( j = 0; j < nb ; j++ ) 
+                                               {
+                                                       umfpack_di_wsolve(umf_flag, A.p, A.irow, A.R, &xi[j*mb], &bi[j*mb], Numeric, Control, Info, Wi, W);
+                                               }
+                               }
+               }
+    else
+               {
+                       for ( j = 0; j < nb ; j++ ) 
+                               {
+                                       umfpack_zi_wsolve(umf_flag, A.p, A.irow, A.R, A.I, &xr[j*mb], &xi[j*mb], &br[j*mb], &bi[j*mb], Numeric, Control, Info, Wi, W);
+                               }
+               }
+
+       LhsVar(1) = Rhs+1;
+       C2F(putlhsvar)();
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/c/sci_umfpack.c b/scilab/modules/umfpack/sci_gateway/c/sci_umfpack.c
new file mode 100644 (file)
index 0000000..f8fbac4
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+
+/*------------------------------------------------------------+
+  | 1) Interface code for the direct solving :                  |
+  |                                                             |
+  |   Scilab call                                               |
+  |   -----------                                               |
+  |   Case 1 :                                                  |
+  |   [x] = umfpack(A,"\",b) -> solve directly Ax=b             |
+  |                                                             |
+  |   Case 2 :                                                  |
+  |   [x] = umfpack(b,"/",A) -> solve directly xA=b <=> A'x'=b' |
+  |                                                             |
+  |   Var description (to complete...)                          |
+  |   ---------------                                           |
+  |      mA : number of rows of the matrix A                    |
+  |      nA : number of columns of A                            |
+  |       A : pointer to a sparse matrix struct                 |
+  |                                                             |
+  |      Require mA == nA (matrix must be square), mA > 0       |
+  |                                                             |
+  |      mb : number of rows of the vector b                    |
+  |      nb : number of columns of the vector b                 |
+  |      lb : index of the first element of b in the stack      |
+  |       b : pointer to the vector b (gotten with b = stk(lb)) |
+  |                                                             |
+  |      Require mb = mA , nb >= 1 in Case 1                    |
+  |              mb >= 1 , nb = mA in Case 2                    |
+  |                                                             |
+  +------------------------------------------------------------*/
+#include "sciumfpack.h"
+#include "gw_umfpack.h"
+#include "stack-c.h"
+
+int sci_umfpack(char* fname,unsigned long l)
+{
+       int mA, nA, mAp1, mb, nb, lrb, lib, itb, ms, ns, ls, itx, lrx, lix, i;
+       int num_A, num_b, one=1;
+       int mW, lW, lWi;
+       int Case, LastNum, stat;
+       double *br, *bi, *xr, *xi;
+       SciSparse AA;
+       CcsSparse A;
+
+       /* umfpack stuff */
+       double *Control = (double *) NULL; //, *Info = (double *) NULL;
+       double Info[UMFPACK_INFO];
+       void *Symbolic, *Numeric;
+       int *Wi;
+       double *W, *Y, *Z, *S;
+
+  
+       /* Check numbers of input/output arguments */
+       CheckRhs(3,3); CheckLhs(1,1);
+
+       /* First get arg #2 : a string of length 1 */
+       GetRhsVar(2,"c", &ms, &ns, &ls);
+
+       /* select Case 1 or 2 depending (of the first char of) the string ... */ 
+       if (*cstk(ls) == '\\')
+               {
+                       Case = 1; num_A = 1; num_b = 3;
+               }
+       else if (*cstk(ls) == '/')
+               {
+                       Case = 2; num_A = 3; num_b = 1;
+               }
+       else
+               {
+                       Scierror(999,"%s: unknown string specifier",fname);
+                       return 0;
+               };
+
+       GetRhsVar(num_A,"s",&mA,&nA,&AA);
+       if ( mA != nA || mA < 1 )
+               {
+                       Scierror(999,"%s: bad dimensions for the matrix (arg #%d)", fname, num_A);
+                       return 0;
+               };
+       GetRhsCVar(num_b,"d",&itb,&mb,&nb,&lrb,&lib);
+       if ( (Case==1 && ( mb != mA || nb < 1 )) || (Case==2 && ( nb != mA || mb < 1 )) )
+               {
+                       Scierror(999,"%s: bad dimensions for the \"vector(s)\" (arg #%d)", fname, num_b);
+                       return 0;
+               };
+
+       SciSparseToCcsSparse(4, &AA, &A);
+
+       /* allocate memory for the solution x */
+       if ( A.it == 1  ||  itb == 1 ) itx = 1; else itx = 0;     
+       CreateCVar(5,"d", &itx, &mb, &nb, &lrx, &lix);
+       xr = stk(lrx); xi = stk(lix);
+
+       /* allocate memory for umfpack_di_wsolve usage or umfpack_zi_wsolve usage*/
+       CreateVar(6, "i", &mA, &one, &lWi); Wi = istk(lWi);
+       if (A.it == 1) mW = 10*mA; else mW = 5*mA;
+       CreateVar(7, "d", &mW, &one, &lW); W  = stk(lW);
+
+       /* get the pointer for b */
+       br = stk(lrb); bi = stk(lib);
+       if ( A.it == 1  &&  itb == 0 )
+               {
+                       CreateVar(8,"d", &mb, &nb, &lib); LastNum = 8;
+                       bi = stk(lib);
+                       for ( i = 0 ; i < mb*nb ; i++ ) bi[i] = 0.0;
+               }
+       else
+               LastNum = 7;
+
+       /* Now calling umfpack routines */
+       if (A.it == 1)
+               stat = umfpack_zi_symbolic(mA, nA, A.p, A.irow, A.R, A.I, &Symbolic, Control, Info);
+       else
+               stat = umfpack_di_symbolic(mA, nA, A.p, A.irow, A.R, &Symbolic, Control, Info);
+       if ( stat  != UMFPACK_OK ) 
+               {
+                       Scierror(999,"%s: failure in the symbolic factorization : %s",fname,UmfErrorMes(stat));
+                       return 0;
+               };
+  
+
+       if (A.it == 1)
+               stat = umfpack_zi_numeric(A.p, A.irow, A.R, A.I, Symbolic, &Numeric, Control, Info);
+       else
+               stat = umfpack_di_numeric(A.p, A.irow, A.R, Symbolic, &Numeric, Control, Info);
+
+       if (A.it == 1) 
+               umfpack_zi_free_symbolic(&Symbolic); 
+       else
+               umfpack_di_free_symbolic(&Symbolic);
+
+       if ( stat  != UMFPACK_OK ) 
+               {
+                       if (A.it == 1)
+                               umfpack_zi_free_numeric(&Numeric); 
+                       else
+                               umfpack_di_free_numeric(&Numeric); 
+                       Scierror(999,"%s: failure in the numeric factorization : %s",fname,UmfErrorMes(stat));
+                       return 0;
+               };
+
+
+       if ( Case == 1 )   /*  x = A\b  <=> Ax = b */
+               {  
+                       if (A.it == 0)
+                               {
+                                       for ( i = 0 ; i < nb ; i++ )
+                                               umfpack_di_wsolve(UMFPACK_A, A.p, A.irow, A.R, &xr[i*mb], &br[i*mb],
+                                                                                 Numeric, Control, Info, Wi, W);
+                                       if (itb == 1)
+                                               for ( i = 0 ; i < nb ; i++ )
+                                                       umfpack_di_wsolve(UMFPACK_A, A.p, A.irow, A.R, &xi[i*mb], &bi[i*mb],
+                                                                                         Numeric, Control, Info, Wi, W);
+                               }
+                       else /*  A.it == 1  */
+                               for ( i = 0 ; i < nb ; i++ )
+                                       umfpack_zi_wsolve(UMFPACK_A, A.p, A.irow, A.R, A.I, &xr[i*mb], &xi[i*mb], 
+                                                                         &br[i*mb], &bi[i*mb], Numeric, Control, Info, Wi, W);
+               }
+       else  /* Case == 2,   x = b/A  <=> x A = b <=> A.'x.' = b.' */
+               {
+                       if (A.it == 0)
+                               {
+                                       TransposeMatrix(br, mb, nb, xr);    /* put b in x (with transposition) */
+                                       for ( i=0 ; i < mb ; i++ )
+                                               umfpack_di_wsolve(UMFPACK_At, A.p, A.irow, A.R, &br[i*nb], &xr[i*nb],
+                                                                                 Numeric, Control, Info, Wi, W);      /* the solutions are in br */
+                                       TransposeMatrix(br, nb, mb, xr);         /* put now br in xr with transposition */
+                                       if (itb == 1)
+                                               {
+                                                       TransposeMatrix(bi, mb, nb, xi);    /* put b in x (with transposition) */
+                                                       for ( i=0 ; i < mb ; i++ )
+                                                               umfpack_di_wsolve(UMFPACK_At, A.p, A.irow, A.R, &bi[i*nb], &xi[i*nb], 
+                                                                                                 Numeric, Control, Info, Wi, W);      /* the solutions are in bi */
+                                                       TransposeMatrix(bi, nb, mb, xi);         /* put now bi in xi with transposition */
+                                               }
+                               }
+                       else /*  A.it==1  */
+                               {
+                                       TransposeMatrix(br, mb, nb, xr);
+                                       TransposeMatrix(bi, mb, nb, xi);
+                                       for ( i=0 ; i < mb ; i++ )
+                                               umfpack_zi_wsolve(UMFPACK_Aat, A.p, A.irow, A.R, A.I, &br[i*nb], &bi[i*nb],
+                                                                                 &xr[i*nb], &xi[i*nb], Numeric, Control, Info, Wi, W);
+                                       TransposeMatrix(br, nb, mb, xr);
+                                       TransposeMatrix(bi, nb, mb, xi);
+                               }
+               }
+
+       if (A.it == 1)
+               umfpack_zi_free_numeric(&Numeric);
+       else
+               umfpack_di_free_numeric(&Numeric);
+
+       LhsVar(1) = 5;
+       C2F(putlhsvar)();
+
+       return 0;
+}
diff --git a/scilab/modules/umfpack/sci_gateway/umfpack_gateway.xml b/scilab/modules/umfpack/sci_gateway/umfpack_gateway.xml
new file mode 100644 (file)
index 0000000..b8afc44
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<!DOCTYPE GATEWAY SYSTEM "../../functions/xml/gateway.dtd">
+<GATEWAY name="umfpack">
+<!-- =================== -->
+<!--
+ Scilab
+ Interface description. In this file, we define the list of the function which
+ will be available into Scilab and the link to the "native" function.
+
+ gatewayId is the position in the hashtable 'Interfaces' defined in the
+ file SCI/modules/core/src/c/callinterf.h
+
+ primitiveId is the position in the hashtable '<module>Table Tab[]' defined
+ in the file modules/<module>/sci_gateway/c/gw_<module>.c
+
+ primitiveName is the name of the Scilab function
+
+ @author Allan CORNET
+ @author Sylvestre LEDRU
+ @date INRIA 2007
+ ===================
+ Don't touch if you do not know what you are doing
+-->
+<!-- =================== -->
+
+<PRIMITIVE gatewayId="58" primitiveId="1" primitiveName="umfpack" />
+<PRIMITIVE gatewayId="58" primitiveId="2" primitiveName="umf_lufact" />
+<PRIMITIVE gatewayId="58" primitiveId="3" primitiveName="umf_lusolve" />
+<PRIMITIVE gatewayId="58" primitiveId="4" primitiveName="umf_ludel" />
+<PRIMITIVE gatewayId="58" primitiveId="5" primitiveName="umf_luinfo" />
+<PRIMITIVE gatewayId="58" primitiveId="6" primitiveName="umf_luget" />
+<PRIMITIVE gatewayId="58" primitiveId="7" primitiveName="taucs_chfact" />
+<PRIMITIVE gatewayId="58" primitiveId="8" primitiveName="taucs_chsolve" />
+<PRIMITIVE gatewayId="58" primitiveId="9" primitiveName="taucs_chdel" />
+<PRIMITIVE gatewayId="58" primitiveId="10" primitiveName="taucs_chinfo" />
+<PRIMITIVE gatewayId="58" primitiveId="11" primitiveName="taucs_chget" />
+<PRIMITIVE gatewayId="58" primitiveId="12" primitiveName="res_with_prec" />
+</GATEWAY>
diff --git a/scilab/modules/umfpack/src/c/common_umfpack.c b/scilab/modules/umfpack/src/c/common_umfpack.c
new file mode 100644 (file)
index 0000000..dca4769
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+/*
+ * First here are some utilities for the interface : 
+ *
+ *   1) When a user computes an LU fact with umf_lufact or a Choleski
+ *      fact with taucs_chfact he/she get at the scilab level only a 
+ *      pointer on to the factorization : the memory for this factorization 
+ *      is outside scilab memory. In order to avoid problem with scilab 
+ *      pointer coming from other usage I manage in this interface a 
+ *      linked list of all the valid pointers onto "umfpack numerical 
+ *      factorisation handle" and the same for the Choleski factorizations. 
+ *      These 2 lists are called 
+ *
+ *         ListNumeric
+ *         ListCholFactor
+ *
+ *      And so you will find here 3 routines to deal with :
+ *
+ *         AddAdrToList, RetrieveAdrFromList, IsAdrInList
+ *
+ *   2) some others  utility routines are used :
+ *
+ *         sci_sparse_to_ccs_sparse: scilab sparse format -> CCS format (for umfpack)
+ *
+ *         spd_sci_sparse_to_taucs_sparse: transform a scilab sparse (supposed to be spd)
+ *                                         in the format wait by taucs 
+ *
+ *         TransposeMatrix: used only to solve x = b/A  (umfpack(b,"/",A)
+ *
+ *         UmfErrorMes : to deal with some few messages from umfpack
+ *
+ *         test_size_for_sparse : to see if stk have enough places to 
+ *                                store a sparse (see comments)
+ *         test_size_for_mat : the same for classic matrix
+ */
+
+#include "sciumfpack.h"
+#include "stack-c.h"
+#include "taucs_scilab.h"
+
+int AddAdrToList(Adr adr, int it_flag, CellAdr **L)
+{
+  CellAdr *NewCell;
+  if ( (NewCell = malloc(sizeof(CellAdr))) == NULL )
+    return 0;
+  else  
+    {
+      NewCell->adr = adr;
+      NewCell->it = it_flag;
+      NewCell->next = *L;
+      *L = NewCell;
+      return 1;
+    }
+}
+
+int RetrieveAdrFromList(Adr adr, CellAdr **L, int *it_flag)
+{
+  /* teste si l'adresse adr est presente ds la liste L, si oui
+     on la retire et la fonction renvoie 1, sinon 0  */
+  CellAdr * Cell;
+
+  if ( *L == NULL )
+    return 0;
+  else if ( (*L)->adr == adr ) 
+    {
+      Cell = *L;
+      *it_flag = Cell->it;
+      *L = (*L)->next;
+      free(Cell);
+      return 1;
+    }
+  else
+    return ( RetrieveAdrFromList(adr, &((*L)->next), it_flag));
+}
+
+int IsAdrInList(Adr adr, CellAdr *L, int *it_flag)
+{
+  /* teste si l'adresse adr est presente ds la liste L, si oui
+     la fonction renvoie 1, sinon 0. On renvoit aussi it */
+
+  if ( L == NULL )
+    return 0;
+  else if ( L->adr == adr ) 
+    {
+      *it_flag = L->it;
+      return 1;
+    }
+  else
+    return ( IsAdrInList(adr, L->next, it_flag) );
+}
+
+
+void TransposeMatrix(double A[], int ma, int na, double At[])
+{
+  /*  compute At the (na,ma) matrix gotten by the
+   *  transposition of the (ma, na) matrix A.  A and
+   *  At are in fact simple 1-d arrays with the fortran 
+   *  storage convention :
+   *     A(i,j) = A[i + ma*j] , At(i,j) = At[i + na*j]
+   *
+   *     At(i,j) = A(j,i) = A[j + ma*i]
+   */
+  int i, j;
+  for ( j = 0 ; j < ma ; j++ )
+    for ( i = 0 ; i < na ; i++ )
+      At[i + na*j] = A[j + ma*i];
+}
+
+int sci_sparse_to_ccs_sparse(int num, SciSparse *A, CcsSparse *B)
+{
+  int taille, one=1, nel = A->nel, m = A->m, n = A->n, it = A->it;
+  int l0, l1, l2, k, kb, i, j, count;
+
+  taille = ((2*it+3)*nel + n+1 )/2 + 2;
+
+  CreateVar(num, "d", &taille, &one, &l0);  /* return 0 in case of failure (not enough memory in stk) */
+
+  B->m = m; B->n = n; B->nel = nel; B->it = it;
+  B->R = stk(l0);
+  if ( it == 1 )
+    {
+      B->I = stk(l0 + nel); l1 = l0 + 2*nel;
+    }
+  else
+    {
+      B->I = NULL; l1 = l0 + nel;
+    }
+  B->p = (int *) stk(l1); l2 = l1 + (n+1)/2 + 1;
+  B->irow = (int *) stk(l2);
+
+  for ( i = 0 ; i <= n ; i++ )
+    B->p[i] = 0;
+
+  for ( k = 0 ; k < nel ; k++ )
+    B->p[A->icol[k]]++;   /* this is because  A->icol[k] is 1-based (and not 0-based) */
+
+  for ( i = 2 ; i <= n ; i++ )
+    B->p[i] += B->p[i-1];
+
+  k = 0;
+  for ( i = 0 ; i < m ; i++ )
+    for ( count = 0 ; count < A->mnel[i] ; count++ )
+      {
+       j = A->icol[k]-1;
+       kb = B->p[j];  /* "pointeur" actuel sur la colonne j */
+       B->irow[kb] = i;
+       B->R[kb] = A->R[k];
+       if (it == 1) B->I[kb] = A->I[k];
+       B->p[j]++;
+       k++;
+      }
+
+  for ( i = n-1 ; i > 0 ; i-- )
+    B->p[i] = B->p[i-1];
+  B->p[0] = 0;
+
+  return 1;
+}
+
+char *UmfErrorMes(int num_error)
+{
+  /* to deal with various umfpack error indicator */
+  char *mes1 = "singular matrix";
+  char *mes2 = "not enough memory";
+  char *mes3 = "internal error";
+  char *mes4 = "invalid matrix";
+  /*  normallly with the different controls in the interface
+   *  the others errors may not occured but we put anyway
+   *  this last one :
+   */
+  char *mes5 = "unidentified error";
+
+  switch (num_error) {
+  case UMFPACK_WARNING_singular_matrix: return(mes1);
+  case UMFPACK_ERROR_out_of_memory:   return(mes2);
+  case UMFPACK_ERROR_internal_error:  return(mes3);
+  case UMFPACK_ERROR_invalid_matrix:  return(mes4);
+  default:                            return(mes5);
+  };
+}
+
+int is_sparse_upper_triangular(SciSparse *A)
+{
+  int i, k=0, nb_elem_row_i;
+  for ( i = 0 ; i < A->m ; i++ )
+    {
+      nb_elem_row_i = A->mnel[i];
+      if (nb_elem_row_i > 0  &&  A->icol[k] <= i)
+       return 0; 
+      k += nb_elem_row_i;
+    }
+  return 1;
+}
+
+int spd_sci_sparse_to_taucs_sparse(int num, SciSparse *A, taucs_ccs_matrix *B)
+{
+  /*  
+   *  this function create a taucs sparse symetric matrix (with only the lower
+   *  triangle part) from a supposed symetric spd scilab sparse one's.
+   *  This is to put a sci sparse in the format wait by taucs routines
+   *
+   *  The scilab sparse may be only upper triangular
+   */
+  int taille, one=1, B_nel, n = A->n;
+  int l0, l1, l2, i, j, k, l, p, nnz;
+
+  if ( A->m != A->n  ||  A->m <= 0  ||  A->it == 1 )
+    return ( MAT_IS_NOT_SPD );
+
+  if ( is_sparse_upper_triangular(A) )
+    B_nel = A->nel;
+  else
+    B_nel = n + (A->nel - n)/2;
+  taille = (3*B_nel + n+1 )/2 + 2;
+
+  CreateVar(num, "d", &taille, &one, &l0);  /* return 0 in case of failure (not enough memory in stk) */
+
+  /* form the taucs sparse matrix struct */
+  B->m = n; B->n = n;
+  B->flags =  TAUCS_SYMMETRIC | TAUCS_LOWER;
+
+  B->values = stk(l0); l1 = l0 + B_nel;
+  B->colptr = (int *) stk(l1); l2 = l1 + (n+1)/2 + 1;
+  B->rowind = (int *) stk(l2);
+
+  nnz = 0;
+  k = 0;
+  for ( i = 0 ; i < n ; i++ )
+    {
+      if ( A->mnel[i] > 0 )
+       {
+         l = 0;
+         while ( l < A->mnel[i]  &&  A->icol[k+l] < i+1 )   /* go to the diagonal element */ 
+           l++;
+         if ( l >= A->mnel[i] )          /* no element A_ij with j >= i => A_ii = 0  */
+           return ( MAT_IS_NOT_SPD );
+         else if ( A->icol[k+l] > i+1 )  /* A_ii = 0 */
+           return ( MAT_IS_NOT_SPD );
+         else if ( A->R[k+l] <= 0 )      /* A_ii <= 0 */
+           return ( MAT_IS_NOT_SPD );
+         else                            /* normal case A_ii > 0 */
+           {        
+             if ( nnz + A->mnel[i] - l > B_nel )    
+               return ( MAT_IS_NOT_SPD );
+             B->colptr[i] = nnz;
+             for ( p = l ; p < A->mnel[i] ; p++)
+               {
+                 B->values[nnz] = A->R[k+p];
+                 B->rowind[nnz] = A->icol[k+p]-1;
+                 nnz++;
+               }
+             k = k + A->mnel[i];
+           }
+       }
+      else
+       return ( MAT_IS_NOT_SPD );
+    }
+  if ( nnz != B_nel )
+    return ( MAT_IS_NOT_SPD );
+
+  B->colptr[n] = nnz;
+  
+  return ( A_PRIORI_OK );
+}
+
+
+/*------------------------------------------------------*
+ * an utility to test if we can create a sparse matrix  *
+ * in the scilab stack                                  *
+ *------------------------------------------------------*/
+
+int test_size_for_sparse(int pos, int m, int it, int nel, int * pl_miss) 
+{
+  /*  test if the scilab stack can currently store at the
+   *  position pos a sparse matrix with m rows and nel 
+   *  non nul elements (Bruno le 17/12/2001 with the help
+   *  of jpc). This function is required because with a failure
+   *  in a CreateVarFromPtr(pos, "s", ...) the control is then
+   *  passed (via Scierror) to the intepretor and we can lose
+   *  the pointer and so don't be able to free the associated
+   *  memory to this pointer 
+   */
+  int lw = pos + Top - Rhs, il;
+
+  if (lw + 1 >= Bot) return FALSE; /* even no place for a supplementary var */
+
+  /* 5 + m + nel : number of "integers" cases required for the sparse */
+  
+  il = iadr(*Lstk(lw )) +  5 + m + nel;
+  *pl_miss =  (sadr(il) + nel*(it+1)) - *Lstk(Bot); 
+
+  if ( *pl_miss > 0 )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+int test_size_for_mat(int pos, int m, int n, int it, int * pl_miss) 
+{
+  /* the same for classic matrix (trick given par jpc) */
+  int lw = pos + Top - Rhs, il;
+
+  if (lw + 1 >= Bot) return FALSE;
+
+  /* 4 is the number of integer "cases" required for a classic matrix
+   * (type , m, n, it)
+   */
+  il = iadr(*Lstk(lw )) + 4;
+
+  *pl_miss =  (sadr(il) + m*n*(it+1)) - *Lstk(Bot); 
+
+  if ( *pl_miss > 0 )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+
+void residu_with_prec(SciSparse *A, double x[], double b[], double r[], double *rn)
+{
+  /*  un essai de calcul de residu : r = Ax - b, en precision double etendue */
+  int i, j, k, l;
+  long double temp, norm2;
+
+  norm2 = 0.0;
+  k = 0;
+  for ( i = 0 ; i < A->m ; i++ )
+    {
+      temp = 0.0;
+      for ( l = 0 ; l < A->mnel[i] ; l++ )
+       {
+         j = A->icol[k] - 1;
+         temp += (long double) A->R[k]  *  (long double) x[j];
+         k++;
+       }
+      temp -=  (long double) b[i];
+      r[i] = (double) temp;
+      norm2 += temp*temp;
+    }
+  *rn = (double) sqrt(norm2);
+  return;
+}
+
+void residu_with_prec_for_chol(SciSparse *A, double x[], double b[], double r[], 
+                                     double *rn, int A_is_upper_triangular, long double wk[])
+{
+  /*  the same than the previous routine but this one take care of the fact that 
+   *  when A_is_upper_triangular=1 only the upper triangle part of A is stored */
+  int i, j, k, l;
+  long double norm2 = 0.0;
+
+  if ( ! A_is_upper_triangular )
+    residu_with_prec(A, x, b, r, rn);
+  else
+    {   /* A*x-b but only the upper triangle of A is stored */
+      for ( i = 0 ; i < A->m ; i++ ) 
+       wk[i] = -(long double) b[i];
+      k = 0;
+      for ( i = 0 ; i < A->m ; i++ )
+       {
+         for ( l = 0 ; l < A->mnel[i] ; l++ )
+           {
+             j = A->icol[k] - 1;
+             wk[i] += (long double) A->R[k]  *  (long double) x[j];
+             if ( j != i )
+               wk[j] += (long double) A->R[k]  *  (long double) x[i];
+             k++;
+           }
+       }
+      for ( i = 0 ; i < A->m ; i++ ) 
+       {
+         r[i] = (double) wk[i];
+         norm2 += wk[i]*wk[i];
+       }
+      *rn = (double) sqrt(norm2);
+    }
+  return;
+}
+
+
+void cmplx_residu_with_prec(SciSparse *A, 
+                                  double xr[], double xi[],
+                                  double br[], double bi[], 
+                                  double rr[], double ri[],
+                                  double *rn)
+{
+  /*  the same for complex system */
+  int i, j, k, l;
+  long double tempr, tempi, norm2;
+
+  norm2 = 0.0;
+  k = 0;
+  for ( i = 0 ; i < A->m ; i++ )
+    {
+      tempr = 0.0; tempi = 0.0;
+      for ( l = 0 ; l < A->mnel[i] ; l++ )
+       {
+         j = A->icol[k] - 1;
+         tempr +=   (long double) A->R[k]  *  (long double) xr[j]
+                   - (long double) A->I[k]  *  (long double) xi[j];
+         tempi +=   (long double) A->I[k]  *  (long double) xr[j]
+                   + (long double) A->R[k]  *  (long double) xi[j];
+         k++;
+       }
+      tempr -=  (long double) br[i];
+      tempi -=  (long double) bi[i];
+      rr[i] = (double) tempr;
+      ri[i] = (double) tempi;
+      norm2 += tempr*tempr + tempi*tempi;
+    }
+  *rn = (double) sqrt(norm2);
+  return;
+}
diff --git a/scilab/modules/umfpack/src/c/sciumfpack.h b/scilab/modules/umfpack/src/c/sciumfpack.h
new file mode 100644 (file)
index 0000000..ceceaba
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *   Copyright Bruno Pinçon, ESIAL-IECN, Inria CORIDA project 
+ *   <bruno.pincon@iecn.u-nancy.fr>
+ *   contributor:  Antonio Manoel Ferreria Frasson, Universidade Federal do 
+ *                 Espírito Santo, Brazil. <frasson@ele.ufes.br>.
+ *
+ * PURPOSE: Scilab interfaces routines onto the UMFPACK sparse solver
+ * (Tim Davis) and onto the TAUCS snmf choleski solver (Sivan Teledo)
+ *
+ * This software is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software.  You can  use,
+ * modify and/or redistribute the software under the terms of the CeCILL
+ * license as circulated by CEA, CNRS and INRIA at the following URL
+ * "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and  rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty  and the software's author,  the holder of the
+ * economic rights,  and the successive licensors  have only  limited
+ * liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading,  using,  modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean  that it is complicated to manipulate,  and  that  also
+ * therefore means  that it is reserved for developers  and  experienced
+ * professionals having in-depth computer knowledge. Users are therefore
+ * encouraged to load and test the software's suitability as regards their
+ * requirements in conditions enabling the security of their systems and/or
+ * data to be ensured and,  more generally, to use and operate it in the
+ * same conditions as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ *
+ */
+//#ifdef UMFPACK_SUITESPARSE
+#include <suitesparse/umfpack.h>
+/*
+#else
+#include <umfpack.h>
+#endif
+*/
+enum {NOT_ENOUGH_PLACE_IN_STK, MAT_IS_NOT_SPD, A_PRIORI_OK};   /* flags for spd_sci_sparse_to_taucs_sparse */
+
+typedef void * Adr;
+
+typedef struct _CellAdr CellAdr ;
+struct _CellAdr {
+       Adr adr;
+       int it;   // added to see if the LU factors comes from a real or complex matrix
+       CellAdr *next;
+};
+
+typedef struct  /* a type to handle a choleski factorisation */
+{
+       int * p;      /* for the permutation    */
+       void * C;     /* for the factor (lower) */
+       int n;        /* to stay the order (in place to read a member of C) */
+} taucs_handle_factors;
+
+typedef struct {
+       int m;          /* number of rows */
+       int n;          /* number of columns */
+       int nel;        /* number of non nuls elements */
+       int it;         /* flag type : it=-1 (boolean) it=0 (real) it=1 (complex) */
+       int *p;         /* n+1 array : ptr_col[n] must be equal to nel */
+       int *irow;   
+       double *R;
+       double *I;
+} CcsSparse;
+
+#define SciSparseToCcsSparse(num, A, B) if (! sci_sparse_to_ccs_sparse(num, A, B)) { return 0;}
+
diff --git a/scilab/modules/umfpack/src/c/taucs_scilab.c b/scilab/modules/umfpack/src/c/taucs_scilab.c
new file mode 100644 (file)
index 0000000..1d356b5
--- /dev/null
@@ -0,0 +1,2180 @@
+/*
+ *   This big file contains all the taucs routines needed for the
+ *   scilab interface onto the taucs supernodal multi-frontal choleski 
+ *   solver :
+ *        - internal structures used by the solver 
+ *        - genmmd interface
+ *        - create / free taucs matrices routines
+ *        - permutations routines
+ *        - symbolic analysis routines
+ *        - super nodal multi frontal factor routines
+ *        - super nodal multi frontal solve routines
+ *        - various utilities
+ *
+ *    All this code is from different files of the TAUCS solver
+ *    lib from Sivan Toledo (see the TAUCS_license.txt file).
+ *
+ *    Very minor modifs have been done (Bruno) :
+ *        - replace the _ for calling fortran routine by the 
+ *          scilab macro F2C  (call to genmmd and calls to blas
+ *          routines)
+ *        - the print messages that I have stayed are redirected
+ *          to the scilab window with sciprint
+ *        - I have added a small routine to get cnz
+ *
+ *    Thanks to Sivan Toledo
+ */
+
+/*************************************************************/
+/*                                                           */
+/*************************************************************/
+
+#include <stdlib.h>
+#include <assert.h>
+#include <math.h>
+#include "taucs_scilab.h"
+#include "stack-c.h"   /* F2C macro */
+#include "BOOL.h"
+
+#define BLAS_FLOPS_CUTOFF  1000.0
+#define SOLVE_DENSE_CUTOFF 5
+
+/*************************************************************/
+/* structures                                                */
+/*************************************************************/
+
+typedef struct {
+  int     sn_size;
+  int     n;
+  int*    rowind;
+
+  int     up_size;
+  int*    sn_vertices;
+  int*    up_vertices;
+  double* f1;
+  double* f2;
+  double* u;
+} supernodal_frontal_matrix;
+
+typedef struct {
+  char    uplo;     /* 'u' for upper, 'l' for lower, ' ' don't know; prefer lower. */
+  int     n;        /* size of matrix */
+  int     n_sn;     /* number of supernodes */
+
+  int* parent;      /* supernodal elimination tree */
+  int* first_child; 
+  int* next_child;
+
+  int* sn_size;     /* size of supernodes (diagonal block) */
+  int* sn_up_size;  /* size of subdiagonal update blocks   */
+  int** sn_struct;  /* row structure of supernodes         */
+
+  int* sn_blocks_ld;  /* lda of supernode blocks */
+  double** sn_blocks; /* supernode blocks        */
+    
+  int* up_blocks_ld;  /* lda of update blocks    */
+  double** up_blocks; /* update blocks           */
+} supernodal_factor_matrix;
+
+/*************************************************************/
+/* for qsort                                                 */
+/*************************************************************/
+
+static int* compare_indirect_map;
+static int compare_indirect_ints(const void* vx, const void* vy)
+{
+  int* ix = (int*)vx;
+  int* iy = (int*)vy;
+  if (compare_indirect_map[*ix] < compare_indirect_map[*iy]) return -1;
+  if (compare_indirect_map[*ix] > compare_indirect_map[*iy]) return  1;
+  return 0;
+}
+
+/*********************************************************/
+/* Interface to MMD                                      */
+/*********************************************************/
+
+void taucs_ccs_genmmd(taucs_ccs_matrix* m, int** perm, int** invperm)
+{
+  int  n, maxint, delta, nofsub;
+  int* xadj;
+  int* adjncy;
+  int* invp;
+  int* prm;
+  int* dhead;
+  int* qsize;
+  int* llist;
+  int* marker;
+
+  int* len;
+  int* next;
+
+  int  nnz,i,j,ip;
+  
+
+  if (!(m->flags & TAUCS_SYMMETRIC)) {
+    sciprint("taucs_ccs_genmmd: GENMMD ordering only works on symmetric matrices.\n\r");
+    *perm    = NULL;
+    *invperm = NULL;
+    return;
+  }
+  /* this routine may actually work on UPPER as well */
+  if (!(m->flags & TAUCS_LOWER)) {
+    sciprint("taucs_ccs_genmmd: the lower part of the matrix must be represented.\n\r");
+    *perm    = NULL;
+    *invperm = NULL;
+    return;
+  }
+
+  *perm    = NULL;
+  *invperm = NULL;
+
+  n   = m->n;
+  nnz = (m->colptr)[n];
+  
+  /* I copied the value of delta and the size of */
+  /* from SuperLU. Sivan                         */
+
+  delta = 1; /* DELTA is a parameter to allow the choice of nodes
+               whose degree <= min-degree + DELTA. */
+
+  maxint = 32000;
+
+  assert(sizeof(int) == 4);
+  maxint = 2147483647; /* 2**31-1, for 32-bit only! */
+
+  xadj   = (int*) malloc((n+1)     * sizeof(int));
+  adjncy = (int*) malloc((2*nnz-n) * sizeof(int));
+  invp   = (int*) malloc((n+1)     * sizeof(int));
+  prm    = (int*) malloc(n         * sizeof(int));
+  dhead  = (int*) malloc((n+1)     * sizeof(int));
+  qsize  = (int*) malloc((n+1)     * sizeof(int));
+  llist  = (int*) malloc(n         * sizeof(int));
+  marker = (int*) malloc(n         * sizeof(int));
+
+  if (!xadj || !adjncy || !invp || !prm 
+      || !dhead || !qsize || !llist || !marker) {
+    free(xadj  );
+    free(adjncy);
+    free(invp  );
+    free(prm   );
+    free(dhead );
+    free(qsize );
+    free(llist );
+    free(marker);
+    return;
+  }
+
+  len  = dhead; /* we reuse space */
+  next = qsize; /* we reuse space */
+
+  for (i=0; i<n; i++) len[i] = 0;
+
+  for (j=0; j<n; j++)
+    for (ip = (m->colptr)[j]; ip < (m->colptr)[j+1]; ip++) 
+      {
+       i = (m->rowind)[ip];
+       if (i != j) 
+         {
+           len[i] ++;
+           len[j] ++;
+         }
+      }
+
+  xadj[0] = 1;
+  for (i=1; i<=n; i++) xadj[i] = xadj[i-1] + len[i-1];
+
+  
+  /* use degree as a temporary */
+  for (i=0; i<n; i++) next[i] = xadj[i] - 1;
+
+  for (j=0; j<n; j++)
+    for (ip = (m->colptr)[j]; ip < (m->colptr)[j+1]; ip++) 
+      {
+       i = (m->rowind)[ip];
+       assert( next[i] < 2*nnz-n );
+       assert( next[j] < 2*nnz-n );
+       if (i != j) 
+         {
+           adjncy[ next[i] ] = j+1;
+           adjncy[ next[j] ] = i+1;
+           next[i] ++;
+           next[j] ++;
+         }
+      }
+
+
+  F2C(genmmd)(&n,
+             xadj, adjncy,
+             invp,prm,
+             &delta,
+             dhead,qsize,llist,marker,
+             &maxint,&nofsub);
+
+  free(marker);
+  free(llist );
+  free(qsize );
+  free(dhead );
+  free(xadj  );
+  free(adjncy);
+
+  for (i=0; i<n; i++) prm[i] --;
+  for (i=0; i<n; i++) invp[ prm[i] ] = i;
+
+  *perm    = prm;
+  *invperm = invp;
+}
+
+/*********************************************************/
+/* CCS : create free taucs matrix routines               */
+/*********************************************************/
+
+taucs_ccs_matrix* 
+taucs_ccs_create(int m, int n, int nnz)
+{
+  taucs_ccs_matrix* matrix;
+  int i,j,k;
+
+  matrix = (taucs_ccs_matrix*) malloc(sizeof(taucs_ccs_matrix));
+  if (!matrix) { 
+    sciprint("taucs_ccs_create: out of memory\n\r");
+    return NULL; 
+  }
+  matrix->flags = 0;;
+  matrix->n = n;
+  matrix->m = m;
+  matrix->colptr = (int*)    malloc((n+1) * sizeof(int));
+  matrix->rowind = (int*)    malloc(nnz   * sizeof(int));
+  matrix->values = (double*) malloc(nnz   * sizeof(double));
+  if (!(matrix->colptr) || !(matrix->rowind) || !(matrix->rowind)) {
+    sciprint("taucs_ccs_create: out of memory (n=%d, nnz=%d)\n\r",n,nnz);
+    free(matrix->colptr); free(matrix->rowind); free(matrix->values);
+    free (matrix);
+    return NULL; 
+  }
+
+  return matrix;
+} 
+
+void 
+taucs_ccs_free(taucs_ccs_matrix* matrix)
+{
+  free(matrix->rowind);
+  free(matrix->colptr);
+  free(matrix->values);
+  free(matrix);
+}
+
+/*********************************************************/
+/* CCS : permutation routines                            */
+/*********************************************************/
+
+taucs_ccs_matrix* 
+taucs_ccs_permute_symmetrically(taucs_ccs_matrix* A, int* perm, int* invperm)
+{
+  taucs_ccs_matrix* PAPT;
+  int n;
+  int nnz;
+  int* colptr;
+  int* len;
+  int i,j,ip,I,J;
+  double AIJ;
+
+  /*assert(A->flags & TAUCS_SYMMETRIC);*/
+  assert(A->flags & TAUCS_LOWER);
+
+  n   = A->n;
+  nnz = (A->colptr)[n];
+
+  PAPT = taucs_ccs_create(n,n,nnz);
+  /*PAPT->flags = TAUCS_SYMMETRIC | TAUCS_LOWER;*/
+  PAPT->flags = A->flags;
+
+  len    = (int*) malloc(n * sizeof(int));
+  colptr = (int*) malloc(n * sizeof(int));
+
+  for (j=0; j<n; j++) len[j] = 0;
+
+  for (j=0; j<n; j++) {
+    for (ip = (A->colptr)[j]; ip < (A->colptr)[j+1]; ip++) {
+      /*i = (A->rowind)[ip] - (A->indshift);*/
+      i = (A->rowind)[ip];
+
+      I = invperm[i];
+      J = invperm[j];
+
+      if (I < J) {
+       int T = I; 
+       I = J;
+       J = T;
+      }
+
+      len[J] ++;
+      
+    }
+  }
+
+  (PAPT->colptr)[0] = 0;
+  for (j=1; j<=n; j++) (PAPT->colptr)[j] = (PAPT->colptr)[j-1] + len[j-1];
+
+  for (j=0; j<n; j++) len[j] = (PAPT->colptr)[j];
+  
+  for (j=0; j<n; j++) {
+    for (ip = (A->colptr)[j]; ip < (A->colptr)[j+1]; ip++) {
+      /*i   = (A->rowind)[ip] - (A->indshift);*/
+      i   = (A->rowind)[ip];
+      AIJ = (A->values)[ip];
+
+      I = invperm[i];
+      J = invperm[j];
+
+      if (I < J) {
+       int T = I; 
+       I = J;
+       J = T;
+      }
+
+      /*(PAPT->rowind)[ len[J] ] = I + (PAPT->indshift);*/
+      (PAPT->rowind)[ len[J] ] = I;
+      (PAPT->values)[ len[J] ] = AIJ;
+
+      len[J] ++;
+    }
+  }
+  
+  return PAPT;
+}
+
+void
+taucs_vec_permute(int n, double v[], double pv[], int p[])
+{
+  int i;
+  for (i=0; i<n; i++) pv[i] = v[p[i]];
+} 
+
+void
+taucs_vec_ipermute(int n, double pv[], double v[], int invp[])
+{
+  int i;
+  for (i=0; i<n; i++) v[invp[i]] = pv[i];
+} 
+
+
+/*************************************************************/
+/* create and free the factor object                         */
+/*************************************************************/
+
+static supernodal_factor_matrix*
+multifrontal_supernodal_create()
+{
+  int sn;
+  supernodal_factor_matrix* L;
+  
+  L = (supernodal_factor_matrix*) malloc(sizeof(supernodal_factor_matrix));
+  if (!L) return NULL;
+  L->uplo      = 'l';
+  L->n         = -1; /* unused */
+
+  L->sn_struct   = NULL;
+  L->sn_size     = NULL;
+  L->sn_up_size  = NULL;
+  L->parent      = NULL;
+  L->first_child = NULL;
+  L->next_child  = NULL;
+  L->sn_blocks_ld  = NULL;
+  L->sn_blocks     = NULL;
+  L->up_blocks_ld  = NULL;
+  L->up_blocks     = NULL;
+
+  return L;
+}
+
+void taucs_supernodal_factor_free(void* vL)
+{
+  supernodal_factor_matrix* L = (supernodal_factor_matrix*) vL;
+  int sn;
+  
+  free(L->parent);
+  free(L->first_child);
+  free(L->next_child);
+
+  free(L->sn_size);
+  free(L->sn_up_size);
+  free(L->sn_blocks_ld);
+  free(L->up_blocks_ld);
+
+  for (sn=0; sn<L->n_sn; sn++) {
+    free(L->sn_struct[sn]);
+    free(L->sn_blocks[sn]);
+    free(L->up_blocks[sn]);
+  }
+
+  free(L->sn_struct);
+  free(L->sn_blocks);
+  free(L->up_blocks);
+
+  free(L);
+}
+
+/*************************************************************/
+/* create and free frontal matrices                          */
+/*************************************************************/
+
+static supernodal_frontal_matrix* 
+supernodal_frontal_create(int* firstcol_in_supernode,
+                         int sn_size,
+                         int n, 
+                         int* rowind)
+{
+  int i;
+  supernodal_frontal_matrix* tmp;
+
+  tmp = (supernodal_frontal_matrix*)malloc(sizeof(supernodal_frontal_matrix));
+  if(tmp==NULL) return NULL;
+
+  tmp->sn_size = sn_size;
+  tmp->n = n;
+
+  tmp->rowind = rowind;
+
+  tmp->n = n;
+  tmp->sn_size = sn_size;
+  tmp->up_size = n-sn_size;
+
+  tmp->sn_vertices = rowind;
+  tmp->up_vertices = rowind + sn_size;
+
+  tmp->f1 = (double*)calloc((tmp->sn_size)*(tmp->sn_size),sizeof(double));
+  tmp->f2 = (double*)calloc((tmp->up_size)*(tmp->sn_size),sizeof(double));
+  tmp->u  = (double*)calloc((tmp->up_size)*(tmp->up_size),sizeof(double));
+
+  if(tmp->f1 == NULL || tmp->f2==NULL || tmp->u==NULL) {
+    free(tmp->u);
+    free(tmp->f1);
+    free(tmp->f2);
+    free(tmp);
+    return NULL;
+  }
+
+  assert(tmp);
+  return tmp;
+}
+
+static void supernodal_frontal_free(supernodal_frontal_matrix* to_del)
+{
+  /* f1 and f2 are moved to the factor */
+  free(to_del->u);
+  free(to_del);
+}
+
+
+/*************************************************************/
+/* factor a frontal matrix                                   */
+/*************************************************************/
+
+static int
+multifrontal_supernodal_front_factor(int sn,
+                                    int* firstcol_in_supernode,
+                                    int sn_size,
+                                    taucs_ccs_matrix* A,
+                                    supernodal_frontal_matrix* mtr,
+                                    int* bitmap,
+                                    supernodal_factor_matrix* snL)
+{
+  int i,j;
+  int* ind;
+  double* re;
+  int INFO;
+  double dzero     =  0.0;
+  double done      =  1.0;
+  double dminusone = -1.0;
+
+  /* creating transform for real indices */
+  for(i=0;i<mtr->sn_size;i++) bitmap[mtr->sn_vertices[i]] = i;
+  for(i=0;i<mtr->up_size;i++) bitmap[mtr->up_vertices[i]] = mtr->sn_size + i;
+
+  /* adding sn_size column of A to first sn_size column of frontal matrix */
+  for(j=0;j<(mtr->sn_size);j++) {
+    ind = &(A->rowind[A->colptr[*(firstcol_in_supernode+j)]]);
+    re  = &(A->values[A->colptr[*(firstcol_in_supernode+j)]]); 
+    for(i=0;
+       i < A->colptr[*(firstcol_in_supernode+j)+1] 
+            - A->colptr[*(firstcol_in_supernode+j)];
+       i++) {
+      if (bitmap[ind[i]] < mtr->sn_size)
+       mtr->f1[ (mtr->sn_size)*j + bitmap[ind[i]]] += re[i];
+      else
+       mtr->f2[ (mtr->up_size)*j + bitmap[ind[i]] - mtr->sn_size] += re[i];
+    }
+  }
+
+  /* we use the BLAS through the Fortran interface */
+
+  /* solving of lower triangular system for L */
+  if (mtr->sn_size)
+    F2C(dpotrf)("LOWER",
+               &(mtr->sn_size),
+               mtr->f1,&(mtr->sn_size),
+               &INFO);
+
+  if (INFO) {
+    sciprint("    CC^T Factorization: Matrix is not positive definite.\n\r");
+    sciprint("                        nonpositive pivot in column %d\n\r",
+                mtr->sn_vertices[INFO-1]);
+    return -1;
+  }
+
+  /* getting completion for found columns of L */
+  if (mtr->up_size && mtr->sn_size)
+    F2C(dtrsm)("Right",
+              "Lower",
+              "Transpose",
+              "No unit diagonal",
+              &(mtr->up_size),&(mtr->sn_size),
+              &done,
+              mtr->f1,&(mtr->sn_size),
+              mtr->f2,&(mtr->up_size));
+
+  (snL->sn_blocks   )[sn] = mtr->f1;
+  (snL->sn_blocks_ld)[sn] = mtr->sn_size;
+
+  (snL->up_blocks   )[sn] = mtr->f2;
+  (snL->up_blocks_ld)[sn] = mtr->up_size;
+
+  /* computation of updated part of frontal matrix */
+  if (mtr->up_size && mtr->sn_size)
+    F2C(dsyrk)("Lower",
+              "No Transpose",
+              &(mtr->up_size),&(mtr->sn_size),
+              &dminusone,
+              mtr->f2,&(mtr->up_size),
+              &done,
+              mtr->u, &(mtr->up_size));
+
+  return 0;
+ }
+
+/*************************************************************/
+/* extend-add                                                */
+/*************************************************************/
+
+static void 
+multifrontal_supernodal_front_extend_add(
+                                        supernodal_frontal_matrix* parent_mtr,
+                                        supernodal_frontal_matrix* my_mtr,
+                                        int* bitmap)
+{
+  int j,i,parent_i,parent_j;
+  double v;
+
+  for(i=0;i<parent_mtr->sn_size;i++) bitmap[parent_mtr->sn_vertices[i]] = i;
+  for(i=0;i<parent_mtr->up_size;i++) bitmap[parent_mtr->up_vertices[i]] = (parent_mtr->sn_size)+i;
+
+  /* extend add operation for update matrix */
+  for(j=0;j<my_mtr->up_size;j++) {
+    for(i=j;i<my_mtr->up_size;i++) {
+      parent_j = bitmap[ my_mtr->up_vertices[j] ];
+      parent_i = bitmap[ my_mtr->up_vertices[i] ];
+      /* we could skip this if indices were sorted */
+      if (parent_j>parent_i) {
+       int tmp = parent_j;
+       parent_j = parent_i;
+       parent_i = tmp;
+      }
+
+      v = (my_mtr->u)[(my_mtr->up_size)*j+i];
+
+      if (parent_j < parent_mtr->sn_size) {
+       if (parent_i < parent_mtr->sn_size) {
+         (parent_mtr->f1)[ (parent_mtr->sn_size)*parent_j + parent_i] += v;
+       } else {
+         (parent_mtr->f2)[ (parent_mtr->up_size)*parent_j + (parent_i-parent_mtr->sn_size)] += v;
+       }
+      } else {
+       (parent_mtr->u)[ (parent_mtr->up_size)*(parent_j-parent_mtr->sn_size) + (parent_i-parent_mtr->sn_size)] += v;
+      }
+    }
+  }
+}
+
+/*************************************************************/
+/* symbolic elimination                                      */
+/*************************************************************/
+
+/* UNION FIND ROUTINES */
+
+static int uf_makeset(int* uf, int i)        { uf[i] = i; return i; }
+static int uf_find   (int* uf, int i)        { if (uf[i] != i) 
+                                                 uf[i] = uf_find(uf,uf[i]); 
+                                               return uf[i]; }
+static int uf_union  (int* uf, int s, int t) {
+  
+  if (uf_find(uf,s) < uf_find(uf,t)) {
+    uf[uf_find(uf,s)] = uf_find(uf,t); 
+    return (uf_find(uf,t)); 
+  } else {
+    uf[uf_find(uf,s)] = uf_find(uf,t); 
+    return (uf_find(uf,t)); 
+  }
+}
+
+static
+void recursive_postorder(int  j,
+                        int  first_child[],
+                        int  next_child[],
+                        int  postorder[],
+                        int  ipostorder[],
+                        int* next)
+{
+  int c;
+  for (c=first_child[j]; c != -1; c = next_child[c]) {
+    recursive_postorder(c,first_child,next_child,
+                       postorder,ipostorder,next);
+  }
+
+  if (postorder)  postorder [*next] = j;
+  if (ipostorder) ipostorder[j] = *next;
+  (*next)++;
+}
+
+#define GILBERT_NG_PEYTON_ANALYSIS_SUP
+
+/* in a few tests the supernodal version seemed slower */
+#undef GILBERT_NG_PEYTON_ANALYSIS_SUP
+
+static int ordered_uf_makeset(int* uf, int i)
+{ 
+  uf[i] = i; 
+  return i; 
+}
+static int ordered_uf_find   (int* uf, int i) 
+{ 
+  if (uf[i] != i) 
+    uf[i] = uf_find(uf,uf[i]); 
+  return uf[i]; 
+}
+static int ordered_uf_union  (int* uf, int s, int t) 
+{
+  assert(uf[t] == t);
+  assert(uf[s] == s);
+  assert(t > s);
+  if (t > s) {
+    uf[s] = t; 
+    return t; 
+  } else
+    uf[t] = s; 
+    return s; 
+}
+
+static void 
+tree_level(int j,
+          int isroot, 
+          int first_child[],
+          int next_child[],
+          int level[],
+          int level_j)
+{
+  int c;
+  if (!isroot) level[j] = level_j;
+  for (c=first_child[j]; c != -1; c = next_child[c]) {
+    tree_level(c,
+              FALSE,
+              first_child,
+              next_child,
+              level,
+              level_j+1);
+  }
+}
+
+static void
+tree_first_descendant(int j,
+                     int isroot, 
+                     int first_child[],
+                     int next_child[],
+                     int ipostorder[],
+                     int first_descendant[])
+{
+  int c;
+  int fd = ipostorder[j];
+  for (c=first_child[j]; c != -1; c = next_child[c]) {
+    tree_first_descendant(c,
+                         FALSE,
+                         first_child,
+                         next_child,
+                         ipostorder,
+                         first_descendant);
+    if (first_descendant[c] < fd) fd = first_descendant[c]; 
+  }
+  if (!isroot) first_descendant[j] = fd;
+}
+
+int 
+taucs_ccs_etree(taucs_ccs_matrix* A,
+               int* parent,
+               int* l_colcount,
+               int* l_rowcount,
+               int* l_nnz)
+{
+  int* prev_p;
+  int* prev_nbr;
+  int* level;
+  int* first_descendant;
+  int* l_cc;
+  int* l_rc;
+  int* wt;
+
+  int  n = A->n;
+  int  u,p,q,pprime;
+  int  ju;
+  int* postorder;
+  int* ipostorder;
+  int  *first_child,*next_child;
+
+  int i,j,k,ip,jp,kp;
+  int nnz,jnnz;
+  int* uf;
+  int* rowptr;
+  int* colind;
+  int* rowcount;
+  int* realroot;
+
+  /* we need the row structures for the lower triangle */
+
+  nnz = (A->colptr)[n];
+  
+  uf       = malloc(n     * sizeof(int));
+  rowcount = malloc((n+1) * sizeof(int));
+  rowptr   = malloc((n+1) * sizeof(int));
+  colind   = malloc(nnz   * sizeof(int));
+
+  for (i=0; i <=n; i++) rowcount[i] = 0;
+  for (j=0; j < n; j++) {
+    jnnz = (A->colptr)[j+1] - (A->colptr)[j];
+    for (ip=0; ip<jnnz; ip++) {
+      i = (A->rowind)[(A->colptr)[j] + ip];
+      if (j < i) rowcount[i]++;
+    }
+  }
+
+  ip = 0;
+  for (i=0; i <= n; i++) {
+    int next_ip = ip + rowcount[i];
+    rowcount[i] = ip;
+    rowptr  [i] = ip;
+    ip = next_ip;
+  }
+
+  for (j=0; j < n; j++) {
+    jnnz = (A->colptr)[j+1] - (A->colptr)[j];
+    for (ip=0; ip<jnnz; ip++) {
+      i = (A->rowind)[(A->colptr)[j] + ip];
+      if (i==j) continue;
+      assert( rowcount[i] < rowptr[i+1] );
+      colind[ rowcount[i] ] = j;
+      rowcount[i]++;
+    }
+  }
+
+  /* now compute the etree */
+
+  {
+    int u,t,vroot;
+    realroot = rowcount; /* reuse space */
+
+    for (i=0; i<n; i++) {
+      uf_makeset(uf,i);
+      realroot[i] = i;
+      parent[i] = n;
+      vroot = i;
+      for (kp=rowptr[i]; kp<rowptr[i+1]; kp++) {
+       k=colind[kp];
+       u = uf_find(uf,k);
+       t = realroot[u];
+       if (parent[t] == n && t != i) {
+         parent[t] = i;
+         vroot = uf_union(uf,vroot,u);
+         realroot[vroot] = i;
+       }
+      }
+    }
+  }
+
+  free(colind);
+  free(rowptr);
+  free(rowcount);
+  
+  /* compute column counts */
+
+  if (l_colcount || l_rowcount || l_nnz) {
+    int* l_nz;
+    int  tmp;
+    int  u,p,q;
+
+    first_child = malloc((n+1)     * sizeof(int));
+    next_child  = malloc((n+1)     * sizeof(int));
+    postorder   = malloc(n     * sizeof(int));
+    ipostorder  = malloc(n     * sizeof(int));
+    wt  = malloc(n     * sizeof(int));
+    level = malloc(n     * sizeof(int));
+    prev_p  = malloc(n     * sizeof(int));
+
+#ifdef GILBERT_NG_PEYTON_ANALYSIS_SUP
+    prev_nbr  = malloc(n     * sizeof(int));
+    first_descendant  = malloc(n     * sizeof(int));
+#endif
+
+
+    /* compute the postorder */
+    
+    for (j=0; j<=n; j++) first_child[j] = -1;
+    for (j=n-1; j>=0; j--) {
+      next_child[j] = first_child[parent[j]];
+      first_child[parent[j]] = j;
+    }
+    
+    {
+      int next = 0;
+      recursive_postorder(n,first_child,next_child,
+                         postorder,
+                         ipostorder,&next);
+    }
+    
+    /* we allocate scratch vectors to avoid conditionals */
+    /* in the inner loop.                                */
+
+    if (l_colcount) l_cc = l_colcount;
+    else            l_cc = (int*) malloc(n*sizeof(int));
+    if (l_rowcount) l_rc = l_rowcount;
+    else            l_rc = (int*) malloc(n*sizeof(int));
+    if (l_nnz)      l_nz = l_nnz;
+    else            l_nz = &tmp;
+
+    /* sort by postorder of etree */
+    /* compute level, fst_desc */
+
+    tree_level(n,TRUE,first_child,next_child,
+              level,-1);
+    
+    for (u=0; u < n; u++) prev_p  [u] = -1;
+    for (u=0; u < n; u++) l_rc    [u] =  1;
+    for (u=0; u < n; u++) ordered_uf_makeset(uf,u);
+    for (u=0; u < n; u++) {
+      if (first_child[u] == -1)
+       wt[u] = 1; /* leaves     */
+      else
+       wt[u] =  0; /* nonleaves */
+    }
+
+#ifdef GILBERT_NG_PEYTON_ANALYSIS_SUP
+    for (u=0; u < n; u++) prev_nbr[u] = -1;
+
+    tree_first_descendant(n,TRUE,
+                         first_child,next_child,ipostorder,
+                         first_descendant);
+#endif
+
+    free(first_child);
+    free(next_child);
+
+    for (p=0; p<n; p++) {
+      jp = postorder[p];
+      if (parent[jp] != n) wt[parent[jp]] --;
+      for (ip = (A->colptr)[jp]; ip < (A->colptr)[jp+1]; ip++) {
+       ju = (A->rowind)[ip];
+       u  = ipostorder[ju];
+       if (ju==jp) continue; /* we only want proper neighbors */
+#ifdef GILBERT_NG_PEYTON_ANALYSIS_SUP
+       if (first_descendant[jp] > prev_nbr[u]) {
+#else
+       if (1) {
+#endif
+         wt[jp] ++;
+         pprime = prev_p[ju];
+         if (pprime == -1) 
+           l_rc[ju] += level[jp] - level[ju];
+         else {
+           q = ordered_uf_find(uf,pprime);
+           l_rc[ju] += level[jp] - level[q];
+           wt[q] --;
+         }
+         prev_p[ju] = jp;
+       }
+#ifdef GILBERT_NG_PEYTON_ANALYSIS_SUP
+       prev_nbr[u] = p;
+#endif
+      }
+      if (parent[jp] != n) {
+       if (!(ipostorder[parent[jp]] > ipostorder[jp])) {
+         sciprint("jp %d parent %d (ipo_j %d ipo_parent %d\n\r",
+                  jp,parent[jp],ipostorder[jp],ipostorder[parent[jp]]);
+       }
+       assert(ipostorder[parent[jp]] > ipostorder[jp]);
+       ordered_uf_union(uf,jp,parent[jp]);
+      }
+    }
+
+    *l_nz = 0;
+    for (u=0; u<n; u++) {
+      l_cc[u] = wt[u];
+      *l_nz += wt[u];
+    }
+    for (u=0; u<n; u++) {
+      if (parent[u] != n) {
+       l_cc[parent[u]] += l_cc[u];
+       *l_nz += l_cc[u];
+      }
+    }
+
+    /* free scrtach vectors                              */
+
+    if (!l_colcount) free(l_cc);
+    if (!l_rowcount) free(l_rc);
+
+    /* free other data structures */
+
+    free(postorder);
+    free(ipostorder);
+    free(wt);
+    free(level);
+    free(prev_p);
+    
+#ifdef GILBERT_NG_PEYTON_ANALYSIS_SUP
+    free(prev_nbr);
+    free(first_descendant);
+#endif
+  }
+
+  free(uf);
+}
+
+
+int 
+taucs_ccs_etree_liu(taucs_ccs_matrix* A,
+                   int* parent,
+                   int* l_colcount,
+                   int* l_rowcount,
+                   int* l_nnz)
+{
+  int n = A->n;
+  int i,j,k,ip,jp,kp;
+  int nnz,jnnz;
+
+  int* uf;
+  int* rowptr;
+  int* colind;
+
+  int* rowcount;
+  int* marker;
+  int* realroot;
+
+  int* l_cc;
+  int* l_rc;
+
+  /* we need the row structures for the lower triangle */
+
+  nnz = (A->colptr)[n];
+  
+  uf       = malloc(n     * sizeof(int));
+  rowcount = malloc((n+1) * sizeof(int));
+  rowptr   = malloc((n+1) * sizeof(int));
+  colind   = malloc(nnz   * sizeof(int));
+
+  for (i=0; i <=n; i++) rowcount[i] = 0;
+
+  for (j=0; j < n; j++) {
+    
+    jnnz = (A->colptr)[j+1] - (A->colptr)[j];
+
+    for (ip=0; ip<jnnz; ip++) {
+      i = (A->rowind)[(A->colptr)[j] + ip];
+      if (j < i) rowcount[i]++;
+    }
+  }
+
+  ip = 0;
+  for (i=0; i <= n; i++) {
+    int next_ip = ip + rowcount[i];
+    rowcount[i] = ip;
+    rowptr  [i] = ip;
+    ip = next_ip;
+  }
+
+  for (j=0; j < n; j++) {
+    jnnz = (A->colptr)[j+1] - (A->colptr)[j];
+
+    for (ip=0; ip<jnnz; ip++) {
+      i = (A->rowind)[(A->colptr)[j] + ip];
+      if (i==j) continue;
+      assert( rowcount[i] < rowptr[i+1] );
+      colind[ rowcount[i] ] = j;
+      rowcount[i]++;
+    }
+  }
+
+  /* now compute the etree */
+
+  {
+    int u,t,vroot;
+    realroot = rowcount; /* reuse space */
+
+    for (i=0; i<n; i++) {
+      uf_makeset(uf,i);
+      realroot[i] = i;
+      parent[i] = n;
+      vroot = i;
+      for (kp=rowptr[i]; kp<rowptr[i+1]; kp++) {
+       k=colind[kp];
+       u = uf_find(uf,k);
+       t = realroot[u];
+       if (parent[t] == n && t != i) {
+         parent[t] = i;
+         vroot = uf_union(uf,vroot,u);
+         realroot[vroot] = i;
+       }
+      }
+    }
+  }
+
+  /* compute column counts */
+
+  if (l_colcount || l_rowcount || l_nnz) {
+    int* l_nz;
+    int  tmp;
+
+    /* we allocate scratch vectors to avoid conditionals */
+    /* in the inner loop.                                */
+
+    if (l_colcount) l_cc = l_colcount;
+    else            l_cc = (int*) malloc(n*sizeof(int));
+    if (l_rowcount) l_rc = l_rowcount;
+    else            l_rc = (int*) malloc(n*sizeof(int));
+    if (l_nnz)      l_nz = l_nnz;
+    else            l_nz = &tmp;
+
+    marker = rowcount; /* we reuse the space */
+    
+    for (j=0; j < n; j++) l_cc[j] = 1;
+    *l_nz = n;
+    
+    for (i=0; i<n; i++) marker[i] = n; /* clear the array */
+    
+    for (i=0; i<n; i++) {
+      l_rc[i] = 1;
+      marker[ i ] = i;
+      for (kp=rowptr[i]; kp<rowptr[i+1]; kp++) {
+       k=colind[kp];
+       j=k;
+       while (marker[j] != i) {
+         l_cc[j]++;
+         l_rc[i]++;
+         (*l_nz)++;
+         marker[j] = i;
+         j = parent[j];
+       }
+      }
+    }
+
+    /* free scrtach vectors                              */
+
+    if (!l_colcount) free(l_cc);
+    if (!l_rowcount) free(l_rc);
+  }
+
+  free(colind);
+  free(rowptr);
+  free(rowcount);
+  free(uf);
+}
+
+static void
+recursive_symbolic_elimination(int            j,
+                              taucs_ccs_matrix* A,
+                              int            first_child[],
+                              int            next_child[],
+                              int*           n_sn,
+                              int            sn_size[],
+                              int            sn_up_size[],
+                              int*           sn_rowind[],
+                              int            sn_first_child[], 
+                              int            sn_next_child[], 
+                              int            rowind[],
+                              int            column_to_sn_map[],
+                              int            map[],
+                              int            do_order,
+                              int            ipostorder[]
+                              )
+{
+  int  i,ip,c,c_sn;
+  int  in_previous_sn;
+  int  nnz;
+  
+  for (c=first_child[j]; c != -1; c = next_child[c]) {
+    recursive_symbolic_elimination(c,A,
+                                  first_child,next_child,
+                                  n_sn,
+                                  sn_size,sn_up_size,sn_rowind,
+                                  sn_first_child,sn_next_child,
+                                  rowind, /* temporary */
+                                  column_to_sn_map,
+                                  map,
+                                  do_order,ipostorder
+                                  );
+  }
+
+  in_previous_sn = 1;
+  if (j == A->n) 
+    in_previous_sn = 0; /* this is not a real column */
+  else if (first_child[j] == -1) 
+    in_previous_sn = 0; /* this is a leaf */
+  else if (next_child[first_child[j]] != -1) 
+    in_previous_sn = 0; /* more than 1 child */
+  else { 
+    /* check that the structure is nested */
+    /* map contains child markers         */
+
+    c=first_child[j];
+    for (ip=(A->colptr)[j]; ip<(A->colptr)[j+1]; ip++) {
+      i = (A->rowind)[ip];
+      in_previous_sn = in_previous_sn && (map[i] == c);
+    }
+  }
+
+  if (in_previous_sn) {
+    c = first_child[j];
+    c_sn = column_to_sn_map[c];
+    column_to_sn_map[j] = c_sn;
+
+    /* swap row indices so j is at the end of the */
+    /* supernode, not in the update indices       */
+    for (ip=sn_size[c_sn]; ip<sn_up_size[c_sn]; ip++) 
+      if (sn_rowind[c_sn][ip] == j) break;
+    assert(ip<sn_up_size[c_sn]);
+    sn_rowind[c_sn][ip] = sn_rowind[c_sn][sn_size[c_sn]];
+    sn_rowind[c_sn][sn_size[c_sn]] = j;
+
+    /* mark the nonzeros in the map */
+    for (ip=sn_size[c_sn]; ip<sn_up_size[c_sn]; ip++) 
+      map[ sn_rowind[c_sn][ip] ] = j;
+
+    sn_size   [c_sn]++;
+
+    return;
+  }
+
+  /* we are in a new supernode */
+
+  if (j < A->n) {
+    nnz = 1;
+    rowind[0] = j;
+    map[j]    = j;
+    
+    for (c=first_child[j]; c != -1; c = next_child[c]) {
+      c_sn = column_to_sn_map[c];
+      for (ip=sn_size[c_sn]; ip<sn_up_size[c_sn]; ip++) {
+       i = sn_rowind[c_sn][ip];
+       if (i > j && map[i] != j) { /* new row index */
+         map[i] = j;
+         rowind[nnz] = i;
+         nnz++;
+       }
+      }
+    }
+    
+    for (ip=(A->colptr)[j]; ip<(A->colptr)[j+1]; ip++) {
+      i = (A->rowind)[ip];
+      if (map[i] != j) { /* new row index */
+       map[i] = j;
+       rowind[nnz] = i;
+       nnz++;
+      }
+    }
+  }
+    
+  /*printf("children of sn %d: ",*n_sn);*/
+  for (c=first_child[j]; c != -1; c = next_child[c]) {
+    c_sn = column_to_sn_map[c];
+    /*printf("%d ",c_sn);*/
+    if (c==first_child[j])
+      sn_first_child[*n_sn] = c_sn;
+    else {
+      sn_next_child[ c_sn ] = sn_first_child[*n_sn];
+      sn_first_child[*n_sn] = c_sn;
+    }
+  }
+  /*printf("\n");*/
+
+  if (j < A->n) {
+    column_to_sn_map[j] = *n_sn;
+    sn_size   [*n_sn] = 1;
+    sn_up_size[*n_sn] = nnz;
+    sn_rowind [*n_sn] = (int*) malloc(nnz * sizeof(int));
+    for (ip=0; ip<nnz; ip++) sn_rowind[*n_sn][ip] = rowind[ip];
+    if (do_order) {
+      /* Sivan and Vladimir: we think that we can sort in */
+      /* column order, not only in etree postorder.       */
+      /*
+       radix_sort(sn_rowind [*n_sn],nnz);
+       qsort(sn_rowind [*n_sn],nnz,sizeof(int),compare_ints);
+      */
+      compare_indirect_map = ipostorder;
+      qsort(sn_rowind [*n_sn],nnz,sizeof(int),compare_indirect_ints);
+    }
+    assert(sn_rowind [*n_sn][0] == j);
+    (*n_sn)++;
+  }
+
+  return;
+}
+
+/* count zeros and nonzeros in a supernode to compute the */
+/* utility of merging fundamental supernodes.             */
+
+typedef struct {
+  double zeros;
+  double nonzeros;
+} znz;
+
+static znz
+recursive_amalgamate_supernodes(int           sn,
+                               int*           n_sn,
+                               int            sn_size[],
+                               int            sn_up_size[],
+                               int*           sn_rowind[],
+                               int            sn_first_child[], 
+                               int            sn_next_child[], 
+                               int            rowind[],
+                               int            column_to_sn_map[],
+                               int            map[],
+                               int            do_order,
+                               int            ipostorder[]
+                               )
+{
+  int  i,ip,c,c_sn,gc_sn;
+  int  nnz;
+  int  nchildren, ichild; /* number of children, child index */
+  znz* c_znz;
+  znz  sn_znz, merged_znz;
+  int zero_count = 0;
+  int new_sn_size, new_sn_up_size;
+
+  sn_znz.zeros    = 0.0;
+  sn_znz.nonzeros = (double) (((sn_up_size[sn] - sn_size[sn]) * sn_size[sn]) 
+                              + (sn_size[sn] * (sn_size[sn] + 1))/2);
+
+  if (sn_first_child[sn] == -1) { /* leaf */
+    return sn_znz;
+  }
+
+  nchildren = 0;
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn])
+    nchildren++;
+
+  c_znz = (znz*) alloca(nchildren * sizeof(znz));
+
+  //printf("supernode %d out of %d\n",sn,*n_sn);
+
+  /* merge the supernode with its children! */
+
+  i = 0;
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+    c_znz[i] = 
+      recursive_amalgamate_supernodes(c_sn,
+                                     n_sn,
+                                     sn_size,sn_up_size,sn_rowind,
+                                     sn_first_child,sn_next_child,
+                                     rowind, /* temporary */
+                                     column_to_sn_map,
+                                     map,
+                                     do_order,ipostorder
+                                     );
+    assert(c_znz[i].zeros + c_znz[i].nonzeros ==
+          (double) (((sn_up_size[c_sn] - sn_size[c_sn]) * sn_size[c_sn]) 
+                    + (sn_size[c_sn] * (sn_size[c_sn] + 1))/2 ));
+    i++;
+  }
+
+  merged_znz.nonzeros = sn_znz.nonzeros;
+  merged_znz.zeros    = sn_znz.zeros;
+                   
+  for (i=0; i<nchildren; i++) {
+    merged_znz.nonzeros += (c_znz[i]).nonzeros;
+    merged_znz.zeros    += (c_znz[i]).zeros;
+  }
+
+  /*  printf("supernode %d out of %d (continuing)\n",sn,*n_sn);*/
+
+  /* should we merge the supernode with its children? */
+
+  nnz = 0;
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+    for (ip=0; ip<sn_size[c_sn]; ip++) {
+      i = sn_rowind[c_sn][ip];
+      assert( map[i] != sn );
+      map[i] = sn;
+      rowind[nnz] = i;
+      nnz++;
+    }
+  }
+
+  for (ip=0; ip<sn_size[sn]; ip++) {
+    i = sn_rowind[sn][ip];
+    assert( map[i] != sn );
+    map[i] = sn;
+    rowind[nnz] = i;
+    nnz++;
+  }
+
+  new_sn_size = nnz;
+
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+    for (ip=sn_size[c_sn]; ip<sn_up_size[c_sn]; ip++) {
+      i = sn_rowind[c_sn][ip];
+      if (map[i] != sn) { /* new row index */
+       map[i] = sn;
+       rowind[nnz] = i;
+       nnz++;
+      }
+    }
+  }
+
+  for (ip=sn_size[sn]; ip<sn_up_size[sn]; ip++) {
+    i = sn_rowind[sn][ip];
+    if (map[i] != sn) { /* new row index */
+      map[i] = sn;
+      rowind[nnz] = i;
+      nnz++;
+    }
+  }
+  
+  new_sn_up_size = nnz;
+
+  if (do_order) {
+    compare_indirect_map = ipostorder;
+    qsort(rowind,nnz,sizeof(int),compare_indirect_ints);
+  }
+
+  /* determine whether we should merge the supernode and its children */
+
+  {
+    int n;
+    double* zcount;
+
+    n = 0;
+    for (ip=0; ip<nnz; ip++) {
+      i = rowind[ip];
+      if (i >= n) n = i+1;
+    }
+
+    zcount = (double*) alloca(n * sizeof(double));
+    assert(zcount);
+    
+    for (ip=0; ip<new_sn_size; ip++) {
+      i = rowind[ip]; assert(i<n);
+      zcount[i] = (double) (ip+1);
+    }
+    for (ip=new_sn_size; ip<new_sn_up_size; ip++) {
+      i = rowind[ip]; assert(i<n);
+      zcount[i] = (double) new_sn_size;
+    }
+
+    /*
+    for (ip=0; ip<new_sn_up_size; ip++) 
+      printf("row %d zcount = %.0f\n",rowind[ip],zcount[rowind[ip]]);
+    */
+    
+    for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+      for (ip=0; ip<sn_size[c_sn]; ip++) {
+       i = sn_rowind[c_sn][ip]; assert(i<n);
+       zcount[i] -= (double) (ip+1);
+      }
+      for (ip=sn_size[c_sn]; ip<sn_up_size[c_sn]; ip++) {
+       i = sn_rowind[c_sn][ip]; assert(i<n);
+       zcount[i] -= (double) sn_size[c_sn];
+      }
+    }
+
+    for (ip=0; ip<sn_size[sn]; ip++) {
+      i = sn_rowind[sn][ip]; assert(i<n);
+      zcount[i] -= (double) (ip+1);
+    }
+    for (ip=sn_size[sn]; ip<sn_up_size[sn]; ip++) {
+      i = sn_rowind[sn][ip]; assert(i<n);
+      zcount[i] -= (double) sn_size[sn];
+    }
+
+    /*
+    for (ip=0; ip<new_sn_up_size; ip++) 
+      printf("ROW %d zcount = %.0f\n",rowind[ip],zcount[rowind[ip]]);
+    printf("zeros before merging %.0f\n",merged_znz.zeros);
+    */
+    
+    for (ip=0; ip<new_sn_up_size; ip++) {
+      i = rowind[ip]; assert(i<n);
+      assert(zcount[i] >= 0.0);
+      merged_znz.zeros += zcount[i];
+    }
+
+    /*printf("zeros after merging %.0f\n",merged_znz.zeros);*/
+
+    /* voodoo constants (need some kind of a utility function */
+    if ((new_sn_size < 16)
+       ||
+       ((sn_size[sn] < 50) && (merged_znz.zeros < 0.5 * merged_znz.nonzeros))
+       ||
+       ((sn_size[sn] < 250) && (merged_znz.zeros < 0.25 * merged_znz.nonzeros))
+       ||
+       ((sn_size[sn] < 500) && (merged_znz.zeros < 0.10 * merged_znz.nonzeros))
+       ||
+       (merged_znz.zeros < 0.05 * merged_znz.nonzeros)
+       ) {
+      /*
+      taucs_printf("merging sn %d, zeros (%f) vs nonzeros (%f)\n",
+                  sn,merged_znz.zeros,merged_znz.nonzeros);
+      */
+    } else {
+      /*
+      taucs_printf("sn %d, too many zeros (%f) vs nonzeros (%f)\n",
+                  sn,merged_znz.zeros,merged_znz.nonzeros);
+      printf("returning without merging\n");
+      */
+      return sn_znz;
+    }
+  }
+
+  /* now merge the children lists */
+
+  sn_size[sn]    = new_sn_size;
+  sn_up_size[sn] = new_sn_up_size;
+  sn_rowind[sn]  = (int*) realloc(sn_rowind[sn], 
+                                 new_sn_up_size * sizeof(int));
+  for (ip=0; ip<new_sn_up_size; ip++) sn_rowind[sn][ip] = rowind[ip];
+
+  //  printf("supernode %d out of %d (merging)\n",sn,*n_sn);
+
+  nchildren = 0;
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+    for (ip=0; ip<sn_size[c_sn]; ip++) {
+      i = (sn_rowind[c_sn])[ip];
+      assert(column_to_sn_map[i] == c_sn);
+      column_to_sn_map[i] = sn;
+    }
+
+    for (gc_sn=sn_first_child[c_sn]; gc_sn != -1; gc_sn = sn_next_child[gc_sn]) {
+      rowind[nchildren] = gc_sn;
+      nchildren++;
+    }
+  }
+
+  /* free the children's rowind vectors */
+  for (c_sn=sn_first_child[sn]; c_sn != -1; c_sn = sn_next_child[c_sn]) {
+    free( sn_rowind[c_sn] );
+    sn_rowind[c_sn]  = NULL;
+    sn_size[c_sn]    = 0;
+    sn_up_size[c_sn] = 0;
+  }
+
+  sn_first_child[sn] = -1;
+  for (i=0; i<nchildren; i++) {
+    sn_next_child[ rowind[i] ] = sn_first_child[sn];
+    sn_first_child[sn] = rowind[i];
+  }    
+
+  /*
+  printf("supernode %d out of %d (done)\n",sn,*n_sn);
+  printf("returning, merging\n");
+  */
+  return merged_znz;
+}
+
+int      
+taucs_ccs_symbolic_elimination(taucs_ccs_matrix* A,
+                              void* vL,
+                              int do_order
+                              )
+{
+  supernodal_factor_matrix* L = (supernodal_factor_matrix*) vL;
+  int* first_child;
+  int* next_child;
+  int j;
+  int* column_to_sn_map;
+  int* map;
+  int* rowind;
+  int* parent;
+  int* ipostorder;
+
+  L->n         = A->n;
+  L->sn_struct = (int**)malloc((A->n  )*sizeof(int*));
+  L->sn_size   = (int*) malloc((A->n+1)*sizeof(int));
+  
+  L->sn_up_size   = (int*) malloc((A->n+1)*sizeof(int));
+  L->first_child = (int*) malloc((A->n+1)*sizeof(int));
+  L->next_child  = (int*) malloc((A->n+1)*sizeof(int));
+  
+  column_to_sn_map = (int*)malloc((A->n+1)*sizeof(int));
+  map              = (int*) malloc((A->n+1)*sizeof(int));
+
+  first_child = (int*) malloc(((A->n)+1)*sizeof(int));
+  next_child  = (int*) malloc(((A->n)+1)*sizeof(int));
+    
+  rowind      = (int*) malloc((A->n)*sizeof(int));
+
+  /* compute the vertex elimination tree */
+  parent      = (int*)malloc((A->n+1)*sizeof(int));
+
+  taucs_ccs_etree(A,parent,NULL,NULL,NULL);
+
+  if (0) {
+    int *cc1,*cc2,*rc1,*rc2;
+    int *p1;
+    int nnz1,nnz2;
+
+    cc1=(int*)malloc((A->n)*sizeof(int));
+    cc2=(int*)malloc((A->n)*sizeof(int));
+    rc1=(int*)malloc((A->n)*sizeof(int));
+    rc2=(int*)malloc((A->n)*sizeof(int));
+    p1 =(int*)malloc((A->n)*sizeof(int));
+
+    taucs_ccs_etree_liu(A,parent,cc1,rc1,&nnz1);
+
+    taucs_ccs_etree(A,p1,cc2,rc2,&nnz2);
+
+    for (j=0; j<(A->n); j++) assert(parent[j]==p1[j]);
+    for (j=0; j<(A->n); j++) {
+      if (cc1[j]!=cc2[j]) sciprint("j=%d cc1=%d cc2=%d\n\r",j,cc1[j],cc2[j]);
+      assert(cc1[j]==cc2[j]);
+    }
+
+    for (j=0; j<(A->n); j++) {
+      if (rc1[j]!=rc2[j]) sciprint("j=%d rc1=%d rc2=%d\n\r",j,rc1[j],rc2[j]);
+      assert(rc1[j]==rc2[j]);
+    }
+
+    if (nnz1!=nnz2) sciprint("nnz1=%d nnz2=%d\n\r",nnz1,nnz2);
+    
+    free(cc1); free(cc2); free(rc1); free(rc2);
+  }
+
+  for (j=0; j <= (A->n); j++) first_child[j] = -1;
+  for (j = (A->n)-1; j >= 0; j--) {
+    int p = parent[j];
+    next_child[j] = first_child[p];
+    first_child[p] = j;
+  }
+  free(parent);
+
+  ipostorder = (int*)malloc((A->n+1)*sizeof(int));
+  { 
+    int next = 0;
+    /*int* postorder = (int*)malloc((A->n+1)*sizeof(int));*/
+    recursive_postorder(A->n,first_child,next_child,
+                       NULL,
+                       ipostorder,&next);
+    /*
+    printf("ipostorder ");
+    for (j=0; j <= (A->n); j++) printf("%d ",ipostorder[j]);
+    printf("\n");
+    printf(" postorder ");
+    for (j=0; j <= (A->n); j++) printf("%d ",postorder[j]);
+    printf("\n");
+    */
+  }
+
+  L->n_sn = 0;
+  for (j=0; j < (A->n); j++) map[j] = -1;
+  for (j=0; j <= (A->n); j++) (L->first_child)[j] = (L->next_child)[j] = -1;
+  
+  recursive_symbolic_elimination(A->n,
+                                A,
+                                first_child,next_child,
+                                &(L->n_sn),
+                                L->sn_size,L->sn_up_size,L->sn_struct,
+                                L->first_child,L->next_child,
+                                rowind,
+                                column_to_sn_map,
+                                map,
+                                do_order,ipostorder
+                                );
+
+  {
+    double nnz   = 0.0;
+    double flops = 0.0;
+    int sn,i,colnnz;
+    for (sn=0; sn<(L->n_sn); sn++) {
+      for (i=0, colnnz = (L->sn_up_size)[sn]; 
+          i<(L->sn_size)[sn]; 
+          i++, colnnz--) {
+       flops += ((double)(colnnz) - 1.0) * ((double)(colnnz) + 2.0) / 2.0;
+       nnz   += (double) (colnnz);
+      }
+    }
+    /*sciprint("\t\tSymbolic Analysis of CC^T: %.2e nonzeros, %.2e flops\n",
+      nnz, flops); */
+  }
+
+  for (j=0; j < (A->n); j++) map[j] = -1;
+
+  (void) recursive_amalgamate_supernodes((L->n_sn) - 1,
+                                        &(L->n_sn),
+                                        L->sn_size,L->sn_up_size,L->sn_struct,
+                                        L->first_child,L->next_child,
+                                        rowind,
+                                        column_to_sn_map,
+                                        map,
+                                        do_order,ipostorder
+                                        );
+
+
+  {
+    double nnz   = 0.0;
+    double flops = 0.0;
+    int sn,i,colnnz;
+    for (sn=0; sn<(L->n_sn); sn++) {
+      for (i=0, colnnz = (L->sn_up_size)[sn]; 
+          i<(L->sn_size)[sn]; 
+          i++, colnnz--) {
+       flops += ((double)(colnnz) - 1.0) * ((double)(colnnz) + 2.0) / 2.0;
+       nnz   += (double) (colnnz);
+      }
+    }
+    /*sciprint("\t\tRelaxed  Analysis of LL^T: %.2e nonzeros, %.2e flops\n",
+      nnz, flops); */
+  }
+
+  /*
+  {
+    int i;
+    printf("c2sn: ");
+    for (i=0; i<A->n; i++) printf("%d ",column_to_sn_map[i]);
+    printf("\n");
+  }
+  */
+  
+
+
+  L->sn_blocks_ld  = malloc((L->n_sn) * sizeof(int));
+  L->sn_blocks     = calloc((L->n_sn), sizeof(double*)); /* so we can free before allocation */
+  
+  L->up_blocks_ld  = malloc((L->n_sn) * sizeof(int));
+  L->up_blocks     = calloc((L->n_sn), sizeof(double*));
+
+  free(rowind);
+  free(map);
+  free(column_to_sn_map);
+  free(next_child);
+  free(first_child);
+}
+
+
+/*************************************************************/
+/* factor routines                                           */
+/*************************************************************/
+
+static supernodal_frontal_matrix*
+recursive_multifrontal_supernodal_factor_llt(int sn,       /* this supernode */
+                                            int is_root,  /* is v the root? */
+                                            int* bitmap,
+                                            taucs_ccs_matrix* A,
+                                            supernodal_factor_matrix* snL,
+                                            int* fail)
+{
+  supernodal_frontal_matrix* my_matrix=NULL;
+  supernodal_frontal_matrix* child_matrix=NULL;
+  int child;
+  int* v; 
+  int  sn_size;
+  int* first_child   = snL->first_child;
+  int* next_child    = snL->next_child;
+
+  v = &( snL->sn_struct[sn][0] );
+
+  if (!is_root)
+    sn_size = snL->sn_size[sn];
+  else
+    sn_size = -1;
+
+  for (child = first_child[sn]; child != -1; child = next_child[child]) {
+    child_matrix = 
+      recursive_multifrontal_supernodal_factor_llt(child,
+                                                  FALSE,
+                                                  bitmap,
+                                                  A,snL,fail);
+    if (*fail) { 
+      if (my_matrix) supernodal_frontal_free(my_matrix);
+      return NULL;
+    }
+
+    if (!is_root) {
+      if (!my_matrix) {
+       my_matrix =  supernodal_frontal_create(v,sn_size,
+                                              snL->sn_up_size[sn],
+                                              snL->sn_struct[sn]);
+       if (!my_matrix) {
+         *fail = TRUE;
+         supernodal_frontal_free(child_matrix);
+         return NULL;
+       }
+      }
+
+      multifrontal_supernodal_front_extend_add(my_matrix,child_matrix,bitmap);
+      supernodal_frontal_free(child_matrix);
+    }
+  }
+
+  /* in case we have no children, we allocate now */
+  if (!is_root && !my_matrix) 
+    my_matrix =  supernodal_frontal_create(v,sn_size,
+                                          snL->sn_up_size[sn],
+                                          snL->sn_struct[sn]);
+
+  if(!is_root) {
+    if (multifrontal_supernodal_front_factor(sn,
+                                            v,sn_size,
+                                            A,
+                                            my_matrix,
+                                            bitmap,
+                                            snL)) { 
+      /* nonpositive pivot */
+      *fail = TRUE;
+      supernodal_frontal_free(my_matrix);
+      return NULL;
+    }
+  }
+  return my_matrix;
+}
+
+void* taucs_ccs_factor_llt_mf(taucs_ccs_matrix* A)
+{
+  supernodal_factor_matrix* L;
+  int i,j,ip,jp;
+  int sn,p;
+  int* map;
+  int fail;
+
+  L = multifrontal_supernodal_create();
+
+  taucs_ccs_symbolic_elimination(A,L,
+                                FALSE /* don't sort row indices */ );
+
+  map = (int*)malloc((A->n+1)*sizeof(int));
+
+  fail = FALSE;
+  recursive_multifrontal_supernodal_factor_llt((L->n_sn),  
+                                              TRUE, 
+                                              map,
+                                              A,L,&fail);
+
+  free(map);
+
+  if (fail) {
+    taucs_supernodal_factor_free(L);
+    return NULL;
+  }
+
+  return (void*) L;
+}
+
+
+/*************************************************************/
+/* supernodal solve routines                                 */
+/*************************************************************/
+
+static void 
+recursive_supernodal_solve_l(int sn,       /* this supernode */
+                            int is_root,  /* is v the root? */
+                            int* first_child, int* next_child,
+                            int** sn_struct, int* sn_sizes, int* sn_up_sizes,
+                            int* sn_blocks_ld,double* sn_blocks[],
+                            int* up_blocks_ld,double* up_blocks[],
+                            double x[], double b[],
+                            double t[])
+{
+  int child;
+  int  sn_size; /* number of rows/columns in the supernode    */
+  int  up_size; /* number of rows that this supernode updates */
+  int    ione = 1;
+  double done = 1.0;
+  double dzero = 0.0;
+  double* xdense;
+  double* bdense;
+  double  flops;
+  int i,j,ip,jp;
+
+  for (child = first_child[sn]; child != -1; child = next_child[child]) {
+    recursive_supernodal_solve_l(child,
+                                FALSE,
+                                first_child,next_child,
+                                sn_struct,sn_sizes,sn_up_sizes,
+                                sn_blocks_ld,sn_blocks,
+                                up_blocks_ld,up_blocks,
+                                x,b,t);
+  }
+
+  if(!is_root) {
+
+    sn_size = sn_sizes[sn];
+    up_size = sn_up_sizes[sn] - sn_sizes[sn];
+
+    flops = ((double)sn_size)*((double)sn_size) 
+      + 2.0*((double)sn_size)*((double)up_size);
+
+    if (flops > BLAS_FLOPS_CUTOFF) {
+      xdense = t;
+      bdense = t + sn_size;
+      
+      for (i=0; i<sn_size; i++)
+       xdense[i] = b[ sn_struct[ sn ][ i ] ];
+      for (i=0; i<up_size; i++)
+       bdense[i] = 0.0;
+      
+      F2C(dtrsm)("Left",
+                "Lower",
+                "No Transpose",
+                "No unit diagonal",
+                &sn_size,&ione,
+                &done,
+                sn_blocks[sn],&(sn_blocks_ld[sn]),
+                xdense       ,&sn_size);
+      
+      if (up_size > 0 & sn_size > 0) {
+       F2C(dgemm)("No Transpose","No Transpose",
+                  &up_size, &ione, &sn_size,
+                  &done,
+                  up_blocks[sn],&(up_blocks_ld[sn]),
+                  xdense       ,&sn_size,
+                  &dzero,
+                  bdense       ,&up_size);
+      }
+      
+      for (i=0; i<sn_size; i++)
+       x[ sn_struct[ sn][ i ] ]  = xdense[i];
+      for (i=0; i<up_size; i++)
+       b[ sn_struct[ sn ][ sn_size + i ] ] -= bdense[i];
+
+    } else if (sn_size > SOLVE_DENSE_CUTOFF) {
+
+      xdense = t;
+      bdense = t + sn_size;
+      
+      for (i=0; i<sn_size; i++)
+       xdense[i] = b[ sn_struct[ sn ][ i ] ];
+      for (i=0; i<up_size; i++)
+       bdense[i] = 0.0;
+      
+      for (jp=0; jp<sn_size; jp++) {
+       xdense[jp] = xdense[jp] / sn_blocks[sn][ sn_blocks_ld[sn]*jp + jp];
+
+       for (ip=jp+1; ip<sn_size; ip++) {
+         xdense[ip] -= xdense[jp] * sn_blocks[sn][ sn_blocks_ld[sn]*jp + ip];
+       }
+      }
+
+      for (jp=0; jp<sn_size; jp++) {
+       for (ip=0; ip<up_size; ip++) {
+         bdense[ip] += xdense[jp] * up_blocks[sn][ up_blocks_ld[sn]*jp + ip];
+       }
+      }
+
+      for (i=0; i<sn_size; i++)
+       x[ sn_struct[ sn][ i ] ]  = xdense[i];
+      for (i=0; i<up_size; i++)
+       b[ sn_struct[ sn ][ sn_size + i ] ] -= bdense[i];
+      
+    } else {
+
+      for (jp=0; jp<sn_size; jp++) {
+       j = sn_struct[sn][jp];
+       x[j] = b[j] / sn_blocks[sn][ sn_blocks_ld[sn]*jp + jp];
+       for (ip=jp+1; ip<sn_size; ip++) {
+         i = sn_struct[sn][ip];
+         b[i] -= x[j] * sn_blocks[sn][ sn_blocks_ld[sn]*jp + ip];
+       }
+
+       for (ip=0; ip<up_size; ip++) {
+         i = sn_struct[sn][sn_size + ip];
+         b[i] -= x[j] * up_blocks[sn][ up_blocks_ld[sn]*jp + ip];
+       }
+      }
+
+    }
+  }
+}
+
+static void 
+recursive_supernodal_solve_lt(int sn,       /* this supernode */
+                             int is_root,  /* is v the root? */
+                             int* first_child, int* next_child,
+                             int** sn_struct, int* sn_sizes, int* sn_up_sizes,
+                             int* sn_blocks_ld,double* sn_blocks[],
+                             int* up_blocks_ld,double* up_blocks[],
+                             double x[], double b[],
+                             double t[])
+{
+  int child;
+  int  sn_size; /* number of rows/columns in the supernode    */
+  int  up_size; /* number of rows that this supernode updates */
+  int    ione = 1;
+  double done = 1.0;
+  double dminusone = -1.0;
+  double dzero = 0.0;
+  double* xdense;
+  double* bdense;
+  double  flops;
+  int i,j,ip,jp;
+
+  if(!is_root) {
+
+    sn_size = sn_sizes[sn];
+    up_size = sn_up_sizes[sn]-sn_sizes[sn];
+    
+    flops = ((double)sn_size)*((double)sn_size) 
+      + 2.0*((double)sn_size)*((double)up_size);
+
+    if (flops > BLAS_FLOPS_CUTOFF) {
+
+      bdense = t;
+      xdense = t + sn_size;
+      
+      for (i=0; i<sn_size; i++)
+       bdense[i] = b[ sn_struct[ sn][ i ] ];
+      for (i=0; i<up_size; i++)
+       xdense[i] = x[ sn_struct[sn][sn_size+i] ];
+      
+      if (up_size > 0 & sn_size > 0)
+       F2C(dgemm)("Transpose","No Transpose",
+                  &sn_size, &ione, &up_size,
+                  &dminusone,
+                  up_blocks[sn],&(up_blocks_ld[sn]),
+                  xdense       ,&up_size,
+                  &done,
+                  bdense       ,&sn_size);
+      
+      F2C(dtrsm)("Left",
+                "Lower",
+                "Transpose",
+                "No unit diagonal",
+                &sn_size,&ione,
+                &done,
+                sn_blocks[sn],&(sn_blocks_ld[sn]),
+                bdense       ,&sn_size);
+      
+      for (i=0; i<sn_size; i++)
+       x[ sn_struct[ sn][ i ] ]  = bdense[i];
+    
+    } else if (sn_size > SOLVE_DENSE_CUTOFF) {
+
+      bdense = t;
+      xdense = t + sn_size;
+      
+      for (i=0; i<sn_size; i++)
+       bdense[i] = b[ sn_struct[ sn][ i ] ];
+      for (i=0; i<up_size; i++)
+       xdense[i] = x[ sn_struct[sn][sn_size+i] ];
+      
+      for (ip=sn_size-1; ip>=0; ip--) {
+       for (jp=0; jp<up_size; jp++) {
+         bdense[ip] -= xdense[jp] * up_blocks[sn][ up_blocks_ld[sn]*ip + jp];
+       }
+      }
+
+      for (ip=sn_size-1; ip>=0; ip--) {
+       for (jp=sn_size-1; jp>ip; jp--) {
+         bdense[ip] -= bdense[jp] * sn_blocks[sn][ sn_blocks_ld[sn]*ip + jp];
+       }
+       bdense[ip] = bdense[ip] / sn_blocks[sn][ sn_blocks_ld[sn]*ip + ip];
+      }
+
+      for (i=0; i<sn_size; i++)
+       x[ sn_struct[ sn][ i ] ]  = bdense[i];
+    
+    } else {
+
+      for (ip=sn_size-1; ip>=0; ip--) {
+       i = sn_struct[sn][ip];
+
+       for (jp=0; jp<up_size; jp++) {
+         j = sn_struct[sn][sn_size + jp];
+         b[i] -= x[j] * up_blocks[sn][ up_blocks_ld[sn]*ip + jp];
+       }
+
+       for (jp=sn_size-1; jp>ip; jp--) {
+         j = sn_struct[sn][jp];
+         b[i] -= x[j] * sn_blocks[sn][ sn_blocks_ld[sn]*ip + jp];
+       }
+       x[i] = b[i] / sn_blocks[sn][ sn_blocks_ld[sn]*ip + ip];
+
+      }
+
+    }
+  }
+
+  for (child = first_child[sn]; child != -1; child = next_child[child]) {
+    recursive_supernodal_solve_lt(child,
+                                 FALSE,
+                                 first_child,next_child,
+                                 sn_struct,sn_sizes,sn_up_sizes,
+                                 sn_blocks_ld,sn_blocks,
+                                 up_blocks_ld,up_blocks,
+                                 x,b,t);
+  }
+}
+
+int taucs_supernodal_solve_llt(void* vL,
+                              double* x, double* b)
+{
+  supernodal_factor_matrix* L = (supernodal_factor_matrix*) vL;
+  double* y;
+  double* t; /* temporary vector */
+  int     i;
+  
+  y = malloc((L->n) * sizeof(double));
+  t = malloc((L->n) * sizeof(double));
+  if (!y || !t) {
+    free(y);
+    free(t);
+    sciprint("multifrontal_supernodal_solve_llt: out of memory\n\r");
+    return -1;
+  }
+
+  for (i=0; i<L->n; i++) x[i] = b[i];
+
+  recursive_supernodal_solve_l (L->n_sn,
+                               TRUE,  /* this is the root */
+                               L->first_child, L->next_child,
+                               L->sn_struct,L->sn_size,L->sn_up_size,
+                               L->sn_blocks_ld, L->sn_blocks,
+                               L->up_blocks_ld, L->up_blocks,
+                               y, x, t);
+
+  recursive_supernodal_solve_lt(L->n_sn,
+                               TRUE,  /* this is the root */
+                               L->first_child, L->next_child,
+                               L->sn_struct,L->sn_size,L->sn_up_size,
+                               L->sn_blocks_ld, L->sn_blocks,
+                               L->up_blocks_ld, L->up_blocks,
+                               x, y, t);
+
+  free(y);
+  free(t);
+    
+  return 0;
+}
+
+/*****************************************************
+ *  some utility routines                            *
+ *****************************************************/
+
+taucs_ccs_matrix*
+taucs_supernodal_factor_to_ccs(void* vL)
+{
+  supernodal_factor_matrix* L = (supernodal_factor_matrix*) vL;
+  taucs_ccs_matrix* C;
+  int n,nnz;
+  int i,j,ip,jp,sn,next;
+  double v;
+  int* len;
+
+  n = L->n;
+
+  len = (int*) malloc(n*sizeof(int));
+  if (!len) return NULL;
+
+  nnz = 0;
+
+  for (sn=0; sn<L->n_sn; sn++) {
+    for (jp=0; jp<(L->sn_size)[sn]; jp++) {
+      j = (L->sn_struct)[sn][jp];
+      len[j] = 0;
+
+      for (ip=jp; ip<(L->sn_size)[sn]; ip++) {
+       i = (L->sn_struct)[sn][ ip ];
+       v = (L->sn_blocks)[sn][ jp*(L->sn_blocks_ld)[sn] + ip ];
+
+       if (v) { 
+         len[j] ++;
+         nnz ++;
+       }
+      }
+      for (ip=(L->sn_size)[sn]; ip<(L->sn_up_size)[sn]; ip++) {
+       i = (L->sn_struct)[sn][ ip ];
+       v = (L->up_blocks)[sn][ jp*(L->up_blocks_ld)[sn] + (ip-(L->sn_size)[sn]) ];
+
+       if (v) { 
+         len[j] ++;
+         nnz ++;
+       }