Linear Equations Solver  1.0
Using Gaussian elimination
Loading...
Searching...
No Matches
methods.cpp File Reference

Implementation of computational functions for solving linear systems. More...

#include "methods.h"
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
+ Include dependency graph for methods.cpp:

Go to the source code of this file.

Functions

int Pivoting (const vector< vector< double > > &m, int current_row, int total_rows)
 Performs partial pivoting and returns the row index with the maximum pivot.
 
void Exchange (vector< vector< double > > &m, int row1, int row2)
 Swaps two rows in the matrix and outputs the action.
 
bool Eliminate (vector< vector< double > > &m, int current_row, int total_rows, int total_cols)
 Performs elimination on the matrix to form an upper triangular matrix.
 
int GaussianElimination (vector< vector< double > > &m, int rows, int cols)
 Performs Gaussian elimination on the augmented matrix with partial pivoting.
 
bool BackSubstitution (const vector< vector< double > > &m, int rows, int cols, vector< double > &solution)
 Performs back-substitution to find the solution vector.
 
int DetermineRank (const vector< vector< double > > &m, int rows, int cols)
 Determines the rank of the coefficient matrix A (excluding augmented column).
 
void ShowGeneralSolution (const vector< vector< double > > &m, int rows, int cols, int rank)
 Displays the general solution for systems with infinitely many solutions.
 
vector< int > IdentifyPivots (const vector< vector< double > > &m, int rows, int cols)
 Identifies the pivot columns in the matrix.
 

Detailed Description

Implementation of computational functions for solving linear systems.

Author
Gilbert Young
Date
2024/09/25

This file implements key algorithms such as Gaussian elimination with partial pivoting, back-substitution, and rank determination. It also includes functionality to display the general solution when the system has infinitely many solutions.

Definition in file methods.cpp.

Function Documentation

◆ BackSubstitution()

bool BackSubstitution ( const vector< vector< double > > & m,
int rows,
int cols,
vector< double > & solution )

Performs back-substitution to find the solution vector.

Parameters
mThe upper triangular matrix after Gaussian elimination.
rowsNumber of rows in the matrix.
colsNumber of columns in the matrix (including augmented column).
solutionReference to store the solution vector.
Returns
true If a unique solution exists.
false If the system is inconsistent.

Definition at line 137 of file methods.cpp.

138{
139 solution.assign(cols - 1, 0.0);
140 cout << "Starting back-substitution process..." << endl;
141 for (int i = rows - 1; i >= 0; i--)
142 {
143 // Find the first non-zero coefficient in the row
144 int pivot_col = -1;
145 for (int j = 0; j < cols - 1; j++)
146 {
147 if (fabs(m[i][j]) > 1e-12)
148 {
149 pivot_col = j;
150 break;
151 }
152 }
153
154 if (pivot_col == -1)
155 {
156 if (fabs(m[i][cols - 1]) > 1e-12)
157 {
158 // Inconsistent equation
159 return false;
160 }
161 else
162 {
163 // 0 = 0, skip
164 continue;
165 }
166 }
167
168 double rhs = m[i][cols - 1];
169 cout << "Calculating x" << pivot_col + 1 << ":" << endl;
170 for (int j = pivot_col + 1; j < cols - 1; j++)
171 {
172 cout << " " << fixed << setprecision(4) << m[i][j] << " * x" << j + 1
173 << " = " << m[i][j] * solution[j] << endl;
174 rhs -= m[i][j] * solution[j];
175 }
176 cout << " RHS after subtraction = " << rhs << endl;
177 solution[pivot_col] = rhs / m[i][pivot_col];
178 cout << " x" << pivot_col + 1 << " = " << rhs << " / " << m[i][pivot_col]
179 << " = " << fixed << setprecision(4) << solution[pivot_col] << endl
180 << endl;
181 }
182 return true;
183}

◆ DetermineRank()

int DetermineRank ( const vector< vector< double > > & m,
int rows,
int cols )

Determines the rank of the coefficient matrix A (excluding augmented column).

Parameters
mThe augmented matrix [A|b].
rowsNumber of rows in the matrix.
colsNumber of columns in the matrix (including augmented column).
Returns
int The rank of the matrix A.

Definition at line 188 of file methods.cpp.

189{
190 int rank = 0;
191 for (int i = 0; i < rows; i++)
192 {
193 bool non_zero = false;
194 for (int j = 0; j < cols - 1; j++)
195 {
196 if (fabs(m[i][j]) > 1e-12)
197 {
198 non_zero = true;
199 break;
200 }
201 }
202 if (non_zero)
203 rank++;
204 }
205 return rank;
206}

◆ Eliminate()

