Exemplo n.º 1
0
/*
 Initialize a sparse Jacobian for the solver.
 */ 
int KINKluSetJacGraph(KINMem kin_memory, cs_di *jac){

	//check inputs
	if(!kin_memory||!jac) return 1;

	//grab the linear solver memory block
	KINKluMem kin_klu_mem=(KINKluMem)kin_memory->kin_lmem;
	if(!kin_klu_mem) return 1;

	//grab needed kinklu objects
	cs_di *kin_klu_jac=kin_klu_mem->jac;
	
	//check whether the jacobian data has already been allocated. if so, free it.
	if(kin_klu_jac){
		cs_di_spfree(kin_klu_jac);
		kin_klu_jac=NULL;
	}

	//check if the input jacobian is in triplet form. compress if so.
	if(CS_TRIPLET(jac)){
		kin_klu_jac=cs_di_compress(jac);
		if(!kin_klu_jac) return 1;
		cs_di_spfree(jac);
		jac = kin_klu_jac;
		return 0;
	}
	
	//assign the input jacobian to the kinklu jacobian
	kin_klu_mem->jac=jac;
	
	//return success
	return 0;
};
Exemplo n.º 2
0
/* free workspace for demo3 */
static int done3 (int ok, cs_dis *S, cs_din *N, double *y, cs_di *W, cs_di *E, int *p)
{
    cs_di_sfree (S) ;
    cs_di_nfree (N) ;
    cs_di_free (y) ;
    cs_di_spfree (W) ;
    cs_di_spfree (E) ;
    cs_di_free (p) ;
    return (ok) ;
}
Exemplo n.º 3
0
/* free a problem */
problem *free_problem (problem *Prob)
{
    if (!Prob) return (NULL) ;
    cs_di_spfree (Prob->A) ;
    if (Prob->sym) cs_di_spfree (Prob->C) ;
    cs_di_free (Prob->b) ;
    cs_di_free (Prob->x) ;
    cs_di_free (Prob->resid) ;
    return (cs_di_free (Prob)) ;
}
void freeAllocationsDC(void) {

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		if (circuit_simulation.method == DIRECT)
		{ 
			cs_di_sfree( S );
			cs_di_nfree( N );
		}
		else
		{
			cs_di_spfree( G2 );
		}
	}
	else
	{
		free( matrix_G );

		if (circuit_simulation.method == DIRECT && circuit_simulation.matrix_type == NONSPD)
		
		{
			free( transposition );
		}
	}

	if (circuit_simulation.method == ITERATIVE)
	{
		free( inv_preconditioner );
	}

	free( vector_x );

	free( vector_b );

}
Exemplo n.º 5
0
/* read a problem from a file; use %g for integers to avoid int conflicts */
problem *get_problem (FILE *f, double tol)
{
    cs_di *T, *A, *C ;
    int sym, m, n, mn, nz1, nz2 ;
    problem *Prob ;
    Prob = cs_di_calloc (1, sizeof (problem)) ;
    if (!Prob) return (NULL) ;
    T = cs_di_load (f) ;                   /* load triplet matrix T from a file */
    Prob->A = A = cs_di_compress (T) ;     /* A = compressed-column form of T */
    cs_di_spfree (T) ;                     /* clear T */
    if (!cs_di_dupl (A)) return (free_problem (Prob)) ; /* sum up duplicates */
    Prob->sym = sym = is_sym (A) ;      /* determine if A is symmetric */
    m = A->m ; n = A->n ;
    mn = CS_MAX (m,n) ;
    nz1 = A->p [n] ;
    cs_di_dropzeros (A) ;                  /* drop zero entries */
    nz2 = A->p [n] ;
    if (tol > 0) cs_di_droptol (A, tol) ;  /* drop tiny entries (just to test) */
    Prob->C = C = sym ? make_sym (A) : A ;  /* C = A + triu(A,1)', or C=A */
    if (!C) return (free_problem (Prob)) ;
    printf ("\n--- Matrix: %g-by-%g, nnz: %g (sym: %g: nnz %g), norm: %8.2e\n",
            (double) m, (double) n, (double) (A->p [n]), (double) sym,
            (double) (sym ? C->p [n] : 0), cs_di_norm (C)) ;
    if (nz1 != nz2) printf ("zero entries dropped: %g\n", (double) (nz1 - nz2));
    if (nz2 != A->p [n]) printf ("tiny entries dropped: %g\n",
            (double) (nz2 - A->p [n])) ;
    Prob->b = cs_di_malloc (mn, sizeof (double)) ;
    Prob->x = cs_di_malloc (mn, sizeof (double)) ;
    Prob->resid = cs_di_malloc (mn, sizeof (double)) ;
    return ((!Prob->b || !Prob->x || !Prob->resid) ? free_problem (Prob) : Prob) ;
}
Exemplo n.º 6
0
/*
 Free memory used by KLU
 */
