diff liboctave/UMFPACK/UMFPACK/Source/umfpack_solve.c @ 5164:57077d0ddc8e

[project @ 2005-02-25 19:55:24 by jwe]
author jwe
date Fri, 25 Feb 2005 19:55:28 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/UMFPACK/UMFPACK/Source/umfpack_solve.c	Fri Feb 25 19:55:28 2005 +0000
@@ -0,0 +1,245 @@
+/* ========================================================================== */
+/* === UMFPACK_solve ======================================================== */
+/* ========================================================================== */
+
+/* -------------------------------------------------------------------------- */
+/* UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis.  CISE Dept,   */
+/* Univ. of Florida.  All Rights Reserved.  See ../Doc/License for License.   */
+/* web: http://www.cise.ufl.edu/research/sparse/umfpack                       */
+/* -------------------------------------------------------------------------- */
+
+/*
+    User-callable.  Solves a linear system using the numerical factorization
+    computed by UMFPACK_numeric.  See umfpack_solve.h for more details.
+
+    For umfpack_*_solve:
+	Dynamic memory usage:  UMFPACK_solve calls UMF_malloc twice, for
+	workspace of size c*n*sizeof(double) + n*sizeof(Int), where c is
+	defined below.  On return, all of this workspace is free'd via UMF_free.
+
+    For umfpack_*_wsolve:
+	No dynamic memory usage.  Input arrays are used for workspace instead.
+	Pattern is a workspace of size n Integers.  The double array W must be
+	at least of size c*n, where c is defined below.
+
+    If iterative refinement is requested, and Ax=b, A'x=b or A.'x=b is being
+    solved, and the matrix A is not singular, then c is 5 for the real version
+    and 10 for the complex version.  Otherwise, c is 1 for the real version and
+    4 for the complex version.
+*/
+
+#include "umf_internal.h"
+#include "umf_valid_numeric.h"
+#include "umf_solve.h"
+
+#ifndef WSOLVE
+#include "umf_malloc.h"
+#include "umf_free.h"
+#ifndef NDEBUG
+PRIVATE Int init_count ;
+#endif
+#endif
+
+GLOBAL Int
+#ifdef WSOLVE
+UMFPACK_wsolve
+#else
+UMFPACK_solve
+#endif
+(
+    Int sys,
+    const Int Ap [ ],
+    const Int Ai [ ],
+    const double Ax [ ],
+#ifdef COMPLEX
+    const double Az [ ],
+#endif
+    double Xx [ ],
+#ifdef COMPLEX
+    double Xz [ ],
+#endif
+    const double Bx [ ],
+#ifdef COMPLEX
+    const double Bz [ ],
+#endif
+    void *NumericHandle,
+    const double Control [UMFPACK_CONTROL],
+    double User_Info [UMFPACK_INFO]
+#ifdef WSOLVE
+    , Int Pattern [ ],
+    double W [ ]
+#endif
+)
+{
+    /* ---------------------------------------------------------------------- */
+    /* local variables */
+    /* ---------------------------------------------------------------------- */
+
+    double Info2 [UMFPACK_INFO], stats [2] ;
+    double *Info ;
+    NumericType *Numeric ;
+    Int n, i, irstep, status ;
+#ifndef WSOLVE
+    Int *Pattern, wsize ;
+    double *W ;
+#endif
+
+    /* ---------------------------------------------------------------------- */
+    /* get the amount of time used by the process so far */
+    /* ---------------------------------------------------------------------- */
+
+    umfpack_tic (stats) ;
+
+#ifndef WSOLVE
+#ifndef NDEBUG
+    init_count = UMF_malloc_count ;
+#endif
+#endif
+
+    /* ---------------------------------------------------------------------- */
+    /* get parameters */
+    /* ---------------------------------------------------------------------- */
+
+    irstep = GET_CONTROL (UMFPACK_IRSTEP, UMFPACK_DEFAULT_IRSTEP) ;
+
+    if (User_Info != (double *) NULL)
+    {
+	/* return Info in user's array */
+	Info = User_Info ;
+	/* clear the parts of Info that are set by UMFPACK_solve */
+	for (i = UMFPACK_IR_TAKEN ; i <= UMFPACK_SOLVE_TIME ; i++)
+	{
+	    Info [i] = EMPTY ;
+	}
+    }
+    else
+    {
+	/* no Info array passed - use local one instead */
+	Info = Info2 ;
+	for (i = 0 ; i < UMFPACK_INFO ; i++)
+	{
+	    Info [i] = EMPTY ;
+	}
+    }
+
+    Info [UMFPACK_STATUS] = UMFPACK_OK ;
+    Info [UMFPACK_SOLVE_FLOPS] = 0 ;
+
+    Numeric = (NumericType *) NumericHandle ;
+    if (!UMF_valid_numeric (Numeric))
+    {
+	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_Numeric_object ;
+	return (UMFPACK_ERROR_invalid_Numeric_object) ;
+    }
+
+    Info [UMFPACK_NROW] = Numeric->n_row ;
+    Info [UMFPACK_NCOL] = Numeric->n_col ;
+
+    if (Numeric->n_row != Numeric->n_col)
+    {
+	/* only square systems can be handled */
+	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_system ;
+	return (UMFPACK_ERROR_invalid_system) ;
+    }
+    n = Numeric->n_row ;
+    if (Numeric->nnzpiv < n
+	|| SCALAR_IS_ZERO (Numeric->rcond) || SCALAR_IS_NAN (Numeric->rcond))
+    {
+	/* turn off iterative refinement if A is singular */
+	/* or if U has NaN's on the diagonal. */
+	irstep = 0 ;
+    }
+
+    if (!Xx || !Bx)
+    {
+	Info [UMFPACK_STATUS] = UMFPACK_ERROR_argument_missing ;
+	return (UMFPACK_ERROR_argument_missing) ;
+    }
+
+    if (sys >= UMFPACK_Pt_L)
+    {
+	/* no iterative refinement except for nonsingular Ax=b, A'x=b, A.'x=b */
+	irstep = 0 ;
+    }
+
+    /* ---------------------------------------------------------------------- */
+    /* allocate or check the workspace */
+    /* ---------------------------------------------------------------------- */
+
+#ifdef WSOLVE
+
+    if (!W || !Pattern)
+    {
+	Info [UMFPACK_STATUS] = UMFPACK_ERROR_argument_missing ;
+	return (UMFPACK_ERROR_argument_missing) ;
+    }
+
+#else
+
+#ifdef COMPLEX
+    if (irstep > 0)
+    {
+	wsize = 10*n ;		/* W, X, Z, S, Y, B2 */
+    }
+    else
+    {
+	wsize = 4*n ;		/* W, X */
+    }
+#else
+    if (irstep > 0)
+    {
+	wsize = 5*n ;		/* W, Z, S, Y, B2 */
+    }
+    else
+    {
+	wsize = n ;		/* W */
+    }
+#endif
+
+    Pattern = (Int *) UMF_malloc (n, sizeof (Int)) ;
+    W = (double *) UMF_malloc (wsize, sizeof (double)) ;
+    if (!W || !Pattern)
+    {
+	DEBUGm4 (("out of memory: solve work\n")) ;
+	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
+	(void) UMF_free ((void *) W) ;
+	(void) UMF_free ((void *) Pattern) ;
+	return (UMFPACK_ERROR_out_of_memory) ;
+    }
+
+#endif	/* WSOLVE */
+
+    /* ---------------------------------------------------------------------- */
+    /* solve the system */
+    /* ---------------------------------------------------------------------- */
+
+    status = UMF_solve (sys, Ap, Ai, Ax, Xx, Bx,
+#ifdef COMPLEX
+	Az, Xz, Bz,
+#endif
+	Numeric, irstep, Info, Pattern, W) ;
+
+    /* ---------------------------------------------------------------------- */
+    /* free the workspace (if allocated) */
+    /* ---------------------------------------------------------------------- */
+
+#ifndef WSOLVE
+    (void) UMF_free ((void *) W) ;
+    (void) UMF_free ((void *) Pattern) ;
+    ASSERT (UMF_malloc_count == init_count) ;
+#endif
+
+    /* ---------------------------------------------------------------------- */
+    /* get the time used by UMFPACK_*solve */
+    /* ---------------------------------------------------------------------- */
+
+    Info [UMFPACK_STATUS] = status ;
+    if (status >= 0)
+    {
+	umfpack_toc (stats) ;
+	Info [UMFPACK_SOLVE_WALLTIME] = stats [0] ;
+	Info [UMFPACK_SOLVE_TIME] = stats [1] ;
+    }
+
+    return (status) ;
+}