34 Container<Number>
lup_solve(Container<Container<Number>>&& A, Container<Number>&& B,
const Number& epsilon = std::numeric_limits<Number>::epsilon()) {
35 const auto n = B.size();
36 assert(n == A.size());
37 for (
SizeT i = 0; i < n; ++i) {
38 assert(n == A[i].size());
39 Number max_a = std::abs(A[i][i]);
41 for (
SizeT k = i + 1; k < n; ++k) {
42 const auto cur = std::abs(A[k][i]);
48 if (max_a <= epsilon) {
49 std::cerr <<
"Error in function " << __FUNCTION__ <<
": Matrix A is degenerate. Returning an empty array..." << std::endl;
53 std::swap(A[i], A[i_max]);
54 std::swap(B[i], B[i_max]);
56 for (
SizeT j = i + 1; j < n; ++j) {
58 for (
SizeT k = i + 1; k < n; ++k) {
59 A[j][k] -= A[j][i] * A[i][k];
63 Container<Number> X(n);
64 for (
SizeT i = 0; i < n; ++i) {
66 for (
SizeT k = 0; k < i; ++k) {
67 X[i] -= A[i][k] * X[k];
70 for (
SizeT iter = 0; iter < n; ++iter) {
71 const auto i = n - 1 - iter;
72 for (
SizeT k = i + 1; k < n; ++k) {
73 X[i] -= A[i][k] * X[k];
104 const Container<Number>& lower,
105 Container<Number>&& diag,
106 const Container<Number>& upper,
107 Container<Number>&& right
109 const auto n = right.size();
110 assert(n == lower.size());
111 assert(n == diag.size());
112 assert(n == upper.size());
116 for (
SizeT i = 0; i < n - 1; ++i) {
117 const auto m = lower[i+1] / diag[i];
118 diag[i+1] -= m * upper[i];
119 right[i+1] -= m * right[i];
121 Container<Number> X(n);
122 X[n-1] = right[n-1] / diag[n-1];
123 for (
SizeT iter = 2; iter <= n; ++iter) {
124 const auto i = n - iter;
125 X[i] = (right[i] - upper[i] * X[i+1]) / diag[i];
151 Container<Number>&& lower,
152 Container<Number>&& diag,
153 Container<Number>&& upper,
154 Container<Number>&& right
156 const auto n = right.size();
157 assert(n == lower.size());
158 assert(n == diag.size());
159 assert(n == upper.size());
164 return {right[0]/diag[0]};
166 for (
SizeT i = 0; i < n - 1; ++i) {
167 if (std::abs(diag[i]) >= std::abs(lower[i+1])) {
168 const auto m = lower[i+1] / diag[i];
169 diag[i+1] -= m * upper[i];
170 right[i+1] -= m * right[i];
176 const auto m = diag[i] / lower[i+1];
177 diag[i] = lower[i+1];
178 lower[i+1] = upper[i+1];
180 std::swap(upper[i], diag[i+1]);
181 diag[i+1] -= m * upper[i];
182 std::swap(right[i], right[i+1]);
183 right[i+1] -= m * right[i];
186 Container<Number> X(n);
187 X[n-1] = right[n-1] / diag[n-1];
188 X[n-2] = (right[n-2] - upper[n-2] * X[n-1]) / diag[n-2];
189 for (
SizeT iter = 3; iter <= n; ++iter) {
190 const auto i = n - iter;
191 X[i] = (right[i] - upper[i] * X[i+1] - lower[i+1] * X[i+2]) / diag[i];