@@ -37,46 +37,36 @@ void DiagoPPCG<T, Device>::lock_epairs(
3737}
3838
3939// ---------------------------------------------------------------------------
40- // Build K = V^H H V and M = V^H S V where V = [psi, w, p ]
40+ // Build K = V^H H V and M = V^H S V where V = [psi, w]
4141// ---------------------------------------------------------------------------
4242template <typename T, typename Device>
4343void DiagoPPCG<T, Device>::build_small_subspace(
4444 const T* psi,
4545 const std::vector<int >& cols,
46- bool use_p,
4746 SmallSubspace& subspace) const
4847{
4948 const int l = static_cast <int >(cols.size ());
50- const int nblk = use_p ? 3 : 2 ;
51- const int dim = nblk * l;
49+ const int dim = 2 * l;
5250 subspace.k .resize (dim * dim);
5351 subspace.m .resize (dim * dim);
5452 subspace.eval .resize (dim);
5553 subspace.w_scale .assign (l, static_cast <Real>(1 ));
56- subspace.p_scale .assign (l, static_cast <Real>(1 ));
5754
5855 std::vector<T> psi_l, spsi_l, hpsi_l;
5956 std::vector<T> w_l, sw_l, hw_l;
60- std::vector<T> p_l, sp_l, hp_l;
6157 copy_cols (psi, cols, psi_l);
6258 copy_cols (spsi_.data (), cols, spsi_l);
6359 copy_cols (hpsi_.data (), cols, hpsi_l);
6460 copy_cols (w_.data (), cols, w_l);
6561 copy_cols (sw_.data (), cols, sw_l);
6662 copy_cols (hw_.data (), cols, hw_l);
67- if (use_p)
68- {
69- copy_cols (p_.data (), cols, p_l);
70- copy_cols (sp_.data (), cols, sp_l);
71- copy_cols (hp_.data (), cols, hp_l);
72- }
7363
7464 // ---------------------------------------------------------------------------
75- // Normalize w and p columns to unit S-norm for numerical stability.
65+ // Normalize w columns to unit S-norm for numerical stability.
7666 //
77- // The [w, p] block of the Gram matrix M has entries O(||w||² ) which
78- // become tiny when residuals are small, making M nearly singular and
79- // causing sygvd to produce garbage eigenvectors.
67+ // The w block of the Gram matrix M has entries O(||w||^2 ) which become
68+ // tiny when residuals are small, making M nearly singular and causing
69+ // sygvd to produce garbage eigenvectors.
8070 //
8171 // Scaling to unit S-norm keeps M well-conditioned (diagonal ~1) without
8272 // changing the subspace. The Ritz values are identical and the Ritz
@@ -117,8 +107,6 @@ void DiagoPPCG<T, Device>::build_small_subspace(
117107 }
118108 };
119109 scale_to_unit_snorm (w_l, sw_l, hw_l, l, subspace.w_scale );
120- if (use_p)
121- scale_to_unit_snorm (p_l, sp_l, hp_l, l, subspace.p_scale );
122110
123111 auto copy_block = [&](const std::vector<T>& src,
124112 const int col0,
@@ -157,12 +145,6 @@ void DiagoPPCG<T, Device>::build_small_subspace(
157145 copy_block (w_l, l, basis);
158146 copy_block (hw_l, l, hbasis);
159147 copy_block (sw_l, l, sbasis);
160- if (use_p)
161- {
162- copy_block (p_l, 2 * l, basis);
163- copy_block (hp_l, 2 * l, hbasis);
164- copy_block (sp_l, 2 * l, sbasis);
165- }
166148
167149 gram (basis.data (), hbasis.data (), dim, dim, subspace.k , dim);
168150 gram (basis.data (), sbasis.data (), dim, dim, subspace.m , dim);
@@ -225,36 +207,25 @@ void DiagoPPCG<T, Device>::update_one_block(
225207 T* psi,
226208 const std::vector<int >& cols,
227209 int l,
228- bool use_p,
229210 const SmallSubspace& subspace)
230211{
231- const int dim = (use_p ? 3 : 2 ) * l;
212+ const int dim = 2 * l;
232213 const T* eigvec = subspace.k .data ();
233214
234215 std::vector<T> psi_l, spsi_l, hpsi_l;
235216 std::vector<T> w_l, sw_l, hw_l;
236- std::vector<T> p_l, sp_l, hp_l;
237217 copy_cols (psi, cols, psi_l);
238218 copy_cols (spsi_.data (), cols, spsi_l);
239219 copy_cols (hpsi_.data (), cols, hpsi_l);
240220 copy_cols (w_.data (), cols, w_l);
241221 copy_cols (sw_.data (), cols, sw_l);
242222 copy_cols (hw_.data (), cols, hw_l);
243- if (use_p)
244- {
245- copy_cols (p_.data (), cols, p_l);
246- copy_cols (sp_.data (), cols, sp_l);
247- copy_cols (hp_.data (), cols, hp_l);
248- }
249223
250224 std::vector<T> psi_new (ld_psi_ * l, T (0 ));
251225 std::vector<T> spsi_new (ld_psi_ * l, T (0 ));
252226 std::vector<T> hpsi_new (ld_psi_ * l, T (0 ));
253227
254228 std::vector<T> coeff_state (dim * l, T (0 ));
255- std::vector<T> coeff_dir;
256- if (use_p)
257- coeff_dir.assign (dim * l, T (0 ));
258229#ifdef _OPENMP
259230#pragma omp parallel for schedule(static) if (l * l > 4096)
260231#endif
@@ -265,19 +236,11 @@ void DiagoPPCG<T, Device>::update_one_block(
265236 coeff_state[i + j * dim] = eigvec[i + j * dim];
266237 const T cw = eigvec[(l + i) + j * dim] * subspace.w_scale [i];
267238 coeff_state[(l + i) + j * dim] = cw;
268- if (use_p)
269- {
270- coeff_dir[(l + i) + j * dim] = cw;
271- const T cp = eigvec[(2 *l + i) + j * dim] * subspace.p_scale [i];
272- coeff_state[(2 *l + i) + j * dim] = cp;
273- coeff_dir[(2 *l + i) + j * dim] = cp;
274- }
275239 }
276240 }
277241
278242 auto fill_basis = [&](const std::vector<T>& a,
279243 const std::vector<T>& b,
280- const std::vector<T>& c,
281244 std::vector<T>& basis)
282245 {
283246 basis.resize (ld_psi_ * dim);
@@ -292,12 +255,6 @@ void DiagoPPCG<T, Device>::update_one_block(
292255 std::copy (b.begin () + j * ld_psi_,
293256 b.begin () + (j + 1 ) * ld_psi_,
294257 basis.begin () + (l + j) * ld_psi_);
295- if (use_p)
296- {
297- std::copy (c.begin () + j * ld_psi_,
298- c.begin () + (j + 1 ) * ld_psi_,
299- basis.begin () + (2 * l + j) * ld_psi_);
300- }
301258 }
302259 };
303260
@@ -325,9 +282,9 @@ void DiagoPPCG<T, Device>::update_one_block(
325282 std::vector<T> psi_basis;
326283 std::vector<T> spsi_basis;
327284 std::vector<T> hpsi_basis;
328- fill_basis (psi_l, w_l, p_l, psi_basis);
329- fill_basis (spsi_l, sw_l, sp_l, spsi_basis);
330- fill_basis (hpsi_l, hw_l, hp_l, hpsi_basis);
285+ fill_basis (psi_l, w_l, psi_basis);
286+ fill_basis (spsi_l, sw_l, spsi_basis);
287+ fill_basis (hpsi_l, hw_l, hpsi_basis);
331288
332289 combine (psi_basis, coeff_state, psi_new);
333290 combine (spsi_basis, coeff_state, spsi_new);
@@ -336,18 +293,6 @@ void DiagoPPCG<T, Device>::update_one_block(
336293 scatter_cols (psi, cols, psi_new);
337294 scatter_cols (spsi_.data (), cols, spsi_new);
338295 scatter_cols (hpsi_.data (), cols, hpsi_new);
339- if (use_p)
340- {
341- std::vector<T> p_new (ld_psi_ * l, T (0 ));
342- std::vector<T> sp_new (ld_psi_ * l, T (0 ));
343- std::vector<T> hp_new (ld_psi_ * l, T (0 ));
344- combine (psi_basis, coeff_dir, p_new);
345- combine (spsi_basis, coeff_dir, sp_new);
346- combine (hpsi_basis, coeff_dir, hp_new);
347- scatter_cols (p_.data (), cols, p_new);
348- scatter_cols (sp_.data (), cols, sp_new);
349- scatter_cols (hp_.data (), cols, hp_new);
350- }
351296}
352297
353298} // namespace hsolver
0 commit comments