/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/neatogen/conjgrad.c

Go to the documentation of this file.
00001 /* $Id: conjgrad.c,v 1.2 2006/12/07 22:49:36 erg Exp $ $Revision: 1.2 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include "matrix_ops.h"
00019 #include "conjgrad.h"
00020 /* #include <math.h> */
00021 #include <stdlib.h>
00022 
00023 
00024 /*************************
00025 ** C.G. method - SPARSE  *
00026 *************************/
00027 
00028 void conjugate_gradient
00029     (vtx_data * A, double *x, double *b, int n, double tol,
00030      int max_iterations) {
00031     /* Solves Ax=b using Conjugate-Gradients method */
00032     /* 'x' and 'b' are orthogonalized against 1 */
00033 
00034     int i;
00035 
00036     double alpha, beta, r_r, r_r_new, p_Ap;
00037     double *r = N_GNEW(n, double);
00038     double *p = N_GNEW(n, double);
00039     double *Ap = N_GNEW(n, double);
00040     double *Ax = N_GNEW(n, double);
00041     double *alphap = N_GNEW(n, double);
00042 
00043     double *orth_b = N_GNEW(n, double);
00044     copy_vector(n, b, orth_b);
00045     orthog1(n, orth_b);
00046     orthog1(n, x);
00047     right_mult_with_vector(A, n, x, Ax);
00048     vectors_subtraction(n, orth_b, Ax, r);
00049     copy_vector(n, r, p);
00050     r_r = vectors_inner_product(n, r, r);
00051 
00052     for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
00053         right_mult_with_vector(A, n, p, Ap);
00054         p_Ap = vectors_inner_product(n, p, Ap);
00055         if (p_Ap == 0)
00056             break;              /*exit(1); */
00057         alpha = r_r / p_Ap;
00058 
00059         /* derive new x: */
00060         vectors_scalar_mult(n, p, alpha, alphap);
00061         vectors_addition(n, x, alphap, x);
00062 
00063         /* compute values for next iteration: */
00064         if (i < max_iterations - 1) {   /* not last iteration */
00065             vectors_scalar_mult(n, Ap, alpha, Ap);
00066             vectors_subtraction(n, r, Ap, r);   /* fast computation of r, the residual */
00067 
00068             /* Alternaive accurate, but slow, computation of the residual - r */
00069             /* right_mult_with_vector(A, n, x, Ax); */
00070             /* vectors_subtraction(n,b,Ax,r); */
00071 
00072             r_r_new = vectors_inner_product(n, r, r);
00073             if (r_r == 0)
00074                 exit(1);
00075             beta = r_r_new / r_r;
00076             r_r = r_r_new;
00077             vectors_scalar_mult(n, p, beta, p);
00078             vectors_addition(n, r, p, p);
00079         }
00080     }
00081 
00082     free(r);
00083     free(p);
00084     free(Ap);
00085     free(Ax);
00086     free(alphap);
00087     free(orth_b);
00088 
00089 }
00090 
00091 
00092 /****************************
00093 ** C.G. method - DENSE      *
00094 ****************************/
00095 
00096 void conjugate_gradient_f
00097     (float **A, double *x, double *b, int n, double tol,
00098      int max_iterations, boolean ortho1) {
00099     /* Solves Ax=b using Conjugate-Gradients method */
00100     /* 'x' and 'b' are orthogonalized against 1 if 'ortho1=true' */
00101 
00102     int i;
00103 
00104     double alpha, beta, r_r, r_r_new, p_Ap;
00105     double *r = N_GNEW(n, double);
00106     double *p = N_GNEW(n, double);
00107     double *Ap = N_GNEW(n, double);
00108     double *Ax = N_GNEW(n, double);
00109     double *alphap = N_GNEW(n, double);
00110 
00111     double *orth_b = N_GNEW(n, double);
00112     copy_vector(n, b, orth_b);
00113     if (ortho1) {
00114         orthog1(n, orth_b);
00115         orthog1(n, x);
00116     }
00117     right_mult_with_vector_f(A, n, x, Ax);
00118     vectors_subtraction(n, orth_b, Ax, r);
00119     copy_vector(n, r, p);
00120     r_r = vectors_inner_product(n, r, r);
00121 
00122     for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
00123         right_mult_with_vector_f(A, n, p, Ap);
00124         p_Ap = vectors_inner_product(n, p, Ap);
00125         if (p_Ap == 0)
00126             break;              /*exit(1); */
00127         alpha = r_r / p_Ap;
00128 
00129         /* derive new x: */
00130         vectors_scalar_mult(n, p, alpha, alphap);
00131         vectors_addition(n, x, alphap, x);
00132 
00133         /* compute values for next iteration: */
00134         if (i < max_iterations - 1) {   /* not last iteration */
00135             vectors_scalar_mult(n, Ap, alpha, Ap);
00136             vectors_subtraction(n, r, Ap, r);   /* fast computation of r, the residual */
00137 
00138             /* Alternaive accurate, but slow, computation of the residual - r */
00139             /* right_mult_with_vector(A, n, x, Ax); */
00140             /* vectors_subtraction(n,b,Ax,r); */
00141 
00142             r_r_new = vectors_inner_product(n, r, r);
00143             if (r_r == 0)
00144                 exit(1);
00145             beta = r_r_new / r_r;
00146             r_r = r_r_new;
00147             vectors_scalar_mult(n, p, beta, p);
00148             vectors_addition(n, r, p, p);
00149         }
00150     }
00151 
00152     free(r);
00153     free(p);
00154     free(Ap);
00155     free(Ax);
00156     free(alphap);
00157     free(orth_b);
00158 
00159 }
00160 
00161 void
00162 conjugate_gradient_mkernel(float *A, float *x, float *b, int n,
00163                            double tol, int max_iterations)
00164 {
00165     /* Solves Ax=b using Conjugate-Gradients method */
00166     /* A is a packed symmetric matrix */
00167     /* matrux A is "packed" (only upper triangular portion exists, row-major); */
00168 
00169     int i;
00170 
00171     double alpha, beta, r_r, r_r_new, p_Ap;
00172     float *r = N_NEW(n, float);
00173     float *p = N_NEW(n, float);
00174     float *Ap = N_NEW(n, float);
00175     float *Ax = N_NEW(n, float);
00176 
00177     /* centering x and b  */
00178     orthog1f(n, x);
00179     orthog1f(n, b);
00180 
00181     right_mult_with_vector_ff(A, n, x, Ax);
00182     /* centering Ax */
00183     orthog1f(n, Ax);
00184 
00185 
00186     vectors_substractionf(n, b, Ax, r);
00187     copy_vectorf(n, r, p);
00188 
00189     r_r = vectors_inner_productf(n, r, r);
00190 
00191     for (i = 0; i < max_iterations && max_absf(n, r) > tol; i++) {
00192         orthog1f(n, p);
00193         orthog1f(n, x);
00194         orthog1f(n, r);
00195 
00196         right_mult_with_vector_ff(A, n, p, Ap);
00197         /* centering Ap */
00198         orthog1f(n, Ap);
00199 
00200         p_Ap = vectors_inner_productf(n, p, Ap);
00201         if (p_Ap == 0)
00202             break;
00203         alpha = r_r / p_Ap;
00204 
00205         /* derive new x: */
00206         vectors_mult_additionf(n, x, (float) alpha, p);
00207 
00208         /* compute values for next iteration: */
00209         if (i < max_iterations - 1) {   /* not last iteration */
00210             vectors_mult_additionf(n, r, (float) -alpha, Ap);
00211 
00212 
00213             r_r_new = vectors_inner_productf(n, r, r);
00214 
00215             if (r_r == 0)
00216                 exit(1);
00217             beta = r_r_new / r_r;
00218             r_r = r_r_new;
00219 
00220             vectors_scalar_multf(n, p, (float) beta, p);
00221 
00222             vectors_additionf(n, r, p, p);
00223         }
00224     }
00225 
00226     free(r);
00227     free(p);
00228     free(Ap);
00229     free(Ax);
00230 }

Generated on Mon Mar 31 19:03:27 2008 for Graphviz by  doxygen 1.5.1