/* ========================================================================== */
/* === umfpack_numeric ====================================================== */
/* ========================================================================== */

/* -------------------------------------------------------------------------- */
/* 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_numeric
(
    const int Ap [ ],
    const int Ai [ ],
    const double Ax [ ],
    void *Symbolic,
    void **Numeric,
    const double Control [UMFPACK_CONTROL],
    double Info [UMFPACK_INFO]
) ;

long umfpack_l_numeric
(
    const long Ap [ ],
    const long Ai [ ],
    const double Ax [ ],
    void *Symbolic,
    void **Numeric,
    const double Control [UMFPACK_CONTROL],
    double Info [UMFPACK_INFO]
) ;

/*
int Syntax:

    #include "umfpack.h"
    void *Symbolic, *Numeric ;
    int *Ap, *Ai, status ;
    double *Ax, Control [UMFPACK_CONTROL], Info [UMFPACK_INFO] ;
    status = umfpack_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info) ;

long Syntax:

    #include "umfpack.h"
    void *Symbolic, *Numeric ;
    long *Ap, *Ai, status ;
    double *Ax, Control [UMFPACK_CONTROL], Info [UMFPACK_INFO] ;
    status = umfpack_l_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info) ;

Purpose:

    Given a sparse matrix A in column-oriented form, and a symbolic analysis
    computed by umfpack_symbolic, the umfpack_numeric routine performs the
    numerical factorization, PAQ=LU, where P and Q are permutation matrices
    (represented as permutation vectors), L is unit-lower triangular, and U
    is upper triangular.  This is required before the system Ax=b (or other
    related linear systems) can be solved.  umfpack_numeric can be called
    multiple times for each call to umfpack_symbolic, to factorize a sequence
    of matrices with identical nonzero pattern.  Simply compute the Symbolic
    object once, with umfpack_*symbolic, and reuse it for subsequent matrices.
    umfpack_numeric safely detects if the pattern changes, and sets an
    appropriate error code.

Returns:

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

Arguments:

    Int Ap [n+1] ;	Input argument, not modified.

	This must be identical to the Ap array passed to umfpack_symbolic.
	The value of n is what was passed to umfpack_symbolic (this is held in
	the Symbolic object).

    Int Ai [nz] ;	Input argument, not modified, of size nz = Ap [n].

	This must be identical to the Ai array passed to umfpack_symbolic.

	Not all changes to Ai and Ap are detected; if the matrix has the same
	number of nonzeros and can be factorized in the existing frontal
	matrices as defined in the Symbolic object, then umfpack_numeric will
	not complain, and will successfully factorize the matrix and return a
	valid Numeric object.

    double Ax [nz] ;	Input argument, not modified, of size nz = Ap [n].

	The numerical values of the sparse matrix A.  The nonzero pattern (row
	indices) for column j is stored in Ai [(Ap [j]) ... (Ap [j+1]-1)], and
	the corresponding numerical values are stored in
	Ax [(Ap [j]) ... (Ap [j+1]-1)].

    void *Symbolic ;	Input argument, not modified.

	The Symbolic object, which holds the symbolic factorization computed by
	umfpack_symbolic.  The Symbolic object is not modified by
	umfpack_numeric.

    void **Numeric ;	Output argument.

	**Numeric is the addres of a (void *) pointer variable in the user's
	calling routine (see Syntax, above).  On input, the contents of this
	variable are not defined.  On output, this variable holds a (void *)
	pointer to the Numeric object (if successful), or (void *) NULL if
	a failure occurred.

    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_PIVOT_TOLERANCE]:  relative pivot tolerance for
	    threshold partial pivoting with row interchanges.  In any given
	    column, an entry is numerically acceptable if it is greater than or
	    equal to Control [UMFPACK_PIVOT_TOLERANCE] times the largest
	    absolute value in the column.  A value of 1.0 gives true partial
	    pivoting.  A value of zero is treated as 1.0.  Default: 0.1.
	    Smaller values tend to lead to sparser LU factors, but the solution
	    to the linear system can become inaccurate.  Larger values can lead
	    to a more accurate solution (but not always), and usually an
	    increase in the total work.

	Control [UMFPACK_RELAXED_AMALGAMATION]:  This controls the creation of
	    "elements" (small dense submatrices) that are formed when a frontal
	    matrix is factorized.  A new element is created if the current one,
	    plus the new pivot, contains "too many" explicitly zero numerical
	    entries.  The two elements are merged if the number of extra zero
	    entries is < Control [UMFPACK_RELAXED_AMALGAMATION] times the
	    size of the merged element.  A lower setting
	    decreases fill-in, but run-time and memory usage can increase.
	    A larger setting increases fill-in (because the extra zeros are
	    treated as normal entries during pivot selection), but this can
	    lead to an increase in run-time but (paradoxically) a decrease in
	    memory usage (one merged elements can take less space than two
	    separate elements).  Except for the initial column ordering,
	    this parameter has the most impact on the run-time, fill-in,
	    operation count, and memory usage.
	    Default: 0.25, which is fine for nearly all matrices.
	    (For nearly all matrices, different values of this parameter can
	    decrease the run-time by at most 5%, but can also dramatically
	    increase the run time for some matrices).

	Control [UMFPACK_RELAXED2_AMALGAMATION]:  This, along with the block
	    size (Control [UMFPACK_BLOCK_SIZE]), controls how often the
	    pending updates are applied when the next pivot entry resides in
	    the current frontal matrix.  If the number of zero entries in the
	    LU part of the current frontal matrix would exceed this parameter
	    times the size of the LU part, then the pending updates are applied
	    before the next pivot is included in the frontal matrix.
	    Default: 0.20 (that is, more than 10% zero entries causes the
	    pending updates to be applied).  This input parameter is new
	    since Version 3.1.

	Control [UMFPACK_RELAXED3_AMALGAMATION]:  This, along with the block
	    size (Control [UMFPACK_BLOCK_SIZE]), controls how often the
	    pending updates are applied when the next pivot entry does NOT reside
	    in the current frontal matrix.  If the number of zero entries in the
	    LU part of the current frontal matrix would exceed this parameter
	    times the size of the LU part, then the pending updates are applied
	    before the next pivot is included in the frontal matrix.
	    Default: 0.10 (that is, more than 10% zero entries causes the
	    pending updates to be applied).  This input parameter is new
	    since Version 3.1.

	Control [UMFPACK_ALLOC_INIT]: When umfpack_numeric starts, it allocates
	    memory for the Numeric object.  Part of this is of fixed size
	    (approximately n double's + 12*n integers).
	    The remainder is of variable size, which grows to hold the LU
	    factors and the frontal matrices created during factorization.
	    A estimate of the upper bound is computed by umfpack_symbolic, and
	    returned by umfpack_*symbolic in
	    Info [UMFPACK_VARIABLE_PEAK_ESTIMATE].  umfpack_numeric initially
	    allocates space for the variable-sized part equal to this estimate
	    times Control [UMFPACK_ALLOC_INIT].  Typically, umfpack_numeric
	    needs only about half the estimated memory space, so a setting of
	    0.5 or 0.6 often provides enough memory for umfpack_numeric to
	    factorize the matrix with no subsequent increases in the size of
	    this block.  A value less than zero is treated as zero (in which
	    case, just the bare minimum amount of memory needed to start the
	    factorization is initially allocated).  The bare initial memory
	    required is returned by umfpack_*symbolic in
	    Info [UMFPACK_VARIABLE_INIT_ESTIMATE] (which in fact not an
	    estimate, but exact).  If the variable-size part of the Numeric
	    object is found to be too small sometime after numerical
	    factorization has started, the memory is increased in size by a
	    factor of 1.2.   If this fails, the request is reduced by a factor
	    of 0.95 until it succeeds, or until it determines that no increase
	    in size is possible.  Garbage collection then occurs.  These two
	    factors (1.2 and 0.95) are fixed control parameters defined in
	    umf_internal.h and cannot be changed at run-time.  You would need
	    to edit umf_internal.h to modify them.  If you do this, be sure that
	    the two factors are greater than 1 and less than 1, respectively.

	    The strategy of attempting to malloc a working space, and re-trying
	    with a smaller space, may not work under Matlab, since mxMalloc
	    aborts the mexFunction if it fails.  I may try to address this is
	    issue in a future release - in the mean time, decrease
	    Control [UMFPACK_ALLOC_INIT] if you run out of memory in Matlab.

	    Default initial allocation size: 0.7.  Thus, with the default
	    control settings, the upper-bound is reached after two reallocations
	    (0.7 * 1.2 * 1.2 = 1.008).

	    Changing this parameter has no affect on fill-in or operation count.
	    It has a small impact on run-time (the extra time required to do
	    the garbage collection and memory reallocation).

	Control [UMFPACK_PIVOT_OPTION]:  If this is nonzero, then entries on
	    the diagonal of A are given preference over off-diagonal entries.
	    This can improve the fill-in on matrices with symmmetric nonzero
	    pattern.  Default: 0 (do not give preference to the diagonal of A).
	    This parameter was added for UMFPACK Version 3.1.

    double Info [UMFPACK_INFO] ;	Output argument.

	Contains statistics about the numeric 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_numeric:

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

	    UMFPACK_OK

		Numeric factorization was successful.  Only in this case
		does umfpack_numeric compute a valid numeric factorization.
		For the other cases below, no Numeric object is created
		(*Numeric is (void *) NULL).

	    UMFPACK_ERROR_out_of_memory

		Insufficient memory to complete the numeric factorization.

	    UMFPACK_ERROR_argument_missing

		One or more required arguments (Ap, Ai, and/or Ax) are missing.

	    UMFPACK_ERROR_singular_matrix

		The input matrix is singular.

	    UMFPACK_ERROR_invalid_Symbolic_object

		Symbolic object provided as input is invalid.

	    UMFPACK_ERROR_different_pattern

		The pattern (Ap and/or Ai) has changed since the call to
		umfpack_*symbolic which produced the Symbolic object.

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

	Info [UMFPACK_NZ]:  the number of entries in the input matrix.
	    This value is obtained from the Symbolic object.

	Info [UMFPACK_SIZE_OF_UNIT]:  the number of bytes in a Unit, for memory
	    usage statistics below.

	Info [UMFPACK_VARIABLE_INIT]: the initial size (in Units) of the
	    variable-sized part of the Numeric object.  If this differs from
	    Info [UMFPACK_VARIABLE_INIT_ESTIMATE], then the pattern (Ap and/or
	    Ai) has changed since the last call to umfpack_*symbolic, which is
	    an error condition.

	Info [UMFPACK_VARIABLE_PEAK]: the peak size (in Units) of the
	    variable-sized part of the Numeric object.  This size is the amount
	    of space actually used inside the block of memory, not the space
	    allocated via UMF_malloc.  You can reduce UMFPACK's memory
	    requirements by setting Control [UMFPACK_ALLOC_INIT] to the ratio
	    Info [UMFPACK_VARIABLE_PEAK] / Info[UMFPACK_VARIABLE_PEAK_ESTIMATE].
	    This will ensure that no memory reallocations occur (you may want to
	    add 0.001 to make sure that integer roundoff does not lead to a
	    memory size that is 1 Unit too small; otherwise, garbage collection
	    and reallocation will occur).

	Info [UMFPACK_VARIABLE_FINAL]: the final size (in Units) of the
	    variable-sized part of the Numeric object.  It holds just the
	    sparse LU factors.

	Info [UMFPACK_NUMERIC_SIZE]:  the actual final size (in Units) of the
	    entire Numeric object, including the final size of the variable
	    part of the object.  Info [UMFPACK_NUMERIC_SIZE_ESTIMATE],
	    an estimate, was computed by umfpack_symbolic.  The estimate is
	    normally an upper bound on the actual final size, but this is not
	    guaranteed.

	Info [UMFPACK_PEAK_MEMORY]:  the actual peak memory usage (in Units) of
	    both umfpack_symbolic and umfpack_numeric.  An estimate,
	    Info [UMFPACK_PEAK_MEMORY_ESTIMATE], was computed by
	    umfpack_symbolic.  The estimate is normally an upper bound on the
	    actual peak usage, but this is not guaranteed.  With testing on
	    hundreds of matrix arising in real applications, I have never
	    observed a matrix where this estimate or the Numeric size estimate
	    was less than the actual result, but this is theoretically possible.
	    Please send me one if you find such a matrix.

	Info [UMFPACK_FLOPS]:  the actual count of the (useful) floating-point
	    operations performed.  An estimate, Info [UMFPACK_FLOPS_ESTIMATE],
	    was computed by umfpack_symbolic.  The estimate is guaranteed to be
	    an upper bound on this flop count.  The flop count excludes
	    "useless" flops on zero values, flops performed during the pivot
	    search (for tentative updates and assembly of candidate columns),
	    and flops performed to add frontal matrices together.  It does
	    include the flops performed to factorize the "dense" and "empty"
	    columns.

	Info [UMFPACK_LNZ]: the actual nonzero entries in final factor L,
	    including the diagonal.  This excludes any zero entries in L,
	    although some of these are stored in the Numeric object.  It does
	    include entries in "dense" or "empty" columns.  The
	    Info [UMFPACK_LU_ENTRIES] statistic does account for all
	    explicitly stored zeros, however.  Info [UMFPACK_LNZ_ESTIMATE],
	    an estimate, was computed by umfpack_symbolic.  The estimate is
	    guaranteed to be an upper bound on Info [UMFPACK_LNZ].

	Info [UMFPACK_UNZ]: the actual nonzero entries in final factor U,
	    including the diagonal.  This excludes any zero entries in U,
	    although some of these are stored in the Numeric object.  It does
	    include entries in "dense" or "empty" columns.  The
	    Info [UMFPACK_LU_ENTRIES] statistic does account for all
	    explicitly stored zeros, however.  Info [UMFPACK_UNZ_ESTIMATE],
	    an estimate, was computed by umfpack_symbolic.  The estimate is
	    guaranteed to be an upper bound on Info [UMFPACK_UNZ].

	Info [UMFPACK_NUMERIC_DEFRAG]:  The number of garbage collections
	    performed during umfpack_numeric, to compact contents of the
	    variable-sized workspace used by umfpack_numeric.  No estimate was
	    computed by umfpack_symbolic.  In the current version of UMFPACK,
	    garbage collection is performed and then the memory is reallocated,
	    so this statistic is the same as Info [UMFPACK_NUMERIC_REALLOC],
	    below.  It may differ in future releases.

	Info [UMFPACK_NUMERIC_REALLOC]:  The number of times that the Numeric
	    object was increased in size from its initial size.  A rough upper
	    bound on the peak size of the Numeric object was computed by
	    umfpack_symbolic, so reallocations should be rare.  However, if
	    umfpack_numeric is unable to allocate that much storage, it reduces
	    its request until either the allocation succeeds, or until it gets
	    too small to do anything with.  If the memory that it finally got
	    was small, but usable, then the reallocation count could be high.
	    No estimate of this count was computed by umfpack_symbolic.

	Info [UMFPACK_NUMERIC_COSTLY_REALLOC]:  The number of times that the
	    system realloc ( ) library routine had to move the workspace.
	    Realloc can sometimes increase the size of a block of memory
	    without moving it, which is much faster.  This statistic will
	    always be <= Info [UMFPACK_NUMERIC_REALLOC].  If your memory space
	    is fragmented, then the number of "costly" realloc's will be equal
	    to Info [UMFPACK_NUMERIC_REALLOC].

	Info [UMFPACK_COMPRESSED_PATTERN]:  The number of integers used to
	    represent the pattern of "sparse" part L and U.  The "sparse" part
	    of L and U excludes entries on the diagonal, which is stored
	    separately.  It excludes entries in the "dense" and "empty"
	    columns.  Those are stored together in a single dense array of
	    size n by (Info [UMFPACK_NDENSE_COL] + Info [UMFPACK_NEMPTY_COL]),
	    and no integers are required to represent their pattern.

	Info [UMFPACK_LU_ENTRIES]:  The total number of numerical values that
	    are stored for the LU factors, including the dense array for "dense"
	    and "empty" columns.  Some of the values may be explicitly zero.

	Info [UMFPACK_NUMERIC_TIME]:  The time taken by umfpack_numeric, 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_numeric.
	Future versions might modify different parts of Info.

*/

