예제 #1
0
void Block::allocate_resource(cholmod_common *cm){
	if( count == 0 ) return;
	nodes = new Node *[count];

	b_ck = cholmod_zeros(count, 1, CHOLMOD_REAL, cm);
	x_ck = cholmod_zeros(count, 1, CHOLMOD_REAL, cm);
	bp = static_cast<double*>(b_ck->x);
	xp = static_cast<double*>(x_ck->x);
	b_new_ck = cholmod_zeros(count, 1, CHOLMOD_REAL, cm);
	bnewp = static_cast<double*>(b_new_ck->x);
	x_old = new double [count];
	x_new = new float [count];
}
예제 #2
0
int main (int argc, char **argv)
{
    double resid, t, ta, tf, ts, tot, bnorm, xnorm, anorm, rnorm, fl, anz, 
	axbnorm, rnorm2, resid2 ;
    FILE *f ;
    cholmod_sparse *A ;
    cholmod_dense *X, *B, *W, *R ;
    double one [2], zero [2], minusone [2], beta [2], xlnz ;
    cholmod_common Common, *cm ;
    cholmod_factor *L ;
    double *Bx, *Rx, *Xx ;
    int i, n, isize, xsize, ordering, xtype, s, ss, lnz ;

    /* ---------------------------------------------------------------------- */
    /* get the file containing the input matrix */
    /* ---------------------------------------------------------------------- */

    ff = NULL ;
    if (argc > 1)
    {
	if ((f = fopen (argv [1], "r")) == NULL)
	{
	    my_handler (CHOLMOD_INVALID, __FILE__, __LINE__,
		    "unable to open file") ;
	}
	ff = f ;
    }
    else
    {
	f = stdin ;
    }

    /* ---------------------------------------------------------------------- */
    /* start CHOLMOD and set parameters */
    /* ---------------------------------------------------------------------- */

    cm = &Common ;
    cholmod_start (cm) ;

    /* use default parameter settings, except for the error handler.  This
     * demo program terminates if an error occurs (out of memory, not positive
     * definite, ...).  It makes the demo program simpler (no need to check
     * CHOLMOD error conditions).  This non-default parameter setting has no
     * effect on performance. */
    cm->error_handler = my_handler ;

    /* Note that CHOLMOD will do a supernodal LL' or a simplicial LDL' by
     * default, automatically selecting the latter if flop/nnz(L) < 40. */

    /* ---------------------------------------------------------------------- */
    /* create basic scalars */
    /* ---------------------------------------------------------------------- */

    zero [0] = 0 ;
    zero [1] = 0 ;
    one [0] = 1 ;
    one [1] = 0 ;
    minusone [0] = -1 ;
    minusone [1] = 0 ;
    beta [0] = 1e-6 ;
    beta [1] = 0 ;

    /* ---------------------------------------------------------------------- */
    /* read in a matrix */
    /* ---------------------------------------------------------------------- */

    printf ("\n---------------------------------- cholmod_demo:\n") ;
    A = cholmod_read_sparse (f, cm) ;
    if (ff != NULL) fclose (ff) ;
    anorm = cholmod_norm_sparse (A, 0, cm) ;
    xtype = A->xtype ;
    printf ("norm (A,inf) = %g\n", anorm) ;
    printf ("norm (A,1)   = %g\n", cholmod_norm_sparse (A, 1, cm)) ;
    cholmod_print_sparse (A, "A", cm) ;

    if (A->nrow > A->ncol)
    {
	/* Transpose A so that A'A+beta*I will be factorized instead */
	cholmod_sparse *C = cholmod_transpose (A, 2, cm) ;
	cholmod_free_sparse (&A, cm) ;
	A = C ;
	printf ("transposing input matrix\n") ;
    }

    /* ---------------------------------------------------------------------- */
    /* create an arbitrary right-hand-side */
    /* ---------------------------------------------------------------------- */

    n = A->nrow ;
    B = cholmod_zeros (n, 1, xtype, cm) ;
    Bx = B->x ;

#if GHS
    {
	/* b = A*ones(n,1), used by Gould, Hu, and Scott in their experiments */
	cholmod_dense *X0 ;
	X0 = cholmod_ones (A->ncol, 1, xtype, cm) ;
	cholmod_sdmult (A, 0, one, zero, X0, B, cm) ;
	cholmod_free_dense (&X0, cm) ;
    }
#else
    if (xtype == CHOLMOD_REAL)
    {
	/* real case */
	for (i = 0 ; i < n ; i++)
	{
	    double x = n ;
	    Bx [i] = 1 + i / x ;
	}
    }
    else
    {
	/* complex case */
	for (i = 0 ; i < n ; i++)
	{
	    double x = n ;
	    Bx [2*i  ] = 1 + i / x ;		/* real part of B(i) */
	    Bx [2*i+1] = (x/2 - i) / (3*x) ;	/* imag part of B(i) */
	}
    }
#endif

    cholmod_print_dense (B, "B", cm) ;
    bnorm = cholmod_norm_dense (B, 0, cm) ;	/* max norm */
    printf ("bnorm %g\n", bnorm) ;

    /* ---------------------------------------------------------------------- */
    /* analyze, factorize, and solve */
    /* ---------------------------------------------------------------------- */

    t = CPUTIME ;
    L = cholmod_analyze (A, cm) ;
    ta = CPUTIME - t ;
    ta = MAX (ta, 0) ;

    printf ("Analyze: flop %g lnz %g\n", cm->fl, cm->lnz) ;

    if (A->stype == 0)
    {
	printf ("Factorizing A*A'+beta*I\n") ;
	t = CPUTIME ;
	cholmod_factorize_p (A, beta, NULL, 0, L, cm) ;
	tf = CPUTIME - t ;
	tf = MAX (tf, 0) ;
    }
    else
    {
	printf ("Factorizing A\n") ;
	t = CPUTIME ;
	cholmod_factorize (A, L, cm) ;
	tf = CPUTIME - t ;
	tf = MAX (tf, 0) ;
    }

    t = CPUTIME ;

    X = cholmod_solve (CHOLMOD_A, L, B, cm) ;
    ts = CPUTIME - t ;
    ts = MAX (ts, 0) ;
    tot = ta + tf + ts ;

    /* ---------------------------------------------------------------------- */
    /* compute the residual */
    /* ---------------------------------------------------------------------- */

    if (A->stype == 0)
    {
	/* (AA'+beta*I)x=b is the linear system that was solved */
	/* W = A'*X */
	W = cholmod_allocate_dense (A->ncol, 1, A->ncol, xtype, cm) ;
	cholmod_sdmult (A, 2, one, zero, X, W, cm) ;
	/* R = B - beta*X */
	R = cholmod_zeros (n, 1, xtype, cm) ;
	Rx = R->x ;
	Xx = X->x ;
	if (xtype == CHOLMOD_REAL)
	{
	    for (i = 0 ; i < n ; i++)
	    {
		Rx [i] = Bx [i] - beta [0] * Xx [i] ;
	    }
	}
	else
	{
	    /* complex case */
	    for (i = 0 ; i < n ; i++)
	    {
		Rx [2*i  ] = Bx [2*i  ] - beta [0] * Xx [2*i  ] ;
		Rx [2*i+1] = Bx [2*i+1] - beta [0] * Xx [2*i+1] ;
	    }
	}
	/* R = A*W - R */
	cholmod_sdmult (A, 0, one, minusone, W, R, cm) ;
	cholmod_free_dense (&W, cm) ;
    }
    else
    {
	/* Ax=b was factorized and solved, R = B-A*X */
	R = cholmod_copy_dense (B, cm) ;
	cholmod_sdmult (A, 0, minusone, one, X, R, cm) ;
    }
    rnorm = cholmod_norm_dense (R, 0, cm) ;	    /* max abs. entry */
    xnorm = cholmod_norm_dense (X, 0, cm) ;	    /* max abs. entry */

    axbnorm = (anorm * xnorm + bnorm + ((n == 0) ? 1 : 0)) ;
    resid = rnorm / axbnorm ;

    /* ---------------------------------------------------------------------- */
    /* iterative refinement (real symmetric case only) */
    /* ---------------------------------------------------------------------- */

    resid2 = -1 ;
    if (A->stype != 0 && A->xtype == CHOLMOD_REAL)
    {
	cholmod_dense *R2 ;

	/* R2 = A\(B-A*X) */
	R2 = cholmod_solve (CHOLMOD_A, L, R, cm) ;
	/* compute X = X + A\(B-A*X) */
	Xx = X->x ;
	Rx = R2->x ;
	for (i = 0 ; i < n ; i++)
	{
	    Xx [i] = Xx [i] + Rx [i] ;
	}
	cholmod_free_dense (&R2, cm) ;
	cholmod_free_dense (&R, cm) ;

	/* compute the new residual, R = B-A*X */
	R = cholmod_copy_dense (B, cm) ;
	cholmod_sdmult (A, 0, minusone, one, X, R, cm) ;
	rnorm2 = cholmod_norm_dense (R, 0, cm) ;
	resid2 = rnorm2 / axbnorm ;
    }

    cholmod_free_dense (&R, cm) ;

    /* ---------------------------------------------------------------------- */
    /* print results */
    /* ---------------------------------------------------------------------- */

    cholmod_print_factor (L, "L", cm) ;

    /* determine the # of integers's and reals's in L.  See cholmod_free */
    if (L->is_super)
    {
	s = L->nsuper + 1 ;
	xsize = L->xsize ;
	ss = L->ssize ;
	isize =
	    n	/* L->Perm */
	    + n	/* L->ColCount, nz in each column of 'pure' L */
	    + s	/* L->pi, column pointers for L->s */
	    + s	/* L->px, column pointers for L->x */
	    + s	/* L->super, starting column index of each supernode */
	    + ss ;	/* L->s, the pattern of the supernodes */
    }
    else
    {
	/* this space can increase if you change parameters to their non-
	 * default values (cm->final_pack, for example). */
	lnz = L->nzmax ;
	xsize = lnz ;
	isize =
	    n	/* L->Perm */
	    + n	/* L->ColCount, nz in each column of 'pure' L */
	    + n+1	/* L->p, column pointers */
	    + lnz	/* L->i, integer row indices */
	    + n	/* L->nz, nz in each column of L */
	    + n+2	/* L->next, link list */
	    + n+2 ;	/* L->prev, link list */
    }

    anz = cm->anz ;
    for (i = 0 ; i < CHOLMOD_MAXMETHODS ; i++)
    {
	fl = cm->method [i].fl ;
	xlnz = cm->method [i].lnz ;
	cm->method [i].fl = -1 ;
	cm->method [i].lnz = -1 ;
	ordering = cm->method [i].ordering ;
	if (fl >= 0)
	{
	    printf ("Ordering: ") ;
	    if (ordering == CHOLMOD_POSTORDERED) printf ("postordered ") ;
	    if (ordering == CHOLMOD_NATURAL)     printf ("natural ") ;
	    if (ordering == CHOLMOD_GIVEN)	     printf ("user    ") ;
	    if (ordering == CHOLMOD_AMD)	     printf ("AMD     ") ;
	    if (ordering == CHOLMOD_METIS)	     printf ("METIS   ") ;
	    if (ordering == CHOLMOD_NESDIS)      printf ("NESDIS  ") ;
	    if (xlnz > 0)
	    {
		printf ("fl/lnz %10.1f", fl / xlnz) ;
	    }
	    if (anz > 0)
	    {
		printf ("  lnz/anz %10.1f", xlnz / anz) ;
	    }
	    printf ("\n") ;
	}
    }

    printf ("ints in L: %d, doubles in L: %d\n", isize, xsize) ;
    printf ("factor flops %g nnz(L) %15.0f (w/no amalgamation)\n",
	    cm->fl, cm->lnz) ;
    if (A->stype == 0)
    {
	printf ("nnz(A):    %15.0f\n", cm->anz) ;
    }
    else
    {
	printf ("nnz(A*A'): %15.0f\n", cm->anz) ;
    }
    if (cm->lnz > 0)
    {
	printf ("flops / nnz(L):  %8.1f\n", cm->fl / cm->lnz) ;
    }
    if (anz > 0)
    {
	printf ("nnz(L) / nnz(A): %8.1f\n", cm->lnz / cm->anz) ;
    }
    printf ("analyze cputime:  %12.4f\n", ta) ;
    printf ("factor  cputime:   %12.4f mflop: %8.1f\n", tf,
	(tf == 0) ? 0 : (1e-6*cm->fl / tf)) ;
    printf ("solve   cputime:   %12.4f mflop: %8.1f\n", ts,
	(ts == 0) ? 0 : (1e-6*4*cm->lnz / ts)) ;
    printf ("overall cputime:   %12.4f mflop: %8.1f\n", 
	    tot, (tot == 0) ? 0 : (1e-6 * (cm->fl + 4 * cm->lnz) / tot)) ;
    printf ("peak memory usage: %12.0f (MB)\n",
	    (double) (cm->memory_usage) / 1048576.) ;
    printf ("residual %8.1e (|Ax-b|/(|A||x|+|b|))\n", resid) ;
    if (resid2 >= 0)
    {
	printf ("residual %8.1e (|Ax-b|/(|A||x|+|b|))"
		" after iterative refinement\n", resid2) ;
    }
    printf ("rcond    %8.1e\n\n", cholmod_rcond (L, cm)) ;
    cholmod_free_factor (&L, cm) ;
    cholmod_free_dense (&X, cm) ;

    /* ---------------------------------------------------------------------- */
    /* free matrices and finish CHOLMOD */
    /* ---------------------------------------------------------------------- */

    cholmod_free_sparse (&A, cm) ;
    cholmod_free_dense (&B, cm) ;
    cholmod_finish (cm) ;
    return (0) ;
}
예제 #3
0
void tele2d::computeVectorField(){

	unsigned time1, time2, time3 ;
	time1 = clock() ;

	std::vector<std::vector<double2>>  allcurves = curves ;
	vector_field.clear() ;
	vector_field.resize(resolution*resolution) ;

	// delete too short curves
	for( int i=0; i<allcurves.size(); ++i ){
		if( allcurves[i].size() < 5 )
			allcurves.erase( allcurves.begin() + i ) ;
	}

	if( allcurves.size() == 0 ){
		std::cout<<"no valid curves!" ;
		exit(1) ;
	}

	// mark constrained vertices
	constrained_vertices_mark.clear() ;
	for( int i=0; i<resolution; ++i ) {
		std::vector<int> a ;
		for( int j=0;j<resolution; ++j )
			a.push_back(0) ;
		constrained_vertices_mark.push_back(a) ;
	}
	for( int i=0; i<allcurves.size(); ++ i){
		for( int j =0; j<allcurves[i].size(); ++ j){
			// get x index of closest vertices
			float x = allcurves[i][j].x * resolution - 0.5 ;
			int ix ;
			if( x-floor(x) < 0.5 ) ix = floor(x) ;
			else	ix = ceil( x ) ;
			// get y index of closest vertices
			float y = allcurves[i][j].y * resolution - 0.5 ;
			int iy ;
			if( y-floor(y) < 0.5 ) iy = floor(y) ;
			else	iy = ceil( y ) ;

			if( ix < 0 ) ix = 0;
			if( ix > resolution-1) ix = resolution -1;
			if( iy < 0 ) iy = 0;
			if( iy > resolution-1) iy = resolution -1;

			constrained_vertices_mark[ix][iy] = 1 ;

		}
	}

	// compute b
	std::vector<double2> b ;
	b.resize(resolution*resolution) ;
	for( int i=0; i<resolution; ++i ){
		for( int j=0; j<resolution; ++j){
			
			if(constrained_vertices_mark[i][j] == 0 ){
				b[i+j*resolution].x = 0; 
				b[i+j*resolution].y = 0; 
				continue ;
			}

			// otherwise, the vertex indexed by (i,j) is constrained
			double vx = ((double)i+0.5)/(double)resolution ; 
			double vy = ((double)j+0.5)/(double)resolution ; 
			
			// search for the closest points
			int curveid_record = 0;
			int pointid_record = 0;
			double mindis = 1000.0f ;
			for( int curveid=0; curveid<allcurves.size(); ++curveid ){				
				for( int pointid=0; pointid<allcurves[curveid].size(); ++pointid  ){
					double quadratic_dis = ( allcurves[curveid][pointid].x - vx )*( allcurves[curveid][pointid].x - vx ) + ( allcurves[curveid][pointid].y - vy )*( allcurves[curveid][pointid].y - vy ) ;
					if( quadratic_dis < mindis ){
							mindis = quadratic_dis ;
							curveid_record = curveid ;
							pointid_record = pointid ;
					}
				}
			}

			// compute the vector of the vertex indexed by (i,j)
			int pid1 = pointid_record-1 > 0 ? pointid_record-1 : 0 ;
			int pid2 = pointid_record+1 <  allcurves[curveid_record].size()-1 ? pointid_record+1 : allcurves[curveid_record].size()-1;

			double2 vector_of_vertex ;
			vector_of_vertex.x = allcurves[curveid_record][pid2].x - allcurves[curveid_record][pid1].x ;
			vector_of_vertex.y = allcurves[curveid_record][pid2].y - allcurves[curveid_record][pid1].y ;
			double norm = sqrt( vector_of_vertex.x * vector_of_vertex.x + vector_of_vertex.y * vector_of_vertex.y) ;
			vector_of_vertex.x /= norm ;
			vector_of_vertex.y /= norm ;


			assert( norm > 0 && norm < 1) ;

			//std::cout<<"norm "<<norm<<std::endl;
			
			b[i+j*resolution ] = vector_of_vertex ;


		}
	}


	// compute Pb
	std::vector<double2> Pb = b ;
	for( int i=0; i<Pb.size(); ++i ){
		Pb[i].x *= 1.0e8 ;
		Pb[i].y *= 1.0e8 ;
	}

	// compute L+P
	int vnum =  resolution*resolution  ;
	sparse_matrix L_add_P(vnum) ;  // create a sparse matrix of vnum rows

	// L_add_P <- D - W
	for( int id_x =0; id_x<resolution; ++id_x ){
		for( int id_y =0; id_y<resolution; ++id_y ){
			int vid = id_x + id_y * resolution ;
			if( id_x != 0 && id_x != resolution-1 && id_y != 0 && id_y != resolution-1 ){ // inner area
				//L_add_P[ vid + vid*vnum] += 6.8284 ;
				L_add_P.pluse(vid,vid,6.8284 ) ;
				int neibour_id_1 =  id_x + id_y * resolution - 1 ;
				int neibour_id_2 =  id_x + id_y * resolution + 1 ;
				int neibour_id_3 =  id_x + (id_y-1) * resolution ;
				int neibour_id_4 =  id_x + (id_y+1) * resolution ;
				int neibour_id_5 =  id_x + (id_y+1) * resolution - 1 ;
				int neibour_id_6 =  id_x + (id_y+1) * resolution + 1 ;
				int neibour_id_7 =  id_x + (id_y-1) * resolution - 1 ;
				int neibour_id_8 =  id_x + (id_y-1) * resolution + 1 ;
				//L_add_P[neibour_id_1+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_1, -1 ) ;
				//L_add_P[neibour_id_2+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_2, -1 ) ;
				//L_add_P[neibour_id_3+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_3, -1 ) ;
				//L_add_P[neibour_id_4+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_4, -1 ) ;
				//L_add_P[neibour_id_5+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_5, -0.7071 ) ;
				//L_add_P[neibour_id_6+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_6, -0.7071 ) ;
				//L_add_P[neibour_id_7+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_7, -0.7071 ) ;
				//L_add_P[neibour_id_8+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_8, -0.7071 ) ;

			}
			else if((id_x == 0 || id_x==resolution-1) && (id_y == 0 || id_y==resolution-1)  ){  // coners
				//L_add_P[ vid + vid*vnum] += 2.7071 ;
				L_add_P.pluse(vid,vid, 2.7071 ) ;
				int neibour_id_1 =  ( id_x == 0 ? ( id_x+id_y * resolution+1) :  ( id_x+id_y * resolution - 1) );
				int neibour_id_2 =  ( id_y == 0 ? ( id_x+ (id_y+1) * resolution) : ( id_x+ (id_y-1) * resolution )) ;
				int neibour_id_3 =  ( id_x == 0 ? 1 : (resolution-2) ) + ( id_y == 0 ? 1 : (resolution - 2)) * resolution ;

				//L_add_P[neibour_id_1+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_1, -1 ) ;
				//L_add_P[neibour_id_2+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_2, -1 ) ;
				//L_add_P[neibour_id_3+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_3, -0.7071 ) ;

			}
			else {																		// boundaries
				//L_add_P[ vid + vid*vnum] += 4.4142 ;
				L_add_P.pluse(vid,vid, 4.4142 ) ;

				int neibour_id_1, neibour_id_2, neibour_id_3, neibour_id_4, neibour_id_5 ;
				if( id_x == 0){
					neibour_id_1 =  id_x + id_y * resolution + 1 ;
					neibour_id_2 =  id_x + (id_y+1) * resolution ;
					neibour_id_3 =  id_x + (id_y-1) * resolution ;
					neibour_id_4 =  id_x + (id_y+1) * resolution + 1;
					neibour_id_5 =  id_x + (id_y-1) * resolution + 1 ;
				}
				else if( id_x == resolution-1 ){
					neibour_id_1 =  id_x + id_y * resolution - 1 ;
					neibour_id_2 =  id_x + (id_y+1) * resolution ;
					neibour_id_3 =  id_x + (id_y-1) * resolution ;
					neibour_id_4 =  id_x + (id_y+1) * resolution - 1;
					neibour_id_5 =  id_x + (id_y-1) * resolution - 1 ;
				}
				else if( id_y == resolution-1 ){
					neibour_id_1 =  id_x + id_y * resolution + 1 ;
					neibour_id_2 =  id_x + id_y * resolution - 1 ;
					neibour_id_3 =  id_x + (id_y-1) * resolution ;
					neibour_id_4 =  id_x + (id_y-1) * resolution + 1;
					neibour_id_5 =  id_x + (id_y-1) * resolution - 1 ;
				}
				else {
					neibour_id_1 =  id_x + id_y * resolution + 1 ;
					neibour_id_2 =  id_x + id_y * resolution - 1 ;
					neibour_id_3 =  id_x + (id_y+1) * resolution ;
					neibour_id_4 =  id_x + (id_y+1) * resolution + 1;
					neibour_id_5 =  id_x + (id_y+1) * resolution - 1 ;
				}
				//L_add_P[neibour_id_1+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_1, -1 ) ;
				//L_add_P[neibour_id_2+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_2, -1 ) ;
				//L_add_P[neibour_id_3+vid*vnum] -= 1 ;
				L_add_P.pluse(vid,neibour_id_3, -1 ) ;
				//L_add_P[neibour_id_4+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_4, -0.7071) ;
				//L_add_P[neibour_id_5+vid*vnum] -=  0.7071;
				L_add_P.pluse(vid,neibour_id_5, -0.7071 ) ;

			}

		}
	}
	// L_add_P <- D - W + P
	for( int i=0; i<resolution; ++i ){
		for( int j=0; j<resolution; ++j){
			if(constrained_vertices_mark[i][j] == 1  ){
				int vid = i + j*resolution ;
				//L_add_P[vid+vid*vnum]+=1e8 ; 
				L_add_P.pluse(vid,vid, 1.0e8  ) ;

			}
		}
	}




	// solve the linear system with cholmod
	cholmod_sparse *A ;
	cholmod_dense *x, *y, *b1 ;
	double one [2] = {1,0}, m1 [2] = {-1,0} ; /* basic scalars */
	cholmod_factor *L ;
	cholmod_common c ;
	cholmod_start (&c) ;; /* start CHOLMOD */
	
	//A = cholmod_read_sparse (pFile, &c) ; /* read in a matrix */
	CMatrix  *SM = new CMatrix( vnum, true, &c) ;
	//for( int i=0; i<vnum; ++i ){
	//	for( int j=0; j<vnum; ++j ){
	//		if( L_add_P.getValue(j,i)!=0 )
	//			SM->set_coef(i, j,L_add_P.getValue(j,i) ) ;
	//	}
	//}
	for( int i=0; i<L_add_P.data.size(); ++i){
		for( int j=0; j<L_add_P.data[i].size(); ++j)
			SM->set_coef(L_add_P.data[i][j].row, i,  L_add_P.data[i][j].val ) ;
	}

	A =(cholmod_sparse *) SM->get_cholmod_sparse();


	time2 = clock() ;

	//cholmod_print_sparse (A, "A", &c) ; /* print the matrix */

	if (A == NULL || A->stype == 0) /* A must be symmetric */
	{
		cholmod_free_sparse (&A, &c) ;
		cholmod_finish (&c) ;
		std::cout << "fail to load the matrix or it's not symmeric!"<<std::endl;
		exit(1) ;
	}

	b1 = cholmod_zeros(vnum, 1, CHOLMOD_REAL, &c);


	// --------------------- x demension -----------------------
	for( int i =0 ;i<Pb.size(); ++i ){
		((double*)(b1->x))[i] = Pb[i].x ;
	}
	L = cholmod_analyze (A, &c) ; /* analyze */
	cholmod_factorize (A, L, &c) ; /* factorize */
	x = cholmod_solve (CHOLMOD_A, L, b1, &c) ; /* solve Ax=b */


	// write x-values
	for( int i=0; i<vector_field.size(); ++i)
		vector_field[i].x = ((double*)(x->x))[i] ;
	// --------------------- y demension -----------------------
	for( int i =0 ;i<Pb.size(); ++i ){
		((double*)(b1->x))[i] = Pb[i].y ;
	}
	y = cholmod_solve (CHOLMOD_A, L, b1, &c) ; /* solve Ay=b */
	// write y-values
	for( int i=0; i<vector_field.size(); ++i)
		vector_field[i].y = ((double*)(y->x))[i] ;



	cholmod_free_factor (&L, &c) ; 
	cholmod_free_dense (&x, &c) ;
	cholmod_free_dense (&y, &c) ;
	cholmod_free_dense (&b1, &c) ;
	//delete L_add_P ;
	delete SM ;
	cholmod_finish (&c) ; /* finish CHOLMOD */



	double normx2, normy2 ;
	normx2 = normy2 = 0.0 ;

	for( int i=0; i<vnum; ++i ){
		normx2 += vector_field[i].x * vector_field[i].x ; 
		normy2 += vector_field[i].y * vector_field[i].y ; 
	}

	//std::cout<<"|x| = "<<sqrt(normx2) <<"\n|y| = "<<sqrt(normy2) <<std::endl;


	// normalize vector field
	for( int i=0; i<vector_field.size(); ++i){
		double norm = sqrt( vector_field[i].x * vector_field[i].x + vector_field[i].y * vector_field[i].y) ;
		vector_field[i].x /= norm ;
		vector_field[i].y /= norm ;

	}

	time3 = clock() ;


	//std::cout<<"time consumed by computing A and b: " << (double)(time2-time1)/CLOCKS_PER_SEC <<" s" <<std::endl ;
	//std::cout<<"time consumed by solving the system: " << (double)(time3-time2)/CLOCKS_PER_SEC <<" s" <<std::endl ;

	//std::cout<<"vector field computing completed."<<std::endl; ;
	int count = 0;
	for( int i=0; i<L_add_P.data.size(); ++i)
		count += L_add_P.data[i].size() ;

	//std::cout << "nonzero number: " << count <<std::endl; 

}
int main (int argc, char **argv)
{
    double resid [4], t, ta, tf, ts [3], tot, bnorm, xnorm, anorm, rnorm, fl,
        anz, axbnorm, rnorm2, resid2, rcond ;
    FILE *f ;
    cholmod_sparse *A ;
    cholmod_dense *X = NULL, *B, *W, *R ;
    double one [2], zero [2], minusone [2], beta [2], xlnz ;
    cholmod_common Common, *cm ;
    cholmod_factor *L ;
    double *Bx, *Rx, *Xx ;
    int i, n, isize, xsize, ordering, xtype, s, ss, lnz ;
    int trial, method, L_is_super ;
    int ver [3] ;

    ts[0] = 0.;
    ts[1] = 0.;
    ts[2] = 0.;

    /* ---------------------------------------------------------------------- */
    /* get the file containing the input matrix */
    /* ---------------------------------------------------------------------- */

    ff = NULL ;
    if (argc > 1)
    {
	if ((f = fopen (argv [1], "r")) == NULL)
	{
	    my_handler (CHOLMOD_INVALID, __FILE__, __LINE__,
		    "unable to open file") ;
	}
	ff = f ;
    }
    else
    {
	f = stdin ;
    }

    /* ---------------------------------------------------------------------- */
    /* start CHOLMOD and set parameters */
    /* ---------------------------------------------------------------------- */

    cm = &Common ;
    cholmod_start (cm) ;
    CHOLMOD_FUNCTION_DEFAULTS (cm) ;    /* just for testing (not required) */

    /* use default parameter settings, except for the error handler.  This
     * demo program terminates if an error occurs (out of memory, not positive
     * definite, ...).  It makes the demo program simpler (no need to check
     * CHOLMOD error conditions).  This non-default parameter setting has no
     * effect on performance. */
    cm->error_handler = my_handler ;

    /* Note that CHOLMOD will do a supernodal LL' or a simplicial LDL' by
     * default, automatically selecting the latter if flop/nnz(L) < 40. */

    /* ---------------------------------------------------------------------- */
    /* create basic scalars */
    /* ---------------------------------------------------------------------- */

    zero [0] = 0 ;
    zero [1] = 0 ;
    one [0] = 1 ;
    one [1] = 0 ;
    minusone [0] = -1 ;
    minusone [1] = 0 ;
    beta [0] = 1e-6 ;
    beta [1] = 0 ;

    /* ---------------------------------------------------------------------- */
    /* read in a matrix */
    /* ---------------------------------------------------------------------- */

    printf ("\n---------------------------------- cholmod_demo:\n") ;
    cholmod_version (ver) ;
    printf ("cholmod version %d.%d.%d\n", ver [0], ver [1], ver [2]) ;
    SuiteSparse_version (ver) ;
    printf ("SuiteSparse version %d.%d.%d\n", ver [0], ver [1], ver [2]) ;
    A = cholmod_read_sparse (f, cm) ;
    if (ff != NULL)
    {
        fclose (ff) ;
        ff = NULL ;
    }
    anorm = cholmod_norm_sparse (A, 0, cm) ;
    xtype = A->xtype ;
    printf ("norm (A,inf) = %g\n", anorm) ;
    printf ("norm (A,1)   = %g\n", cholmod_norm_sparse (A, 1, cm)) ;
    cholmod_print_sparse (A, "A", cm) ;

    if (A->nrow > A->ncol)
    {
	/* Transpose A so that A'A+beta*I will be factorized instead */
	cholmod_sparse *C = cholmod_transpose (A, 2, cm) ;
	cholmod_free_sparse (&A, cm) ;
	A = C ;
	printf ("transposing input matrix\n") ;
    }

    /* ---------------------------------------------------------------------- */
    /* create an arbitrary right-hand-side */
    /* ---------------------------------------------------------------------- */

    n = A->nrow ;
    B = cholmod_zeros (n, 1, xtype, cm) ;
    Bx = B->x ;

#if GHS
    {
	/* b = A*ones(n,1), used by Gould, Hu, and Scott in their experiments */
	cholmod_dense *X0 ;
	X0 = cholmod_ones (A->ncol, 1, xtype, cm) ;
	cholmod_sdmult (A, 0, one, zero, X0, B, cm) ;
	cholmod_free_dense (&X0, cm) ;
    }
#else
    if (xtype == CHOLMOD_REAL)
    {
	/* real case */
	for (i = 0 ; i < n ; i++)
	{
	    double x = n ;
	    Bx [i] = 1 + i / x ;
	}
    }
    else
    {
	/* complex case */
	for (i = 0 ; i < n ; i++)
	{
	    double x = n ;
	    Bx [2*i  ] = 1 + i / x ;		/* real part of B(i) */
	    Bx [2*i+1] = (x/2 - i) / (3*x) ;	/* imag part of B(i) */
	}
    }
#endif

    cholmod_print_dense (B, "B", cm) ;
    bnorm = cholmod_norm_dense (B, 0, cm) ;	/* max norm */
    printf ("bnorm %g\n", bnorm) ;

    /* ---------------------------------------------------------------------- */
    /* analyze and factorize */
    /* ---------------------------------------------------------------------- */

    t = CPUTIME ;
    L = cholmod_analyze (A, cm) ;
    ta = CPUTIME - t ;
    ta = MAX (ta, 0) ;

    printf ("Analyze: flop %g lnz %g\n", cm->fl, cm->lnz) ;

    if (A->stype == 0)
    {
	printf ("Factorizing A*A'+beta*I\n") ;
	t = CPUTIME ;
	cholmod_factorize_p (A, beta, NULL, 0, L, cm) ;
	tf = CPUTIME - t ;
	tf = MAX (tf, 0) ;
    }
    else
    {
	printf ("Factorizing A\n") ;
	t = CPUTIME ;
	cholmod_factorize (A, L, cm) ;
	tf = CPUTIME - t ;
	tf = MAX (tf, 0) ;
    }

    cholmod_print_factor (L, "L", cm) ;

    /* determine the # of integers's and reals's in L.  See cholmod_free */
    if (L->is_super)
    {
	s = L->nsuper + 1 ;
	xsize = L->xsize ;
	ss = L->ssize ;
	isize =
	    n	/* L->Perm */
	    + n	/* L->ColCount, nz in each column of 'pure' L */
	    + s	/* L->pi, column pointers for L->s */
	    + s	/* L->px, column pointers for L->x */
	    + s	/* L->super, starting column index of each supernode */
	    + ss ;	/* L->s, the pattern of the supernodes */
    }
    else
    {
	/* this space can increase if you change parameters to their non-
	 * default values (cm->final_pack, for example). */
	lnz = L->nzmax ;
	xsize = lnz ;
	isize =
	    n	/* L->Perm */
	    + n	/* L->ColCount, nz in each column of 'pure' L */
	    + n+1	/* L->p, column pointers */
	    + lnz	/* L->i, integer row indices */
	    + n	/* L->nz, nz in each column of L */
	    + n+2	/* L->next, link list */
	    + n+2 ;	/* L->prev, link list */
    }

    /* solve with Bset will change L from simplicial to supernodal */
    rcond = cholmod_rcond (L, cm) ;
    L_is_super = L->is_super ;

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

    for (method = 0 ; method <= 3 ; method++)
    {
        double x = n ;

        if (method == 0)
        {
            /* basic solve, just once */
            t = CPUTIME ;
            X = cholmod_solve (CHOLMOD_A, L, B, cm) ;
            ts [0] = CPUTIME - t ;
            ts [0] = MAX (ts [0], 0) ;
        }
        else if (method == 1)
        {
            /* basic solve, many times, but keep the last one */
            t = CPUTIME ;
            for (trial = 0 ; trial < NTRIALS ; trial++)
            {
                cholmod_free_dense (&X, cm) ;
                Bx [0] = 1 + trial / x ;        /* tweak B each iteration */
                X = cholmod_solve (CHOLMOD_A, L, B, cm) ;
            }
            ts [1] = CPUTIME - t ;
            ts [1] = MAX (ts [1], 0) / NTRIALS ;
        }
        else if (method == 2)
        {
            /* solve with reused workspace */
            cholmod_dense *Ywork = NULL, *Ework = NULL ;
            cholmod_free_dense (&X, cm) ;

            t = CPUTIME ;
            for (trial = 0 ; trial < NTRIALS ; trial++)
            {
                Bx [0] = 1 + trial / x ;        /* tweak B each iteration */
                cholmod_solve2 (CHOLMOD_A, L, B, NULL, &X, NULL,
                    &Ywork, &Ework, cm) ;
            }
            cholmod_free_dense (&Ywork, cm) ;
            cholmod_free_dense (&Ework, cm) ;
            ts [2] = CPUTIME - t ;
            ts [2] = MAX (ts [2], 0) / NTRIALS ;
        }
        else
        {
            /* solve with reused workspace and sparse Bset */
            cholmod_dense *Ywork = NULL, *Ework = NULL ;
            cholmod_dense *X2 = NULL, *B2 = NULL ;
            cholmod_sparse *Bset, *Xset = NULL ;
            int *Bsetp, *Bseti, *Xsetp, *Xseti, xlen, j, k, *Lnz ;
            double *X1x, *X2x, *B2x, err ;
            FILE *timelog = fopen ("timelog.m", "w") ;
            if (timelog) fprintf (timelog, "results = [\n") ;

            B2 = cholmod_zeros (n, 1, xtype, cm) ;
            B2x = B2->x ;

            Bset = cholmod_allocate_sparse (n, 1, 1, FALSE, TRUE, 0,
                CHOLMOD_PATTERN, cm) ;
            Bsetp = Bset->p ;
            Bseti = Bset->i ;
            Bsetp [0] = 0 ;     /* nnz(B) is 1 (it can be anything) */
            Bsetp [1] = 1 ;
            resid [3] = 0 ;

            for (i = 0 ; i < MIN (100,n) ; i++)
            {
                /* B (i) is nonzero, all other entries are ignored
                   (implied to be zero) */
                Bseti [0] = i ;
                if (xtype == CHOLMOD_REAL)
                {
                    B2x [i] = 3.1 * i + 0.9 ;
                }
                else
                {
                    B2x [2*i  ] = i + 0.042 ;
                    B2x [2*i+1] = i - 92.7 ;
                }

                /* first get the entire solution, to compare against */
                cholmod_solve2 (CHOLMOD_A, L, B2, NULL, &X, NULL,
                    &Ywork, &Ework, cm) ;

                /* now get the sparse solutions; this will change L from
                   supernodal to simplicial */

                if (i == 0)
                {
                    /* first solve can be slower because it has to allocate
                       space for X2, Xset, etc, and change L.
                       So don't time it */
                    cholmod_solve2 (CHOLMOD_A, L, B2, Bset, &X2, &Xset,
                        &Ywork, &Ework, cm) ;
                }

                t = CPUTIME ;
                for (trial = 0 ; trial < NTRIALS ; trial++)
                {
                    /* solve Ax=b but only to get x(i).
                       b is all zero except for b(i).
                       This takes O(xlen) time */
                    cholmod_solve2 (CHOLMOD_A, L, B2, Bset, &X2, &Xset,
                        &Ywork, &Ework, cm) ;
                }
                t = CPUTIME - t ;
                t = MAX (t, 0) / NTRIALS ;

                /* check the solution and log the time */
                Xsetp = Xset->p ;
                Xseti = Xset->i ;
                xlen = Xsetp [1] ;
                X1x = X->x ;
                X2x = X2->x ;
                Lnz = L->nz ;

                /*
                printf ("\ni %d xlen %d  (%p %p)\n", i, xlen, X1x, X2x) ;
                */

                if (xtype == CHOLMOD_REAL)
                {
                    fl = 2 * xlen ;
                    for (k = 0 ; k < xlen ; k++)
                    {
                        j = Xseti [k] ;
                        fl += 4 * Lnz [j] ;
                        err = X1x [j] - X2x [j] ;
                        err = ABS (err) ;
                        resid [3] = MAX (resid [3], err) ;
                    }
                }
                else
                {
                    fl = 16 * xlen ;
                    for (k = 0 ; k < xlen ; k++)
                    {
                        j = Xseti [k] ;
                        fl += 16 * Lnz [j] ;
                        err = X1x [2*j  ] - X2x [2*j  ] ;
                        err = ABS (err) ;
                        resid [3] = MAX (resid [3], err) ;
                        err = X1x [2*j+1] - X2x [2*j+1] ;
                        err = ABS (err) ;
                        resid [3] = MAX (resid [3], err) ;
                    }
                }
                if (timelog) fprintf (timelog, "%g %g %g %g\n",
                    (double) i, (double) xlen, fl, t);

                /* clear B for the next test */
                if (xtype == CHOLMOD_REAL)
                {
                    B2x [i] = 0 ;
                }
                else
                {
                    B2x [2*i  ] = 0 ;
                    B2x [2*i+1] = 0 ;
                }

            }

            if (timelog)
            {
                fprintf (timelog, "] ; resid = %g ;\n", resid [3]) ;
                fprintf (timelog, "lnz = %g ;\n", cm->lnz) ;
                fprintf (timelog, "t = %g ;   %% dense solve time\n", ts [2]) ;
                fclose (timelog) ;
            }

            resid [3] = resid [3] / cholmod_norm_dense (X, 1, cm) ;

            cholmod_free_dense (&Ywork, cm) ;
            cholmod_free_dense (&Ework, cm) ;
            cholmod_free_dense (&X2, cm) ;
            cholmod_free_dense (&B2, cm) ;
            cholmod_free_sparse (&Xset, cm) ;
            cholmod_free_sparse (&Bset, cm) ;
        }

        /* ------------------------------------------------------------------ */
        /* compute the residual */
        /* ------------------------------------------------------------------ */

        if (method < 3)
        {

            if (A->stype == 0)
            {
                /* (AA'+beta*I)x=b is the linear system that was solved */
                /* W = A'*X */
                W = cholmod_allocate_dense (A->ncol, 1, A->ncol, xtype, cm) ;
                cholmod_sdmult (A, 2, one, zero, X, W, cm) ;
                /* R = B - beta*X */
                R = cholmod_zeros (n, 1, xtype, cm) ;
                Rx = R->x ;
                Xx = X->x ;
                if (xtype == CHOLMOD_REAL)
                {
                    for (i = 0 ; i < n ; i++)
                    {
                        Rx [i] = Bx [i] - beta [0] * Xx [i] ;
                    }
                }
                else
                {
                    /* complex case */
                    for (i = 0 ; i < n ; i++)
                    {
                        Rx [2*i  ] = Bx [2*i  ] - beta [0] * Xx [2*i  ] ;
                        Rx [2*i+1] = Bx [2*i+1] - beta [0] * Xx [2*i+1] ;
                    }
                }
                /* R = A*W - R */
                cholmod_sdmult (A, 0, one, minusone, W, R, cm) ;
                cholmod_free_dense (&W, cm) ;
            }
            else
            {
                /* Ax=b was factorized and solved, R = B-A*X */
                R = cholmod_copy_dense (B, cm) ;
                cholmod_sdmult (A, 0, minusone, one, X, R, cm) ;
            }
            rnorm = cholmod_norm_dense (R, 0, cm) ;	    /* max abs. entry */
            xnorm = cholmod_norm_dense (X, 0, cm) ;	    /* max abs. entry */

            axbnorm = (anorm * xnorm + bnorm + ((n == 0) ? 1 : 0)) ;
            resid [method] = rnorm / axbnorm ;
        }
    }

    tot = ta + tf + ts [0] ;

    /* ---------------------------------------------------------------------- */
    /* iterative refinement (real symmetric case only) */
    /* ---------------------------------------------------------------------- */

    resid2 = -1 ;
    if (A->stype != 0 && A->xtype == CHOLMOD_REAL)
    {
	cholmod_dense *R2 ;

	/* R2 = A\(B-A*X) */
	R2 = cholmod_solve (CHOLMOD_A, L, R, cm) ;
	/* compute X = X + A\(B-A*X) */
	Xx = X->x ;
	Rx = R2->x ;
	for (i = 0 ; i < n ; i++)
	{
	    Xx [i] = Xx [i] + Rx [i] ;
	}
	cholmod_free_dense (&R2, cm) ;
	cholmod_free_dense (&R, cm) ;

	/* compute the new residual, R = B-A*X */
	R = cholmod_copy_dense (B, cm) ;
	cholmod_sdmult (A, 0, minusone, one, X, R, cm) ;
	rnorm2 = cholmod_norm_dense (R, 0, cm) ;
	resid2 = rnorm2 / axbnorm ;
    }

    cholmod_free_dense (&R, cm) ;

    /* ---------------------------------------------------------------------- */
    /* print results */
    /* ---------------------------------------------------------------------- */

    anz = cm->anz ;
    for (i = 0 ; i < CHOLMOD_MAXMETHODS ; i++)
    {
	fl = cm->method [i].fl ;
	xlnz = cm->method [i].lnz ;
	cm->method [i].fl = -1 ;
	cm->method [i].lnz = -1 ;
	ordering = cm->method [i].ordering ;
	if (fl >= 0)
	{
	    printf ("Ordering: ") ;
	    if (ordering == CHOLMOD_POSTORDERED) printf ("postordered ") ;
	    if (ordering == CHOLMOD_NATURAL)     printf ("natural ") ;
	    if (ordering == CHOLMOD_GIVEN)	     printf ("user    ") ;
	    if (ordering == CHOLMOD_AMD)	     printf ("AMD     ") ;
	    if (ordering == CHOLMOD_METIS)	     printf ("METIS   ") ;
	    if (ordering == CHOLMOD_NESDIS)      printf ("NESDIS  ") ;
	    if (xlnz > 0)
	    {
		printf ("fl/lnz %10.1f", fl / xlnz) ;
	    }
	    if (anz > 0)
	    {
		printf ("  lnz/anz %10.1f", xlnz / anz) ;
	    }
	    printf ("\n") ;
	}
    }

    printf ("ints in L: %15.0f, doubles in L: %15.0f\n",
        (double) isize, (double) xsize) ;
    printf ("factor flops %g nnz(L) %15.0f (w/no amalgamation)\n",
	    cm->fl, cm->lnz) ;
    if (A->stype == 0)
    {
	printf ("nnz(A):    %15.0f\n", cm->anz) ;
    }
    else
    {
	printf ("nnz(A*A'): %15.0f\n", cm->anz) ;
    }
    if (cm->lnz > 0)
    {
	printf ("flops / nnz(L):  %8.1f\n", cm->fl / cm->lnz) ;
    }
    if (anz > 0)
    {
	printf ("nnz(L) / nnz(A): %8.1f\n", cm->lnz / cm->anz) ;
    }
    printf ("analyze cputime:  %12.4f\n", ta) ;
    printf ("factor  cputime:   %12.4f mflop: %8.1f\n", tf,
	(tf == 0) ? 0 : (1e-6*cm->fl / tf)) ;
    printf ("solve   cputime:   %12.4f mflop: %8.1f\n", ts [0],
	(ts [0] == 0) ? 0 : (1e-6*4*cm->lnz / ts [0])) ;
    printf ("overall cputime:   %12.4f mflop: %8.1f\n", 
	    tot, (tot == 0) ? 0 : (1e-6 * (cm->fl + 4 * cm->lnz) / tot)) ;
    printf ("solve   cputime:   %12.4f mflop: %8.1f (%d trials)\n", ts [1],
	(ts [1] == 0) ? 0 : (1e-6*4*cm->lnz / ts [1]), NTRIALS) ;
    printf ("solve2  cputime:   %12.4f mflop: %8.1f (%d trials)\n", ts [2],
	(ts [2] == 0) ? 0 : (1e-6*4*cm->lnz / ts [2]), NTRIALS) ;
    printf ("peak memory usage: %12.0f (MB)\n",
	    (double) (cm->memory_usage) / 1048576.) ;
    printf ("residual (|Ax-b|/(|A||x|+|b|)): ") ;
    for (method = 0 ; method <= 3 ; method++)
    {
        printf ("%8.2e ", resid [method]) ;
    }
    printf ("\n") ;
    if (resid2 >= 0)
    {
	printf ("residual %8.1e (|Ax-b|/(|A||x|+|b|))"
		" after iterative refinement\n", resid2) ;
    }

    printf ("rcond    %8.1e\n\n", rcond) ;

    if (L_is_super)
    {
        cholmod_gpu_stats (cm) ;
    }

    cholmod_free_factor (&L, cm) ;
    cholmod_free_dense (&X, cm) ;

    /* ---------------------------------------------------------------------- */
    /* free matrices and finish CHOLMOD */
    /* ---------------------------------------------------------------------- */

    cholmod_free_sparse (&A, cm) ;
    cholmod_free_dense (&B, cm) ;
    cholmod_finish (cm) ;
    
    return (0) ;
}
예제 #5
0
int main(void)
{
    int N = 2 ;
    int i, j, n ;
    int nz = 0;
    double *Ax ;
    double x, error ;
    cholmod_dense *A, *invK, *spinvK, *I ;
    cholmod_sparse *K, *V ;
    cholmod_factor *L ;
    cholmod_common Common,*cm ;
    clock_t start, end;
    double cpu_time_used;
    cm=&Common;
    // Start using CHOLMOD
    cholmod_start(cm) ;
    cm->print=5;
    /* SPARSE COVARIANCE MATRIX CONSTRUCTION */

    // Generate random symmetric positive (semi)definite matrix
    A = cholmod_zeros(N, N, CHOLMOD_REAL, &Common) ;
    Ax =(double*) A->x ;
    nz = N ;

    // Make positive-definite by adding something positive to the
    // diagonal
    for (n = 0; n < N; n++)
    {
        Ax[n+n*N] += 5;
    }

    // Make the matrix sparse
    K = cholmod_dense_to_sparse(A, TRUE, &Common) ;
    K->stype = 1 ; // NEED TO MAKE THE MATRIX SYMMETRIC

    // Identity matrix
    I = cholmod_eye(N,N,CHOLMOD_REAL,&Common) ;

    /* SIMPLICIAL */

    // Factorize
    Common.supernodal = CHOLMOD_SIMPLICIAL ;
    L = cholmod_analyze(K, &Common) ;
    cholmod_factorize(K, L, &Common) ;
    invK = cholmod_solve(CHOLMOD_A, L, I, &Common) ;

    // Compute the sparse inverse and the full inverse
    start = clock();
    V = cholmod_spinv(L, &Common) ;
    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    // Show results
    cholmod_print_sparse(K,"Original",&Common) ;
    cholmod_print_factor(L,"Factor",&Common) ;
    cholmod_print_sparse(V,"Sparse inverse",&Common) ;
    cholmod_print_dense(invK,"Dense inverse",&Common);

    // Free memory
    cholmod_free_factor(&L, &Common) ;
    cholmod_free_sparse(&K, &Common) ;
    cholmod_free_dense(&I, &Common) ;
    cholmod_free_dense(&A, &Common) ;
    cholmod_finish(&Common) ;
    return 0 ;
}