int estiva_cgsolver(void *A, double *x, double *b) { static double *work; long n, ldw, iter, info, i; double resid = 1.0e-7; if ( !symcheckmx(A) ) { fprintf(stderr,"matrix is not symmetric\n"); return 1; } setAmx(A); ldw = iter = n = dim1(b); ary1(work,n*4+1); setveclength(n); forall (0, i, n ) x[i] = b[i]; ILUdecomp(A); distributemx(A); cg_(&n,b+1,x+1,work,&ldw,&iter,&resid,estiva_matvecmpi2,estiva_psolve,&info); if (defop("-v")) fprintf(stderr, "cg iter = %ld\n",iter); return 0; }
int check_cg_pc (int n, int it_max, double it_eps, int verbose, double tiny) { if (verbose != 0) { fprintf (stdout, "==================================================\n" "check_cg_pc(n=%d): start\n", n); } int check = 0; double max = 0.0; double *a = (double *)malloc (sizeof (double) * n * n); double *b = (double *)malloc (sizeof (double) * n); double *x = (double *)malloc (sizeof (double) * n); double *x_ = (double *)malloc (sizeof (double) * n); double *lu = (double *)malloc (sizeof (double) * n * n); CHECK_MALLOC (a, "check_cg_pc"); CHECK_MALLOC (b, "check_cg_pc"); CHECK_MALLOC (x, "check_cg_pc"); CHECK_MALLOC (x_, "check_cg_pc"); CHECK_MALLOC (lu, "check_cg_pc"); // symmetric matrix int i, j; for (i = 0; i < n; i ++) { a[i * n + i] = (double)(i+1); for (j = i+1; j < n; j ++) { a[i * n + j] = 1.0/(double)(i+j); a[j * n + i] = 1.0/(double)(i+j); } } srand48(0); for (i = 0; i < n; i ++) { b[i] = drand48(); } struct iter *it = iter_init ("cg", it_max, 0, it_eps, // solver param n, NULL, 0, // guess 0, NULL); // debug info CHECK_MALLOC (it, "check_cg_pc"); char label[80]; // cg_ for (i = 0; i < n; i ++) { x[i] = 0.0; } double t0 = ptime_ms_d (); cg_ (n, b, x, local_atimes, (void *)a, it); double t1 = ptime_ms_d (); if (verbose != 0) { fprintf (stdout, "cg_ " "iter = %d, res = %e, CPU time = %f\n", it->niter, sqrt(it->res2), t1 - t0); } // cg_pc with inv_diag() for (i = 0; i < n; i ++) { x_[i] = 0.0; } t0 = ptime_ms_d (); cg_pc (n, b, x_, local_atimes, (void *)a, inv_diag, (void *)a, it); t1 = ptime_ms_d (); if (verbose != 0) { fprintf (stdout, "cg_pc(diag) " "iter = %d, res = %e, CPU time = %f\n", it->niter, sqrt(it->res2), t1 - t0); } for (i = 0; i < n; i ++) { sprintf (label, "x[%d]", i); check += compare_max (x[i], x_[i], label, verbose, tiny, &max); } // cg_pc with inv_ILU() for (i = 0; i < n; i ++) { x_[i] = 0.0; } LU_Gauss (n, a, lu); t0 = ptime_ms_d (); cg_pc (n, b, x_, local_atimes, (void *)a, inv_ILU, (void *)lu, it); t1 = ptime_ms_d (); if (verbose != 0) { fprintf (stdout, "cg_pc(LU) " "iter = %d, res = %e, CPU time = %f\n", it->niter, sqrt(it->res2), t1 - t0); } for (i = 0; i < n; i ++) { sprintf (label, "x[%d]", i); check += compare_max (x[i], x_[i], label, verbose, tiny, &max); } iter_free (it); free (a); free (b); free (x); free (x_); free (lu); if (verbose != 0) { fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }