Routine Name: solveLinearSystemInline
Author: Andrew Aposhian
Language: C++
To use this function, include the correct header file at the top of your file as follows:
#include "LinearSolvers.hpp"
Description/Purpose: The purpose of this overloaded function is to solve a linear system of equations by performing row reduction on the coefficient matrix then performing backsubstitution. Unlike solveLinearSystem
, solveLinearSystemInline
does not use the rowReduce
and backsub
routines, but rather does these operations in-line. The routine outputs the solution to the system of equations as a vector.
Input:
A
: an Array of doubles of dimensionality n x nb
: an Array of doubles of dimensionality n x 1
Output: A vector of doubles of dimensionality n x 1 representing the solution to the linear system
Usage/Example: The example below shows creating a random coefficient matrix and b vector, printing them, finding the solution to the linear system using the routine, then printing the solution.
std::cout << "Diagonally dominant coefficient matrix A_3 to be solved: " << std::endl;
DenseArray<double>* A_3 = new DenseArray<double>(3, 3);
A_3->makeRandomDD(1.0, 10.0);
A_3->print();
std::cout << "b_3: " << std::endl;
Vector<double>* b_3 = new Vector<double>(3);
b_3->makeRandom(1.0, 10.0);
b_3->print();
std::cout << "x found for A_3 system: " << std::endl;
Vector<double> x_a3 = solveLinearSystemInline(*A_3, *b_3);
x_a3.print();
Output from lines above:
Diagonally dominant coefficient matrix A_3 to be solved:
9.81712 7.15914 1.05711
7.10768 9.97901 2.8692
2.79929 6.74427 9.89667
b_3:
8.69537
1.42704
1.52729
x found for A_3 system:
1.73375
-1.23778
0.507437
Implementation/Code: See LinearSolvers.cpp on GitHub
Vector<double>& solveLinearSystemInline(DenseArray<double>& A, Vector<double>& b) {
// TODO: Add scaled partial pivoting
assertLinearSystem(A, b);
unsigned int n = A.rowDim();
for (unsigned int pivotIdx = 0; pivotIdx < n; pivotIdx++) {
double pivot = A(pivotIdx, pivotIdx);
for (unsigned int i = pivotIdx + 1; i < n; i++) {
double l = A(i, pivotIdx) / pivot;
A.set(i, pivotIdx, 0.0);
for (unsigned int j = pivotIdx + 1; j < n; j++) {
double oldVal = A(i, j);
A.set(i, j, oldVal - l * A(pivotIdx, j));
}
double oldBVal = b(i);
b.set(i, oldBVal - l * b(pivotIdx));
}
}
Vector<double>* x = new Vector<double>(n, true);
unsigned int lastIndex = n - 1;
double x_n = b(lastIndex, 0) / A(lastIndex, lastIndex);
x->set(lastIndex, x_n);
// Note that the loop ends when i is negative
for (int i = lastIndex - 1; i >= 0; i--) {
double sum = 0.0;
for (unsigned int j = i + 1; j < n; j++) {
sum += A(i, j) * (*x)(j);
}
double x_i = (b(i, 0) - sum) / A(i, i);
x->set(i, x_i);
}
return *x;
}
Last Modified: May/2019