-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
PrasannaLanka
committed
May 15, 2024
1 parent
f1512cb
commit 3abaef0
Showing
1 changed file
with
69 additions
and
234 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,254 +1,89 @@ | ||
// #include <vector> | ||
// #include <cmath> | ||
// #include <stdexcept> | ||
#ifndef __VECTOR_SOLVER_H__ | ||
#define __VECTOR_SOLVER_H__ | ||
|
||
// using namespace std; | ||
|
||
// // Function to compute the absolute value | ||
// static double absval(double val) { | ||
// return val >= 0 ? val : -val; | ||
// } | ||
|
||
// // Function to compute the matrix multiplication C = A * B | ||
// vector<vector<double>> matrix_multiply(const vector<vector<double>>& A, const | ||
// vector<vector<double>>& B) { | ||
// int n = A.size(); | ||
// int m = A[0].size(); | ||
// int p = B[0].size(); | ||
|
||
// if (m != B.size()) { | ||
// throw invalid_argument("Matrix dimensions do not match for | ||
// multiplication"); | ||
// } | ||
|
||
// vector<vector<double>> C(n, vector<double>(p, 0.0)); | ||
|
||
// for (int i = 0; i < n; ++i) { | ||
// for (int j = 0; j < p; ++j) { | ||
// for (int k = 0; k < m; ++k) { | ||
// C[i][j] += A[i][k] * B[k][j]; | ||
// } | ||
// } | ||
// } | ||
|
||
// return C; | ||
// } | ||
|
||
// // Function to solve X = A_inverse * B | ||
// vector<vector<double>> solve(const vector<vector<double>>& A, const | ||
// vector<vector<double>>& B) { | ||
// // Check if A is square matrix | ||
// int n = A.size(); | ||
// int m = A[0].size(); | ||
// if (n != m) { | ||
// throw invalid_argument("Matrix A is not square"); | ||
// } | ||
|
||
// // Calculate the inverse of matrix A | ||
// // Note: In a production environment, consider using a more efficient | ||
// method for matrix inversion vector<vector<double>> A_inverse(n, | ||
// vector<double>(n, 0.0)); | ||
// // Compute A_inverse (you can use any method suitable for matrix | ||
// inversion) | ||
|
||
// // Multiply A_inverse with matrix B | ||
// return matrix_multiply(A_inverse, B); | ||
// } | ||
// #include <vector> | ||
// #include <cmath> | ||
// #include <stdexcept> | ||
|
||
// using namespace std; | ||
|
||
// // Function to compute the absolute value | ||
// static double absval(double val) { | ||
// return val >= 0 ? val : -val; | ||
// } | ||
|
||
// // Function to perform LU decomposition with partial pivoting | ||
// void lu_decomposition(const vector<vector<double>>& A, | ||
// vector<vector<double>>& L, vector<vector<double>>& U, vector<int>& P) { | ||
// int n = A.size(); | ||
// L = vector<vector<double>>(n, vector<double>(n, 0.0)); | ||
// U = A; // Copy A to U | ||
// P = vector<int>(n); | ||
|
||
// for (int i = 0; i < n; ++i) { | ||
// P[i] = i; | ||
// } | ||
|
||
// for (int k = 0; k < n - 1; ++k) { | ||
// // Partial pivoting: Find pivot | ||
// double max_val = absval(U[k][k]); | ||
// int max_row = k; | ||
// for (int i = k + 1; i < n; ++i) { | ||
// if (absval(U[i][k]) > max_val) { | ||
// max_val = absval(U[i][k]); | ||
// max_row = i; | ||
// } | ||
// } | ||
|
||
// // Swap rows in U and P | ||
// if (max_row != k) { | ||
// swap(U[k], U[max_row]); | ||
// swap(P[k], P[max_row]); | ||
// } | ||
|
||
// // Perform LU decomposition | ||
// for (int i = k + 1; i < n; ++i) { | ||
// L[i][k] = U[i][k] / U[k][k]; | ||
// for (int j = k; j < n; ++j) { | ||
// U[i][j] -= L[i][k] * U[k][j]; | ||
// } | ||
// } | ||
// } | ||
|
||
// // Set diagonal elements of L to 1 | ||
// for (int i = 0; i < n; ++i) { | ||
// L[i][i] = 1.0; | ||
// } | ||
// } | ||
|
||
// // Function to solve X = A_inverse * B using LU decomposition | ||
// vector<vector<double>> solve(const vector<vector<double>>& A, const | ||
// vector<vector<double>>& B) { | ||
// // Check if A is square matrix | ||
// int n = A.size(); | ||
// int m = A[0].size(); | ||
// if (n != m) { | ||
// throw invalid_argument("Matrix A is not square"); | ||
// } | ||
|
||
// // Perform LU decomposition with partial pivoting | ||
// vector<vector<double>> L, U; | ||
// vector<int> P; | ||
// lu_decomposition(A, L, U, P); | ||
|
||
// // Solve LY = PB | ||
// int p = B[0].size(); | ||
// vector<vector<double>> Y(n, vector<double>(p, 0.0)); | ||
// for (int i = 0; i < n; ++i) { | ||
// for (int j = 0; j < p; ++j) { | ||
// double sum = 0.0; | ||
// for (int k = 0; k < i; ++k) { | ||
// sum += L[i][k] * Y[k][j]; | ||
// } | ||
// Y[i][j] = B[P[i]][j] - sum; | ||
// } | ||
// } | ||
|
||
// // Solve UX = Y | ||
// vector<vector<double>> X(n, vector<double>(p, 0.0)); | ||
// for (int i = n - 1; i >= 0; --i) { | ||
// for (int j = 0; j < p; ++j) { | ||
// double sum = 0.0; | ||
// for (int k = i + 1; k < n; ++k) { | ||
// sum += U[i][k] * X[k][j]; | ||
// } | ||
// X[i][j] = (Y[i][j] - sum) / U[i][i]; | ||
// } | ||
// } | ||
|
||
// return X; | ||
// } | ||
#include <algorithm> | ||
#include <cmath> | ||
#include <stdexcept> | ||
#include <iostream> | ||
#include <limits> | ||
#include <vector> | ||
|
||
using namespace std; | ||
typedef std::vector<std::vector<double>> matrix; | ||
// Function to swap rows in a matrix | ||
void swapRows(std::vector<double> &row1, std::vector<double> &row2) { | ||
std::swap(row1, row2); | ||
} | ||
|
||
// Function to compute the absolute value | ||
static double absval(double val) { return val >= 0 ? val : -val; } | ||
|
||
// Function to perform LU decomposition with partial pivoting | ||
void lu_decomposition(const vector<vector<double>> &A, | ||
vector<vector<double>> &L, vector<vector<double>> &U, | ||
vector<int> &P) { | ||
int n = A.size(); | ||
L = vector<vector<double>>(n, vector<double>(n, 0.0)); | ||
U = A; // Copy A to U | ||
P = vector<int>(n); | ||
|
||
for (int i = 0; i < n; ++i) { | ||
P[i] = i; | ||
} | ||
|
||
for (int k = 0; k < n - 1; ++k) { | ||
// Partial pivoting: Find pivot | ||
double max_val = absval(U[k][k]); | ||
int max_row = k; | ||
for (int i = k + 1; i < n; ++i) { | ||
if (absval(U[i][k]) > max_val) { | ||
max_val = absval(U[i][k]); | ||
max_row = i; | ||
} | ||
} | ||
|
||
// Check if pivot is too small | ||
const double EPSILON = 1e-32; // Adjust as needed | ||
if (absval(U[max_row][k]) < EPSILON) { | ||
throw runtime_error("Matrix is nearly singular"); | ||
} | ||
|
||
// Swap rows in U and P | ||
if (max_row != k) { | ||
swap(U[k], U[max_row]); | ||
swap(P[k], P[max_row]); | ||
} | ||
|
||
// Perform LU decomposition | ||
for (int i = k + 1; i < n; ++i) { | ||
L[i][k] = U[i][k] / U[k][k]; | ||
for (int j = k; j < n; ++j) { | ||
U[i][j] -= L[i][k] * U[k][j]; | ||
const double EPS = 1e-9; | ||
|
||
void gaussJordan(matrix a, int k, matrix &ans) { | ||
int n = (int)a.size(); | ||
int m = (int)a[0].size() - k; | ||
|
||
vector<int> where(m, -1); | ||
for (int col = 0, row = 0; col < m && row < n; ++col) { | ||
int sel = row; | ||
for (int i = row; i < n; ++i) | ||
if (abs(a[i][col]) > abs(a[sel][col])) | ||
sel = i; | ||
if (abs(a[sel][col]) < EPS) | ||
continue; | ||
for (int i = 0; i < m + k; ++i) | ||
swap(a[sel][i], a[row][i]); | ||
where[col] = row; | ||
|
||
for (int i = 0; i < n; ++i) | ||
if (i != row) { | ||
double c = a[i][col] / a[row][col]; | ||
for (int j = col; j < m + k; ++j) | ||
a[i][j] -= a[row][j] * c; | ||
} | ||
} | ||
++row; | ||
} | ||
|
||
// Set diagonal elements of L to 1 | ||
ans.assign(m, vector<double>(k, 0)); | ||
for (int i = 0; i < m; ++i) | ||
if (where[i] != -1) | ||
for (int j = 0; j < k; ++j) | ||
ans[i][j] = a[where[i]][m + j] / a[where[i]][i]; | ||
|
||
for (int i = 0; i < n; ++i) { | ||
L[i][i] = 1.0; | ||
for (int j = 0; j < k; ++j) { | ||
double sum = 0; | ||
for (int l = 0; l < m; ++l) | ||
sum += ans[l][j] * a[i][l]; | ||
if (abs(sum - a[i][m + j]) > EPS) | ||
return; | ||
} | ||
} | ||
} | ||
// Function to solve X = A_inverse * B using LU decomposition | ||
vector<vector<double>> solve(const vector<vector<double>> &A, | ||
const vector<vector<double>> &B) { | ||
// Check if A is square matrix | ||
int n = A.size(); | ||
int m = A[0].size(); | ||
if (n != m) { | ||
throw invalid_argument("Matrix A is not square"); | ||
matrix solve(matrix &A, matrix &B) { | ||
int m = A.size(); | ||
int n = B[0].size(); | ||
|
||
// Check if dimensions are compatible (m rows in A, same m rows in B) | ||
if (m != B.size()) { | ||
throw std::invalid_argument( | ||
"Matrix dimensions are not compatible for solving AX=B"); | ||
} | ||
|
||
// Perform LU decomposition with partial pivoting | ||
vector<vector<double>> L, U; | ||
vector<int> P; | ||
lu_decomposition(A, L, U, P); | ||
|
||
// Solve LY = PB | ||
int p = B[0].size(); | ||
vector<vector<double>> Y(n, vector<double>(p, 0.0)); | ||
for (int i = 0; i < n; ++i) { | ||
for (int j = 0; j < p; ++j) { | ||
double sum = 0.0; | ||
for (int k = 0; k < i; ++k) { | ||
sum += L[i][k] * Y[k][j]; | ||
} | ||
Y[i][j] = B[P[i]][j] - sum; | ||
matrix augmented(m, std::vector<double>(m + n)); | ||
for (int i = 0; i < m; ++i) { | ||
for (int j = 0; j < m; ++j) { | ||
augmented[i][j] = A[i][j]; | ||
} | ||
for (int j = 0; j < n; ++j) { | ||
augmented[i][m + j] = B[i][j]; | ||
} | ||
} | ||
|
||
// Solve UX = Y | ||
vector<vector<double>> X(n, vector<double>(p, 0.0)); | ||
for (int i = n - 1; i >= 0; --i) { | ||
for (int j = 0; j < p; ++j) { | ||
double sum = 0.0; | ||
for (int k = i + 1; k < n; ++k) { | ||
sum += U[i][k] * X[k][j]; | ||
} | ||
X[i][j] = (Y[i][j] - sum) / U[i][i]; | ||
gaussJordan(augmented, B[0].size(), B); | ||
matrix X(m, std::vector<double>(n)); | ||
for (int i = 0; i < m; ++i) { | ||
for (int j = 0; j < n; ++j) { | ||
X[i][j] = B[i][j]; | ||
} | ||
} | ||
|
||
return X; | ||
} | ||
|
||
#endif // __VECTOR_SOLVER_H__ |