openGPMP
Open Source Mathematics Package
Public Member Functions | Public Attributes | List of all members
gpmp::linalg::LinSys Class Reference

Class for solving linear systems and performing matrix operations. More...

#include <linsys.hpp>

Public Member Functions

 LinSys (const std::vector< std::vector< double >> &mat)
 Constructor for LinSys class. More...
 
void display_mtx () const
 Display the augmented matrix. More...
 
void display (const std::vector< std::vector< double >> &mat) const
 
std::vector< double > solve_gauss ()
 Solve the linear system using Gaussian Elimination. More...
 
double determinant () const
 Calculate the determinant of the matrix. More...
 
void invert_mtx ()
 Invert the matrix. More...
 
std::pair< std::vector< std::vector< double > >, std::vector< std::vector< double > > > lu_decomp ()
 Perform LU decomposition of the matrix. More...
 
void solve_lu ()
 Solve the linear system using LU decomposition. More...
 
void solve_cholesky ()
 Solve the linear system using Cholesky decomposition. More...
 
void solve_jacobi (int maxIterations=100, double tolerance=1e-10)
 Solve the linear system using Jacobi iteration. More...
 
bool is_symmetric () const
 Check if the matrix is symmetric. More...
 
double frobenius_norm () const
 Calculate the Frobenius norm of the matrix. More...
 
double one_norm () const
 Calculate the 1-norm of the matrix. More...
 
double inf_norm () const
 Calculate the infinity norm of the matrix. More...
 
void gram_schmidt ()
 Perform Gram-Schmidt orthogonalization on the matrix. More...
 
bool diagonally_dominant () const
 Check if the matrix is diagonally dominant. More...
 
bool is_consistent () const
 Check if the linear system is consistent. More...
 
bool is_homogeneous () const
 Check if the linear system is homogeneous. More...
 

Public Attributes

std::vector< std::vector< double > > matrix
 
int num_rows
 
int num_cols
 

Detailed Description

Class for solving linear systems and performing matrix operations.

Definition at line 48 of file linsys.hpp.

Constructor & Destructor Documentation

◆ LinSys()

gpmp::linalg::LinSys::LinSys ( const std::vector< std::vector< double >> &  mat)

Constructor for LinSys class.

Parameters
matThe augmented matrix [A|B] representing the linear system

Definition at line 40 of file linsys.cpp.

41  : matrix(mat) {
42  num_rows = matrix.size();
43  num_cols = matrix[0].size();
44 }
std::vector< std::vector< double > > matrix
Definition: linsys.hpp:50

References matrix, num_cols, and num_rows.

Member Function Documentation

◆ determinant()

double gpmp::linalg::LinSys::determinant ( ) const

Calculate the determinant of the matrix.

Returns
Determinant of the matrix

Definition at line 107 of file linsys.cpp.

107  {
108  // assuming square matrix
109  if (num_rows != num_cols) {
110  std::cerr << "Error: Determinant is undefined for non-square matrices."
111  << std::endl;
112  return 0.0;
113  }
114 
115  std::vector<std::vector<double>> temp_mtx = matrix;
116  double det = 1.0;
117 
118  for (int i = 0; i < num_rows - 1; ++i) {
119  for (int k = i + 1; k < num_rows; ++k) {
120  double factor = temp_mtx[k][i] / temp_mtx[i][i];
121  for (int j = i; j < num_cols; ++j) {
122  temp_mtx[k][j] -= factor * temp_mtx[i][j];
123  }
124  }
125  }
126 
127  for (int i = 0; i < num_rows; ++i) {
128  det *= temp_mtx[i][i];
129  }
130 
131  return det;
132 }

Referenced by is_symmetric().

◆ diagonally_dominant()

bool gpmp::linalg::LinSys::diagonally_dominant ( ) const

Check if the matrix is diagonally dominant.

Returns
True if the matrix is diagonally dominant, false otherwise

Definition at line 396 of file linsys.cpp.