bool Eliminate ( vector< vector< double > > & m,
int current_row,
int total_rows,
int total_cols )

Performs elimination on the matrix to form an upper triangular matrix.

Definition at line 47 of file methods.cpp.

48{
49 double pivot = m[current_row][current_row];
50 if (fabs(pivot) < 1e-12)
51 {
52 // Pivot is too small, cannot eliminate
53 return false;
54 }
55
56 for (int i = current_row + 1; i < total_rows; i++)
57 {
58 double factor = m[i][current_row] / pivot;
59 cout << "Eliminating element in row " << i + 1 << ", column " << current_row + 1 << ":" << endl;
60 cout << "Multiplying row " << current_row + 1 << " by " << fixed << setprecision(4) << factor
61 << " and subtracting from row " << i + 1 << "." << endl;
62 m[i][current_row] = 0.0;
63 for (int j = current_row + 1; j < total_cols; j++)
64 {
65 m[i][j] -= factor * m[current_row][j];
66 }
67 cout << endl;
68 }
69 return true;
70}

◆ Exchange()

void Exchange ( vector< vector< double > > & m,
int row1,
int row2 )

Swaps two rows in the matrix and outputs the action.

Definition at line 40 of file methods.cpp.

41{
42 swap(m[row1], m[row2]);
43 cout << "Swapping row " << row1 + 1 << " with row " << row2 + 1 << "." << endl;
44}

◆ GaussianElimination()

int GaussianElimination ( vector< vector< double > > & m,
int rows,
int cols )

Performs Gaussian elimination on the augmented matrix with partial pivoting.

Parameters
mReference to the augmented matrix [A|b] to be modified.
rowsNumber of rows in the matrix.
colsNumber of columns in the matrix (including augmented column).
Returns
int Number of row exchanges performed during elimination.

Definition at line 75 of file methods.cpp.

76{
77 int exchange_count = 0;
78 int n = min(rows, cols - 1); // Number of variables
79
80 for (int k = 0; k < n; k++)
81 {
82 cout << "Processing column " << k + 1 << "..." << endl;
83
84 // Find the row with the maximum pivot element
85 int imax = Pivoting(m, k, rows);
86
87 // Swap the current row with the pivot row if necessary
88 if (imax != k)
89 {
90 Exchange(m, k, imax);
91 exchange_count++;
92 }
93 else
94 {
95 cout << "No need to swap rows for column " << k + 1 << "." << endl;
96 }
97
98 // Check if pivot element is near zero (singular matrix)
99 if (fabs(m[k][k]) < 1e-12)
100 {
101 cout << "Warning: Pivot element in row " << k + 1 << " is close to zero. The matrix may be singular." << endl;
102 continue; // Skip elimination for this pivot
103 }
104
105 // Eliminate entries below the pivot
106 if (!Eliminate(m, k, rows, cols))
107 {
108 cout << "Elimination failed for column " << k + 1 << "." << endl;
109 }
110
111 // Display current matrix state
112 cout << "Current matrix state:" << endl;
113 for (int r = 0; r < rows; r++)
114 {
115 for (int c = 0; c < cols; c++)
116 {
117 double coeff = round(m[r][c] * 1e12) / 1e12; // Handle floating-point precision
118 if (fabs(coeff - round(coeff)) < 1e-12)
119 {
120 cout << static_cast<long long>(round(coeff)) << "\t";
121 }
122 else
123 {
124 cout << fixed << setprecision(2) << coeff << "\t";
125 }
126 }
127 cout << endl;
128 }
129 cout << "-------------------------------------" << endl;
130 }
131 return exchange_count;
132}
int Pivoting(const vector< vector< double > > &m, int current_row, int total_rows)
Performs partial pivoting and returns the row index with the maximum pivot.
Definition methods.cpp:23
bool Eliminate(vector< vector< double > > &m, int current_row, int total_rows, int total_cols)
Performs elimination on the matrix to form an upper triangular matrix.
Definition methods.cpp:47
void Exchange(vector< vector< double > > &m, int row1, int row2)
Swaps two rows in the matrix and outputs the action.
Definition methods.cpp:40

◆ IdentifyPivots()

vector< int > IdentifyPivots ( const vector< vector< double > > & m,
int rows,
int cols )

Identifies the pivot columns in the matrix.

Parameters
mThe matrix after Gaussian elimination.
rowsNumber of rows in the matrix.
colsNumber of columns in the matrix (including augmented column).
Returns
std::vector<int> A vector containing the indices of the pivot columns.

Definition at line 320 of file methods.cpp.

