91 static constexpr char UPLO =
UL;
96 IT n{-1}, klu{-1}, lead{-1}, block{-1}, lines{-1};
98 std::vector<DT> a, b, work;
103 auto init_storage(
const IT n,
const IT klu) {
106 loc.lead = loc.klu + 1;
107 loc.block = std::max(loc.n / std::max(IT{1},
this->ctx.n_rows - 1) + 1, std::max(2 * loc.klu,
this->ctx.row_block(loc.n)));
108 loc.block = std::min(loc.block, loc.n);
109 loc.lines = this->ctx.rows(loc.n, loc.block);
110 loc.desc1d_a = {501, this->trans_ctx.context, loc.n, loc.block, 0, loc.lead, 0, 0, 0};
112 loc.a.resize(loc.lead * loc.lines);
115 using base_t::to_band_symm;
116 using base_t::to_full;
134 auto operator()(IT
i, IT
j)
const {
137 if(
i <
j) std::swap(
i,
j);
138 if(
i -
j > klu)
return IT{-1};
142 if(
i >
j) std::swap(
i,
j);
143 if(
j -
i > klu)
return IT{-1};
144 return 2 *
j -
i + (
j + 1) * klu;
149 template<band_symm_container_t AT, full_container_t BT> IT solve(
AT&& A,
BT&&
B) {
return solve(to_band_symm(std::forward<AT>(A)), to_full(std::forward<BT>(
B))); }
150 template<band_symm_container_t AT> IT solve(
AT&& A,
full_mat<DT, IT>&&
B) {
return solve(to_band_symm(std::forward<AT>(A)), to_full(std::move(
B))); }
153 if(!this->ctx.is_valid() || !
this->trans_ctx.is_valid())
return 0;
155 if(A.n_rows != A.n_cols || A.n_cols !=
B.n_rows)
return -1;
157 init_storage(A.n_cols, A.klu);
161 this->trans_ctx.scatter(
163 this->trans_ctx.desc_g(loc.lead, loc.n),
165 this->trans_ctx.desc_l(loc.lead, loc.n, loc.lead, loc.block, loc.lead)
168 const IT
laf = (loc.block + 2 * loc.klu) * loc.klu;
169 const IT lwork = loc.klu * std::max(
B.n_cols, loc.klu);
170 loc.work.resize(
laf + lwork);
174 if constexpr(std::is_same_v<DT, double>) {
176 pdpbtrf(&UPLO, &loc.n, &loc.klu, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
178 else if constexpr(std::is_same_v<DT, float>) {
180 pspbtrf(&UPLO, &loc.n, &loc.klu, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
182 else if constexpr(std::is_same_v<DT, complex16>) {
184 pzpbtrf(&UPLO, &loc.n, &loc.klu, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
186 else if constexpr(std::is_same_v<DT, complex8>) {
188 pcpbtrf(&UPLO, &loc.n, &loc.klu, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
192 if((info = this->trans_ctx.amx(info)) != 0)
return info;
194 return solve(std::move(
B));
198 if(
B.n_rows != loc.n)
return -1;
200 if(!this->ctx.is_valid() || !
this->trans_ctx.is_valid())
return 0;
202 const auto lead_b = std::max(loc.block, loc.lines);
204 loc.b.resize(
lead_b *
B.n_cols);
206 const auto full_desc_b = this->ctx.desc_g(
B.n_rows,
B.n_cols);
211 const IT
laf = (loc.block + 2 * loc.klu) * loc.klu;
212 const IT lwork = loc.klu * std::max(
B.n_cols, loc.klu);
213 loc.work.resize(
laf + lwork);
219 if constexpr(std::is_same_v<DT, double>) {
221 pdpbtrs(&UPLO, &loc.n, &loc.klu, &
B.n_cols, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.b.data(), &
this->ONE,
desc1d_b.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
223 else if constexpr(std::is_same_v<DT, float>) {
225 pspbtrs(&UPLO, &loc.n, &loc.klu, &
B.n_cols, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.b.data(), &
this->ONE,
desc1d_b.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
227 else if constexpr(std::is_same_v<DT, complex16>) {
229 pzpbtrs(&UPLO, &loc.n, &loc.klu, &
B.n_cols, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.b.data(), &
this->ONE,
desc1d_b.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);
231 else if constexpr(std::is_same_v<DT, complex8>) {
233 pcpbtrs(&UPLO, &loc.n, &loc.klu, &
B.n_cols, (
E*)loc.a.data(), &
this->ONE, loc.desc1d_a.data(), (
E*)loc.b.data(), &
this->ONE,
desc1d_b.data(), (
E*)loc.work.data(), &
laf, (
E*)(loc.work.data() +
laf), &lwork, &info);