396  {
397  for (int i = 0; i < num_rows; ++i) {
398  double diagonalValue = std::abs(matrix[i][i]);
399  double rowSum = 0.0;
400  for (int j = 0; j < num_cols; ++j) {
401  if (j != i) {
402  rowSum += std::abs(matrix[i][j]);
403  }
404  }
405  if (diagonalValue <= rowSum) {
406  return false;
407  }
408  }
409  return true;
410 }

◆ display()

void gpmp::linalg::LinSys::display ( const std::vector< std::vector< double >> &  mat) const

Definition at line 56 of file linsys.cpp.

57  {
58  uint32_t rows = mat.size();
59  uint32_t cols = mat[0].size();
60 
61  for (uint32_t i = 0; i < rows; ++i) {
62  for (uint32_t j = 0; j < cols; ++j) {
63  std::cout << mat[i][j] << " ";
64  }
65  std::cout << std::endl;
66  }
67 }

References test_linalg::cols, and test_linalg::rows.

◆ display_mtx()

void gpmp::linalg::LinSys::display_mtx ( ) const

Display the augmented matrix.

Definition at line 47 of file linsys.cpp.

47  {
48  for (int i = 0; i < num_rows; ++i) {
49  for (int j = 0; j < num_cols; ++j) {
50  std::cout << matrix[i][j] << " ";
51  }
52  std::cout << std::endl;
53  }
54 }

◆ frobenius_norm()

double gpmp::linalg::LinSys::frobenius_norm ( ) const

Calculate the Frobenius norm of the matrix.

Returns
The Frobenius norm of the matrix

Definition at line 338 of file linsys.cpp.

338  {
339  double sum = 0.0;
340  for (int i = 0; i < num_rows; ++i) {
341  for (int j = 0; j < num_cols; ++j) {
342  sum += std::pow(matrix[i][j], 2);
343  }
344  }
345  return std::sqrt(sum);
346 }

◆ gram_schmidt()

void gpmp::linalg::LinSys::gram_schmidt ( )

Perform Gram-Schmidt orthogonalization on the matrix.

Definition at line 375 of file linsys.cpp.

375  {
376  std::vector<std::vector<double>> orthoBasis(
377  num_rows,
378  std::vector<double>(num_cols, 0.0));
379 
380  for (int j = 0; j < num_cols; ++j) {
381  for (int i = 0; i < num_rows; ++i) {
382  double projection = 0.0;
383  for (int k = 0; k < i; ++k) {
384  projection += (matrix[i][j] * orthoBasis[k][j]) /
385  (orthoBasis[k][j] * orthoBasis[k][j]);
386  }
387  orthoBasis[i][j] = matrix[i][j] - projection;
388  }
389  }
390 
391  // Replace the matrix with the orthogonalized basis
392  matrix = orthoBasis;
393 }

◆ inf_norm()

double gpmp::linalg::LinSys::inf_norm ( ) const

Calculate the infinity norm of the matrix.

Returns
The infinity norm of the matrix

Definition at line 362 of file linsys.cpp.

362  {
363  double maxRowSum = 0.0;
364  for (int i = 0; i < num_rows; ++i) {
365  double rowSum = 0.0;
366  for (int j = 0; j < num_cols; ++j) {
367  rowSum += std::abs(matrix[i][j]);
368  }
369  maxRowSum = std::max(maxRowSum, rowSum);
370  }
371  return maxRowSum;
372 }

◆ invert_mtx()

void gpmp::linalg::LinSys::invert_mtx ( )

Invert the matrix.

Definition at line 135 of file linsys.cpp.