void FreeKINKlu(KINMem kin_memory){
	
	/*
	do memory deallocation from the bottom up. first, deallocate memory
	used by the KLU memory block.
	*/
	
	//grab the KLU memory block
	KINKluMem kin_klu_mem = (KINKluMem)kin_memory->kin_lmem;
	if(!kin_klu_mem) return;
	
	//free the jacobian matrix
	if(kin_klu_mem->jac) cs_di_spfree(kin_klu_mem->jac);
	
	//free the klu objects
	if(kin_klu_mem->symbolic) klu_free_symbolic(&(kin_klu_mem->symbolic), &(kin_klu_mem->klu_comm));
	
	if(kin_klu_mem->numeric) klu_free_numeric(&(kin_klu_mem->numeric), &(kin_klu_mem->klu_comm));
	
	//now release the klu memory block
	free(kin_klu_mem);
	kin_memory->kin_lmem = NULL;
	
	//return
	return;
};
void freeAllocationsTransient(void) {
  int i;
	
			
	for(i = 0; i < circuit_simulation.number_of_elements[CURRENT_SOURCE] + circuit_simulation.group2_elements; i++) {
	      if(sources[i]->transient != NULL) {
		  free(sources[i]->transient->vals);
	      }
	}
	
	free( sources );

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		cs_di_spfree( C2 );
	}
	else
	{
		free( matrix_C );
	}
	

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		if (circuit_simulation.method == DIRECT)
		{ 
			cs_di_sfree( S );
			cs_di_nfree( N );
		}
		else
		{
			cs_di_spfree( G2 );
		}
	}
	else
	{
		free( matrix_G );

		if (circuit_simulation.method == DIRECT && circuit_simulation.matrix_type == NONSPD)
		
		{
			free( transposition );
		}
	}

}
Exemplo n.º 8
0
/* C = A + triu(A,1)' */
static cs_di *make_sym (cs_di *A)
{
    cs_di *AT, *C ;
    AT = cs_di_transpose (A, 1) ;          /* AT = A' */
    cs_di_fkeep (AT, &dropdiag, NULL) ;    /* drop diagonal entries from AT */
    C = cs_di_add (A, AT, 1, 1) ;          /* C = A+AT */
    cs_di_spfree (AT) ;
    return (C) ;
}
Exemplo n.º 9
0
void CholeskyDecomposition(void)
{
	int k, i, j;
	unsigned int dimension;
	double sum, temp;
#if DEBUG
	int l;
#endif

	dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements;

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		printf( "\n\nCholesky Decomposition...\n\n" );
		S = cs_di_schol( 1, G2 );
		N = cs_di_chol( G2, S );
		cs_di_spfree( G2 );

		if (N == NULL)
		{
			printf( "Error, the matrix must be symmetric & positive definite.\n\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}

	}
	else
	{
		printf( "\n\nCholesky Decomposition...\n\n" );

		for (k = 0; k < dimension; k++)
		{
			for (sum = 0, j = 0; j < k; j++)
			{
			      if (matrix_G[k * dimension + j] != matrix_G[j * dimension + k])
			      {
					printf( "Error, the matrix must be symmetric & positive definite.\n\n" );
					printf( "Terminating.\n" );
					exit( -1 );
			      }
			      
			      sum += matrix_G[k * dimension + j] * matrix_G[k * dimension + j];				
			}

			if ((temp = matrix_G[k * dimension + k] - sum) < 0)
			{
				printf( "Error, the matrix must be symmetric & positive definite.\n\n" );
				printf( "Terminating.\n" );
				exit( -1 );
			}
			matrix_G[k * dimension + k] = sqrt( temp );

			for (i = k + 1; i < dimension; i++)
			{
				for (sum = 0, j = 0; j < k; j++)
				{
					sum += matrix_G[i * dimension + j] * matrix_G[k * dimension + j];
				}
				matrix_G[k * dimension + i] = matrix_G[i * dimension + k] = (matrix_G[k * dimension + i] - sum) / matrix_G[k * dimension + k];
			}
		}

	}
	
#if DEBUG
		printf("\nCholesky Decomposition\n~~~~~~~~~~~~~~~~~~~~~~~\n\n");
		printf("\nDecomposed Matrix:\n\n");
		for(k = 0; k < dimension; k++)
		{
			for(l = 0; l < dimension; l++)
			{
				if(l == k)
				{
					printf("  \\\\");
				}
				
				if (circuit_simulation.matrix_sparsity == SPARSE)
				{
				      if(l <= k)
				      {
					      printf("%12lf ", getElementAt(N -> L, k, l));
				      }
				      else
				      {
					      printf("%12lf ", getElementAt(N -> L, l, k));
				      }
				}
				else {
				      printf("%12lf ", matrix_G[k * dimension + l]);
				}
				
				if(l == k)
				{
					printf("  \\\\");
				}

			}
			printf("\n\n");
		}

		printf("\n\n");
#endif

}
Exemplo n.º 10
0
void LUDecomposition(void)
{
#if DEBUG
	int l;
#endif
	int k, i, m, j;
	unsigned int dimension;

	dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements;

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		printf( "\n\nLU Decomposition...\n\n" );
		
		S = cs_di_sqr( 2, G2, 0 );
		N = cs_di_lu( G2, S, 1 );
		cs_di_spfree( G2 );

		if (N == NULL)
		{
			printf( "Error, the matrix cannot be inverted.\n\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}

	}
	else
	{
		transposition = ( int * ) malloc( dimension * sizeof(int) );

		if (transposition == NULL)
		{
			printf( "Could not allocate matrices.\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}

		for (i = 0; i < dimension; i++)
		{
			transposition[i] = i;
		}

		printf( "\n\nLU Decomposition...\n\n" );

		for (k = 0; k < dimension - 1; k++)
		{
			for (m = i = k; i < dimension; i++)
			{
				if (fabs( matrix_G[i * dimension + k] ) > fabs( matrix_G[m * dimension + k] ))
				{
					m = i;
				}
			}

			interchange( m, k );

			if (fabs( matrix_G[k * dimension + k] ) == 0)
			{
				printf( "Error, the matrix cannot be inverted.\n\n" );
				printf( "Terminating.\n" );
				exit( -1 );
			}

			for (i = k + 1; i < dimension; i++)
			{
				matrix_G[i * dimension + k] /= matrix_G[k * dimension + k];
				for (j = k + 1; j < dimension; j++)
				{
					matrix_G[i * dimension + j] += -matrix_G[i * dimension + k] * matrix_G[k * dimension + j];
				}
			}
		}

	}
	
#if DEBUG
		printf("\nLU Decomposition\n~~~~~~~~~~~~~~~~~\n\n");
		printf("\nDecomposed Matrix:\n\n");
		for(k = 0; k < dimension; k++)
		{
			for(l = 0; l < dimension; l++)
			{
				if(l == k)
				{
					printf("  \\\\");
				}
				
				if (circuit_simulation.matrix_sparsity == SPARSE)
				{
				      if(l >= k)
				      {
					      printf("%12lf ", getElementAt(N -> U, k, l));
				      }
				      else
				      {
					      printf("%12lf ", getElementAt(N -> L, k, l));
				      }
				}
				else {
				      printf("%12lf ", matrix_G[k * dimension + l]);  
				}
			}
			printf("\n\n");
		}

		printf("\n\n");

		printf("\nLine Transposition:\n");
		for(k = 0; k < dimension; k++)
		{		
		      if (circuit_simulation.matrix_sparsity == SPARSE)
		      {
			    printf("line %d contains line %d\n", N -> pinv[k], k);
		      }
		      else {
			    printf("line %d contains line %d\n", k, transposition[k]);
		      }
		}
		printf("\n\n");
#endif

}
Exemplo n.º 11
0
/* Cholesky update/downdate */
int demo3 (problem *Prob)
{
    cs_di *A, *C, *W = NULL, *WW, *WT, *E = NULL, *W2 ;
    int n, k, *Li, *Lp, *Wi, *Wp, p1, p2, *p = NULL, ok ;
    double *b, *x, *resid, *y = NULL, *Lx, *Wx, s,  t, t1 ;
    cs_dis *S = NULL ;
    cs_din *N = NULL ;
    if (!Prob || !Prob->sym || Prob->A->n == 0) return (0) ;
    A = Prob->A ; C = Prob->C ; b = Prob->b ; x = Prob->x ; resid = Prob->resid;
    n = A->n ;
    if (!Prob->sym || n == 0) return (1) ;
    rhs (x, b, n) ;                             /* compute right-hand side */
    printf ("\nchol then update/downdate ") ;
    print_order (1) ;
    y = cs_di_malloc (n, sizeof (double)) ;
    t = tic () ;
    S = cs_di_schol (1, C) ;                       /* symbolic Chol, amd(A+A') */
    printf ("\nsymbolic chol time %8.2f\n", toc (t)) ;
    t = tic () ;
    N = cs_di_chol (C, S) ;                        /* numeric Cholesky */
    printf ("numeric  chol time %8.2f\n", toc (t)) ;
    if (!S || !N || !y) return (done3 (0, S, N, y, W, E, p)) ;
    t = tic () ;
    cs_di_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_di_lsolve (N->L, y) ;                       /* y = L\y */
    cs_di_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_di_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    printf ("solve    chol time %8.2f\n", toc (t)) ;
    printf ("original: ") ;
    print_resid (1, C, x, b, resid) ;           /* print residual */
    k = n/2 ;                                   /* construct W  */
    W = cs_di_spalloc (n, 1, n, 1, 0) ;
    if (!W) return (done3 (0, S, N, y, W, E, p)) ;
    Lp = N->L->p ; Li = N->L->i ; Lx = N->L->x ;
    Wp = W->p ; Wi = W->i ; Wx = W->x ;
    Wp [0] = 0 ;
    p1 = Lp [k] ;
    Wp [1] = Lp [k+1] - p1 ;
    s = Lx [p1] ;
    srand (1) ;
    for ( ; p1 < Lp [k+1] ; p1++)
    {
        p2 = p1 - Lp [k] ;
        Wi [p2] = Li [p1] ;
        Wx [p2] = s * rand () / ((double) RAND_MAX) ;
    }
    t = tic () ;
    ok = cs_di_updown (N->L, +1, W, S->parent) ;   /* update: L*L'+W*W' */
    t1 = toc (t) ;
    printf ("update:   time: %8.2f\n", t1) ;
    if (!ok) return (done3 (0, S, N, y, W, E, p)) ;
    t = tic () ;
    cs_di_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_di_lsolve (N->L, y) ;                       /* y = L\y */
    cs_di_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_di_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    p = cs_di_pinv (S->pinv, n) ;
    W2 = cs_di_permute (W, p, NULL, 1) ;           /* E = C + (P'W)*(P'W)' */
    WT = cs_di_transpose (W2,1) ;
    WW = cs_di_multiply (W2, WT) ;
    cs_di_spfree (WT) ;
    cs_di_spfree (W2) ;
    E = cs_di_add (C, WW, 1, 1) ;
    cs_di_spfree (WW) ;
    if (!E || !p) return (done3 (0, S, N, y, W, E, p)) ;
    printf ("update:   time: %8.2f (incl solve) ", t1+t) ;
    print_resid (1, E, x, b, resid) ;           /* print residual */
    cs_di_nfree (N) ;                              /* clear N */
    t = tic () ;
    N = cs_di_chol (E, S) ;                        /* numeric Cholesky */
    if (!N) return (done3 (0, S, N, y, W, E, p)) ;
    cs_di_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_di_lsolve (N->L, y) ;                       /* y = L\y */
    cs_di_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_di_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    printf ("rechol:   time: %8.2f (incl solve) ", t) ;
    print_resid (1, E, x, b, resid) ;           /* print residual */
    t = tic () ;
    ok = cs_di_updown (N->L, -1, W, S->parent) ;   /* downdate: L*L'-W*W' */
    t1 = toc (t) ;
    if (!ok) return (done3 (0, S, N, y, W, E, p)) ;
    printf ("downdate: time: %8.2f\n", t1) ;
    t = tic () ;
    cs_di_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_di_lsolve (N->L, y) ;                       /* y = L\y */
    cs_di_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_di_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    printf ("downdate: time: %8.2f (incl solve) ", t1+t) ;
    print_resid (1, C, x, b, resid) ;           /* print residual */
    return (done3 (1, S, N, y, W, E, p)) ;
}