Linear Equations Solver  1.0
Using Gaussian elimination
Loading...
Searching...
No Matches
methods.cpp
Go to the documentation of this file.
1
12#include "methods.h"
13#include <iostream>
14#include <iomanip>
15#include <cmath>
16#include <algorithm>
17#include <string>
18#include <vector>
19
20using namespace std;
21
23int Pivoting(const vector<vector<double>> &m, int current_row, int total_rows)
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}
38
40void Exchange(vector<vector<double>> &m, int row1, int row2)
41{
42 swap(m[row1], m[row2]);
43 cout << "Swapping row " << row1 + 1 << " with row " << row2 + 1 << "." << endl;
44}
45
47bool Eliminate(vector<vector<double>> &m, int current_row, int total_rows, int total_cols)
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}
71
75int GaussianElimination(vector<vector<double>> &m, int rows, int cols)
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}
133
137bool BackSubstitution(const vector<vector<double>> &m, int rows, int cols, vector<double> &solution)
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}
184
188int DetermineRank(const vector<vector<double>> &m, int rows, int cols)
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}
207
211void ShowGeneralSolution(const vector<vector<double>> &m, int rows, int cols, int rank)
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}
316
320vector<int> IdentifyPivots(const vector<vector<double>> &m, int rows, int cols)
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}
vector< int > IdentifyPivots(const vector< vector< double > > &m, int rows, int cols)
Identifies the pivot columns in the matrix.
Definition methods.cpp:320
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
int DetermineRank(const vector< vector< double > > &m, int rows, int cols)
Determines the rank of the coefficient matrix A (excluding augmented column).
Definition methods.cpp:188
int GaussianElimination(vector< vector< double > > &m, int rows, int cols)
Performs Gaussian elimination on the augmented matrix with partial pivoting.
Definition methods.cpp:75
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
bool BackSubstitution(const vector< vector< double > > &m, int rows, int cols, vector< double > &solution)
Performs back-substitution to find the solution vector.
Definition methods.cpp:137
void ShowGeneralSolution(const vector< vector< double > > &m, int rows, int cols, int rank)
Displays the general solution for systems with infinitely many solutions.
Definition methods.cpp:211
Core computational functions for solving linear systems.