135  {
136  // assuming square matrix
137  if (num_rows != num_cols) {
138  std::cerr
139  << "Error: Matrix inversion is undefined for non-square matrices."
140  << std::endl;
141  return;
142  }
143 
144  std::vector<std::vector<double>> identity(
145  num_rows,
146  std::vector<double>(num_cols, 0.0));
147 
148  // augment the matrix with the identity matrix
149  for (int i = 0; i < num_rows; ++i) {
150  matrix[i].insert(matrix[i].end(),
151  identity[i].begin(),
152  identity[i].end());
153  }
154 
155  // perform Gaussian elimination
156  solve_gauss();
157 
158  // separate the inverse matrix
159  for (int i = 0; i < num_rows; ++i) {
160  matrix[i].erase(matrix[i].begin(), matrix[i].begin() + num_rows);
161  }
162 }
std::vector< double > solve_gauss()
Solve the linear system using Gaussian Elimination.
Definition: linsys.cpp:70

◆ is_consistent()

bool gpmp::linalg::LinSys::is_consistent ( ) const

Check if the linear system is consistent.

Returns
True if the system is consistent, false otherwise

Definition at line 413 of file linsys.cpp.

413  {
414  for (int i = 0; i < num_rows; ++i) {
415  bool allZeros = true;
416  for (int j = 0; j < num_cols - 1; ++j) {
417  if (fabs(matrix[i][j]) > std::numeric_limits<double>::epsilon()) {
418 
419  allZeros = false;
420  break;
421  }
422  }
423  if (allZeros && fabs(matrix[i][num_cols - 1]) >
424  std::numeric_limits<double>::epsilon()) {
425  return false;
426  }
427  }
428  return true;
429 }

◆ is_homogeneous()

bool gpmp::linalg::LinSys::is_homogeneous ( ) const

Check if the linear system is homogeneous.

Returns
True if the system is homogeneous, false otherwise

Definition at line 432 of file linsys.cpp.

432  {
433  for (int i = 0; i < num_rows; ++i) {
434  if (fabs(matrix[i][num_cols - 1]) >
435  std::numeric_limits<double>::epsilon()) {
436  return false;
437  }
438  }
439  return true;
440 }

◆ is_symmetric()

bool gpmp::linalg::LinSys::is_symmetric ( ) const

Check if the matrix is symmetric.

Returns
True if the matrix is symmetric, false otherwise

Definition at line 302 of file linsys.cpp.

302  {
303  // assuming square matrix
304  if (num_rows != num_cols) {
305  return false;
306  }
307 
308  // check symmetry
309  for (int i = 0; i < num_rows; ++i) {
310  for (int j = 0; j < num_cols; ++j) {
311  // if (matrix[i][j] != matrix[j][i]) {
312  if (fabs(matrix[i][j] - matrix[j][i]) >
313  std::numeric_limits<double>::epsilon()) {
314  return false;
315  }
316  }
317  }
318 
319  // check positive definiteness
320  for (int i = 0; i < num_rows; ++i) {
321  std::vector<std::vector<double>> submatrix(i + 1,
322  std::vector<double>(i + 1));
323  for (int j = 0; j <= i; ++j) {
324  for (int k = 0; k <= i; ++k) {
325  submatrix[j][k] = matrix[j][k];
326  }
327  }
328 
329  double det = LinSys(submatrix).determinant();
330  if (det <= 0.0) {
331  return false;
332  }
333  }
334 
335  return true;
336 }
LinSys(const std::vector< std::vector< double >> &mat)
Constructor for LinSys class.
Definition: linsys.cpp:40

References determinant().

◆ lu_decomp()

std::pair< std::vector< std::vector< double > >, std::vector< std::vector< double > > > gpmp::linalg::LinSys::lu_decomp ( )

Perform LU decomposition of the matrix.

Returns
the Lower and Upper matrices of the decomposition

Definition at line 165 of file linsys.cpp.

