void conjugate_gradient (double **A, double *x, double *b, int n, double tol, int max_iterations, bool ortho1) { /* Solves Ax=b using Conjugate-Gradients method */ /* 'x' and 'b' are orthogonalized against 1 if 'ortho1=true' */ int i; double alpha, beta, r_r, r_r_new, p_Ap; double r[n]; double p[n]; double Ap[n]; double Ax[n]; double alphap[n]; double orth_b[n]; copy_vector(n, b, orth_b); if (ortho1) { orthog1(n, orth_b); orthog1(n, x); } right_mult_with_vector_d(A, n, n, x, Ax); vectors_subtraction(n, orth_b, Ax, r); copy_vector(n, r, p); r_r = vectors_inner_product(n, r, r); for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) { right_mult_with_vector_d(A, n, n, p, Ap); p_Ap = vectors_inner_product(n, p, Ap); if (p_Ap == 0) break; alpha = r_r / p_Ap; /* derive new x: */ vectors_scalar_mult(n, p, alpha, alphap); vectors_addition(n, x, alphap, x); /* compute values for next iteration: */ if (i < max_iterations - 1) { /* not last iteration */ vectors_scalar_mult(n, Ap, alpha, Ap); vectors_subtraction(n, r, Ap, r); /* fast computation of r, the residual */ /* Alternaive accurate, but slow, computation of the residual - r */ /* right_mult_with_vector(A, n, x, Ax); */ /* vectors_subtraction(n,b,Ax,r); */ r_r_new = vectors_inner_product(n, r, r); if (r_r == 0) exit(1); beta = r_r_new / r_r; r_r = r_r_new; vectors_scalar_mult(n, p, beta, p); vectors_addition(n, r, p, p); } } }
int conjugate_gradient_f (float **A, double *x, double *b, int n, double tol, int max_iterations, boolean ortho1) { /* Solves Ax=b using Conjugate-Gradients method */ /* 'x' and 'b' are orthogonalized against 1 if 'ortho1=true' */ int i, rv = 0; double alpha, beta, r_r, r_r_new, p_Ap; double *r = N_GNEW(n, double); double *p = N_GNEW(n, double); double *Ap = N_GNEW(n, double); double *Ax = N_GNEW(n, double); double *alphap = N_GNEW(n, double); double *orth_b = N_GNEW(n, double); copy_vector(n, b, orth_b); if (ortho1) { orthog1(n, orth_b); orthog1(n, x); } right_mult_with_vector_f(A, n, x, Ax); vectors_subtraction(n, orth_b, Ax, r); copy_vector(n, r, p); r_r = vectors_inner_product(n, r, r); for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) { right_mult_with_vector_f(A, n, p, Ap); p_Ap = vectors_inner_product(n, p, Ap); if (p_Ap == 0) break; /*exit(1); */ alpha = r_r / p_Ap; /* derive new x: */ vectors_scalar_mult(n, p, alpha, alphap); vectors_addition(n, x, alphap, x); /* compute values for next iteration: */ if (i < max_iterations - 1) { /* not last iteration */ vectors_scalar_mult(n, Ap, alpha, Ap); vectors_subtraction(n, r, Ap, r); /* fast computation of r, the residual */ /* Alternaive accurate, but slow, computation of the residual - r */ /* right_mult_with_vector(A, n, x, Ax); */ /* vectors_subtraction(n,b,Ax,r); */ r_r_new = vectors_inner_product(n, r, r); if (r_r == 0) { rv = 1; agerr (AGERR, "conjugate_gradient: unexpected length 0 vector\n"); goto cleanup1; } beta = r_r_new / r_r; r_r = r_r_new; vectors_scalar_mult(n, p, beta, p); vectors_addition(n, r, p, p); } } cleanup1: free(r); free(p); free(Ap); free(Ax); free(alphap); free(orth_b); return rv; }