/* ========================================================================== */
/* === UMF_set_stats ======================================================== */
/* ========================================================================== */

/* -------------------------------------------------------------------------- */
/* 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.    */
/* -------------------------------------------------------------------------- */

/*
    Sets statistics in Info array.  Calculates everything in double precision,
    rather than Int or size_t, so that usage estimates can be computed even if
    the problem is so large that it would cause integer overflow.
*/

#include "umf_internal.h"
#include "umf_symbolic_usage.h"

GLOBAL void UMF_set_stats
(
    double Info [ ],
    SymbolicType *Symbolic,
    double max_usage,		/* peak size of Numeric->Memory, in Units */
    double num_mem_size,	/* final size of Numeric->Memory, in Units */
    double flops,		/* "true flops" */
    double lnz,			/* nz in L */
    double unz,			/* nz in U */
    double maxfrsize,		/* largest front size */
    Int what			/* ESTIMATE or ACTUAL */
)
{

    double sym_size, num_fixed_size, kernel_usage, n,
	num_usage, maxncols, maxnrows ;

    n = Symbolic->n ;
    maxncols = Symbolic->maxncols ;
    maxnrows = Symbolic->maxnrows ;

    /* final Symbolic object size */
    sym_size = UMF_symbolic_usage (Symbolic->n, Symbolic->nchains, Symbolic->nfr) ;

    /* size of Numeric object, except Memory */
    num_fixed_size = DUNITS (NumericType, 1) + DUNITS (double, n+1)
	+ 8 * DUNITS (Int, n+1) ;

    /* peak size of Numeric->Memory */
    Info [UMFPACK_VARIABLE_PEAK + what] = max_usage ;

    /* final size of Numeric->Memory */
    Info [UMFPACK_VARIABLE_FINAL + what] = num_mem_size ;

    /* final size of Numeric object, including Memory */
    Info [UMFPACK_NUMERIC_SIZE + what] =
	num_fixed_size
	+ num_mem_size ;			/* final Numeric->Memory size */

    /* largest front size (Work->Fx size, or actual size used) */
    Info [UMFPACK_MAX_FRONT_SIZE + what] = maxfrsize ;

    /* UMF_kernel usage (except sym_size and num_fixed_size) */
    kernel_usage = DUNITS (double, Symbolic->maxfrsize)	/* Work->Fx size */
	    + 5 * DUNITS (Int, n+1)
	    + DUNITS (Int, 2*n+1)
	    + 3 * DUNITS (Int, maxncols + 1)
	    + 2 * DUNITS (Int, maxnrows + 1)
	    + DUNITS (Int, MAX (maxnrows, maxncols) + 1) ;
    /* plus peak Numeric->Memory usage: */
    kernel_usage += max_usage ;

    /* peak memory for just UMFPACK_numeric */
    num_usage = sym_size + num_fixed_size + kernel_usage ;

    /* peak memory usage for both UMFPACK_*symbolic and UMFPACK_numeric */
    Info [UMFPACK_PEAK_MEMORY + what] =
	MAX (Symbolic->peak_sym_usage, num_usage) ;

    Info [UMFPACK_FLOPS + what] = flops ;
    Info [UMFPACK_LNZ + what] = lnz ;
    Info [UMFPACK_UNZ + what] = unz ;
}
