void solve_direct_methods_Complex() { unsigned int dimension; #if DEBUG int k; #endif double complex *vector_temp_complex = NULL; dimension = circuit_simulation.number_of_nodes + circuit_simulation.group2_elements; //printf("\n\nSolving (Forward/Backward) ...\n\n"); if (circuit_simulation.matrix_sparsity == SPARSE) { vector_temp_complex = ( double complex * ) calloc( dimension, sizeof(double complex) ); if (vector_temp_complex == NULL) { printf( "Could not allocate matrices.\n" ); printf( "Terminating.\n" ); exit( -1 ); } memcpy( vector_x_complex, vector_b_complex, dimension * sizeof(double complex) ); if (circuit_simulation.matrix_type == NONSPD) { /*Forward Backward LU*/ cs_ci_ipvec( Ncomplex->pinv, vector_x_complex, vector_temp_complex, dimension ); cs_ci_lsolve( Ncomplex->L, vector_temp_complex ); cs_ci_usolve( Ncomplex->U, vector_temp_complex ); cs_ci_ipvec( Scomplex->q, vector_temp_complex, vector_x_complex, dimension ); } else {/*Forward Backward Cholesky*/ cs_ci_ipvec( Scomplex->pinv, vector_x_complex, vector_temp_complex, dimension ); cs_ci_lsolve( Ncomplex->L, vector_temp_complex ); cs_ci_ltsolve( Ncomplex->L, vector_temp_complex ); cs_ci_pvec( Scomplex->pinv, vector_temp_complex, vector_x_complex, dimension ); } free( vector_temp_complex ); } else { forward_substitution_Complex(); backward_substitution_Complex(); } #if DEBUG printf("\nVector x:\n\n"); for(k = 0; k < dimension; k++) { printf("(%7.3lf %7.3lfi)\n", creal(vector_x_complex[k]), cimag(vector_x_complex[k])); } printf("\n\n"); #endif }
/* 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)) ; }