source: CIVL/mods/dev.civl.abc/examples/fevs/gausselim/gausselim_bad.c

main
Last change on this file was aad342c, checked in by Stephen Siegel <siegel@…>, 3 years ago

Performing huge refactor to incorporate ABC, GMC, and SARL into CIVL repo and use Java modules.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5664 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 7.4 KB
Line 
1/* FEVS: A Functional Equivalence Verification Suite for High-Performance
2 * Scientific Computing
3 *
4 * Copyright (C) 2004-2010, Stephen F. Siegel, Timothy K. Zirkel,
5 * University of Delaware, University of Massachusetts
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23
24/*
25 * Name: gausselim_seq.c
26 * Date: 21 Jul 2004
27 * Revised: 24 Jul 2004
28 * Author: Anastasia V. Mironova <mironova@laser.cs.umass.edu>
29 * Author: Stephen Siegel <siegel@cs.umass.edu>
30 * Maintainer: Anastasia V. Mironova <mironova@laser.cs.umass.edu>
31 * Reader:
32 *
33 * Compile: cc gausselim_seq.c
34 * Run: a.out n m A[0,0] A[0,1] ... A[n-1,m-1]
35 *
36 * n : number of rows in matrix
37 * m : number of columns in matrix
38 * A[0,0] .. A[n-1,m-1] : entries of matrix (doubles)
39 *
40 * Description: This is a sequential implementation of the
41 * Gauss-Jordan elimination algorithm. The input is an n x m matrix A
42 * of double precision floating point numbers. At termination, A has
43 * been placed in reduced row-echelon form. The original algorithm is
44 * described in many places; see for example Howard Anton, Elementary
45 * Linear Algebra, Wiley, 1977, Section 1.2. In this implementation a
46 * modification to this algorithm has been made to perform backward
47 * subsitution together with the process of reduction to row-echelon
48 * form.
49 *
50 * The entries of the matrix are stored in row-major order, i.e., if
51 * A is the 2x3 matrix
52 *
53 * A[0,0] A[0,1] A[0,2]
54 * A[1,0] A[1,1] A[1,2]
55 *
56 * then its entries are stored as A[0,0], A[0,1], A[0,2], A[1,0],
57 * A[1,1], A[1,2].
58 *
59 * This has the error of not updating col in the main for loop of gausselim()
60 */
61#include <stdio.h>
62#include <string.h>
63#include <stdlib.h>
64
65
66
67/* Prints the given matrix of doubles to stdout. The parameter numRows
68 * gives the number of rows in the matrix, and numCols the number of
69 * columns. The string message is printed before the matrix.
70 */
71void printMatrix(char* message, double* matrix, int numRows, int numCols) {
72 int k;
73
74 printf("%s",message);
75 for (k = 0; k < numRows*numCols; k++) {
76 printf("%lf ", matrix[k]);
77 if ((k+1)%numCols == 0) {
78 printf("\n");
79 }
80 }
81 printf("\n");
82}
83
84
85/* Performs Gaussian elimination on the given matrix of doubles. The
86 * parameter numRows gives the number of rows in the matrix, and
87 * numCols the number of columns. Upon return, the matrix will be in
88 * reduced row-echelon form.
89 */
90void gausselim(double* matrix, int numRows, int numCols, int debug) {
91 int top = 0; // index of current top row
92 int col = 0; // index of current left column
93 int pivotRow = 0; // index of row containing the pivot
94 double pivot = 0.0; // the value of the pivot
95 int i = 0; // loop variable over rows of matrix
96 int j = 0; // loop variable over columns of matrix
97 double tmp = 0.0; // temporary double variable
98
99 for (top=col=0; top<numRows && col< numCols; top++) {
100
101 /* At this point we know that the submatarix consisting of the
102 * first top rows of A is in reduced row-echelon form. We will
103 * now consider the submatrix B consisting of the remaining rows.
104 * We know, additionally, that the first col columns of B are all
105 * zero.
106 */
107
108 if (debug) printf("Top: %d\n\n", top);
109
110 /* Step 1: Locate the leftmost column of B that does not consist
111 * entirely of zeros, if one exists. The top nonzero entry of
112 * this column is the pivot. */
113
114 pivot = 0.0;
115 for (; col < numCols; col++) {
116 for (pivotRow = top; pivotRow < numRows; pivotRow++) {
117 pivot = matrix[pivotRow*numCols + col];
118 if (pivot) break;
119 }
120 if (pivot) break;
121 }
122
123 if (col >= numCols) {
124 break;
125 }
126
127 /* At this point we are guaranteed that pivot = A[pivotRow,col] is
128 * nonzero. We also know that all the columns of B to the left of
129 * col consist entirely of zeros. */
130
131 if (debug) {
132 printf("Step 1 result: col=%d, pivotRow=%d, pivot=%lf.\n\n",
133 col, pivotRow, pivot);
134 }
135
136 /* Step 2: Interchange the top row with the pivot row, if
137 * necessary, so that the entry at the top of the column found in
138 * Step 1 is nonzero. */
139
140 if (pivotRow != top) {
141 for (j = 0; j < numCols; j++) {
142 tmp = matrix[top*numCols + j];
143 matrix[top*numCols + j] = matrix[pivotRow*numCols + j];
144 matrix[pivotRow*numCols + j] = tmp;
145 }
146 }
147
148 if (debug) {
149 printMatrix("Step 2 result:\n", matrix, numRows, numCols);
150 }
151
152 /* At this point we are guaranteed that A[top,col] = pivot is
153 * nonzero. Also, we know that (i>=top and j<col) implies
154 * A[i,j] = 0. */
155
156 /* Step 3: Divide the top row by pivot in order to introduce a
157 * leading 1. */
158
159 for (j = col; j < numCols; j++) {
160 matrix[top*numCols + j] /= pivot;
161 }
162
163 if (debug) {
164 printMatrix("Step 3 result:\n", matrix, numRows, numCols);
165 }
166
167 /* At this point we are guaranteed that A[top,col] is 1.0,
168 * assuming that floating point arithmetic guarantees that a/a
169 * equals 1.0 for any nonzero double a. */
170
171 /* Step 4: Add suitable multiples of the top row to all other rows
172 * so that all entries above and below the leading 1 become
173 * zero. */
174
175 for (i = 0; i < numRows; i++) {
176 if (i != top){
177 tmp = matrix[i*numCols + col];
178 for (j = col; j < numCols; j++) {
179 matrix[i*numCols + j] -= matrix[top*numCols + j]*tmp;
180 }
181 }
182 }
183
184 if (debug) {
185 printMatrix("Step 4 result:\n", matrix, numRows, numCols);
186 }
187 }
188}
189
190
191/*
192 * Usage: ges [-debug] n m A[0,0] A[0,1] ... A[n-1,m-1]
193 *
194 * n : number of rows in matrix
195 * m : number of columns in matrix
196 * A[0,0] .. A[n-1,m-1] : entries of matrix (doubles)
197 *
198 * Computes reduced row-echelon form and prints intermediate steps.
199 */
200int main(int argc, char ** argv) {
201 int numRows;
202 int numCols;
203 int k;
204 double* matrix;
205 int debug = 0;
206
207 if (argc < 3) {
208 printf("Too few arguments.\n");
209 printf("Usage: ges [-debug] n m A[0,0] A[0,1] ... A[n-1,m-1]\n");
210 printf(" n : number of rows in matrix\n");
211 printf(" m : number of columns in matrix\n");
212 printf(" A[0,0] .. A[n-1,m-1] : entries of matrix (doubles)\n");
213 exit(1);
214 }
215 if (!strcmp("-debug", argv[1])) {
216 debug = 1;
217 }
218 sscanf(argv[1+debug], "%d", &numRows);
219 sscanf(argv[2+debug], "%d", &numCols);
220 if (argc != 3 + debug + numRows*numCols) {
221 printf("Incorrect number of matrix entries: %d expected, %d given.\n",
222 numRows*numCols, argc-3-debug);
223 exit(1);
224 }
225 matrix = (double *) malloc(numRows*numCols * sizeof(double));
226 for (k = 0; k < numRows*numCols; k++) {
227 sscanf(argv[k+3+debug], "%lf", &matrix[k]);
228 }
229 printMatrix("Original matrix:\n", matrix, numRows, numCols);
230 gausselim(matrix, numRows, numCols, debug);
231 printMatrix("Reduced row-echelon form:\n", matrix, numRows, numCols);
232 return 0;
233}
Note: See TracBrowser for help on using the repository browser.