GCC Code Coverage Report


Directory: ./
File: src/eps/impls/krylov/krylovschur/ks-indef.c
Date: 2025-10-04 04:19:13
Exec Total Coverage
Lines: 61 63 96.8%
Functions: 1 1 100.0%
Branches: 168 258 65.1%

Line Branch Exec Source
1 /*
2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 SLEPc - Scalable Library for Eigenvalue Problem Computations
4 Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5
6 This file is part of SLEPc.
7 SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 */
10 /*
11 SLEPc eigensolver: "krylovschur"
12
13 Method: Krylov-Schur for symmetric-indefinite eigenproblems
14 */
15 #include <slepc/private/epsimpl.h>
16 #include "krylovschur.h"
17
18 121 PetscErrorCode EPSSolve_KrylovSchur_Indefinite(EPS eps)
19 {
20 121 EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data;
21 121 PetscInt k,l,ld,nv,t,nconv=0;
22 121 Mat U,D;
23 121 Vec vomega,w=eps->work[0];
24 121 PetscReal *a,*b,beta,beta1=1.0,*omega;
25 121 PetscBool breakdown=PETSC_FALSE,symmlost=PETSC_FALSE;
26
27
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
121 PetscFunctionBegin;
28
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(DSGetLeadingDimension(eps->ds,&ld));
29
30 /* Get the starting Lanczos vector */
31
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(EPSGetStartVector(eps,0,NULL));
32
33 /* Extract sigma[0] from BV, computed during normalization */
34
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(DSSetDimensions(eps->ds,1,PETSC_DETERMINE,PETSC_DETERMINE));
35
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(BVSetActiveColumns(eps->V,0,1));
36
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
37
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(BVGetSignature(eps->V,vomega));
38
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
39 121 l = 0;
40
41 /* Restart loop */
42 121 while (eps->reason == EPS_CONVERGED_ITERATING) {
43 6999 eps->its++;
44
45 /* Compute an nv-step Lanczos factorization */
46 6999 nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
47
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l));
48
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&a));
49 6999 b = a + ld;
50
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_D,&omega));
51
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(EPSPseudoLanczos(eps,a,b,omega,eps->nconv+l,&nv,&breakdown,&symmlost,NULL,w));
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
6999 if (symmlost) {
53 eps->reason = EPS_DIVERGED_SYMMETRY_LOST;
54 if (nv==eps->nconv+l+1) { eps->nconv = nconv; break; }
55 }
56 6999 beta = b[nv-1];
57
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&a));
58
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega));
59
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l));
60
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSetState(eps->ds,l?DS_STATE_RAW:DS_STATE_INTERMEDIATE));
61
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(BVSetActiveColumns(eps->V,eps->nconv,nv));
62
63 /* Solve projected problem */
64
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSolve(eps->ds,eps->eigr,eps->eigi));
65
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSort(eps->ds,eps->eigr,eps->eigi,NULL,NULL,NULL));
66
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSUpdateExtraRow(eps->ds));
67
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSSynchronize(eps->ds,eps->eigr,eps->eigi));
68
69 /* Check convergence */
70
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSGetDimensions(eps->ds,NULL,NULL,NULL,&t));
71 #if 0
72 /* take into account also left residual */
73 PetscCall(BVGetColumn(eps->V,nv,&u));
74 PetscCall(VecNorm(u,NORM_2,&beta1));
75 PetscCall(BVRestoreColumn(eps->V,nv,&u));
76 PetscCall(VecNorm(w,NORM_2,&beta2)); /* w contains B*V[nv] */
77 beta1 = PetscMax(beta1,beta2);
78 #endif
79
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,t-eps->nconv,beta*beta1,0.0,1.0,&k));
80
5/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
6999 if (!symmlost) PetscCall((*eps->stopping)(eps,eps->its,eps->max_it,k,eps->nev,&eps->reason,eps->stoppingctx));
81 6999 nconv = k;
82
83 /* Update l */
84
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
6999 if (eps->reason != EPS_CONVERGED_ITERATING || breakdown) l = 0;
85 else {
86 6878 l = PetscMax(1,(PetscInt)((nv-k)*ctx->keep));
87 6878 l = PetscMin(l,t);
88
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(DSGetTruncateSize(eps->ds,k,t,&l));
89 }
90
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6999 if (!ctx->lock && l>0) { l += k; k = 0; } /* non-locking variant: reset no. of converged pairs */
91
6/8
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
6999 if (l) PetscCall(PetscInfo(eps,"Preparing to restart keeping l=%" PetscInt_FMT " vectors\n",l));
92
93
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
6999 if (eps->reason == EPS_CONVERGED_ITERATING) {
94
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6878 PetscCheck(!breakdown,PetscObjectComm((PetscObject)eps),PETSC_ERR_CONV_FAILED,"Breakdown in Indefinite Krylov-Schur (beta=%g)",(double)beta);
95 /* Prepare the Rayleigh quotient for restart */
96
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(DSTruncate(eps->ds,k+l,PETSC_FALSE));
97 }
98 /* Update the corresponding vectors V(:,idx) = V*Q(:,idx) */
99
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSGetMat(eps->ds,DS_MAT_Q,&U));
100
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(BVMultInPlace(eps->V,U,eps->nconv,k+l));
101
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6999 PetscCall(DSRestoreMat(eps->ds,DS_MAT_Q,&U));
102
103 /* Move restart vector and update signature */
104
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
6999 if (eps->reason == EPS_CONVERGED_ITERATING && !breakdown) {
105
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(BVCopyColumn(eps->V,nv,k+l));
106
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(BVSetActiveColumns(eps->V,0,k+l));
107
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
108
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(BVSetSignature(eps->V,vomega));
109
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6878 PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
110 }
111
112 6999 eps->nconv = k;
113
7/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
7120 PetscCall(EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,nv));
114 }
115
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
121 PetscCall(DSTruncate(eps->ds,eps->nconv,PETSC_TRUE));
116
6/12
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
29 PetscFunctionReturn(PETSC_SUCCESS);
117 }
118