/* ========================================================================== */
/* === umfpack_solve ======================================================== */
/* ========================================================================== */

/* -------------------------------------------------------------------------- */
/* UMFPACK Version 3.2 (Jan. 1, 2002), Copyright (c) 2002 by Timothy A.       */
/* Davis, University of Florida, davis@cise.ufl.edu.  All Rights Reserved.    */
/* See README, umfpack.h, or type "umfpack_details" in Matlab for License.    */
/* -------------------------------------------------------------------------- */

int umfpack_solve
(
    const char sys [ ],
    const int Ap [ ],
    const int Ai [ ],
    const double Ax [ ],
    double X [ ],
    const double B [ ],
    void *Numeric,
    const double Control [UMFPACK_CONTROL],
    double Info [UMFPACK_INFO]
) ;

long umfpack_l_solve
(
    const char sys [ ],
    const long Ap [ ],
    const long Ai [ ],
    const double Ax [ ],
    double X [ ],
    const double B [ ],
    void *Numeric,
    const double Control [UMFPACK_CONTROL],
    double Info [UMFPACK_INFO]
) ;

/*
int Syntax:

    #include "umfpack.h"
    void *Numeric ;
    int status, *Ap, *Ai ;
    char *sys ;
    double *B, *X, *Ax, Info [UMFPACK_INFO], Control [UMFPACK_CONTROL] ;
    status = umfpack_solve (sys, Ap, Ai, Ax, X, B, Numeric, Control, Info) ;

long Syntax:

    #include "umfpack.h"
    void *Numeric ;
    long status, *Ap, *Ai ;
    char *sys ;
    double *B, *X, *Ax, Info [UMFPACK_INFO], Control [UMFPACK_CONTROL] ;
    status = umfpack_l_solve (sys, Ap, Ai, Ax, X, B, Numeric, Control, Info);

Purpose:

    Given LU factors computed by umfpack_numeric (PAQ=LU) and the
    right-hand-side, B, solve a linear system for the solution X.  Iterative
    refinement is optionally performed.  This routine dynamically allocates
    workspace of size O(n).

Returns:

    The status code is returned.  See Info [UMFPACK_STATUS], below.

Arguments:

    char sys [ ] ;		Input argument, not modified.

	A string that defines which system to solve.  Iterative refinement can
	be optionally performed when the sys argument is:

	    "Ax=b"
	    "A'x=b"

	For these values of the sys argument, iterative refinement is not
	performed (Control [UMFPACK_IRSTEP], Ap, Ai, and Ax are ignored):

	    "P'Lx=b"
	    "L'Px=b"
	    "UQ'x=b"
	    "QU'x=b"
	    "Lx=b"
	    "L'x=b"
	    "Ux=b"
	    "U'x=b"

    Int Ap [n+1] ;		Input argument, not modified.
    Int Ai [nz] ;		Input argument, not modified.
    double Ax [nz] ;		Input argument, not modified.

	If iterative refinement is requested (Control [UMFPACK_IRSTEP] >= 1 and
	Ax=b or A'x=b is being solved), then these arrays must be identical to
	the same ones passed to umfpack_numeric.  The umfpack_solve routine
	does not check the contents of these three arguments, so the results
	are undefined if Ap, Ai, and/or Ax are modified between the calls the
	umfpack_numeric and umfpack_solve.  These three arrays do not need to
	be present (NULL pointers can be passed) if Control [UMFPACK_IRSTEP] is
	zero, or if a system other than Ax=b or A'x=b is being solved.

    double X [n] ;		Output argument.

	The solution to the linear system.

    double B [n] ;		Input argument, not modified.

	The right-hand side vector, b, stored as a conventional array of size n.
	This routine does not solve for multiple right-hand-sides, nor does it
	allow b to be stored in a sparse-column form.

    void *Numeric ;		Input argument, not modified.

	Numeric must point to a valid Numeric object, computed by
	umfpack_numeric.

    double Control [UMFPACK_CONTROL] ;	Input argument, not modified.

	If a (double *) NULL pointer is passed, then the default control
	settings are used.  Otherwise, the settings are determined from the
	Control array.  See umfpack_defaults on how to fill the Control
	array with the default settings.  The following Control parameters
	are used:

	Control [UMFPACK_IRSTEP]:  The maximum number of iterative refinement
	    steps to attempt.  A value less than zero is treated as zero.  If
	    less than 1, or if Ax=b or A'x=b is not being solved, then the Ap,
	    Ai, and Ax arguments are not accessed.  Default: 2.

    double Info [UMFPACK_INFO] ;	Output argument.

	Contains statistics about the solution factorization.  If a
	(double *) NULL pointer is passed, then no statistics are returned in
	Info (this is not an error condition).  The following statistics are
	computed in umfpack_solve:

	Info [UMFPACK_STATUS]: status code.  This is also the return value,
	    whether or not Info is present.

	    UMFPACK_OK

		The linear system was successfully solved.

	    UMFPACK_ERROR_out_of_memory

		Insufficient memory to solve the linear system.

	    UMFPACK_ERROR_argument_missing

		One or more required arguments are missing.  The B, X, and
		sys arguments are always required.  Info and Control are
		not required.  Ap, Ai, and Ax are required if Ax=b or A'x=b
		is to be solve and the (default) iterative refinement is
		requested.

	    UMFPACK_ERROR_invalid_Numeric_object

		The Numeric object is not valid.

	Info [UMFPACK_N]:  the value of n stored in the Numeric object.

	Info [UMFPACK_NZ]:  the number of entries in the input matrix, Ap [n],
	    if iterative refinement is requested (sys is "Ax=b" or "A'x=b"
	    and Control [UMFPACK_IRSTEP] >= 1).

	Info [UMFPACK_IR_TAKEN]:  The number of iterative refinement steps
	    effectively taken.  The number of steps attempted may be one more
	    than this; the refinement algorithm backtracks if the last
	    refinement step worsens the solution.  This is set to -1 if
	    iterative refinement was not requested.

	Info [UMFPACK_IR_ATTEMPTED]:   The number of iterative refinement steps
	    attempted.  The number of times a linear system was solved is one
	    more than this (once for the initial Ax=b, and once for each Ay=r
	    solved for each iterative refinement step attempted).  This
	    statistic is set to -1 if iterative refinement was not requested.

	Info [UMFPACK_OMEGA1]:  sparse backward error estimate, omega1, if
	    iterative refinement was performed, or -1 if iterative refinement
	    not performed.

	Info [UMFPACK_OMEGA2]:  sparse backward error estimate, omega2, if
	    iterative refinement was performed, or -1 if iterative refinement
	    not performed.

	Info [UMFPACK_SOLVE_FLOPS]:  the number of floating point operations
	    performed to solve the linear system.  This includes the work
	    taken for all iterative refinement steps, including the backtrack
	    (if any).

	Info [UMFPACK_SOLVE_TIME]:  The time taken by umfpack_solve, in
	    seconds.  In the ANSI C version, this may be invalid if the time
	    taken is more than about 36 minutes, because of wrap-around in
	    the ANSI C clock ( ) function.  Compile UMFPACK with -DGETRUSAGE
	    if you have the more accurate getrusage ( ) function.

	Only the above listed Info [...] entries are accessed.  The remaining
	entries of Info are not accessed or modified by umfpack_solve.
	Future versions might modify different parts of Info.
*/
