/* ========================================================================== */
/* === UMFPACK_report_info ================================================== */
/* ========================================================================== */

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

/*
    User-callable.  Prints the Info array.  See umfpack_report_info.h for
    details.
*/

#include "umf_internal.h"

#define PRINT_INFO(format,x) { if ((x) >= 0) PRINTF ((format, x)) ; }

/* ========================================================================== */
/* === print_ratio ========================================================== */
/* ========================================================================== */

PRIVATE void print_ratio
(
    char *what,
    double estimate,
    double actual
)
{
    if (estimate < 0 && actual < 0)
    {
	return ;
    }
    PRINTF (("    %-27s", what)) ;
    if (estimate >= 0)
    {
	PRINTF ((" %20.f", estimate)) ;
    }
    else
    {
	PRINTF (("                    -")) ;
    }
    if (actual >= 0)
    {
	PRINTF ((" %20.f", actual)) ;
    }
    else
    {
	PRINTF (("                    -")) ;
    }
    if (estimate >= 0 && actual >= 0)
    {
	PRINTF ((" %5.0f%%\n", 100 * RATIO (actual, estimate, 1))) ;
    }
    else
    {
	PRINTF (("      -\n")) ;
    }
}


/* ========================================================================== */

GLOBAL void UMFPACK_report_info
(
    const double Control [UMFPACK_CONTROL],
    const double Info [UMFPACK_INFO]
)
{

    double lnz_est, unz_est, lunz_est, lnz, unz, lunz ;
    Int n, prl ;

    /* ---------------------------------------------------------------------- */
    /* get control settings and status to determine what to print */
    /* ---------------------------------------------------------------------- */

    if (Control)
    {
	prl = (Int) Control [UMFPACK_PRL] ;
    }
    else
    {
	prl = UMFPACK_DEFAULT_PRL ;
    }

    if (!Info || prl < 2)
    {
	/* no output generated if Info is (double *) NULL */
	/* or if prl is less than 2 */
	return ;
    }

    /* ---------------------------------------------------------------------- */
    /* print umfpack version */
    /* ---------------------------------------------------------------------- */

    PRINTF (("\n%s, Info:\n", UMFPACK_VERSION)) ;

    /* ---------------------------------------------------------------------- */
    /* print run-time options */
    /* ---------------------------------------------------------------------- */

    /* This is a "run-time" option because both umfpack_* and umfpack_l_* are */
    /* compiled into the UMFPACK library. */
#if defined (DINT)
    PRINTF (("    Int (generic integer) is defined as: int\n")) ;
#else
    PRINTF (("    Int (generic integer) is defined as: long\n")) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* print compile-time options */
    /* ---------------------------------------------------------------------- */

    PRINTF (("    BLAS: ")) ;
#ifndef NBLAS
    PRINTF (("yes.")) ;
#else
    PRINTF (("no.")) ;
#endif

    PRINTF (("  Matlab: ")) ;
#ifdef MATLAB_MEX_FILE
    PRINTF (("yes.")) ;
#else
#ifdef MATHWORKS
    PRINTF (("yes (using internal ut* routines).")) ;
#else
    PRINTF (("no.")) ;
#endif
#endif

    PRINTF (("  CPU timer: ")) ;
#ifdef GETRUSAGE
    PRINTF (("getrusage.\n")) ;
#else
    PRINTF (("ANSI C clock (may wrap-around).\n")) ;
#endif

#ifndef NDEBUG
    PRINTF (("    Debugging enabled (umfpack will be exceedingly slow!)\n")) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* print n and nz */
    /* ---------------------------------------------------------------------- */

    n = (Int) Info [UMFPACK_N] ;
    PRINT_INFO ("    n:  "ID"\n", n) ;
    PRINT_INFO ("    entries in input matrix:  "ID"\n",
	(Int) Info [UMFPACK_NZ]) ;
    PRINT_INFO ("    memory usage is reported below in "ID"-byte Units\n",
	(Int) Info [UMFPACK_SIZE_OF_UNIT]) ;

    PRINT_INFO ("    size of int:  "ID" bytes\n",
	(Int) Info [UMFPACK_SIZE_OF_INT]) ;
    PRINT_INFO ("    size of long:  "ID" bytes\n",
	(Int) Info [UMFPACK_SIZE_OF_LONG]) ;
    PRINT_INFO ("    size of pointer:  "ID" bytes\n",
	(Int) Info [UMFPACK_SIZE_OF_POINTER]) ;
    PRINT_INFO ("    size of numerical entry:  "ID" bytes\n",
	(Int) Info [UMFPACK_SIZE_OF_ENTRY]) ;

    /* ---------------------------------------------------------------------- */
    /* estimates vs actual nonzeros in L and U */
    /* ---------------------------------------------------------------------- */

    lnz_est = Info [UMFPACK_LNZ_ESTIMATE] ;
    unz_est = Info [UMFPACK_UNZ_ESTIMATE] ;
    if (lnz_est >= 0 && unz_est >= 0)
    {
	lunz_est = lnz_est + unz_est - n ;
    }
    else
    {
	lunz_est = EMPTY ;
    }
    lnz = Info [UMFPACK_LNZ] ;
    unz = Info [UMFPACK_UNZ] ;
    if (lnz >= 0 && unz >= 0)
    {
	lunz = lnz + unz - n ;
    }
    else
    {
	lunz = EMPTY ;
    }

    /* ---------------------------------------------------------------------- */
    /* print header for table of estimates/actual statistics */
    /* ---------------------------------------------------------------------- */

    PRINTF (("    symbolic/numeric factorization:         estimate")) ;
    PRINTF (("               actual      %%\n")) ;

    /* ---------------------------------------------------------------------- */
    /* symbolic factorization */
    /* ---------------------------------------------------------------------- */

    PRINT_INFO (
    "    number of \"dense\" rows                         - %20.0f      -\n",
	Info [UMFPACK_NDENSE_ROW]) ;
    PRINT_INFO (
    "    rows with entries only in \"dense\" columns      - %20.0f      -\n",
	Info [UMFPACK_NEMPTY_ROW]) ;
    PRINT_INFO (
    "    number of \"dense\" columns                      - %20.0f      -\n",
	Info [UMFPACK_NDENSE_COL]) ;
    PRINT_INFO (
    "    columns with entries only in \"dense\" rows      - %20.0f      -\n",
	Info [UMFPACK_NEMPTY_COL]) ;
    PRINT_INFO (
    "    symbolic factorization defragmentations        - %20.0f      -\n",
	Info [UMFPACK_SYMBOLIC_DEFRAG]) ;
    PRINT_INFO (
    "    symbolic memory usage (Units)                  - %20.0f      -\n",
	Info [UMFPACK_SYMBOLIC_PEAK_MEMORY]) ;
    PRINT_INFO (
    "    Symbolic size (Units)                          - %20.0f      -\n",
	Info [UMFPACK_SYMBOLIC_SIZE]) ;
    PRINT_INFO (
    "    symbolic factorization time (sec)              - %20.2f      -\n",
	Info [UMFPACK_SYMBOLIC_TIME]) ;

    /* ---------------------------------------------------------------------- */
    /* estimate/actual in symbolic/numeric factorization */
    /* ---------------------------------------------------------------------- */

    if (Info [UMFPACK_SYMBOLIC_DEFRAG] >= 0	/* UMFPACK_*symbolic called */
    ||  Info [UMFPACK_NUMERIC_DEFRAG] >= 0)	/* UMFPACK_numeric called */
    {
	PRINTF (("    variable-sized part of Numeric object:\n")) ;
    }
    print_ratio ("    initial size (Units)",
	Info [UMFPACK_VARIABLE_INIT_ESTIMATE], Info [UMFPACK_VARIABLE_INIT]) ;
    print_ratio ("    peak size (Units)",
	Info [UMFPACK_VARIABLE_PEAK_ESTIMATE], Info [UMFPACK_VARIABLE_PEAK]) ;
    print_ratio ("    final size (Units)",
	Info [UMFPACK_VARIABLE_FINAL_ESTIMATE], Info [UMFPACK_VARIABLE_FINAL]) ;
    print_ratio ("Numeric final size (Units)",
	Info [UMFPACK_NUMERIC_SIZE_ESTIMATE], Info [UMFPACK_NUMERIC_SIZE]) ;
    print_ratio ("peak memory usage (Units)",
	Info [UMFPACK_PEAK_MEMORY_ESTIMATE], Info [UMFPACK_PEAK_MEMORY]) ;
    print_ratio ("numeric factorization flops",
	Info [UMFPACK_FLOPS_ESTIMATE], Info [UMFPACK_FLOPS]) ;
    print_ratio ("nz in L (incl diagonal)", lnz_est, lnz) ;
    print_ratio ("nz in U (incl diagonal)", unz_est, unz) ;
    print_ratio ("nz in L+U (incl diagonal)", lunz_est, lunz) ;
    print_ratio ("largest front (# entries)",
	Info [UMFPACK_MAX_FRONT_SIZE_ESTIMATE], Info [UMFPACK_MAX_FRONT_SIZE]) ;

    /* ---------------------------------------------------------------------- */
    /* numeric factorization */
    /* ---------------------------------------------------------------------- */

    PRINT_INFO (
    "    indices in compressed pattern                  - %20.0f      -\n",
	Info [UMFPACK_COMPRESSED_PATTERN]) ;
    PRINT_INFO (
    "    numerical values stored in Numeric object      - %20.0f      -\n",
	Info [UMFPACK_LU_ENTRIES]) ;
    PRINT_INFO (
    "    numeric factorization defragmentations         - %20.0f      -\n",
	Info [UMFPACK_NUMERIC_DEFRAG]) ;
    PRINT_INFO (
    "    numeric factorization reallocations            - %20.0f      -\n",
	Info [UMFPACK_NUMERIC_REALLOC]) ;
    PRINT_INFO (
    "    costly numeric factorization reallocations     - %20.0f      -\n",
	Info [UMFPACK_NUMERIC_COSTLY_REALLOC]) ;
    PRINT_INFO (
    "    numeric factorization time (sec)               - %20.2f      -\n",
	Info [UMFPACK_NUMERIC_TIME]) ;

    /* ---------------------------------------------------------------------- */
    /* solve */
    /* ---------------------------------------------------------------------- */

    PRINT_INFO (
    "    solve flops                                    - %20.0f      -\n",
	Info [UMFPACK_SOLVE_FLOPS]) ;
    PRINT_INFO (
    "    iterative refinement steps taken               - %20.0f      -\n",
	Info [UMFPACK_IR_TAKEN]) ;
    PRINT_INFO (
    "    iterative refinement steps attempted           - %20.0f      -\n",
	Info [UMFPACK_IR_ATTEMPTED]) ;
    PRINT_INFO (
    "    sparse backward error omega1                   - %20g      -\n",
	Info [UMFPACK_OMEGA1]) ;
    PRINT_INFO (
    "    sparse backward error omega2                   - %20g      -\n",
	Info [UMFPACK_OMEGA2]) ;
    PRINT_INFO (
    "    solve time (sec)                               - %20.2f      -\n",
	Info [UMFPACK_SOLVE_TIME]) ;

    PRINTF (("\n")) ;

}