321{
322 vector<int> pivots;
323 int n = min(rows, cols - 1);
324 for (int i = 0; i < n; i++)
325 {
326 // Find the pivot column in the current row
327 int pivot_col = -1;
328 for (int j = 0; j < cols - 1; j++)
329 {
330 if (fabs(m[i][j]) > 1e-12)
331 {
332 pivot_col = j;
333 break;
334 }
335 }
336 if (pivot_col != -1)
337 pivots.push_back(pivot_col);
338 }
339 return pivots;
340}

◆ Pivoting()

int Pivoting ( const vector< vector< double > > & m,
int current_row,
int total_rows )

Performs partial pivoting and returns the row index with the maximum pivot.

Definition at line 23 of file methods.cpp.

24{
25 int imax = current_row;
26 double max_val = fabs(m[current_row][current_row]);
27 for (int i = current_row + 1; i < total_rows; i++)
28 {
29 double val = fabs(m[i][current_row]);
30 if (val > max_val)
31 {
32 imax = i;
33 max_val = val;
34 }
35 }
36 return imax;
37}

◆ ShowGeneralSolution()

void ShowGeneralSolution ( const vector< vector< double > > & m,
int rows,
int cols,
int rank )

Displays the general solution for systems with infinitely many solutions.

Parameters
mThe matrix after Gaussian elimination.
rowsNumber of rows in the matrix.
colsNumber of columns in the matrix (including augmented column).
rankThe rank of the coefficient matrix A.

Definition at line 211 of file methods.cpp.

212{
213 cout << "The system has infinitely many solutions." << endl;
214 cout << "Solution space dimension: " << (cols - 1 - rank) << endl;
215
216 // Identify pivot columns
217 vector<int> pivots = IdentifyPivots(m, rows, cols);
218
219 // Identify free variables
220 vector<int> free_vars;
221 for (int j = 0; j < cols - 1; j++)
222 {
223 if (find(pivots.begin(), pivots.end(), j) == pivots.end())
224 {
225 free_vars.push_back(j);
226 }
227 }
228
229 // Assign parameters to free variables
230 int num_free = free_vars.size();
231 vector<string> params;
232 for (int i = 0; i < num_free; i++)
233 {
234 params.push_back("t" + to_string(i + 1));
235 }
236
237 // Initialize solution vector with parameters
238 vector<double> particular_solution(cols - 1, 0.0);
239 vector<vector<double>> basis_vectors;
240
241 // Find a particular solution by setting all free variables to 0
242 for (int i = rows - 1; i >= 0; i--)
243 {
244 // Find the first non-zero coefficient in the row
245 int pivot_col = -1;
246 for (int j = 0; j < cols - 1; j++)
247 {
248 if (fabs(m[i][j]) > 1e-12)
249 {
250 pivot_col = j;
251 break;
252 }
253 }
254
255 if (pivot_col == -1)
256 {
257 continue; // 0 = 0, skip
258 }
259
260 double rhs = m[i][cols - 1];
261 for (int j = pivot_col + 1; j < cols - 1; j++)
262 {
263 rhs -= m[i][j] * particular_solution[j];
264 }
265 particular_solution[pivot_col] = rhs / m[i][pivot_col];
266 }
267
268 // Now, find basis vectors by setting each free variable to 1 and others to 0
269 for (int i = 0; i < num_free; i++)
270 {
271 vector<double> basis(cols - 1, 0.0);
272 basis[free_vars[i]] = 1.0; // Set the free variable to 1
273
274 // Perform back-substitution for pivot variables
275 for (int r = rank - 1; r >= 0; r--)
276 {
277 int pivot_col = pivots[r];
278 double rhs = 0.0;
279 for (int j = pivot_col + 1; j < cols - 1; j++)
280 {
281 rhs -= m[r][j] * basis[j];
282 }
283 basis[pivot_col] = rhs / m[r][pivot_col];
284 }
285
286 basis_vectors.push_back(basis);
287 }
288
289 // Display the general solution
290 cout << "General solution:" << endl;
291 cout << "x = [";
292 for (int j = 0; j < cols - 1; j++)
293 {
294 cout << fixed << setprecision(4) << particular_solution[j];
295 if (j < cols - 2)
296 cout << ", ";
297 }
298 cout << "]";
299
300 for (int i = 0; i < num_free; i++)
301 {
302 cout << " + " << params[i] << " * [";
303 for (int j = 0; j < cols - 1; j++)
304 {
305 cout << fixed << setprecision(4) << basis_vectors[i][j];
306 if (j < cols - 2)
307 cout << ", ";
308 }
309 cout << "]";
310 if (i < num_free - 1)
311 cout << " + ";
312 }
313 cout << endl
314 << endl;
315}
vector< int > IdentifyPivots(const vector< vector< double > > &m, int rows, int cols)
Identifies the pivot columns in the matrix.
Definition methods.cpp:320