|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 /* solves the system ab=c using gauss reduction */ 00016 #include <math.h> 00017 #include <stdlib.h> 00018 #include <stdio.h> 00019 #include "render.h" 00020 #define asub(i,j) a[(i)*n + (j)] 00021 00022 00023 void solve(double *a, double *b, double *c, int n) 00024 { /*a[n][n],b[n],c[n] */ 00025 double *asave, *csave; 00026 double amax, dum, pivot; 00027 register int i, ii, j; 00028 register int k, m, mp; 00029 register int istar, ip; 00030 register int nm, nsq, t; 00031 00032 istar = 0; /* quiet warnings */ 00033 nsq = n * n; 00034 asave = N_GNEW(nsq, double); 00035 csave = N_GNEW(n, double); 00036 00037 for (i = 0; i < n; i++) 00038 csave[i] = c[i]; 00039 for (i = 0; i < nsq; i++) 00040 asave[i] = a[i]; 00041 /* eliminate ith unknown */ 00042 nm = n - 1; 00043 for (i = 0; i < nm; i++) { 00044 /* find largest pivot */ 00045 amax = 0.; 00046 for (ii = i; ii < n; ii++) { 00047 dum = fabs(asub(ii, i)); 00048 if (dum < amax) 00049 continue; 00050 istar = ii; 00051 amax = dum; 00052 } 00053 /* return if pivot is too small */ 00054 if (amax < 1.e-10) 00055 goto bad; 00056 /* switch rows */ 00057 for (j = i; j < n; j++) { 00058 t = istar * n + j; 00059 dum = a[t]; 00060 a[t] = a[i * n + j]; 00061 a[i * n + j] = dum; 00062 } 00063 dum = c[istar]; 00064 c[istar] = c[i]; 00065 c[i] = dum; 00066 /*pivot */ 00067 ip = i + 1; 00068 for (ii = ip; ii < n; ii++) { 00069 pivot = a[ii * n + i] / a[i * n + i]; 00070 c[ii] = c[ii] - pivot * c[i]; 00071 for (j = 0; j < n; j++) 00072 a[ii * n + j] = a[ii * n + j] - pivot * a[i * n + j]; 00073 } 00074 } 00075 /* return if last pivot is too small */ 00076 if (fabs(a[n * n - 1]) < 1.e-10) 00077 goto bad; 00078 b[n - 1] = c[n - 1] / a[n * n - 1]; 00079 /* back substitute */ 00080 for (k = 0; k < nm; k++) { 00081 m = n - k - 2; 00082 b[m] = c[m]; 00083 mp = m + 1; 00084 for (j = mp; j < n; j++) 00085 b[m] = b[m] - a[m * n + j] * b[j]; 00086 b[m] = b[m] / a[m * n + m]; 00087 } 00088 /* restore original a,c */ 00089 for (i = 0; i < n; i++) 00090 c[i] = csave[i]; 00091 for (i = 0; i < nsq; i++) 00092 a[i] = asave[i]; 00093 free(asave); 00094 free(csave); 00095 return; 00096 bad: 00097 printf("ill-conditioned\n"); 00098 free(asave); 00099 free(csave); 00100 return; 00101 }
1.7.5