17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_BANDMATRIXSOLVER_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_BANDMATRIXSOLVER_H
52template <
int32_t BandW
idthT>
59 assert(N > 0 && Bdim > 0);
60 mA.resize(mN * BandWidthT, 0.);
61 mB.resize(mN * mBdim, 0.);
68 mA.assign(mA.size(), std::numeric_limits<double>::signaling_NaN());
69 mB.assign(mB.size(), std::numeric_limits<double>::signaling_NaN());
73 double&
A(int32_t
i, int32_t
j)
75 auto ij = std::minmax(
i,
j);
76 assert(ij.first >= 0 && ij.second < mN);
77 int32_t k = ij.second - ij.first;
78 assert(k < BandWidthT);
79 return mA[ij.first * BandWidthT + k];
83 double&
B(int32_t
i, int32_t
j)
85 assert(
i >= 0 && i < mN && j >= 0 &&
j < mBdim);
86 return mB[
i * mBdim +
j];
96 static int32_t
test(
bool prn = 0)
102 template <
int32_t nRows>
103 void triangulateBlock(
double AA[],
double bb[]);
105 template <
int32_t nCols>
106 void dioganalizeBlock(
double A[],
double b[]);
111 std::vector<double> mA;
112 std::vector<double> mB;
120template <
int32_t BandW
idthT>
121template <
int32_t nRows>
125 int32_t
m = BandWidthT;
128 double c = 1. /
A[0];
130 double* rowi =
A + BandWidthT - 1;
131 for (int32_t
i = 1;
i <
m;
i++) {
132 double ai =
c *
A[
i];
133 for (int32_t
j =
i;
j <
m;
j++) {
134 rowi[
j] -= ai *
A[
j];
137 rowi += BandWidthT - 1;
144 for (int32_t k = 0; k < mBdim; k++) {
145 int32_t
m = BandWidthT;
150 for (int32_t
i = 1;
i <
m;
i++) {
151 b[mBdim *
i + k] -=
A[
i] * bk;
161template <
int32_t BandW
idthT>
162template <
int32_t nCols>
163inline void BandMatrixSolver<BandWidthT>::dioganalizeBlock(
double AA[],
double bb[])
165 for (int32_t k = 0; k < mBdim; k++) {
166 int32_t
rows = BandWidthT;
171 for (int32_t
i = 1;
i <
rows;
i++) {
172 b[-
i * mBdim + k] -=
A[BandWidthT * (-
i) +
i] * bk;
181template <
int32_t BandW
idthT>
186 const int32_t stepA = BandWidthT;
187 const int32_t stepB = mBdim;
193 for (; k < mN - BandWidthT; k += 1, Ak += stepA, bk += stepB) {
194 triangulateBlock<1>(Ak, bk);
197 triangulateBlock<BandWidthT>(Ak, bk);
203 double* Ak = &mA[BandWidthT * k];
204 double* bk = &mB[mBdim * k];
205 for (; k > BandWidthT - 1; k -= 1, Ak -= stepA, bk -= stepB) {
206 dioganalizeBlock<1>(Ak, bk);
209 dioganalizeBlock<BandWidthT>(Ak, bk);
213template <
int32_t BandW
idthT>
231 const int32_t stepA = 2 * BandWidthT;
232 const int32_t stepB = 2 * mBdim;
238 for (; k < mN - BandWidthT; k += 2, Ak += stepA, bk += stepB) {
239 triangulateBlock<2>(Ak, bk);
242 triangulateBlock<BandWidthT>(Ak, bk);
248 double* Ak = &mA[BandWidthT * k];
249 double* bk = &mB[mBdim * k];
250 for (; k > BandWidthT - 1; k -= 2, Ak -= stepA, bk -= stepB) {
251 dioganalizeBlock<2>(Ak, bk);
254 dioganalizeBlock<BandWidthT>(Ak, bk);
double & A(int32_t i, int32_t j)
access to A elements
double & B(int32_t i, int32_t j)
access to B elements
static int32_t test(bool prn=0)
Test the class functionality. Returns 1 when ok, 0 when not ok.
void initWithNaN()
debug tool: init arrays with NaN's
BandMatrixSolver(int32_t N, int32_t Bdim)
Consructor.
void solve()
solve the equation
void solveType1()
solve an equation of a special type
GLboolean GLboolean GLboolean b
constexpr std::array< int, nLayers > nRows
std::vector< ReadoutWindowData > rows