165  {
166  std::vector<std::vector<double>> L(num_rows,
167  std::vector<double>(num_cols, 0.0));
168  std::vector<std::vector<double>> U(num_rows,
169  std::vector<double>(num_cols, 0.0));
170 
171  for (int i = 0; i < num_rows; ++i) {
172  // Set diagonal elements of L to 1
173  L[i][i] = 1.0;
174 
175  for (int j = i; j < num_cols; ++j) {
176  U[i][j] = matrix[i][j];
177  for (int k = 0; k < i; ++k) {
178  U[i][j] -= L[i][k] * U[k][j];
179  }
180  }
181 
182  for (int j = i + 1; j < num_rows; ++j) {
183  L[j][i] = matrix[j][i];
184  for (int k = 0; k < i; ++k) {
185  L[j][i] -= L[j][k] * U[k][i];
186  }
187  L[j][i] /= U[i][i];
188  }
189  }
190 
191  return {L, U};
192 }

◆ one_norm()

double gpmp::linalg::LinSys::one_norm ( ) const

Calculate the 1-norm of the matrix.

Returns
The 1-norm of the matrix

Definition at line 349 of file linsys.cpp.

349  {
350  double maxColSum = 0.0;
351  for (int j = 0; j < num_cols; ++j) {
352  double colSum = 0.0;
353  for (int i = 0; i < num_rows; ++i) {
354  colSum += std::abs(matrix[i][j]);
355  }
356  maxColSum = std::max(maxColSum, colSum);
357  }
358  return maxColSum;
359 }

◆ solve_cholesky()

void gpmp::linalg::LinSys::solve_cholesky ( )

Solve the linear system using Cholesky decomposition.

Definition at line 214 of file linsys.cpp.

214  {
215  // assuming symmetric and positive-definite matrix
216  if (!is_symmetric()) {
217  std::cerr << "Error: Cholesky decomposition is only applicable to"
218  "symmetric positive-definite matrices\n";
219  }
220 
221  for (int i = 0; i < num_rows; ++i) {
222  for (int j = 0; j <= i; ++j) {
223  if (i == j) {
224  double sum = 0.0;
225  for (int k = 0; k < j; ++k) {
226  sum += std::pow(matrix[j][k], 2);
227  }
228  matrix[j][j] = std::sqrt(matrix[j][j] - sum);
229  }
230 
231  else {
232  double sum = 0.0;
233  for (int k = 0; k < j; ++k) {
234  sum += matrix[i][k] * matrix[j][k];
235  }
236  matrix[i][j] = (matrix[i][j] - sum) / matrix[j][j];
237  }
238  }
239  }
240 
241  // forward substitution
242  for (int i = 0; i < num_rows; ++i) {
243  double sum = 0.0;
244  for (int j = 0; j < i; ++j) {
245  sum += matrix[i][j] * matrix[num_cols - 1][j];
246  }
247  matrix[num_cols - 1][i] =
248  (matrix[num_cols - 1][i] - sum) / matrix[i][i];
249  }
250 
251  // back-substitution
252  for (int i = num_rows - 1; i >= 0; --i) {
253  double sum = 0.0;
254  for (int j = i + 1; j < num_cols - 1; ++j) {
255  sum += matrix[j][i] * matrix[i][num_cols - 1];
256  }
257  matrix[i][num_cols - 1] =
258  (matrix[i][num_cols - 1] - sum) / matrix[i][i];
259  }
260 }
bool is_symmetric() const
Check if the matrix is symmetric.
Definition: linsys.cpp:302

◆ solve_gauss()

std::vector< double > gpmp::linalg::LinSys::solve_gauss ( )

Solve the linear system using Gaussian Elimination.

Returns
vector containing solutinos to system

Definition at line 70 of file linsys.cpp.

