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

Go to the documentation of this file.
00001 /* $Id: solve.c,v 1.1.1.1 2004/12/23 04:05:16 ellson Exp $ $Revision: 1.1.1.1 $ */
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 /* solves the system ab=c using gauss reduction */
00019 #include <render.h>
00020 #include <math.h>
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #define asub(i,j) a[(i)*n + (j)]
00024 
00025 
00026 void solve(double *a, double *b, double *c, int n)
00027 {                               /*a[n][n],b[n],c[n] */
00028     double *asave, *csave;
00029     double amax, dum, pivot;
00030     register int i, ii, j;
00031     register int k, m, mp;
00032     register int istar, ip;
00033     register int nm, nsq, t;
00034 
00035     istar = 0;                  /* quiet warnings */
00036     nsq = n * n;
00037     asave = N_GNEW(nsq, double);
00038     csave = N_GNEW(n, double);
00039 
00040     for (i = 0; i < n; i++)
00041         csave[i] = c[i];
00042     for (i = 0; i < nsq; i++)
00043         asave[i] = a[i];
00044     /* eliminate ith unknown */
00045     nm = n - 1;
00046     for (i = 0; i < nm; i++) {
00047         /* find largest pivot */
00048         amax = 0.;
00049         for (ii = i; ii < n; ii++) {
00050             dum = fabs(asub(ii, i));
00051             if (dum < amax)
00052                 continue;
00053             istar = ii;
00054             amax = dum;
00055         }
00056         /* return if pivot is too small */
00057         if (amax < 1.e-10)
00058             goto bad;
00059         /* switch rows */
00060         for (j = i; j < n; j++) {
00061             t = istar * n + j;
00062             dum = a[t];
00063             a[t] = a[i * n + j];
00064             a[i * n + j] = dum;
00065         }
00066         dum = c[istar];
00067         c[istar] = c[i];
00068         c[i] = dum;
00069         /*pivot */
00070         ip = i + 1;
00071         for (ii = ip; ii < n; ii++) {
00072             pivot = a[ii * n + i] / a[i * n + i];
00073             c[ii] = c[ii] - pivot * c[i];
00074             for (j = 0; j < n; j++)
00075                 a[ii * n + j] = a[ii * n + j] - pivot * a[i * n + j];
00076         }
00077     }
00078     /* return if last pivot is too small */
00079     if (fabs(a[n * n - 1]) < 1.e-10)
00080         goto bad;
00081     b[n - 1] = c[n - 1] / a[n * n - 1];
00082     /* back substitute */
00083     for (k = 0; k < nm; k++) {
00084         m = n - k - 2;
00085         b[m] = c[m];
00086         mp = m + 1;
00087         for (j = mp; j < n; j++)
00088             b[m] = b[m] - a[m * n + j] * b[j];
00089         b[m] = b[m] / a[m * n + m];
00090     }
00091     /* restore original a,c */
00092     for (i = 0; i < n; i++)
00093         c[i] = csave[i];
00094     for (i = 0; i < nsq; i++)
00095         a[i] = asave[i];
00096     free(asave);
00097     free(csave);
00098     return;
00099   bad:
00100     printf("ill-conditioned\n");
00101     free(asave);
00102     free(csave);
00103     return;
00104 }

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