Solver for general band matrices.
- Note
- Although the
pdbsv solver supports KL=0 and/or KU=0, a zero (half) bandwidth would lead to unwanted warning message from ScaLAPACK.
-
See: https://github.com/Reference-ScaLAPACK/scalapack/issues/116
It solves the system of linear equations A * X = B with a general band matrix A. The band matrix A has KL sub-diagonals and KU super-diagonals. It shall be stored in the following format. The band storage scheme is illustrated by the following example, when M=N=6, KL=2, KU=1.
. a12 a23 a34 a45 a56
a11 a22 a33 a44 a55 a66
a21 a32 a43 a54 a65 .
a31 a42 a53 a64 . .
The lead dimension should be (KL+KU+1).
With zero based indexing, for a general band matrix A, the element at row i and column j is stored at A[IDX(i, j)].
const auto IDX = [&](const int i, const int j) {
if(i - j > KL || j - i > KU) return -1;
return KU + i - j + j * (KL + KU + 1);
};
The example usage can be seen as follows.
#include <iomanip>
#include <iostream>
using namespace ezp;
int main() {
const auto& env = get_env<int_t>();
constexpr auto N = 10, NRHS = 1, KL = 2, KU = 2;
constexpr auto LDA = KL + KU + 1;
std::vector<double> A, B;
const auto IDX = par_ddbsv<int_t>::indexer{N, KL, KU};
if(0 == env.rank()) {
A.resize(N * LDA, 0.);
B.resize(N * NRHS, 1.);
for(auto I = 0; I < N; ++I) A[IDX(I, I)] = I + 1;
}
auto solver = par_ddbsv(env.size());
const auto info = solver.solve({N, N, KL, KU, A.data()}, {N, NRHS, B.data()});
if(0 == env.rank() && 0 == info) {
std::cout << std::setprecision(6) << std::fixed << "Info: " << info << '\n';
std::cout << "Solution:\n";
for(const double i : B) std::cout << i << '\n';
}
return info;
}
- Author
- tlc
- Date
- 07/03/2025
- Version
- 1.0.0