Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit 67069c1

Browse files
committed
LUPSolve.cpp
1 parent 6eff97e commit 67069c1

File tree

3 files changed

+163
-1
lines changed

3 files changed

+163
-1
lines changed

LUPSolve.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_LUPSolve
22+
#endif
23+
24+
#ifndef FUNC_LUPSolve
25+
#define FUNC_LUPSolve
26+
27+
#include "utils.h"
28+
29+
#include "SquareMatrixMultiply.cpp"
30+
31+
using PT = std::vector<size_t>;
32+
33+
template <typename T>
34+
Matrix<T> LUPSolve(Matrix<T>& L, Matrix<T>& U, PT& pi, Matrix<T>& b) {
35+
size_t n = L.rows;
36+
Matrix<T> x(n, 1, 0), y(n, 1, 0);
37+
for (size_t i = 0; i < n; i++) {
38+
T& yy = y[i][0];
39+
yy = b[pi[i]][0];
40+
for (size_t j = 0; j < i; j++)
41+
yy -= L[i][j] * y[j][0];
42+
}
43+
for (size_t i = n; i-- > 0; ) {
44+
T& xx = x[i][0];
45+
xx = y[i][0];
46+
for (size_t j = i + 1; j < n; j++)
47+
xx -= U[i][j] * x[j][0];
48+
xx /= U[i][i];
49+
}
50+
return x;
51+
}
52+
53+
template <typename T>
54+
void LUDecomposition(Matrix<T>& A, Matrix<T>& L, Matrix<T>& U) {
55+
const size_t n = A.rows;
56+
U = L = Matrix<T>(n, n, 0);
57+
for (size_t i = 0; i < n; i++)
58+
L[i][i] = 1;
59+
for (size_t k = 0; k < n; k++) {
60+
U[k][k] = A[k][k];
61+
for (size_t i = k + 1; i < n; i++) {
62+
L[i][k] = A[i][k] / U[k][k];
63+
U[k][i] = A[k][i];
64+
}
65+
for (size_t i = k + 1; i < n; i++)
66+
for (size_t j = k + 1; j < n; j++)
67+
A[i][j] -= L[i][k] * U[k][j];
68+
}
69+
}
70+
71+
template <typename T>
72+
PT LUPDecomposition(Matrix<T>& A) {
73+
const size_t n = A.rows;
74+
PT pi(n);
75+
for (size_t i = 0; i < n; i++)
76+
pi[i] = i;
77+
for (size_t k = 0; k < n; k++) {
78+
T p = 0;
79+
size_t kk;
80+
for (size_t i = k; i < n; i++) {
81+
T abs = A[i][k] < 0 ? -A[i][k] : A[i][k];
82+
if (abs > p) {
83+
p = abs;
84+
kk = i;
85+
}
86+
}
87+
if (p == 0)
88+
throw std::invalid_argument("singular matrix");
89+
std::swap(pi[k], pi[kk]);
90+
for (size_t i = 0; i < n; i++)
91+
std::swap(A[k][i], A[kk][i]);
92+
for (size_t i = k + 1; i < n; i++) {
93+
A[i][k] /= A[k][k];
94+
for (size_t j = k + 1; j < n; j++)
95+
A[i][j] -= A[i][k] * A[k][j];
96+
}
97+
}
98+
return pi;
99+
}
100+
#endif
101+
102+
#ifdef MAIN_LUPSolve
103+
int main(int argc, char *argv[]) {
104+
const size_t n = get_argv(argc, argv, 1, 16);
105+
const size_t compute = get_argv(argc, argv, 2, 3);
106+
std::vector<int> int_a, int_b;
107+
random_integers(int_a, -n, n, n * n);
108+
random_integers(int_b, -n, n, n);
109+
using T = double;
110+
std::vector<T> buf_a(n * n), buf_b(n);
111+
for (size_t i = 0; i < int_a.size(); i++)
112+
buf_a[i] = int_a[i];
113+
for (size_t i = 0; i < int_b.size(); i++)
114+
buf_b[i] = int_b[i];
115+
Matrix<T> A(n, n, buf_a);
116+
Matrix<T> b(n, 1, buf_b);
117+
std::cout << A << std::endl;
118+
Matrix<T> ans1(b), ans2(n, 0);
119+
if (compute >> 0 & 1) {
120+
Matrix<T> A1(A), L(0, 0), U(0, 0);
121+
PT pi(n);
122+
for (size_t i = 0; i < n; i++)
123+
pi[i] = i;
124+
LUDecomposition(A1, L, U);
125+
Matrix<T> x = LUPSolve(L, U, pi, b);
126+
ans2 = ans2.concat_h(x);
127+
Matrix<T> bb = SquareMatrixMultiply(A, x, (T) 0);
128+
ans1 = ans1.concat_h(bb);
129+
}
130+
if (compute >> 1 & 1) {
131+
Matrix<T> A2(A);
132+
PT pi = LUPDecomposition(A2);
133+
Matrix<T> x = LUPSolve(A2, A2, pi, b);
134+
ans2 = ans2.concat_h(x);
135+
Matrix<T> bb = SquareMatrixMultiply(A, x, (T) 0);
136+
ans1 = ans1.concat_h(bb);
137+
}
138+
for (size_t i = 0; i < n; i++) {
139+
output_integers(ans1[i], "\t");
140+
}
141+
std::cout << std::endl;
142+
for (size_t i = 0; i < n; i++) {
143+
std::cout << "\t";
144+
output_integers(ans2[i], "\t");
145+
}
146+
std::cout << std::endl;
147+
return 0;
148+
}
149+
#endif
150+

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@
184184
| 27 | PMergeSort.cpp | Binary Search | 799 |
185185
| 27 | PMergeSort.cpp | P Merge | 800 |
186186
| 27 | PMergeSort.cpp | P Merge Sort | 803 |
187+
| 28 | LUPSolve.cpp | LUP Solve | 817 |
188+
| 28 | LUPSolve.cpp | LU Decomposition | 821 |
189+
| 28 | LUPSolve.cpp | LUP Decomposition | 824 |
187190

188191
# Supplementary Files
189192
* `utils.h`: Utils

SquareMatrixMultiply.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ class Matrix {
7979
os << rhs.data[i] << std::endl;
8080
return os;
8181
}
82+
std::ostream& octave(std::ostream& os) {
83+
os << '[';
84+
for (size_t i = 0; i < rows; i++) {
85+
os << data[i];
86+
if (i != rows - 1)
87+
os << ';';
88+
}
89+
return os << ']' << std::endl;
90+
}
8291
MatrixRow<T>& operator[](size_t index) { return data[index]; }
8392
bool operator==(const Matrix<T>& rhs) const {
8493
return data == rhs.data;
@@ -186,7 +195,7 @@ Matrix<T> SquareMatrixMultiply(Matrix<T>&A, Matrix<T>&B, T T0){
186195
Matrix<T> C(A.rows, B.cols, T0);
187196
for (size_t i = 0; i < C.rows; i++) {
188197
for(size_t j = 0; j < C.cols; j++) {
189-
int& loc = C.data[i][j];
198+
T& loc = C.data[i][j];
190199
for(size_t k = 0; k < A.cols; k++) {
191200
loc += A[i][k] * B[k][j];
192201
}

0 commit comments

Comments
 (0)