Exemplo n.º 1
0
void amdtest (cholmod_sparse *A)
{
    double Control [AMD_CONTROL], Info [AMD_INFO], alpha ;
    Int *P, *Cp, *Ci, *Sp, *Si, *Bp, *Bi, *Ep, *Ei, *Fp, *Fi,
	*Len, *Nv, *Next, *Head, *Elen, *Deg, *Wi, *W, *Flag ;
    cholmod_sparse *C, *B, *S, *E, *F ;
    Int i, j, n, nrow, ncol, ok, cnz, bnz, p, trial, sorted ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    printf ("\nAMD test\n") ;

    if (A == NULL)
    {
	return ;
    }

    if (A->stype)
    {
	B = CHOLMOD(copy) (A, 0, 0, cm) ;
    }
    else
    {
	B = CHOLMOD(aat) (A, NULL, 0, 0, cm) ;
    }

    if (A->nrow != A->ncol)
    {
	F = CHOLMOD(copy_sparse) (B, cm) ;
	OK (F->nrow == F->ncol) ;
	CHOLMOD(sort) (F, cm) ;
    }
    else
    {
	/* A is square and unsymmetric, and may have entries in A+A' that
	 * are not in A */
	F = CHOLMOD(copy_sparse) (A, cm) ;
	CHOLMOD(sort) (F, cm) ;
    }

    C = CHOLMOD(copy_sparse) (B, cm) ;

    nrow = C->nrow ;
    ncol = C->ncol ;
    n = nrow ;
    OK (nrow == ncol) ;

    Cp = C->p ;
    Ci = C->i ;

    Bp = B->p ;
    Bi = B->i ;

    /* ---------------------------------------------------------------------- */
    /* S = sorted form of B, using AMD_preprocess */
    /* ---------------------------------------------------------------------- */

    cnz = CHOLMOD(nnz) (C, cm) ;
    S = CHOLMOD(allocate_sparse) (n, n, cnz, TRUE, TRUE, 0, CHOLMOD_PATTERN,
	    cm);
    Sp = S->p ;
    Si = S->i ;

    W = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Flag = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace for amd */
    /* ---------------------------------------------------------------------- */

    P = CHOLMOD(malloc) (n+1, sizeof (Int), cm) ;

    Len  = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Nv   = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Next = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Head = CHOLMOD(malloc) (n+1, sizeof (Int), cm) ;
    Elen = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Deg  = CHOLMOD(malloc) (n, sizeof (Int), cm) ;
    Wi   = CHOLMOD(malloc) (n, sizeof (Int), cm) ;

    /* ---------------------------------------------------------------------- */

    for (sorted = 0 ; sorted <= 1 ; sorted++)
    {

	if (sorted) CHOLMOD(sort) (C, cm) ;

	Cp = C->p ;
	Ci = C->i ;

	/* ------------------------------------------------------------------ */
	/* order C with AMD_order */
	/* ------------------------------------------------------------------ */

	AMD_defaults (Control) ;
	AMD_defaults (NULL) ;
	AMD_control (Control) ;
	AMD_control (NULL) ;
	AMD_info (NULL) ;

	ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation", cm)) ;

	/* no dense rows/cols */
	alpha = Control [AMD_DENSE] ;
	Control [AMD_DENSE] = -1 ;
	AMD_control (Control) ;
	ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (alpha=-1)", cm)) ;

	/* many dense rows/cols */
	Control [AMD_DENSE] = 0 ;
	AMD_control (Control) ;
	ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (alpha=0)", cm)) ;
	Control [AMD_DENSE] = alpha ;

	/* no aggressive absorption */
	Control [AMD_AGGRESSIVE] = FALSE ;
	AMD_control (Control) ;
	ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (no agg) ", cm)) ;
	Control [AMD_AGGRESSIVE] = TRUE ;

	/* ------------------------------------------------------------------ */
	/* order F with AMD_order */
	/* ------------------------------------------------------------------ */

	Fp = F->p ;
	Fi = F->i ;
	ok = AMD_order (n, Fp, Fi, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "F: AMD permutation", cm)) ;

	/* ------------------------------------------------------------------ */
	/* order S with AMD_order */
	/* ------------------------------------------------------------------ */

	ok = AMD_order (n, Sp, Si, P, Control, Info) ;
	printf ("amd return value: "ID"\n", ok) ;
	AMD_info (Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation", cm)) ;

	/* ------------------------------------------------------------------ */
	/* order E with AMD_2, which destroys its contents */
	/* ------------------------------------------------------------------ */

	E = CHOLMOD(copy) (B, 0, -1, cm) ;	/* remove diagonal entries */
	bnz = CHOLMOD(nnz) (E, cm) ;

	/* add the bare minimum extra space to E */
	ok = CHOLMOD(reallocate_sparse) (bnz + n, E, cm) ;
	OK (ok) ;
	Ep = E->p ;
	Ei = E->i ;

	for (j = 0 ; j < n ; j++)
	{
	    Len [j] = Ep [j+1] - Ep [j] ;
	}

	printf ("calling AMD_2:\n") ;
	if (n > 0)
	{
	    AMD_2 (n, Ep, Ei, Len, E->nzmax, Ep [n], Nv, Next, P, Head, Elen,
		Deg, Wi, Control, Info) ;
	    AMD_info (Info) ;
	    OK (CHOLMOD(print_perm) (P, n, n, "AMD2 permutation", cm)) ;
	}

	/* ------------------------------------------------------------------ */
	/* error tests */
	/* ------------------------------------------------------------------ */

	ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	ok = AMD_order (-1, Cp, Ci, P, Control, Info) ;
	OK (ok == AMD_INVALID);
	ok = AMD_order (0, Cp, Ci, P, Control, Info) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	ok = AMD_order (n, NULL, Ci, P, Control, Info) ;
	OK (ok == AMD_INVALID);
	ok = AMD_order (n, Cp, NULL, P, Control, Info) ;
	OK (ok == AMD_INVALID);
	ok = AMD_order (n, Cp, Ci, NULL, Control, Info) ;
	OK (ok == AMD_INVALID);

	if (n > 0)
	{
	    printf ("AMD error tests:\n") ;

	    p = Cp [n] ;
	    Cp [n] = -1 ;
	    ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	    OK (ok == AMD_INVALID) ;

	    if (Size_max/2 == Int_max)
	    {
		Cp [n] = Int_max ;
		ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
		printf ("AMD status is "ID"\n", ok) ;
		OK (ok == AMD_OUT_OF_MEMORY) ;
	    }

	    Cp [n] = p ;
	    ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	    OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	    if (Cp [n] > 0)
	    {
		printf ("Mangle column zero:\n") ;
		i = Ci [0] ;
		Ci [0] = -1 ;
		ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
		AMD_info (Info) ;
		OK (ok == AMD_INVALID) ;
		Ci [0] = i ;
	    }
	}

	ok = AMD_valid (n, n, Sp, Si) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	ok = AMD_valid (-1, n, Sp, Si) ;	    OK (ok == AMD_INVALID) ;
	ok = AMD_valid (n, -1, Sp, Si) ;	    OK (ok == AMD_INVALID) ;
	ok = AMD_valid (n, n, NULL, Si) ;	    OK (ok == AMD_INVALID) ;
	ok = AMD_valid (n, n, Sp, NULL) ;	    OK (ok == AMD_INVALID) ;

	if (n > 0 && Sp [n] > 0)
	{

	    p = Sp [n] ;
	    Sp [n] = -1 ;
	    ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ;
	    Sp [n] = p ;

	    p = Sp [0] ;
	    Sp [0] = -1 ;
	    ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ;
	    Sp [0] = p ;

	    p = Sp [1] ;
	    Sp [1] = -1 ;
	    ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ;
	    Sp [1] = p ;

	    i = Si [0] ;
	    Si [0] = -1 ;
	    ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ;
	    Si [0] = i ;

	}

	ok = AMD_valid (n, n, Sp, Si) ;
	OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;
	AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ;
	ok = AMD_valid (n, n, Sp, Si) ;
	OK (ok == AMD_OK) ;

	if (n > 0 && Bp [n] > 0)
	{

	    p = Bp [n] ;
	    Bp [n] = -1 ;
	    ok = AMD_valid (n, n, Bp, Bi) ;	    OK (ok == AMD_INVALID) ;
	    Bp [n] = p ;


	    p = Bp [1] ;
	    Bp [1] = -1 ;
	    ok = AMD_valid (n, n, Bp, Bi) ;	    OK (ok == AMD_INVALID) ;
	    Bp [1] = p ;

	    i = Bi [0] ;
	    Bi [0] = -1 ;
	    ok = AMD_valid (n, n, Bp, Bi) ;	    OK (ok == AMD_INVALID) ;
	    Bi [0] = i ;
	}

	AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ;

	Info [AMD_STATUS] = 777 ;
	AMD_info (Info) ;

	/* ------------------------------------------------------------------ */
	/* memory tests */
	/* ------------------------------------------------------------------ */

	if (n > 0)
	{
	    amd_malloc = cm->malloc_memory ;
	    amd_free = cm->free_memory ;
	    ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
	    OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ;

	    test_memory_handler ( ) ;
	    amd_malloc = cm->malloc_memory ;
	    amd_free = cm->free_memory ;
	    for (trial = 0 ; trial < 6 ; trial++)
	    {
		my_tries = trial ;
		printf ("AMD memory trial "ID"\n", trial) ;
		ok = AMD_order (n, Cp, Ci, P, Control, Info) ;
		AMD_info (Info) ;
		OK (ok == AMD_OUT_OF_MEMORY
		    || (sorted ? (ok == AMD_OK) : (ok >= AMD_OK))) ;
	    }
	    normal_memory_handler ( ) ;
	    OK (CHOLMOD(print_perm) (P, n, n, "AMD2 permutation", cm)) ;

	    amd_malloc = cm->malloc_memory ;
	    amd_free = cm->free_memory ;
	}

	CHOLMOD(free_sparse) (&E, cm) ;
    }

    /* ---------------------------------------------------------------------- */
    /* free everything */
    /* ---------------------------------------------------------------------- */

    CHOLMOD(free) (n, sizeof (Int), Len,  cm) ;
    CHOLMOD(free) (n, sizeof (Int), Nv,   cm) ;
    CHOLMOD(free) (n, sizeof (Int), Next, cm) ;
    CHOLMOD(free) (n+1, sizeof (Int), Head, cm) ;
    CHOLMOD(free) (n, sizeof (Int), Elen, cm) ;
    CHOLMOD(free) (n, sizeof (Int), Deg,  cm) ;
    CHOLMOD(free) (n, sizeof (Int), Wi,   cm) ;

    CHOLMOD(free) (n+1, sizeof (Int), P, cm) ;

    CHOLMOD(free) (n, sizeof (Int), W, cm) ;
    CHOLMOD(free) (n, sizeof (Int), Flag, cm) ;

    CHOLMOD(free_sparse) (&S, cm) ;
    CHOLMOD(free_sparse) (&B, cm) ;
    CHOLMOD(free_sparse) (&C, cm) ;
    CHOLMOD(free_sparse) (&F, cm) ;
}
Exemplo n.º 2
0
void memory_tests (cholmod_triplet *T)
{
    double err ;
    cholmod_sparse *A ;
    Int trial ;
    size_t count, inuse ;

    test_memory_handler ( ) ;
    inuse = cm->memory_inuse ;

    cm->nmethods = 8 ;
    cm->print = 0 ;
    cm->final_resymbol = TRUE ;

    cm->final_asis = FALSE ;
    cm->final_super = FALSE ;
    cm->final_ll = FALSE ;
    cm->final_pack = FALSE ;
    cm->final_monotonic = FALSE ;

    /* ---------------------------------------------------------------------- */
    /* test raw factorizations */
    /* ---------------------------------------------------------------------- */

    printf ("==================================== fac memory test\n") ;
    count = cm->malloc_count ;
    my_tries = -1 ;
    for (trial = 0 ; my_tries <= 0 ; trial++)
    {
	cm->print = 0 ;
	fflush (stdout) ;
	my_tries = trial ;
	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
	my_srand (trial+1) ;					/* RAND reset */
	err = raw_factor (A, FALSE) ;				/* RAND */
	CHOLMOD(free_sparse) (&A, cm) ;
	OK (CHOLMOD(print_common) ("cm", cm)) ;
	CHOLMOD(free_work) (cm) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }
    CHOLMOD(free_work) (cm) ;
    printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ;
    printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
    printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
    OK (count == cm->malloc_count) ;
    OK (inuse == cm->memory_inuse) ;

    /* ---------------------------------------------------------------------- */
    /* test raw factorizations (rowfac_mask) */
    /* ---------------------------------------------------------------------- */

    printf ("==================================== fac memory test2\n") ;
    count = cm->malloc_count ;
    my_tries = -1 ;
    for (trial = 0 ; my_tries <= 0 ; trial++)
    {
	cm->print = 0 ;
	fflush (stdout) ;
	my_tries = trial ;
	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
	my_srand (trial+1) ;					/* RAND reset */
	err = raw_factor2 (A, 0., 0) ;				/* RAND */
	CHOLMOD(free_sparse) (&A, cm) ;
	OK (CHOLMOD(print_common) ("cm", cm)) ;
	CHOLMOD(free_work) (cm) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }
    CHOLMOD(free_work) (cm) ;
    printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ;
    printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
    printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
    OK (count == cm->malloc_count) ;
    OK (inuse == cm->memory_inuse) ;

    /* ---------------------------------------------------------------------- */
    /* test augmented system solver */
    /* ---------------------------------------------------------------------- */

    printf ("==================================== aug memory test\n") ;
    count = cm->malloc_count ;
    my_tries = -1 ;
    for (trial = 0 ; my_tries <= 0 ; trial++)
    {
	cm->print = 0 ;
	fflush (stdout) ;
	my_tries = trial ;
	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
	err = aug (A) ;				/* no random number use */
	CHOLMOD(free_sparse) (&A, cm) ;
	OK (CHOLMOD(print_common) ("cm", cm)) ;
	CHOLMOD(free_work) (cm) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }
    CHOLMOD(free_work) (cm) ;
    printf ("memory test: aug error %.1g trials "ID"\n", err, trial) ;
    printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
    printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
    OK (count == cm->malloc_count) ;
    OK (inuse == cm->memory_inuse) ;

    /* ---------------------------------------------------------------------- */
    /* test ops */
    /* ---------------------------------------------------------------------- */

    printf ("==================================== test_ops memory test\n") ;
    count = cm->malloc_count ;
    my_tries = -1 ;
    for (trial = 0 ; my_tries <= 0 ; trial++)
    {
	cm->print = 0 ;
	fflush (stdout) ;
	my_tries = trial ;
	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
	my_srand (trial+1) ;					/* RAND reset */
	err = test_ops (A) ;					/* RAND */
	CHOLMOD(free_sparse) (&A, cm) ;
	OK (CHOLMOD(print_common) ("cm", cm)) ;
	CHOLMOD(free_work) (cm) ;
	printf ("inuse "ID" "ID"\n", inuse, cm->memory_inuse) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }
    printf ("memory test: testops error %.1g trials "ID"\n", err, trial) ;
    printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
    printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
    OK (count == cm->malloc_count) ;
    OK (inuse == cm->memory_inuse) ;

    /* ---------------------------------------------------------------------- */
    /* test lpdemo */
    /* ---------------------------------------------------------------------- */

    if (T == NULL || T->nrow != T->ncol)
    {
	printf ("==================================== lpdemo memory test\n") ;
	count = cm->malloc_count ;
	my_tries = -1 ;
	for (trial = 0 ; my_tries <= 0 ; trial++)
	{
	    cm->print = 0 ;
	    fflush (stdout) ;
	    my_tries = trial ;
	    my_srand (trial+1) ;				/* RAND reset */
	    err = lpdemo (T) ;					/* RAND */
	    OK (CHOLMOD(print_common) ("cm", cm)) ;
	    CHOLMOD(free_work) (cm) ;
	    OK (count == cm->malloc_count) ;
	    OK (inuse == cm->memory_inuse) ;
	}
	CHOLMOD(free_work) (cm) ;
	printf ("memory test: lpdemo error %.1g trials "ID"\n", err, trial) ;
	printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
	printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }

    /* ---------------------------------------------------------------------- */
    /* test solver */
    /* ---------------------------------------------------------------------- */

    printf ("==================================== solve memory test\n") ;
    count = cm->malloc_count ;
    my_tries = -1 ;
    for (trial = 0 ; my_tries <= 0 ; trial++)
    {
	CHOLMOD(defaults) (cm) ;
	cm->supernodal = CHOLMOD_SUPERNODAL ;
	cm->metis_memory = 2.0 ;
	cm->nmethods = 4 ;
	cm->print = 0 ;
	fflush (stdout) ;
	my_tries = trial ;
	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
	my_srand (trial+1) ;					/* RAND reset */
	err = solve (A) ;					/* RAND */
	CHOLMOD(free_sparse) (&A, cm) ;
	OK (CHOLMOD(print_common) ("cm", cm)) ;
	CHOLMOD(free_work) (cm) ;
	OK (count == cm->malloc_count) ;
	OK (inuse == cm->memory_inuse) ;
    }
    CHOLMOD(free_work) (cm) ;
    printf ("memory test: solve error %.1g trials "ID"\n", err, trial) ;
    printf ("initial count: "ID" final count "ID"\n",
	    (Int) count, (Int) cm->malloc_count) ;
    printf ("initial inuse: "ID" final inuse "ID"\n",
	    (Int) inuse, (Int) cm->memory_inuse) ;
    OK (count == cm->malloc_count) ;
    OK (inuse == cm->memory_inuse) ;
    cm->supernodal = CHOLMOD_AUTO ;
    progress (1, '|') ;

    /* ---------------------------------------------------------------------- */
    /* restore original memory handler */
    /* ---------------------------------------------------------------------- */

    normal_memory_handler ( ) ;
    cm->print = 1 ;

    printf ("All memory tests OK, no error\n") ;
}
Exemplo n.º 3
0
void cctest (cholmod_sparse *A)
{

    double knobs [CCOLAMD_KNOBS], knobs2 [CCOLAMD_KNOBS] ;
    Int *P, *Cmember, *Cp, *Ci, *Front_npivcol, *Front_nrows, *Front_ncols,
	*Front_parent, *Front_cols, *InFront, *Si, *Sp ;
    cholmod_sparse *C, *A2, *B, *S ;
    Int nrow, ncol, alen, ok, stats [CCOLAMD_STATS], csets, i, nfr, c, p ;
    size_t s ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    my_srand (42) ;						/* RAND reset */

    printf ("\nCCOLAMD test\n") ;

    if (A == NULL)
    {
	return ;
    }

    if (A->stype)
    {
	A2 = CHOLMOD(copy) (A, 0, 0, cm) ;
	B = A2 ;
    }
    else
    {
	A2 = NULL ;
	B = A ;
    }
    S = CHOLMOD(copy_sparse) (A, cm) ;

    nrow = B->nrow ;
    ncol = B->ncol ;
    Si = S->i ;
    Sp = S->p ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace and Cmember for ccolamd */
    /* ---------------------------------------------------------------------- */

    P = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    Cmember = CHOLMOD(malloc) (nrow, sizeof (Int), cm) ;
    Front_npivcol = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    Front_nrows   = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    Front_ncols   = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    Front_parent  = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    Front_cols    = CHOLMOD(malloc) (nrow+1, sizeof (Int), cm) ;
    InFront       = CHOLMOD(malloc) (ncol, sizeof (Int), cm) ;

    csets = MIN (6, nrow) ;
    for (i = 0 ; i < nrow ; i++)
    {
	Cmember [i] = nrand (csets) ;
    }

    CCOLAMD_set_defaults (knobs) ;
    CCOLAMD_set_defaults (knobs2) ;
    CCOLAMD_set_defaults (NULL) ;
    CCOLAMD_report (NULL) ;
    CSYMAMD_report (NULL) ;

    alen = CCOLAMD_recommended (B->nzmax, ncol, nrow) ;
    C = CHOLMOD(allocate_sparse) (ncol, nrow, alen, TRUE, TRUE, 0,
	    CHOLMOD_PATTERN, cm) ;
    Cp = C->p ;
    Ci = C->i ;

    /* ---------------------------------------------------------------------- */
    /* order with ccolamd */
    /* ---------------------------------------------------------------------- */

    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    CHOLMOD(print_sparse) (C, "C for ccolamd", cm) ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, NULL, stats, Cmember) ;
    CCOLAMD_report (stats) ;
    OK (ok) ;
    ok = stats [CCOLAMD_STATUS] ;
    ok = (ok == CCOLAMD_OK || ok == CCOLAMD_OK_BUT_JUMBLED) ;
    OK (ok) ;

    /* permutation returned in C->p, if the ordering succeeded */
    /* make sure P obeys the constraints */
    OK (check_constraints (Cp, Cmember, nrow)) ;

    /* ---------------------------------------------------------------------- */
    /* order with ccolamd2 */
    /* ---------------------------------------------------------------------- */

    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    ok = CCOLAMD_2 (ncol, nrow, alen, Ci, Cp, NULL, stats,
	    Front_npivcol, Front_nrows, Front_ncols, Front_parent,
	    Front_cols, &nfr, InFront, Cmember) ;
    CCOLAMD_report (stats) ;
    OK (check_constraints (Cp, Cmember, nrow)) ;

    /* ---------------------------------------------------------------------- */
    /* with a small dense-row threshold */
    /* ---------------------------------------------------------------------- */

    knobs2 [CCOLAMD_DENSE_ROW] = 0 ;
    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs2, stats, Cmember) ;
    CCOLAMD_report (stats) ;

    knobs2 [CCOLAMD_DENSE_ROW] = 0.625 ;
    knobs2 [CCOLAMD_DENSE_COL] = 0 ;
    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs2, stats, Cmember) ;
    CCOLAMD_report (stats) ;

    knobs2 [CCOLAMD_DENSE_ROW] = 0.625 ;
    knobs2 [CCOLAMD_DENSE_COL] = -1 ;
    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs2, stats, Cmember) ;
    CCOLAMD_report (stats) ;

    knobs2 [CCOLAMD_DENSE_COL] = 0 ;

    /* ---------------------------------------------------------------------- */
    /* duplicate entries */
    /* ---------------------------------------------------------------------- */

    if (ncol > 2 && nrow > 2)
    {
	ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ;
	OK (ok) ;
	if (Cp [1] - Cp [0] > 2)
	{
	    Ci [0] = Ci [1] ;
	}
	ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs2, stats, Cmember) ;
	CCOLAMD_report (stats) ;
	OK (CHOLMOD(print_perm) (Cp, nrow, nrow, "ccolamd perm", cm)) ;
    }

    /* ---------------------------------------------------------------------- */
    /* csymamd */
    /* ---------------------------------------------------------------------- */

    if (nrow == ncol)
    {
	Int n = nrow ;

	ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats,
		cm->calloc_memory, cm->free_memory, Cmember, A->stype) ;
	OK (ok) ;
	OK (check_constraints (P, Cmember, n)) ;
	CSYMAMD_report (stats) ;

	/* ------------------------------------------------------------------ */
	/* csymamd errors */
	/* ------------------------------------------------------------------ */

	ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, NULL, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);

	ok = CSYMAMD_MAIN (n, NULL, Sp, P, NULL, stats, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);
	CSYMAMD_report (stats) ;

	ok = CSYMAMD_MAIN (n, Si, NULL, P, NULL, stats, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);
	CSYMAMD_report (stats) ;

	ok = CSYMAMD_MAIN (-1, Si, Sp, P, NULL, stats, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);
	CSYMAMD_report (stats) ;

	p = Sp [n] ;
	Sp [n] = -1 ;
	ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);
	CSYMAMD_report (stats) ;
	Sp [n] = p ;

	Sp [0] = -1 ;
	ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		cm->free_memory, Cmember, A->stype) ;		       NOT (ok);
	CSYMAMD_report (stats) ;
	Sp [0] = 0 ;

	if (n > 2 && Sp [n] > 3)
	{
	    p = Sp [1] ;
	    Sp [1] = -1 ;
	    ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		    cm->free_memory, Cmember, A->stype) ;	       NOT (ok);
	    CSYMAMD_report (stats) ;
	    Sp [1] = p ;

	    i = Si [0] ;
	    Si [0] = -1 ;
	    ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		    cm->free_memory, Cmember, A->stype) ;	       NOT (ok);
	    CSYMAMD_report (stats) ;
	    Si [0] = i ;

	    /* ok, but jumbled */
	    i = Si [0] ;
	    Si [0] = Si [1] ;
	    Si [1] = i ;
	    ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		    cm->free_memory, Cmember, A->stype) ;	       OK (ok);
	    CSYMAMD_report (stats) ;
	    i = Si [0] ;
	    Si [0] = Si [1] ;
	    Si [1] = i ;

	    test_memory_handler ( ) ;
	    ok = CSYMAMD_MAIN (n, Si, Sp, P, NULL, stats, cm->calloc_memory,
		    cm->free_memory, Cmember, A->stype) ;	       NOT(ok);
	    CSYMAMD_report (stats) ;
	    normal_memory_handler ( ) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* error tests */
    /* ---------------------------------------------------------------------- */

    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ;   OK (ok) ;
    ok = CCOLAMD_MAIN (ncol, nrow, 0, Ci, Cp, knobs, stats, Cmember) ;     NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CCOLAMD_MAIN (ncol, nrow, alen, NULL, Cp, knobs, stats, Cmember); NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, NULL, knobs, stats, Cmember); NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, NULL, Cmember) ;   NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CCOLAMD_MAIN (-1, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;    NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CCOLAMD_MAIN (ncol, -1, alen, Ci, Cp, knobs, stats, Cmember) ;    NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ; OK (ok) ;
    Cp [nrow] = -1 ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;  NOT (ok) ;
    CCOLAMD_report (stats) ;

    Cp [0] = 1 ;
    ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;  NOT (ok) ;
    CCOLAMD_report (stats) ;

    ok = CHOLMOD(transpose_unsym) (B, 0, NULL, NULL, 0, C, cm) ;   OK (ok) ;

    if (nrow > 0 && alen > 0 && Cp [1] > 0)
    {
	c = Cmember [0] ;
	Cmember [0] = -1 ;
	ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;NOT(ok);
	CCOLAMD_report (stats) ;
	Cmember [0] = c ;

	p = Cp [1] ;
	Cp [1] = -1 ;
	ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;NOT(ok);
	CCOLAMD_report (stats) ;
	Cp [1] = p ;

	i = Ci [0] ;
	Ci [0] = -1 ;
	ok = CCOLAMD_MAIN (ncol, nrow, alen, Ci, Cp, knobs, stats, Cmember) ;NOT(ok);
	CCOLAMD_report (stats) ;
	Ci [0] = i ;
    }

    s = CCOLAMD_recommended (-1, 0, 0) ;
    OK (s == 0) ;

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

    CHOLMOD(free) (nrow+1, sizeof (Int), Front_npivcol, cm) ;
    CHOLMOD(free) (nrow+1, sizeof (Int), Front_nrows, cm) ;
    CHOLMOD(free) (nrow+1, sizeof (Int), Front_ncols, cm) ;
    CHOLMOD(free) (nrow+1, sizeof (Int), Front_parent, cm) ;
    CHOLMOD(free) (nrow+1, sizeof (Int), Front_cols, cm) ;
    CHOLMOD(free) (nrow+1, sizeof (Int), P, cm) ;
    CHOLMOD(free) (nrow, sizeof (Int), Cmember, cm) ;
    CHOLMOD(free) (ncol, sizeof (Int), InFront, cm) ;

    CHOLMOD(free_sparse) (&S, cm) ;
    CHOLMOD(free_sparse) (&A2, cm) ;
    CHOLMOD(free_sparse) (&C, cm) ;
    cm->print = 1 ;
}
Exemplo n.º 4
0
int main (void)
{
    KLU_common Common ;
    cholmod_sparse *A, *A2 ;
    cholmod_dense *X, *B ;
    cholmod_common ch ;
    Int *Ap, *Ai, *Puser, *Quser, *Gunk ;
    double *Ax, *Bx, *Xx, *A2x ;
    double one [2], zero [2], xsave, maxerr ;
    Int n, i, j, nz, save, isreal, k, nan ;
    KLU_symbolic *Symbolic, *Symbolic2 ;
    KLU_numeric *Numeric ;

    one [0] = 1 ;
    one [1] = 0 ;
    zero [0] = 0 ;
    zero [1] = 0 ;

    printf ("klu test: -------------------------------------------------\n") ;
    OK (klu_defaults (&Common)) ;
    CHOLMOD_start (&ch) ;
    ch.print = 0 ;
    normal_memory_handler (&Common) ;

    /* ---------------------------------------------------------------------- */
    /* read in a sparse matrix from stdin */
    /* ---------------------------------------------------------------------- */

    A = CHOLMOD_read_sparse (stdin, &ch) ;

    if (A->nrow != A->ncol || A->stype != 0)
    {
	fprintf (stderr, "error: only square unsymmetric matrices handled\n") ;
	CHOLMOD_free_sparse (&A, &ch) ;
	return (0) ;
    }
    if (!(A->xtype == CHOLMOD_REAL || A->xtype == CHOLMOD_COMPLEX))
    {
	fprintf (stderr, "error: only real or complex matrices hanlded\n") ;
	CHOLMOD_free_sparse (&A, &ch) ;
	return (0) ;
    }

    n = A->nrow ;
    Ap = A->p ;
    Ai = A->i ;
    Ax = A->x ;
    nz = Ap [n] ;
    isreal = (A->xtype == CHOLMOD_REAL) ;

    /* ---------------------------------------------------------------------- */
    /* construct random permutations */
    /* ---------------------------------------------------------------------- */

    Puser = randperm (n, n) ;
    Quser = randperm (n, n) ;

    /* ---------------------------------------------------------------------- */
    /* select known solution to Ax=b */
    /* ---------------------------------------------------------------------- */

    X = CHOLMOD_allocate_dense (n, NRHS, n, A->xtype, &ch) ;
    Xx = X->x ;
    for (j = 0 ; j < NRHS ; j++)
    {
	for (i = 0 ; i < n ; i++)
	{
	    if (isreal)
	    {
		Xx [i] = 1 + ((double) i) / ((double) n) + j * 100;
	    }
	    else
	    {
		Xx [2*i  ] = 1 + ((double) i) / ((double) n) + j * 100 ;
		Xx [2*i+1] =  - ((double) i+1) / ((double) n + j) ;
		if (j == NRHS-1)
		{
		    Xx [2*i+1] = 0 ;	/* zero imaginary part */
		}
		else if (j == NRHS-2)
		{
		    Xx [2*i] = 0 ;	/* zero real part */
		}
	    }
	}
	Xx += isreal ? n : 2*n ;
    }

    /* B = A*X */
    B = CHOLMOD_allocate_dense (n, NRHS, n, A->xtype, &ch) ;
    CHOLMOD_sdmult (A, 0, one, zero, X, B, &ch) ;
    Bx = B->x ;

    /* ---------------------------------------------------------------------- */
    /* test KLU */
    /* ---------------------------------------------------------------------- */

    test_memory_handler (&Common) ;
    maxerr = do_solves (A, B, X, Puser, Quser, &Common, &ch, &nan) ;

    /* ---------------------------------------------------------------------- */
    /* basic error checking */
    /* ---------------------------------------------------------------------- */

    FAIL (klu_defaults (NULL)) ;

    FAIL (klu_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	    NULL, NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	    NULL, NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_analyze (0, NULL, NULL, NULL)) ;
    FAIL (klu_analyze (0, NULL, NULL, &Common)) ;

    FAIL (klu_analyze_given (0, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_analyze_given (0, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_cholmod (0, NULL, NULL, NULL, NULL)) ;

    FAIL (klu_factor (NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_factor (NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_factor (NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_factor (NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_refactor (NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_refactor (NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_refactor (NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_refactor (NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_rgrowth (NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_rgrowth (NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_rgrowth (NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_rgrowth (NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_condest (NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_condest (NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_condest (NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_condest (NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_flops (NULL, NULL, NULL)) ;
    FAIL (klu_flops (NULL, NULL, &Common)) ;

    FAIL (klu_z_flops (NULL, NULL, NULL)) ;
    FAIL (klu_z_flops (NULL, NULL, &Common)) ;

    FAIL (klu_rcond (NULL, NULL, NULL)) ;
    FAIL (klu_rcond (NULL, NULL, &Common)) ;

    FAIL (klu_z_rcond (NULL, NULL, NULL)) ;
    FAIL (klu_z_rcond (NULL, NULL, &Common)) ;

    FAIL (klu_free_symbolic (NULL, NULL)) ;
    OK (klu_free_symbolic (NULL, &Common)) ;

    FAIL (klu_free_numeric (NULL, NULL)) ;
    OK (klu_free_numeric (NULL, &Common)) ;

    FAIL (klu_z_free_numeric (NULL, NULL)) ;
    OK (klu_z_free_numeric (NULL, &Common)) ;

    FAIL (klu_scale (0, 0, NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_scale (0, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ;
    OK (klu_scale (-1, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_z_scale (0, 0, NULL, NULL, NULL, NULL, NULL, NULL)) ;
    FAIL (klu_z_scale (0, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ;
    OK (klu_z_scale (-1, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ;

    FAIL (klu_solve (NULL, NULL, 0, 0, NULL, NULL)) ;
    FAIL (klu_solve (NULL, NULL, 0, 0, NULL, &Common)) ;

    FAIL (klu_z_solve (NULL, NULL, 0, 0, NULL, NULL)) ;
    FAIL (klu_z_solve (NULL, NULL, 0, 0, NULL, &Common)) ;

    FAIL (klu_tsolve (NULL, NULL, 0, 0, NULL, NULL)) ;
    FAIL (klu_tsolve (NULL, NULL, 0, 0, NULL, &Common)) ;

    FAIL (klu_z_tsolve (NULL, NULL, 0, 0, NULL, 0, NULL)) ;
    FAIL (klu_z_tsolve (NULL, NULL, 0, 0, NULL, 0, &Common)) ;

    FAIL (klu_malloc (0, 0, NULL)) ;
    FAIL (klu_malloc (0, 0, &Common)) ;
    FAIL (klu_malloc (Int_MAX, 1, &Common)) ;

    FAIL (klu_realloc (0, 0, 0, NULL, NULL)) ;
    FAIL (klu_realloc (0, 0, 0, NULL, &Common)) ;
    FAIL (klu_realloc (Int_MAX, 1, 0, NULL, &Common)) ;
    Gunk = (Int *) klu_realloc (1, 0, sizeof (Int), NULL, &Common) ;
    OK (Gunk) ;
    OK (klu_realloc (Int_MAX, 1, sizeof (Int), Gunk, &Common)) ;
    OK (Common.status == KLU_TOO_LARGE) ;
    klu_free (Gunk, 1, sizeof (Int), &Common) ;

    /* ---------------------------------------------------------------------- */
    /* mangle the matrix, and other error checking */
    /* ---------------------------------------------------------------------- */

    printf ("\nerror handling:\n") ;
    Symbolic = klu_analyze (n, Ap, Ai, &Common) ;
    OK (Symbolic) ;

    Xx = X->x ;
    if (nz > 0)
    {

	/* ------------------------------------------------------------------ */
	/* row index out of bounds */
	/* ------------------------------------------------------------------ */

	save = Ai [0] ;
	Ai [0] = -1 ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	if (isreal)
	{
	    FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	else
	{
	    FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	Ai [0] = save ;

	/* ------------------------------------------------------------------ */
	/* row index out of bounds */
	/* ------------------------------------------------------------------ */

	save = Ai [0] ;
	Ai [0] = Int_MAX ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	if (isreal)
	{
	    FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	else
	{
	    FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	Ai [0] = save ;

	/* ------------------------------------------------------------------ */
	/* column pointers mangled */
	/* ------------------------------------------------------------------ */

	save = Ap [n] ;
	Ap [n] = -1 ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	if (isreal)
	{
	    FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	else
	{
	    FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	Ap [n] = save ;

	/* ------------------------------------------------------------------ */
	/* column pointers mangled */
	/* ------------------------------------------------------------------ */

	save = Ap [n] ;
	Ap [n] = Ap [n-1] - 1 ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	if (isreal)
	{
	    FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	else
	{
	    FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	}
	Ap [n] = save ;

	/* ------------------------------------------------------------------ */
	/* duplicates */
	/* ------------------------------------------------------------------ */

	if (n > 1 && Ap [1] - Ap [0] > 1)
	{
	    save = Ai [1] ;
	    Ai [1] = Ai [0] ;
	    FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	    if (isreal)
	    {
		FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	    }
	    else
	    {
		FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ;
	    }
	    Ai [1] = save ;
	}

	/* ------------------------------------------------------------------ */
	/* invalid ordering */
	/* ------------------------------------------------------------------ */

	save = Common.ordering ;
	Common.ordering = 42 ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	Common.ordering = save ;

	/* ------------------------------------------------------------------ */
	/* invalid ordering (klu_cholmod, with NULL user_ordering) */
	/* ------------------------------------------------------------------ */

	save = Common.ordering ;
	Common.user_order = NULL ;
	Common.ordering = 3 ;
	FAIL (klu_analyze (n, Ap, Ai, &Common)) ;
	Common.ordering = save ;
    }

    /* ---------------------------------------------------------------------- */
    /* tests with valid symbolic factorization */
    /* ---------------------------------------------------------------------- */

    Common.halt_if_singular = FALSE ;
    Common.scale = 0 ;
    Numeric = NULL ;

    if (nz > 0)
    {

	/* ------------------------------------------------------------------ */
	/* Int overflow */
	/* ------------------------------------------------------------------ */

	if (n == 100)
	{
	    Common.ordering = 2 ;
	    Symbolic2 = klu_analyze (n, Ap, Ai, &Common) ;
	    OK (Symbolic2) ;
	    Common.memgrow = Int_MAX ;
	    if (isreal)
	    {
		Numeric = klu_factor (Ap, Ai, Ax, Symbolic2, &Common) ;
	    }
	    else
	    {
		Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic2, &Common) ;
	    }
	    Common.memgrow = 1.2 ;
	    Common.ordering = 0 ;
	    klu_free_symbolic (&Symbolic2, &Common) ;
	    klu_free_numeric (&Numeric, &Common) ;
	}

	/* ------------------------------------------------------------------ */
	/* Int overflow again */
	/* ------------------------------------------------------------------ */

	Common.initmem = Int_MAX ;
	Common.initmem_amd = Int_MAX ;
	if (isreal)
	{
	    Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	}
	else
	{
	    Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	}
	Common.initmem = 10 ;
	Common.initmem_amd = 1.2 ;
	klu_free_numeric (&Numeric, &Common) ;

	/* ------------------------------------------------------------------ */
	/* mangle the matrix */
	/* ------------------------------------------------------------------ */

	save = Ai [0] ;
	Ai [0] = -1 ;

	if (isreal)
	{
	    Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	}
	else
	{
	    Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	}
	FAIL (Numeric) ;
	Ai [0] = save ;

	/* ------------------------------------------------------------------ */
	/* nan and inf handling */
	/* ------------------------------------------------------------------ */

	xsave = Ax [0] ;
	Ax [0] = one [0] / zero [0] ;
	if (isreal)
	{
	    Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	    klu_rcond (Symbolic, Numeric, &Common) ;
	    klu_condest (Ap, Ax, Symbolic, Numeric, &Common) ;
	}
	else
	{
	    Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ;
	    klu_z_rcond (Symbolic, Numeric, &Common) ;
	    klu_z_condest (Ap, Ax, Symbolic, Numeric, &Common) ;
	}
	printf ("Nan case: rcond %g condest %g\n",
	    Common.rcond, Common.condest) ;
	OK (Numeric) ;
	Ax [0] = xsave ;

	/* ------------------------------------------------------------------ */
	/* mangle the matrix again */
	/* ------------------------------------------------------------------ */

	save = Ai [0] ;
	Ai [0] = -1 ;
	if (isreal)
	{
	    FAIL (klu_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common)) ;
	}
	else
	{
	    FAIL (klu_z_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common)) ;
	}
	Ai [0] = save ;

	/* ------------------------------------------------------------------ */
	/* all zero */
	/* ------------------------------------------------------------------ */

	A2 = CHOLMOD_copy_sparse (A, &ch) ;
	A2x = A2->x ;
	for (k = 0 ; k < nz * (isreal ? 1:2) ; k++)
	{
	    A2x [k] = 0 ;
	}
	for (Common.halt_if_singular = 0 ; Common.halt_if_singular <= 1 ;
	    Common.halt_if_singular++)
	{
	    for (Common.scale = -1 ; Common.scale <= 2 ; Common.scale++)
	    {
		if (isreal)
		{
		    klu_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ;
		    klu_condest (Ap, A2x, Symbolic, Numeric, &Common) ;
		}
		else
		{
		    klu_z_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ;
		    klu_z_condest (Ap, A2x, Symbolic, Numeric, &Common) ;
		}
		OK (Common.status = KLU_SINGULAR) ;
	    }
	}
	CHOLMOD_free_sparse (&A2, &ch) ;

	/* ------------------------------------------------------------------ */
	/* all one, or all 1i for complex case */
	/* ------------------------------------------------------------------ */

	A2 = CHOLMOD_copy_sparse (A, &ch) ;
	A2x = A2->x ;
	for (k = 0 ; k < nz ; k++)
	{
	    if (isreal)
	    {
		A2x [k] = 1 ;
	    }
	    else
	    {
		A2x [2*k  ] = 0 ;
		A2x [2*k+1] = 1 ;
	    }
	}
	Common.halt_if_singular = 0 ;
	Common.scale = 0 ;
	if (isreal)
	{
	    klu_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ;
	    klu_condest (Ap, A2x, Symbolic, Numeric, &Common) ;
	}
	else
	{
	    klu_z_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ;
	    klu_z_condest (Ap, A2x, Symbolic, Numeric, &Common) ;
	}
	OK (Common.status = KLU_SINGULAR) ;
	CHOLMOD_free_sparse (&A2, &ch) ;
    }

    klu_free_symbolic (&Symbolic, &Common) ;
    if (isreal)
    {
	klu_free_numeric (&Numeric, &Common) ;
    }
    else
    {
	klu_z_free_numeric (&Numeric, &Common) ;
    }

    /* ---------------------------------------------------------------------- */
    /* free problem and quit */
    /* ---------------------------------------------------------------------- */

    CHOLMOD_free_dense (&X, &ch) ;
    CHOLMOD_free_dense (&B, &ch) ;
    CHOLMOD_free_sparse (&A, &ch) ;
    free (Puser) ;
    free (Quser) ;
    CHOLMOD_finish (&ch) ;
    fprintf (stderr, " maxerr %10.3e", maxerr) ;
    printf (" maxerr %10.3e", maxerr) ;
    if (maxerr < 1e-8)
    {
	fprintf (stderr, "  test passed") ;
	printf ("  test passed") ;
    }
    else
    {
	fprintf (stderr, "  test FAILED") ;
	printf ("  test FAILED") ;
    }
    if (nan)
    {
	fprintf (stderr, " *") ;
	printf (" *") ;
    }
    fprintf (stderr, "\n") ;
    printf ("\n-----------------------------------------------------------\n") ;
    return (0) ;
}