32 Container<Number>
lup_solve(Container<Container<Number>>&& A, Container<Number>&& B, Number epsilon = std::numeric_limits<Number>::epsilon()) {
33 const auto n = B.size();
34 assert(n == A.size());
35 for (
SizeT i = 0; i < n; ++i) {
36 assert(n == A[i].size());
37 Number max_a = std::abs(A[i][i]);
39 for (
SizeT k = i + 1; k < n; ++k) {
40 const auto cur = std::abs(A[k][i]);
46 if (max_a < epsilon) {
47 std::cerr <<
"Error in function " << __FUNCTION__ <<
": Matrix A is degenerate. Returning an empty array..." << std::endl;
51 std::swap(A[i], A[i_max]);
52 std::swap(B[i], B[i_max]);
54 for (
SizeT j = i + 1; j < n; ++j) {
56 for (
SizeT k = i + 1; k < n; ++k) {
57 A[j][k] -= A[j][i] * A[i][k];
61 Container<Number> X(n);
62 for (
SizeT i = 0; i < n; ++i) {
64 for (
SizeT k = 0; k < i; ++k) {
65 X[i] -= A[i][k] * X[k];
68 for (
SizeT iter = 0; iter < n; ++iter) {
69 const auto i = n - 1 - iter;
70 for (
SizeT k = i + 1; k < n; ++k) {
71 X[i] -= A[i][k] * X[k];
102 const Container<Number>& lower,
103 Container<Number>&& diag,
104 const Container<Number>& upper,
105 Container<Number>&& right
107 const auto n = right.size();
108 assert(n == lower.size());
109 assert(n == diag.size());
110 assert(n == upper.size());
114 for (
SizeT i = 0; i < n - 1; ++i) {
115 const auto m = lower[i+1] / diag[i];
116 diag[i+1] -= m * upper[i];
117 right[i+1] -= m * right[i];
119 Container<Number> X(n);
120 X[n-1] = right[n-1] / diag[n-1];
121 for (
SizeT iter = 2; iter <= n; ++iter) {
122 const auto i = n - iter;
123 X[i] = (right[i] - upper[i] * X[i+1]) / diag[i];
149 Container<Number>&& lower,
150 Container<Number>&& diag,
151 Container<Number>&& upper,
152 Container<Number>&& right
154 const auto n = right.size();
155 assert(n == lower.size());
156 assert(n == diag.size());
157 assert(n == upper.size());
162 return {right[0]/diag[0]};
164 for (
SizeT i = 0; i < n - 1; ++i) {
165 if (std::abs(diag[i]) >= std::abs(lower[i+1])) {
166 const auto m = lower[i+1] / diag[i];
167 diag[i+1] -= m * upper[i];
168 right[i+1] -= m * right[i];
174 const auto m = diag[i] / lower[i+1];
175 diag[i] = lower[i+1];
176 lower[i+1] = upper[i+1];
178 std::swap(upper[i], diag[i+1]);
179 diag[i+1] -= m * upper[i];
180 std::swap(right[i], right[i+1]);
181 right[i+1] -= m * right[i];
184 Container<Number> X(n);
185 X[n-1] = right[n-1] / diag[n-1];
186 X[n-2] = (right[n-2] - upper[n-2] * X[n-1]) / diag[n-2];
187 for (
SizeT iter = 3; iter <= n; ++iter) {
188 const auto i = n - iter;
189 X[i] = (right[i] - upper[i] * X[i+1] - lower[i+1] * X[i+2]) / diag[i];