142 if (nlinfo.
empty()) {
149 fill(mask_nlinfo, nlinfo,
true);
153 difference_type inv_loc_counter = 0;
154 for (difference_type p2 = 0; p2 < mask_nlinfo.
width(); ++p2) {
155 for (difference_type p1 = 0; p1 < mask_nlinfo.
height(); ++p1) {
156 if (!mask_nlinfo(p1,p2)) {
157 A_inv_loc(p1,p2) = inv_loc_counter++;
164 std::set<sparse_tree_element> sparse_tree;
165 std::vector<double> b;
166 for (difference_type p2 = 0; p2 < A_inv_loc.
width(); ++p2) {
167 for (difference_type p1 = 0; p1 < A_inv_loc.
height(); ++p1) {
169 if ((p1 > 0 && p1 < A_inv_loc.
height()-1) || (p2 > 0 && p2 < A_inv_loc.
width()-1)) {
171 if (p1 == 0 || p1 == A_inv_loc.
height()-1) {
173 if (A_inv_loc(p1,p2-1) != -1 || A_inv_loc(p1,p2) != -1 || A_inv_loc(p1,p2+1) != -1) {
176 if (A_inv_loc(p1,p2-1) == -1) { b[b.size()-1] -= A(p1,p2-1); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2-1), 1}); }
177 if (A_inv_loc(p1,p2) == -1) { b[b.size()-1] += 2*A(p1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2), -2}); }
178 if (A_inv_loc(p1,p2+1) == -1) { b[b.size()-1] -= A(p1,p2+1); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2+1), 1}); }
180 }
else if (p2 == 0 || p2 == A_inv_loc.
width()-1) {
182 if (A_inv_loc(p1-1,p2) != -1 || A_inv_loc(p1,p2) != -1 || A_inv_loc(p1+1,p2) != -1) {
185 if (A_inv_loc(p1-1,p2) == -1) { b[b.size()-1] -= A(p1-1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1-1,p2), 1}); }
186 if (A_inv_loc(p1,p2) == -1) { b[b.size()-1] += 2*A(p1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2), -2}); }
187 if (A_inv_loc(p1+1,p2) == -1) { b[b.size()-1] -= A(p1+1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1+1,p2), 1}); }
191 if (A_inv_loc(p1-1,p2) != -1 || A_inv_loc(p1+1,p2) != -1 || A_inv_loc(p1,p2) != -1 || A_inv_loc(p1,p2-1) != -1 || A_inv_loc(p1,p2+1) != -1) {
194 if (A_inv_loc(p1-1,p2) == -1) { b[b.size()-1] -= A(p1-1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1-1,p2), 1}); }
195 if (A_inv_loc(p1+1,p2) == -1) { b[b.size()-1] -= A(p1+1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1+1,p2), 1}); }
196 if (A_inv_loc(p1,p2) == -1) { b[b.size()-1] += 4*A(p1,p2); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2), -4}); }
197 if (A_inv_loc(p1,p2-1) == -1) { b[b.size()-1] -= A(p1,p2-1); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2-1), 1}); }
198 if (A_inv_loc(p1,p2+1) == -1) { b[b.size()-1] -= A(p1,p2+1); }
else {
add_to_sparse_tree(sparse_tree, {difference_type(b.size())-1, A_inv_loc(p1,p2+1), 1}); }
213 cholmod_sparse *A_sparse = cholmod_l_allocate_sparse(b.size(),
221 ((SuiteSparse_long*)A_sparse->p)[inv_loc_counter] = sparse_tree.size();
222 for (difference_type counter = 0, p2 = 0; p2 < inv_loc_counter; ++p2) {
223 ((SuiteSparse_long*)A_sparse->p)[p2] = counter;
224 while (!sparse_tree.empty() && p2 == sparse_tree.begin()->p2) {
226 auto it_ste = sparse_tree.begin();
227 ((SuiteSparse_long*)A_sparse->i)[counter] = it_ste->p1;
228 ((
double*)A_sparse->x)[counter] = it_ste->val;
229 sparse_tree.erase(it_ste);
235 cholmod_dense *b_dense = cholmod_l_allocate_dense(b.size(),
240 for (difference_type p = 0; p < difference_type(b.size()); ++p) {
241 ((
double*)b_dense->x)[p] = b[p];
247 cholmod_dense *x_dense = SuiteSparseQR<double>(A_sparse, b_dense, &c);
248 difference_type counter = 0;
249 for (difference_type p2 = 0; p2 < mask_nlinfo.
width(); ++p2) {
250 for (difference_type p1 = 0; p1 < mask_nlinfo.
height(); ++p1) {
251 if (!mask_nlinfo(p1,p2)) {
252 A(p1,p2) = ((
double*)x_dense->x)[counter++];
258 cholmod_l_free_dense(&x_dense, &c);
259 cholmod_l_free_dense(&b_dense, &c);
260 cholmod_l_free_sparse(&A_sparse, &c);
263 cholmod_l_finish(&c);