Example #1
0
void CholeskyDecompositionComplex(long int run)
{
	int k, i, j;
	unsigned int dimension;
	double sum, temp;
	double complex sum2;
#if DEBUG
	int l;
	double complex temp_val;
#endif

	dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements;

	if (circuit_simulation.matrix_sparsity == SPARSE)
	{
		if(run == 0) {
	             printf( "\n\nCholesky Decomposition...\n\n" );
		}
		Scomplex = cs_ci_schol( 1, G2complex );
		Ncomplex = cs_ci_chol( G2complex, Scomplex );
		cs_ci_spfree( G2complex );

		if (Ncomplex == NULL)
		{
			printf( "Error, the matrix must be hermitian & positive definite.\n\n" );
			printf( "Terminating.\n" );
			exit( -1 );
		}
	}
	else
	{
	        if(run == 0) {
		    printf( "\n\nCholesky Decomposition...\n\n" );
                }

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

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

			for (i = k + 1; i < dimension; i++)
			{
				for (sum2 = 0, j = 0; j < k; j++)
				{
					sum2 += conj(matrix_Gcomplex[i * dimension + j]) * matrix_Gcomplex[k * dimension + j];
				}
				matrix_Gcomplex[k * dimension + i] = matrix_Gcomplex[i * dimension + k] = (matrix_Gcomplex[k * dimension + i] - sum2) / matrix_Gcomplex[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)
				      {
					    temp_val = getElementAtComplex(Ncomplex -> L, k, l);
					    printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				      else
				      {
					    temp_val = getElementAtComplex(Ncomplex -> L, l, k);
					    printf("(%7.3lf %7.3lfi) ", creal(temp_val), cimag(temp_val));
				      }
				}
				else {
				     printf("(%7.3lf %7.3lfi) ", creal(matrix_Gcomplex[k * dimension + l]), cimag(matrix_Gcomplex[k * dimension + l]));
				}
				
				if(l == k)
				{
					printf("  \\\\");
				}

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

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

}
Example #2
0
/* Cholesky update/downdate */
int demo3 (problem *Prob)
{
    cs_ci *A, *C, *W = NULL, *WW, *WT, *E = NULL, *W2 ;
    int n, k, *Li, *Lp, *Wi, *Wp, p1, p2, *p = NULL, ok ;
    cs_complex_t *b, *x, *resid, *y = NULL, *Lx, *Wx, s ;
    double t, t1 ;
    cs_cis *S = NULL ;
    cs_cin *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_ci_malloc (n, sizeof (cs_complex_t)) ;
    t = tic () ;
    S = cs_ci_schol (1, C) ;                       /* symbolic Chol, amd(A+A') */
    printf ("\nsymbolic chol time %8.2f\n", toc (t)) ;
    t = tic () ;
    N = cs_ci_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_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_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_ci_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_ci_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_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_pvec (S->pinv, y, x, n) ;                /* x = P'*y */
    t = toc (t) ;
    p = cs_ci_pinv (S->pinv, n) ;
    W2 = cs_ci_permute (W, p, NULL, 1) ;           /* E = C + (P'W)*(P'W)' */
    WT = cs_ci_transpose (W2,1) ;
    WW = cs_ci_multiply (W2, WT) ;
    cs_ci_spfree (WT) ;
    cs_ci_spfree (W2) ;
    E = cs_ci_add (C, WW, 1, 1) ;
    cs_ci_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_ci_nfree (N) ;                              /* clear N */
    t = tic () ;
    N = cs_ci_chol (E, S) ;                        /* numeric Cholesky */
    if (!N) return (done3 (0, S, N, y, W, E, p)) ;
    cs_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_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_ci_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_ci_ipvec (S->pinv, b, y, n) ;               /* y = P*b */
    cs_ci_lsolve (N->L, y) ;                       /* y = L\y */
    cs_ci_ltsolve (N->L, y) ;                      /* y = L'\y */
    cs_ci_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)) ;
}