70  {
71  // temp matrix because our result is a vector of solutions
72  std::vector<std::vector<double>> temp_mtx = matrix;
73 
74  for (int i = 0; i < num_rows - 1; ++i) {
75  // perform partial pivot
76  int pivotRow = i;
77  for (int k = i + 1; k < num_rows; ++k) {
78  if (std::abs(temp_mtx[k][i]) > std::abs(temp_mtx[pivotRow][i]))
79  pivotRow = k;
80  }
81  std::swap(temp_mtx[i], temp_mtx[pivotRow]);
82 
83  // eliminate entries below pivot
84  for (int k = i + 1; k < num_rows; ++k) {
85  double factor = temp_mtx[k][i] / temp_mtx[i][i];
86  for (int j = i; j < num_cols; ++j) {
87  temp_mtx[k][j] -= factor * temp_mtx[i][j];
88  }
89  }
90  }
91 
92  // back-substitution
93  std::vector<double> solutions(num_rows, 0);
94 
95  for (int i = num_rows - 1; i >= 0; --i) {
96  double sum = 0.0;
97  for (int j = i + 1; j < num_cols - 1; ++j) {
98  sum += temp_mtx[i][j] * solutions[j];
99  }
100  solutions[i] = (temp_mtx[i][num_cols - 1] - sum) / temp_mtx[i][i];
101  }
102 
103  return solutions;
104 }

◆ solve_jacobi()

void gpmp::linalg::LinSys::solve_jacobi ( int  maxIterations = 100,
double  tolerance = 1e-10 
)

Solve the linear system using Jacobi iteration.

Parameters
maxIterationsMaximum number of iterations (default: 100)
toleranceConvergence tolerance (default: 1e-10)

Definition at line 263 of file linsys.cpp.

263  {
264  std::vector<std::vector<double>> x(num_rows, std::vector<double>(1, 0.0));
265  std::vector<std::vector<double>> xOld = x;
266 
267  for (int iter = 0; iter < maxIterations; ++iter) {
268  for (int i = 0; i < num_rows; ++i) {
269  double sum = 0.0;
270  for (int j = 0; j < num_cols - 1; ++j) {
271  if (j != i) {
272  sum += matrix[i][j] * xOld[j][0];
273  }
274  }
275  x[i][0] = (matrix[i][num_cols - 1] - sum) / matrix[i][i];
276  }
277 
278  // check convergence
279  double maxDiff = 0.0;
280  for (int i = 0; i < num_rows; ++i) {
281  double diff = std::abs(x[i][0] - xOld[i][0]);
282  if (diff > maxDiff) {
283  maxDiff = diff;
284  }
285  }
286 
287  // converged
288  if (maxDiff < tolerance) {
289  break;
290  }
291 
292  xOld = x;
293  }
294 
295  // copy the solution back to the augmented matrix
296  for (int i = 0; i < num_rows; ++i) {
297  matrix[i][num_cols - 1] = x[i][0];
298  }
299 }

◆ solve_lu()

void gpmp::linalg::LinSys::solve_lu ( )

Solve the linear system using LU decomposition.

Definition at line 195 of file linsys.cpp.

195  {
196  lu_decomp();
197 
198  // forward substitution
199  for (int i = 0; i < num_rows - 1; ++i) {
200  for (int j = i + 1; j < num_rows; ++j) {
201  matrix[j][num_cols - 1] -= matrix[j][i] * matrix[i][num_cols - 1];
202  }
203  }
204 
205  // back-substitution
206  for (int i = num_rows - 1; i >= 0; --i) {
207  for (int j = i + 1; j < num_cols - 1; ++j) {
208  matrix[i][num_cols - 1] -= matrix[i][j] * matrix[j][num_cols - 1];
209  }
210  matrix[i][num_cols - 1] /= matrix[i][i];
211  }
212 }
std::pair< std::vector< std::vector< double > >, std::vector< std::vector< double > > > lu_decomp()
Perform LU decomposition of the matrix.
Definition: linsys.cpp:165

Member Data Documentation

◆ matrix

std::vector<std::vector<double> > gpmp::linalg::LinSys::matrix

Definition at line 50 of file linsys.hpp.

Referenced by LinSys().

◆ num_cols

int gpmp::linalg::LinSys::num_cols

Definition at line 52 of file linsys.hpp.

Referenced by LinSys().

◆ num_rows

int gpmp::linalg::LinSys::num_rows

Definition at line 51 of file linsys.hpp.

Referenced by LinSys().


The documentation for this class was generated from the following files: