From d8705234dad37c8fd73149ac142bd3af0f615ff1 Mon Sep 17 00:00:00 2001 From: Christian Engwer <christi@mathe-macht-spass.de> Date: Thu, 29 Sep 2022 20:03:23 +0000 Subject: [PATCH] Merge branch 'fix-lsq-bug' into 'master' Fixes segfault for least squares problems with SPQR See merge request core/dune-istl!489 (cherry picked from commit 9a72de2d686b15fbc13a320d9e47dcfd5b322973) d5eba453 Allow SPQR solver to work with non-square matrices --- CHANGELOG.md | 3 +++ dune/istl/spqr.hh | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2528d488..426ff793c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,9 @@ SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception - You can now use `std::tuple_element` to get the types of `MultiTypeBlockVector` entries and `MultiTypeBlockMatrix` rows. +- The SPQR solver can now work with non-square matrices (a bug which caused a segfault when previously + attempting to do it was found and resolved). + ## Deprecations and removals - The deprecated ILU functions `bilu_backsolve`, `bilu0_decomposition`, `bilu_backsolve`, diff --git a/dune/istl/spqr.hh b/dune/istl/spqr.hh index 4cce4468b..92a1d1626 100644 --- a/dune/istl/spqr.hh +++ b/dune/istl/spqr.hh @@ -286,20 +286,25 @@ namespace Dune { /** @brief Computes the QR decomposition. */ void decompose() { - const std::size_t dimMat(spqrMatrix_.N()); - const std::size_t nnz(spqrMatrix_.getColStart()[dimMat]); + const std::size_t nrows(spqrMatrix_.N()); + const std::size_t ncols(spqrMatrix_.M()); + const std::size_t nnz(spqrMatrix_.getColStart()[ncols]); + // initialise the matrix A (sorted, packed, unsymmetric, real entries) - A_ = cholmod_l_allocate_sparse(dimMat, dimMat, nnz, 1, 1, 0, 1, cc_); + A_ = cholmod_l_allocate_sparse(nrows, ncols, nnz, 1, 1, 0, 1, cc_); + // copy all the entries of Ap, Ai, Ax - for(std::size_t k = 0; k != (dimMat+1); ++k) + for(std::size_t k = 0; k != (ncols+1); ++k) (static_cast<long int *>(A_->p))[k] = spqrMatrix_.getColStart()[k]; + for(std::size_t k = 0; k != nnz; ++k) { (static_cast<long int*>(A_->i))[k] = spqrMatrix_.getRowIndex()[k]; (static_cast<T*>(A_->x))[k] = spqrMatrix_.getValues()[k]; } + // initialise the vector B - B_ = cholmod_l_allocate_dense(dimMat, 1, dimMat, A_->xtype, cc_); + B_ = cholmod_l_allocate_dense(nrows, 1, nrows, A_->xtype, cc_); // compute factorization of A spqrfactorization_=SuiteSparseQR_factorize<T>(SPQR_ORDERING_DEFAULT,SPQR_DEFAULT_TOL,A_,cc_); } -- GitLab