コード例 #1
0
ファイル: umfpack_get_numeric.c プロジェクト: rforge/matrix
GLOBAL Int UMFPACK_get_numeric
(
    Int Lp [ ],
    Int Lj [ ],
    double Lx [ ],
#ifdef COMPLEX
    double Lz [ ],
#endif
    Int Up [ ],
    Int Ui [ ],
    double Ux [ ],
#ifdef COMPLEX
    double Uz [ ],
#endif
    Int P [ ],
    Int Q [ ],
    double Dx [ ],
#ifdef COMPLEX
    double Dz [ ],
#endif
    Int *p_do_recip,
    double Rs [ ],
    void *NumericHandle
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    NumericType *Numeric ;
    Int getL, getU, *Rperm, *Cperm, k, nn, n_row, n_col, *Wi, *Pattern,
	n_inner ;
    double *Rs1 ;
    Entry *D ;

#ifndef NDEBUG
    init_count = UMF_malloc_count ;
#endif

    Wi = (Int *) NULL ;
    Pattern = (Int *) NULL ;

    /* ---------------------------------------------------------------------- */
    /* check input parameters */
    /* ---------------------------------------------------------------------- */

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    n_row = Numeric->n_row ;
    n_col = Numeric->n_col ;
    nn = MAX (n_row, n_col) ;
    n_inner = MIN (n_row, n_col) ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    getL = Lp && Lj && Lx ;
    getU = Up && Ui && Ux ;

    if (getL || getU)
    {
	Wi = (Int *) UMF_malloc (nn, sizeof (Int)) ;
	Pattern = (Int *) UMF_malloc (nn, sizeof (Int)) ;
	if (!Wi || !Pattern)
	{
	    (void) UMF_free ((void *) Wi) ;
	    (void) UMF_free ((void *) Pattern) ;
	    ASSERT (UMF_malloc_count == init_count) ;
	    DEBUGm4 (("out of memory: get numeric\n")) ;
	    return (UMFPACK_ERROR_out_of_memory) ;
	}
	ASSERT (UMF_malloc_count == init_count + 2) ;
    }

    /* ---------------------------------------------------------------------- */
    /* get contents of Numeric */
    /* ---------------------------------------------------------------------- */

    if (P != (Int *) NULL)
    {
	Rperm = Numeric->Rperm ;
	for (k = 0 ; k < n_row ; k++)
	{
	    P [k] = Rperm [k] ;
	}
    }

    if (Q != (Int *) NULL)
    {
	Cperm = Numeric->Cperm ;
	for (k = 0 ; k < n_col ; k++)
	{
	    Q [k] = Cperm [k] ;
	}
    }

    if (getL)
    {
	get_L (Lp, Lj, Lx,
#ifdef COMPLEX
	    Lz,
#endif
	    Numeric, Pattern, Wi) ;
    }

    if (getU)
    {
	get_U (Up, Ui, Ux,
#ifdef COMPLEX
	    Uz,
#endif
	    Numeric, Pattern, Wi) ;
    }

    if (Dx != (double *) NULL)
    {
	D = Numeric->D ;
#ifdef COMPLEX
	if (SPLIT (Dz))
	{
	    for (k = 0 ; k < n_inner ; k++)
	    {
		Dx [k] = REAL_COMPONENT (D [k]) ;
		Dz [k] = IMAG_COMPONENT (D [k]) ;
	    }
	}
	else
	{
	    for (k = 0 ; k < n_inner ; k++)
	    {
	        Dx [2*k  ] =  REAL_COMPONENT (D [k]) ;
	        Dx [2*k+1] =  IMAG_COMPONENT (D [k]) ;
	    }
	}
#else
	{
	    D = Numeric->D ;
	    for (k = 0 ; k < n_inner ; k++)
	    {
		Dx [k] = D [k] ;
	    }
	}
#endif
    }

    /* return the flag stating whether the scale factors are to be multiplied,
     * or divided.   If do_recip is TRUE, multiply.  Otherwise, divided.
     * If NRECIPROCAL is defined at compile time, the scale factors are always
     * to be used by dividing.
     */
    if (p_do_recip != (Int *) NULL)
    {
#ifndef NRECIPROCAL
	*p_do_recip = Numeric->do_recip ;
#else
	*p_do_recip = FALSE ;
#endif
    }

    if (Rs != (double *) NULL)
    {
	Rs1 = Numeric->Rs ;
	if (Rs1 == (double *) NULL)
	{
	    /* R is the identity matrix.  */
	    for (k = 0 ; k < n_row ; k++)
	    {
		Rs [k] = 1.0 ;
	    }
	}
	else
	{
	    for (k = 0 ; k < n_row ; k++)
	    {
		Rs [k] = Rs1 [k] ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* free the workspace */
    /* ---------------------------------------------------------------------- */

    (void) UMF_free ((void *) Wi) ;
    (void) UMF_free ((void *) Pattern) ;
    ASSERT (UMF_malloc_count == init_count) ;

    return (UMFPACK_OK) ;
}
コード例 #2
0
GLOBAL Int UMFPACK_report_numeric
(
    void *NumericHandle,
    const double Control [UMFPACK_CONTROL]
)
{
    Int prl, *W, nn, n_row, n_col, n_inner, num_fixed_size, numeric_size,
	npiv ;
    NumericType *Numeric ;

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    PRINTF (("Numeric object:  ")) ;

    Numeric = (NumericType *) NumericHandle ;
    if (!UMF_valid_numeric (Numeric))
    {
	PRINTF (("ERROR: LU factors invalid\n\n")) ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    n_row = Numeric->n_row ;
    n_col = Numeric->n_col ;
    nn = MAX (n_row, n_col) ;
    n_inner = MIN (n_row, n_col) ;
    npiv = Numeric->npiv ;

    DEBUG1 (("n_row "ID" n_col "ID" nn "ID" n_inner "ID" npiv "ID"\n",
	n_row, n_col, nn, n_inner, npiv)) ;

    /* size of Numeric object, except Numeric->Memory and Numeric->Upattern */
    /* see also UMF_set_stats */
    num_fixed_size =
	UNITS (NumericType, 1)		/* Numeric structure */
	+ UNITS (Entry, n_inner+1)	/* D */
	+ UNITS (Int, n_row+1)		/* Rperm */
	+ UNITS (Int, n_col+1)		/* Cperm */
	+ 6 * UNITS (Int, npiv+1)	/* Lpos, Uilen, Uip, Upos, Lilen, Lip */
	+ ((Numeric->scale != UMFPACK_SCALE_NONE) ?
		UNITS (Entry, n_row) : 0) ; /* Rs */

    DEBUG1 (("num fixed size: "ID"\n", num_fixed_size)) ;
    DEBUG1 (("Numeric->size "ID"\n", Numeric->size)) ;
    DEBUG1 (("ulen units "ID"\n", UNITS (Int, Numeric->ulen))) ;

    /* size of Numeric->Memory is Numeric->size */
    /* size of Numeric->Upattern is Numeric->ulen */
    numeric_size = num_fixed_size + Numeric->size
	+ UNITS (Int, Numeric->ulen) ;

    DEBUG1 (("numeric total size "ID"\n", numeric_size)) ;

    if (prl >= 4)
    {
	PRINTF (("\n    n_row: "ID"  n_col: "ID"\n", n_row, n_col)) ;

	PRINTF (("    relative pivot tolerance used:              %g\n",
	    Numeric->relpt)) ;
	PRINTF (("    relative symmetric pivot tolerance used:    %g\n",
	    Numeric->relpt2)) ;

	PRINTF (("    matrix scaled: ")) ;
	if (Numeric->scale == UMFPACK_SCALE_NONE)
	{
	    PRINTF (("no")) ;
	}
	else if (Numeric->scale == UMFPACK_SCALE_SUM)
	{
	    PRINTF (("yes (divided each row by sum abs value in each row)\n")) ;
	    PRINTF (("    minimum sum (abs (rows of A)):              %.5e\n",
		Numeric->rsmin)) ;
	    PRINTF (("    maximum sum (abs (rows of A)):              %.5e",
		Numeric->rsmax)) ;
	}
	else if (Numeric->scale == UMFPACK_SCALE_MAX)
	{
	    PRINTF (("yes (divided each row by max abs value in each row)\n")) ;
	    PRINTF (("    minimum max (abs (rows of A)):              %.5e\n",
		Numeric->rsmin)) ;
	    PRINTF (("    maximum max (abs (rows of A)):              %.5e",
		Numeric->rsmax)) ;
	}
	PRINTF (("\n")) ;

	PRINTF (("    initial allocation parameter used:          %g\n",
	    Numeric->alloc_init)) ;
	PRINTF (("    frontal matrix allocation parameter used:   %g\n",
	    Numeric->front_alloc_init)) ;
	PRINTF (("    final total size of Numeric object (Units): "ID"\n",
	    numeric_size)) ;
	PRINTF (("    final total size of Numeric object (MBytes): %.1f\n",
	    MBYTES (numeric_size))) ;
	PRINTF (("    peak size of variable-size part (Units):    "ID"\n",
	    Numeric->max_usage)) ;
	PRINTF (("    peak size of variable-size part (MBytes):   %.1f\n",
	    MBYTES (Numeric->max_usage))) ;
	PRINTF (("    largest actual frontal matrix size:         "ID"\n",
	    Numeric->maxfrsize)) ;
	PRINTF (("    memory defragmentations:                    "ID"\n",
	    Numeric->ngarbage)) ;
	PRINTF (("    memory reallocations:                       "ID"\n",
	    Numeric->nrealloc)) ;
	PRINTF (("    costly memory reallocations:                "ID"\n",
	    Numeric->ncostly)) ;
	PRINTF (("    entries in compressed pattern (L and U):    "ID"\n",
	    Numeric->isize)) ;
	PRINTF (("    number of nonzeros in L (excl diag):        "ID"\n",
	    Numeric->lnz)) ;
	PRINTF (("    number of entries stored in L (excl diag):  "ID"\n",
	    Numeric->nLentries)) ;
	PRINTF (("    number of nonzeros in U (excl diag):        "ID"\n",
	    Numeric->unz)) ;
	PRINTF (("    number of entries stored in U (excl diag):  "ID"\n",
	    Numeric->nUentries)) ;
	PRINTF (("    factorization floating-point operations:    %g\n",
	    Numeric->flops)) ;
	PRINTF (("    number of nonzeros on diagonal of U:        "ID"\n",
	    Numeric->nnzpiv)) ;
	PRINTF (("    min abs. value on diagonal of U:            %.5e\n",
	    Numeric->min_udiag)) ;
	PRINTF (("    max abs. value on diagonal of U:            %.5e\n",
	    Numeric->max_udiag)) ;
	PRINTF (("    reciprocal condition number estimate:       %.2e\n",
	    Numeric->rcond)) ;
    }

    W = (Int *) UMF_malloc (nn, sizeof (Int)) ;
    if (!W)
    {
	PRINTF ((" ERROR: out of memory to check Numeric object\n\n")) ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }

    if (Numeric->Rs)
    {
#ifndef NRECIPROCAL
	if (Numeric->do_recip)
	{
	    PRINTF4 (("\nScale factors applied via multiplication\n")) ;
	}
	else
#endif
	{
	    PRINTF4 (("\nScale factors applied via division\n")) ;
	}
	PRINTF4 (("Scale factors, Rs: ")) ;
	(void) UMF_report_vector (n_row, Numeric->Rs, (double *) NULL,
	    prl, FALSE, TRUE) ;
    }
    else
    {
	PRINTF4 (("Scale factors, Rs: (not present)\n")) ;
    }

    PRINTF4 (("\nP: row ")) ;
    if (UMF_report_perm (n_row, Numeric->Rperm, W, prl, 0) != UMFPACK_OK)
    {
	(void) UMF_free ((void *) W) ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    PRINTF4 (("\nQ: column ")) ;
    if (UMF_report_perm (n_col, Numeric->Cperm, W, prl, 0) != UMFPACK_OK)
    {
	(void) UMF_free ((void *) W) ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    if (!report_L (Numeric, W, prl))
    {
	(void) UMF_free ((void *) W) ;
	PRINTF ((" ERROR: L factor invalid\n\n")) ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    if (!report_U (Numeric, W, prl))
    {
	(void) UMF_free ((void *) W) ;
	PRINTF ((" ERROR: U factor invalid\n\n")) ;
	return (UMFPACK_ERROR_invalid_Numeric_object) ;
    }

    /* The diagonal of U is in "merged" (Entry) form, not "split" form. */
    PRINTF4 (("\ndiagonal of U: ")) ;
    (void) UMF_report_vector (n_inner, (double *) Numeric->D, (double *) NULL,
	prl, FALSE, FALSE) ;

    (void) UMF_free ((void *) W) ;

    PRINTF4 (("    Numeric object:  ")) ;
    PRINTF (("OK\n\n")) ;
    return (UMFPACK_OK) ;
}