90 typedef typename math::scalar_of<value_type>::type scalar_type;
91 typedef typename math::rhs_of<value_type>::type rhs_type;
95 static size_t coarse_enough()
100 template <
class Matrix>
101 SkylineLUSolver(
const Matrix& A,
const params& = params())
102 : n(backend::nbRow(A))
105 , D(n, math::zero<value_type>())
109 ordering::get(A, perm);
112 std::vector<int> invperm(n);
113 for (
int i = 0; i < n; ++i)
114 invperm[perm[i]] = i;
126 for (
int i = 0; i < n; ++i) {
127 for (
auto a = backend::row_begin(A, i); a; ++a) {
129 value_type v = a.value();
131 int newi = invperm[i];
132 int newj = invperm[j];
134 if (!math::is_zero(v)) {
137 if (ptr[newi] < newi - newj)
138 ptr[newi] = newi - newj;
140 else if (newi < newj) {
142 if (ptr[newj] < newj - newi)
143 ptr[newj] = newj - newi;
153 for (
int i = 1; i <= n; ++i) {
155 ptr[i] = ptr[i - 1] + last;
161 L.resize(ptr.back(), math::zero<value_type>());
162 U.resize(ptr.back(), math::zero<value_type>());
166 for (
int i = 0; i < n; ++i) {
167 for (
auto a = backend::row_begin(A, i); a; ++a) {
169 value_type v = a.value();
171 int newi = invperm[i];
172 int newj = invperm[j];
174 if (!math::is_zero(v)) {
176 U[ptr[newj + 1] + newi - newj] = v;
178 else if (newi == newj) {
182 L[ptr[newi + 1] + newj - newi] = v;
191 template <
class Vec1,
class Vec2>
192 void operator()(
const Vec1& rhs, Vec2& x)
const
198 for (
int i = 0; i < n; ++i) {
201 for (
int k = ptr[i], j = i - ptr[i + 1] + k; k < ptr[i + 1]; ++k, ++j)
207 for (
int j = n - 1; j >= 0; --j) {
208 for (
int k = ptr[j], i = j - ptr[j + 1] + k; k < ptr[j + 1]; ++k, ++i)
212 for (
int i = 0; i < n; ++i)
218 return backend::bytes(perm) +
219 backend::bytes(ptr) +
228 std::vector<int> perm;
229 std::vector<int> ptr;
230 std::vector<value_type> L;
231 std::vector<value_type> U;
232 std::vector<value_type> D;
234 mutable std::vector<rhs_type> y;
265 precondition(!math::is_zero(D[0]),
"Zero diagonal in skyline_lu");
266 D[0] = math::inverse(D[0]);
268 for (
int k = 0; k < n - 1; ++k) {
270 if (ptr[k + 1] + k + 1 == ptr[k + 2]) {
271 U[ptr[k + 1]] = D[0] * U[ptr[k + 1]];
275 int indexEntry = ptr[k + 1];
276 int iBeginCol = k + 1 - ptr[k + 2] + ptr[k + 1];
277 for (
int i = iBeginCol; i <= k; ++indexEntry, ++i) {
281 value_type sum = U[indexEntry];
284 int jBeginRow = i - ptr[i + 1] + ptr[i];
285 int jBeginMult = std::max(iBeginCol, jBeginRow);
287 int indexL = ptr[i] + jBeginMult - jBeginRow;
288 int indexU = ptr[k + 1] + jBeginMult - iBeginCol;
289 for (
int j = jBeginMult; j < i; ++j, ++indexL, ++indexU)
290 sum -= L[indexL] * U[indexU];
292 U[indexEntry] = D[i] * sum;
296 indexEntry = ptr[k + 1];
297 int jBeginRow = k + 1 - ptr[k + 2] + ptr[k + 1];
298 for (
int i = iBeginCol; i <= k; ++indexEntry, ++i) {
302 value_type sum = L[indexEntry];
305 int jBeginCol = i - ptr[i + 1] + ptr[i];
306 int jBeginMult = std::max(jBeginCol, jBeginRow);
308 int indexL = ptr[k + 1] + jBeginMult - jBeginRow;
309 int indexU = ptr[i] + jBeginMult - jBeginCol;
311 for (
int j = jBeginMult; j < i; ++j, ++indexL, ++indexU)
312 sum -= L[indexL] * U[indexU];
318 value_type sum = D[k + 1];
319 for (
int j = ptr[k + 1]; j < ptr[k + 2]; ++j)
322 precondition(!math::is_zero(sum),
323 "Zero sum in skyline_lu factorization");
325 D[k + 1] = math::inverse(sum);