GCC Code Coverage Report


Directory: ./
File: src/eps/impls/krylov/lanczos/lanczos.c
Date: 2026-02-22 03:58:10
Exec Total Coverage
Lines: 462 493 93.7%
Functions: 17 18 94.4%
Branches: 925 1596 58.0%

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: "lanczos"
12
13 Method: Explicitly Restarted Symmetric/Hermitian Lanczos
14
15 Algorithm:
16
17 Lanczos method for symmetric (Hermitian) problems, with explicit
18 restart and deflation. Several reorthogonalization strategies can
19 be selected.
20
21 References:
22
23 [1] "Lanczos Methods in SLEPc", SLEPc Technical Report STR-5,
24 available at https://slepc.upv.es.
25 */
26
27 #include <slepc/private/epsimpl.h> /*I "slepceps.h" I*/
28 #include <slepcblaslapack.h>
29
30 typedef struct {
31 EPSLanczosReorthogType reorthog; /* user-provided reorthogonalization parameter */
32 PetscInt allocsize; /* number of columns of work BV's allocated at setup */
33 BV AV; /* work BV used in selective reorthogonalization */
34 } EPS_LANCZOS;
35
36 290 static PetscErrorCode EPSSetUp_Lanczos(EPS eps)
37 {
38 290 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
39 290 BVOrthogRefineType refine;
40 290 BVOrthogBlockType btype;
41 290 PetscReal eta;
42
43
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
290 PetscFunctionBegin;
44
4/10
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
290 EPSCheckHermitianDefinite(eps);
45
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
290 EPSCheckNotStructured(eps);
46
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(EPSSetDimensions_Default(eps,&eps->nev,&eps->ncv,&eps->mpd));
47
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
290 PetscCheck(eps->ncv<=eps->nev+eps->mpd,PetscObjectComm((PetscObject)eps),PETSC_ERR_USER_INPUT,"The value of ncv must not be larger than nev+mpd");
48
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
290 if (eps->max_it==PETSC_DETERMINE) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
49
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
290 if (!eps->which) PetscCall(EPSSetWhichEigenpairs_Default(eps));
50
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
290 PetscCheck(eps->which!=EPS_ALL,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver does not support computing all eigenvalues");
51
9/22
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 8 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 8 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
290 EPSCheckUnsupported(eps,EPS_FEATURE_ARBITRARY | EPS_FEATURE_REGION | EPS_FEATURE_EXTRACTION | EPS_FEATURE_THRESHOLD);
52
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
290 EPSCheckIgnored(eps,EPS_FEATURE_BALANCE);
53
54
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
290 PetscCheck(lanczos->reorthog!=(EPSLanczosReorthogType)-1,PetscObjectComm((PetscObject)eps),PETSC_ERR_USER_INPUT,"You should explicitly provide the reorthogonalization type, e.g., -eps_lanczos_reorthog local. Note that the EPSLANCZOS solver is *NOT RECOMMENDED* for general use, because it uses explicit restart which typically has slow convergence. The recommended solver is EPSKRYLOVSCHUR (the default), which implements Lanczos with thick restart in the case of symmetric/Hermitian problems");
55
56
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(EPSAllocateSolution(eps,1));
57
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(EPS_SetInnerProduct(eps));
58
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
290 if (lanczos->reorthog != EPS_LANCZOS_REORTHOG_FULL) {
59
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
232 PetscCall(BVGetOrthogonalization(eps->V,NULL,&refine,&eta,&btype));
60
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
232 PetscCall(BVSetOrthogonalization(eps->V,BV_ORTHOG_MGS,refine,eta,btype));
61
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
232 PetscCall(PetscInfo(eps,"Switching to MGS orthogonalization\n"));
62 }
63
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
290 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_SELECTIVE) {
64
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
24 if (!lanczos->allocsize) {
65
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
8 PetscCall(BVDuplicate(eps->V,&lanczos->AV));
66
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
8 PetscCall(BVGetSizes(lanczos->AV,NULL,NULL,&lanczos->allocsize));
67 } else { /* make sure V and AV have the same size */
68
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
16 PetscCall(BVGetSizes(eps->V,NULL,NULL,&lanczos->allocsize));
69
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
16 PetscCall(BVResize(lanczos->AV,lanczos->allocsize,PETSC_FALSE));
70 }
71 }
72
73
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(DSSetType(eps->ds,DSHEP));
74
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(DSSetCompact(eps->ds,PETSC_TRUE));
75
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(DSAllocate(eps->ds,eps->ncv+1));
76
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
290 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_LOCAL) PetscCall(EPSSetWorkVecs(eps,1));
77
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.
72 PetscFunctionReturn(PETSC_SUCCESS);
78 }
79
80 /*
81 EPSLocalLanczos - Local reorthogonalization.
82
83 This is the simplest variant. At each Lanczos step, the corresponding Lanczos vector
84 is orthogonalized with respect to the two previous Lanczos vectors, according to
85 the three term Lanczos recurrence. WARNING: This variant does not track the loss of
86 orthogonality that occurs in finite-precision arithmetic and, therefore, the
87 generated vectors are not guaranteed to be (semi-)orthogonal.
88 */
89 4158 static PetscErrorCode EPSLocalLanczos(EPS eps,PetscReal *alpha,PetscReal *beta,PetscInt k,PetscInt *M,PetscBool *breakdown)
90 {
91 4158 PetscInt i,j,m = *M;
92 4158 Mat Op;
93 4158 PetscBool *which,lwhich[100];
94 4158 PetscScalar *hwork,lhwork[100];
95
96
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4158 PetscFunctionBegin;
97
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4158 if (m > 100) PetscCall(PetscMalloc2(m,&which,m,&hwork));
98 else {
99 4158 which = lwhich;
100 4158 hwork = lhwork;
101 }
102
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
14535 for (i=0;i<k;i++) which[i] = PETSC_TRUE;
103
104
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(BVSetActiveColumns(eps->V,0,m));
105
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(STGetOperator(eps->st,&Op));
106
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
60457 for (j=k;j<m;j++) {
107
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
56299 PetscCall(BVMatMultColumn(eps->V,Op,j));
108 56299 which[j] = PETSC_TRUE;
109
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
56299 if (j-2>=k) which[j-2] = PETSC_FALSE;
110
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
56299 PetscCall(BVOrthogonalizeSomeColumn(eps->V,j+1,which,hwork,beta+j,breakdown));
111 56299 alpha[j] = PetscRealPart(hwork[j]);
112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
56299 if (PetscUnlikely(*breakdown)) {
113 *M = j+1;
114 break;
115
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
56299 } else PetscCall(BVScaleColumn(eps->V,j+1,1/beta[j]));
116 }
117
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(STRestoreOperator(eps->st,&Op));
118
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
4158 if (m > 100) PetscCall(PetscFree2(which,hwork));
119
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.
1043 PetscFunctionReturn(PETSC_SUCCESS);
120 }
121
122 /*
123 DenseTridiagonal - Solves a real tridiagonal Hermitian Eigenvalue Problem.
124
125 Input Parameters:
126 + n - dimension of the eigenproblem
127 . D - pointer to the array containing the diagonal elements
128 - E - pointer to the array containing the off-diagonal elements
129
130 Output Parameters:
131 + w - pointer to the array to store the computed eigenvalues
132 - V - pointer to the array to store the eigenvectors
133
134 Notes:
135 If V is NULL then the eigenvectors are not computed.
136
137 This routine use LAPACK routines xSTEVR.
138 */
139 5396 static PetscErrorCode DenseTridiagonal(PetscInt n_,PetscReal *D,PetscReal *E,PetscReal *w,PetscScalar *V)
140 {
141 5396 PetscReal abstol = 0.0,vl,vu,*work;
142 5396 PetscBLASInt il,iu,m,*isuppz,n,lwork,*iwork,liwork,info;
143 5396 const char *jobz;
144 #if defined(PETSC_USE_COMPLEX)
145 2704 PetscInt i,j;
146 2704 PetscReal *VV=NULL;
147 #endif
148
149
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
5396 PetscFunctionBegin;
150
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscBLASIntCast(n_,&n));
151
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscBLASIntCast(20*n_,&lwork));
152
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscBLASIntCast(10*n_,&liwork));
153
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
5396 if (V) {
154 2704 jobz = "V";
155 #if defined(PETSC_USE_COMPLEX)
156
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
2704 PetscCall(PetscMalloc1(n*n,&VV));
157 #endif
158 } else jobz = "N";
159
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscMalloc3(2*n,&isuppz,lwork,&work,liwork,&iwork));
160
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
161 #if defined(PETSC_USE_COMPLEX)
162
10/20
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
2704 PetscCallBLAS("LAPACKstevr",LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,VV,&n,isuppz,work,&lwork,iwork,&liwork,&info));
163 #else
164
10/20
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
2692 PetscCallBLAS("LAPACKstevr",LAPACKstevr_(jobz,"A",&n,D,E,&vl,&vu,&il,&iu,&abstol,&m,w,V,&n,isuppz,work,&lwork,iwork,&liwork,&info));
165 #endif
166
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscFPTrapPop());
167
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5396 SlepcCheckLapackInfo("stevr",info);
168 #if defined(PETSC_USE_COMPLEX)
169
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
2704 if (V) {
170
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
28212 for (i=0;i<n;i++)
171
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
339048 for (j=0;j<n;j++)
172 313540 V[i*n+j] = VV[i*n+j];
173
5/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
2704 PetscCall(PetscFree(VV));
174 }
175 #endif
176
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(PetscFree3(isuppz,work,iwork));
177
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.
1349 PetscFunctionReturn(PETSC_SUCCESS);
178 }
179
180 /*
181 EPSSelectiveLanczos - Selective reorthogonalization.
182 */
183 304 static PetscErrorCode EPSSelectiveLanczos(EPS eps,PetscReal *alpha,PetscReal *beta,PetscInt k,PetscInt *M,PetscBool *breakdown,PetscReal anorm)
184 {
185 304 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
186 304 PetscInt i,j,m = *M,n,nritz=0,nritzo;
187 304 Vec vj1,av;
188 304 Mat Op;
189 304 PetscReal *d,*e,*ritz,norm;
190 304 PetscScalar *Y,*hwork;
191 304 PetscBool *which;
192
193
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
304 PetscFunctionBegin;
194
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(PetscCalloc6(m+1,&d,m,&e,m,&ritz,m*m,&Y,m,&which,m,&hwork));
195
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
684 for (i=0;i<k;i++) which[i] = PETSC_TRUE;
196
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(STGetOperator(eps->st,&Op));
197
198
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5700 for (j=k;j<m;j++) {
199
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(BVSetActiveColumns(eps->V,0,m));
200
201 /* Lanczos step */
202
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(BVMatMultColumn(eps->V,Op,j));
203 5396 which[j] = PETSC_TRUE;
204
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5396 if (j-2>=k) which[j-2] = PETSC_FALSE;
205
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(BVOrthogonalizeSomeColumn(eps->V,j+1,which,hwork,&norm,breakdown));
206 5396 alpha[j] = PetscRealPart(hwork[j]);
207 5396 beta[j] = norm;
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
5396 if (PetscUnlikely(*breakdown)) {
209 *M = j+1;
210 break;
211 }
212
213 /* Compute eigenvalues and eigenvectors Y of the tridiagonal block */
214 5396 n = j-k+1;
215
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
56188 for (i=0;i<n;i++) {
216 50792 d[i] = alpha[i+k];
217 50792 e[i] = beta[i+k];
218 }
219
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(DenseTridiagonal(n,d,e,ritz,Y));
220
221 /* Estimate ||A|| */
222
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
56188 for (i=0;i<n;i++)
223
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
50792 if (PetscAbsReal(ritz[i]) > anorm) anorm = PetscAbsReal(ritz[i]);
224
225 /* Compute nearly converged Ritz vectors */
226 nritzo = 0;
227
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
56188 for (i=0;i<n;i++) {
228
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
50792 if (norm*PetscAbsScalar(Y[i*n+n-1]) < PETSC_SQRT_MACHINE_EPSILON*anorm) nritzo++;
229 }
230
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5396 if (nritzo>nritz) {
231 nritz = 0;
232
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
1424 for (i=0;i<n;i++) {
233
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
1244 if (norm*PetscAbsScalar(Y[i*n+n-1]) < PETSC_SQRT_MACHINE_EPSILON*anorm) {
234
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
276 PetscCall(BVSetActiveColumns(eps->V,k,k+n));
235
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
276 PetscCall(BVGetColumn(lanczos->AV,nritz,&av));
236
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
276 PetscCall(BVMultVec(eps->V,1.0,0.0,av,Y+i*n));
237
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
276 PetscCall(BVRestoreColumn(lanczos->AV,nritz,&av));
238 276 nritz++;
239 }
240 }
241 }
242
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5396 if (nritz > 0) {
243
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2008 PetscCall(BVGetColumn(eps->V,j+1,&vj1));
244
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2008 PetscCall(BVSetActiveColumns(lanczos->AV,0,nritz));
245
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2008 PetscCall(BVOrthogonalizeVec(lanczos->AV,vj1,hwork,&norm,breakdown));
246
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2008 PetscCall(BVRestoreColumn(eps->V,j+1,&vj1));
247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
2008 if (PetscUnlikely(*breakdown)) {
248 *M = j+1;
249 break;
250 }
251 }
252
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
5396 PetscCall(BVScaleColumn(eps->V,j+1,1.0/norm));
253 }
254
255
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(STRestoreOperator(eps->st,&Op));
256
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(PetscFree6(d,e,ritz,Y,which,hwork));
257
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.
76 PetscFunctionReturn(PETSC_SUCCESS);
258 }
259
260 6440 static void update_omega(PetscReal *omega,PetscReal *omega_old,PetscInt j,PetscReal *alpha,PetscReal *beta,PetscReal eps1,PetscReal anorm)
261 {
262 6440 PetscInt k;
263 6440 PetscReal T,binv;
264
265
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
6440 PetscFunctionBegin;
266 /* Estimate of contribution to roundoff errors from A*v
267 fl(A*v) = A*v + f,
268 where ||f|| \approx eps1*||A||.
269 For a full matrix A, a rule-of-thumb estimate is eps1 = sqrt(n)*eps */
270 6440 T = eps1*anorm;
271 6440 binv = 1.0/beta[j+1];
272
273 /* Update omega(1) using omega(0)==0 */
274 6440 omega_old[0]= beta[1]*omega[1] + (alpha[0]-alpha[j])*omega[0] - beta[j]*omega_old[0];
275
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
6440 if (omega_old[0] > 0) omega_old[0] = binv*(omega_old[0] + T);
276 3868 else omega_old[0] = binv*(omega_old[0] - T);
277
278 /* Update remaining components */
279
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
58584 for (k=1;k<j-1;k++) {
280 52144 omega_old[k] = beta[k+1]*omega[k+1] + (alpha[k]-alpha[j])*omega[k] + beta[k]*omega[k-1] - beta[j]*omega_old[k];
281
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
52144 if (omega_old[k] > 0) omega_old[k] = binv*(omega_old[k] + T);
282 27143 else omega_old[k] = binv*(omega_old[k] - T);
283 }
284 6440 omega_old[j-1] = binv*T;
285
286 /* Swap omega and omega_old */
287
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
71320 for (k=0;k<j;k++) {
288 64880 omega[k] = omega_old[k];
289 64880 omega_old[k] = omega[k];
290 }
291 6440 omega[j] = eps1;
292
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.
6440 PetscFunctionReturnVoid();
293 }
294
295 404 static void compute_int(PetscBool *which,PetscReal *mu,PetscInt j,PetscReal delta,PetscReal eta)
296 {
297 404 PetscInt i,k,maxpos;
298 404 PetscReal max;
299 404 PetscBool found;
300
301
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
404 PetscFunctionBegin;
302 /* initialize which */
303 404 found = PETSC_FALSE;
304 404 maxpos = 0;
305 404 max = 0.0;
306
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
6392 for (i=0;i<j;i++) {
307
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5988 if (PetscAbsReal(mu[i]) >= delta) {
308 1456 which[i] = PETSC_TRUE;
309 1456 found = PETSC_TRUE;
310 4532 } else which[i] = PETSC_FALSE;
311
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5988 if (PetscAbsReal(mu[i]) > max) {
312 664 maxpos = i;
313 664 max = PetscAbsReal(mu[i]);
314 }
315 }
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
404 if (!found) which[maxpos] = PETSC_TRUE;
317
318
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
6392 for (i=0;i<j;i++) {
319
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5988 if (which[i]) {
320 /* find left interval */
321
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
5248 for (k=i;k>=0;k--) {
322
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
5248 if (PetscAbsReal(mu[k])<eta || which[k]) break;
323 else which[k] = PETSC_TRUE;
324 }
325 /* find right interval */
326
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
9040 for (k=i+1;k<j;k++) {
327
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
8784 if (PetscAbsReal(mu[k])<eta || which[k]) break;
328 3792 else which[k] = PETSC_TRUE;
329 }
330 }
331 }
332
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.
404 PetscFunctionReturnVoid();
333 }
334
335 /*
336 EPSPartialLanczos - Partial reorthogonalization.
337 */
338 608 static PetscErrorCode EPSPartialLanczos(EPS eps,PetscReal *alpha,PetscReal *beta,PetscInt k,PetscInt *M,PetscBool *breakdown,PetscReal anorm)
339 {
340 608 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
341 608 PetscInt i,j,m = *M;
342 608 Mat Op;
343 608 PetscReal norm,*omega,lomega[100],*omega_old,lomega_old[100],eps1,delta,eta;
344 608 PetscBool *which,lwhich[100],*which2,lwhich2[100];
345 608 PetscBool reorth = PETSC_FALSE,force_reorth = PETSC_FALSE;
346 608 PetscBool fro = PETSC_FALSE,estimate_anorm = PETSC_FALSE;
347 608 PetscScalar *hwork,lhwork[100];
348
349
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
608 PetscFunctionBegin;
350
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
608 if (m>100) PetscCall(PetscMalloc5(m,&omega,m,&omega_old,m,&which,m,&which2,m,&hwork));
351 else {
352 608 omega = lomega;
353 608 omega_old = lomega_old;
354 608 which = lwhich;
355 608 which2 = lwhich2;
356 608 hwork = lhwork;
357 }
358
359 608 eps1 = PetscSqrtReal((PetscReal)eps->n)*PETSC_MACHINE_EPSILON/2;
360 608 delta = PETSC_SQRT_MACHINE_EPSILON/PetscSqrtReal((PetscReal)eps->ncv);
361 608 eta = PetscPowReal(PETSC_MACHINE_EPSILON,3.0/4.0)/PetscSqrtReal((PetscReal)eps->ncv);
362
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
608 if (anorm < 0.0) {
363 48 anorm = 1.0;
364 48 estimate_anorm = PETSC_TRUE;
365 }
366
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
61408 for (i=0;i<PetscMax(100,m);i++) omega[i] = omega_old[i] = 0.0;
367
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
1368 for (i=0;i<k;i++) which[i] = PETSC_TRUE;
368
369
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(BVSetActiveColumns(eps->V,0,m));
370
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(STGetOperator(eps->st,&Op));
371
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
11400 for (j=k;j<m;j++) {
372
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
10792 PetscCall(BVMatMultColumn(eps->V,Op,j));
373
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
10792 if (fro) {
374 /* Lanczos step with full reorthogonalization */
375
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
3744 PetscCall(BVOrthogonalizeColumn(eps->V,j+1,hwork,&norm,breakdown));
376 3744 alpha[j] = PetscRealPart(hwork[j]);
377 } else {
378 /* Lanczos step */
379 7048 which[j] = PETSC_TRUE;
380
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7048 if (j-2>=k) which[j-2] = PETSC_FALSE;
381
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7048 PetscCall(BVOrthogonalizeSomeColumn(eps->V,j+1,which,hwork,&norm,breakdown));
382 7048 alpha[j] = PetscRealPart(hwork[j]);
383 7048 beta[j] = norm;
384
385 /* Estimate ||A|| if needed */
386
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7048 if (estimate_anorm) {
387
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
912 if (j>k) anorm = PetscMax(anorm,PetscAbsReal(alpha[j])+norm+beta[j-1]);
388
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
48 else anorm = PetscMax(anorm,PetscAbsReal(alpha[j])+norm);
389 }
390
391 /* Check if reorthogonalization is needed */
392 7048 reorth = PETSC_FALSE;
393
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7048 if (j>k) {
394 6440 update_omega(omega,omega_old,j,alpha,beta-1,eps1,anorm);
395
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
70360 for (i=0;i<j-k;i++) {
396
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
57480 if (PetscAbsReal(omega[i]) > delta) reorth = PETSC_TRUE;
397 }
398 }
399
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7048 if (reorth || force_reorth) {
400
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
2352 for (i=0;i<k;i++) which2[i] = PETSC_FALSE;
401
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
22232 for (i=k;i<=j;i++) which2[i] = PETSC_TRUE;
402
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
1328 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_PERIODIC) {
403 /* Periodic reorthogonalization */
404
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
656 if (force_reorth) force_reorth = PETSC_FALSE;
405 388 else force_reorth = PETSC_TRUE;
406
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
10304 for (i=0;i<j-k;i++) omega[i] = eps1;
407 } else {
408 /* Partial reorthogonalization */
409
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
672 if (force_reorth) force_reorth = PETSC_FALSE;
410 else {
411 404 force_reorth = PETSC_TRUE;
412 404 compute_int(which2+k,omega,j-k,delta,eta);
413
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
6796 for (i=0;i<j-k;i++) {
414
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
5988 if (which2[i+k]) omega[i] = eps1;
415 }
416 }
417 }
418
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
1328 PetscCall(BVOrthogonalizeSomeColumn(eps->V,j+1,which2,hwork,&norm,breakdown));
419 }
420 }
421
422
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
10792 if (PetscUnlikely(*breakdown || norm < eps->n*anorm*PETSC_MACHINE_EPSILON)) {
423 *M = j+1;
424 break;
425 }
426
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
10792 if (!fro && norm*delta < anorm*eps1) {
427 224 fro = PETSC_TRUE;
428
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
224 PetscCall(PetscInfo(eps,"Switching to full reorthogonalization at iteration %" PetscInt_FMT "\n",eps->its));
429 }
430 10792 beta[j] = norm;
431
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
10792 PetscCall(BVScaleColumn(eps->V,j+1,1.0/norm));
432 }
433
434
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(STRestoreOperator(eps->st,&Op));
435
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
608 if (m>100) PetscCall(PetscFree5(omega,omega_old,which,which2,hwork));
436
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.
152 PetscFunctionReturn(PETSC_SUCCESS);
437 }
438
439 /*
440 EPSBasicLanczos - Computes an m-step Lanczos factorization. The first k
441 columns are assumed to be locked and therefore they are not modified. On
442 exit, the following relation is satisfied:
443
444 OP * V - V * T = f * e_m^T
445
446 where the columns of V are the Lanczos vectors, T is a tridiagonal matrix,
447 f is the residual vector and e_m is the m-th vector of the canonical basis.
448 The Lanczos vectors (together with vector f) are B-orthogonal (to working
449 accuracy) if full reorthogonalization is being used, otherwise they are
450 (B-)semi-orthogonal. On exit, beta contains the B-norm of f and the next
451 Lanczos vector can be computed as v_{m+1} = f / beta.
452
453 This function simply calls another function which depends on the selected
454 reorthogonalization strategy.
455 */
456 7572 static PetscErrorCode EPSBasicLanczos(EPS eps,PetscInt k,PetscInt *m,PetscReal *betam,PetscBool *breakdown,PetscReal anorm)
457 {
458 7572 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
459 7572 PetscScalar *T;
460 7572 PetscInt i,n=*m,ld;
461 7572 PetscReal *alpha,*beta;
462 7572 BVOrthogRefineType orthog_ref;
463 7572 Mat Op,M;
464
465
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
7572 PetscFunctionBegin;
466
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSGetLeadingDimension(eps->ds,&ld));
467
5/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
7572 switch (lanczos->reorthog) {
468 4158 case EPS_LANCZOS_REORTHOG_LOCAL:
469
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&alpha));
470 4158 beta = alpha + ld;
471
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(EPSLocalLanczos(eps,alpha,beta,k,m,breakdown));
472 4158 *betam = beta[*m-1];
473
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4158 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&alpha));
474 break;
475 2302 case EPS_LANCZOS_REORTHOG_FULL:
476
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2302 PetscCall(STGetOperator(eps->st,&Op));
477
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2302 PetscCall(DSGetMat(eps->ds,DS_MAT_T,&M));
478
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2302 PetscCall(BVMatLanczos(eps->V,Op,M,k,m,betam,breakdown));
479
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2302 PetscCall(DSRestoreMat(eps->ds,DS_MAT_T,&M));
480
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2302 PetscCall(STRestoreOperator(eps->st,&Op));
481 break;
482 304 case EPS_LANCZOS_REORTHOG_SELECTIVE:
483
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&alpha));
484 304 beta = alpha + ld;
485
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(EPSSelectiveLanczos(eps,alpha,beta,k,m,breakdown,anorm));
486 304 *betam = beta[*m-1];
487
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
304 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&alpha));
488 break;
489 608 case EPS_LANCZOS_REORTHOG_PERIODIC:
490 case EPS_LANCZOS_REORTHOG_PARTIAL:
491
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&alpha));
492 608 beta = alpha + ld;
493
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(EPSPartialLanczos(eps,alpha,beta,k,m,breakdown,anorm));
494 608 *betam = beta[*m-1];
495
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
608 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&alpha));
496 break;
497 200 case EPS_LANCZOS_REORTHOG_DELAYED:
498
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
200 PetscCall(PetscMalloc1(n*n,&T));
499
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
200 PetscCall(BVGetOrthogonalization(eps->V,NULL,&orthog_ref,NULL,NULL));
500
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
200 if (orthog_ref == BV_ORTHOG_REFINE_NEVER) PetscCall(EPSDelayedArnoldi1(eps,T,n,k,m,betam,breakdown));
501
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
200 else PetscCall(EPSDelayedArnoldi(eps,T,n,k,m,betam,breakdown));
502 200 n = *m;
503
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
200 PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&alpha));
504 200 beta = alpha + ld;
505
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
3500 for (i=k;i<n-1;i++) {
506 3300 alpha[i] = PetscRealPart(T[n*i+i]);
507 3300 beta[i] = PetscRealPart(T[n*i+i+1]);
508 }
509 200 alpha[n-1] = PetscRealPart(T[n*(n-1)+n-1]);
510 200 beta[n-1] = *betam;
511
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
200 PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&alpha));
512
5/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
200 PetscCall(PetscFree(T));
513 break;
514 }
515
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.
1882 PetscFunctionReturn(PETSC_SUCCESS);
516 }
517
518 290 static PetscErrorCode EPSSolve_Lanczos(EPS eps)
519 {
520 290 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
521 290 PetscInt nconv,i,j,k,l,x,n,*perm,restart,ncv=eps->ncv,r,ld;
522 290 Vec vi,vj,w;
523 290 Mat U;
524 290 PetscScalar *Y,*ritz,stmp;
525 290 PetscReal *bnd,anorm,beta,norm,rtmp,resnorm;
526 290 PetscBool breakdown;
527 290 char *conv,ctmp;
528
529
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
290 PetscFunctionBegin;
530
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(DSGetLeadingDimension(eps->ds,&ld));
531
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(PetscMalloc4(ncv,&ritz,ncv,&bnd,ncv,&perm,ncv,&conv));
532
533 /* The first Lanczos vector is the normalized initial vector */
534
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(EPSGetStartVector(eps,0,NULL));
535
536 anorm = -1.0;
537 nconv = 0;
538
539 /* Restart loop */
540 7862 while (eps->reason == EPS_CONVERGED_ITERATING) {
541 7572 eps->its++;
542
543 /* Compute an ncv-step Lanczos factorization */
544 7572 n = PetscMin(nconv+eps->mpd,ncv);
545
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSetDimensions(eps->ds,n,nconv,PETSC_DETERMINE));
546
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(EPSBasicLanczos(eps,nconv,&n,&beta,&breakdown,anorm));
547
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSetDimensions(eps->ds,n,nconv,0));
548
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSetState(eps->ds,DS_STATE_INTERMEDIATE));
549
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(BVSetActiveColumns(eps->V,nconv,n));
550
551 /* Solve projected problem */
552
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSolve(eps->ds,ritz,NULL));
553
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSort(eps->ds,ritz,NULL,NULL,NULL,NULL));
554
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSSynchronize(eps->ds,ritz,NULL));
555
556 /* Estimate ||A|| */
557
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
107775 for (i=nconv;i<n;i++)
558
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
103610 anorm = PetscMax(anorm,PetscAbsReal(PetscRealPart(ritz[i])));
559
560 /* Compute residual norm estimates as beta*abs(Y(m,:)) + eps*||A|| */
561
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSGetArray(eps->ds,DS_MAT_Q,&Y));
562
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
107775 for (i=nconv;i<n;i++) {
563 100203 resnorm = beta*PetscAbsScalar(Y[n-1+i*ld]) + PETSC_MACHINE_EPSILON*anorm;
564
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
100203 PetscCall((*eps->converged)(eps,ritz[i],eps->eigi[i],resnorm,&bnd[i],eps->convergedctx));
565
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
100203 if (bnd[i]<eps->tol) conv[i] = 'C';
566 98851 else conv[i] = 'N';
567 }
568
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSRestoreArray(eps->ds,DS_MAT_Q,&Y));
569
570 /* purge repeated ritz values */
571
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7572 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_LOCAL) {
572
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
56299 for (i=nconv+1;i<n;i++) {
573
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
52141 if (conv[i] == 'C' && PetscAbsScalar((ritz[i]-ritz[i-1])/ritz[i]) < eps->tol) conv[i] = 'R';
574 }
575 }
576
577 /* Compute restart vector */
578
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
7572 if (breakdown) PetscCall(PetscInfo(eps,"Breakdown in Lanczos method (it=%" PetscInt_FMT " norm=%g)\n",eps->its,(double)beta));
579 else {
580 restart = nconv;
581
3/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
8744 while (restart<n && conv[restart] != 'N') restart++;
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
7564 if (restart >= n) {
583 breakdown = PETSC_TRUE;
584 } else {
585
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
98879 for (i=restart+1;i<n;i++) {
586
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
91315 if (conv[i] == 'N') {
587
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
91287 PetscCall(SlepcSCCompare(eps->sc,ritz[restart],0.0,ritz[i],0.0,&r));
588
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
91287 if (r>0) restart = i;
589 }
590 }
591
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7564 PetscCall(DSGetArray(eps->ds,DS_MAT_Q,&Y));
592
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7564 PetscCall(BVMultColumn(eps->V,1.0,0.0,n,Y+restart*ld+nconv));
593
4/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
7564 PetscCall(DSRestoreArray(eps->ds,DS_MAT_Q,&Y));
594 }
595 }
596
597 /* Count and put converged eigenvalues first */
598
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
107775 for (i=nconv;i<n;i++) perm[i] = i;
599
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
8904 for (k=nconv;k<n;k++) {
600
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
8896 if (conv[perm[k]] != 'C') {
601 7586 j = k + 1;
602
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
98921 while (j<n && conv[perm[j]] != 'C') j++;
603
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7586 if (j>=n) break;
604 22 l = perm[k]; perm[k] = perm[j]; perm[j] = l;
605 }
606 }
607
608 /* Sort eigenvectors according to permutation */
609
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSGetArray(eps->ds,DS_MAT_Q,&Y));
610
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
8904 for (i=nconv;i<k;i++) {
611 1332 x = perm[i];
612
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
1332 if (x != i) {
613 22 j = i + 1;
614
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
50 while (perm[j] != i) j++;
615 /* swap eigenvalues i and j */
616 22 stmp = ritz[x]; ritz[x] = ritz[i]; ritz[i] = stmp;
617 22 rtmp = bnd[x]; bnd[x] = bnd[i]; bnd[i] = rtmp;
618 22 ctmp = conv[x]; conv[x] = conv[i]; conv[i] = ctmp;
619 22 perm[j] = x; perm[i] = i;
620 /* swap eigenvectors i and j */
621
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
440 for (l=0;l<n;l++) {
622 418 stmp = Y[l+x*ld]; Y[l+x*ld] = Y[l+i*ld]; Y[l+i*ld] = stmp;
623 }
624 }
625 }
626
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSRestoreArray(eps->ds,DS_MAT_Q,&Y));
627
628 /* compute converged eigenvectors */
629
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSGetMat(eps->ds,DS_MAT_Q,&U));
630
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(BVMultInPlace(eps->V,U,nconv,k));
631
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(DSRestoreMat(eps->ds,DS_MAT_Q,&U));
632
633 /* purge spurious ritz values */
634
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7572 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_LOCAL) {
635
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
4754 for (i=nconv;i<k;i++) {
636
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(BVGetColumn(eps->V,i,&vi));
637
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(VecNorm(vi,NORM_2,&norm));
638
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(VecScale(vi,1.0/norm));
639 596 w = eps->work[0];
640
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(STApply(eps->st,vi,w));
641
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(VecAXPY(w,-ritz[i],vi));
642
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(BVRestoreColumn(eps->V,i,&vi));
643
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall(VecNorm(w,NORM_2,&norm));
644
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
596 PetscCall((*eps->converged)(eps,ritz[i],eps->eigi[i],norm,&bnd[i],eps->convergedctx));
645
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
596 if (bnd[i]>=eps->tol) conv[i] = 'S';
646 }
647
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
4750 for (i=nconv;i<k;i++) {
648
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
596 if (conv[i] != 'C') {
649 4 j = i + 1;
650
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 while (j<k && conv[j] != 'C') j++;
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (j>=k) break;
652 /* swap eigenvalues i and j */
653 stmp = ritz[j]; ritz[j] = ritz[i]; ritz[i] = stmp;
654 rtmp = bnd[j]; bnd[j] = bnd[i]; bnd[i] = rtmp;
655 ctmp = conv[j]; conv[j] = conv[i]; conv[i] = ctmp;
656 /* swap eigenvectors i and j */
657 PetscCall(BVGetColumn(eps->V,i,&vi));
658 PetscCall(BVGetColumn(eps->V,j,&vj));
659 PetscCall(VecSwap(vi,vj));
660 PetscCall(BVRestoreColumn(eps->V,i,&vi));
661
0/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
592 PetscCall(BVRestoreColumn(eps->V,j,&vj));
662 }
663 }
664 k = i;
665 }
666
667 /* store ritz values and estimated errors */
668
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
107775 for (i=nconv;i<n;i++) {
669 100203 eps->eigr[i] = ritz[i];
670 100203 eps->errest[i] = bnd[i];
671 }
672 7572 nconv = k;
673
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall(EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,n));
674
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7572 PetscCall((*eps->stopping)(eps,eps->its,eps->max_it,nconv,eps->nev,&eps->reason,eps->stoppingctx));
675
676
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
7572 if (eps->reason == EPS_CONVERGED_ITERATING) { /* copy restart vector */
677
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
7282 PetscCall(BVCopyColumn(eps->V,n,nconv));
678
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
7282 if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_LOCAL && !breakdown) {
679 /* Reorthonormalize restart vector */
680
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
4014 PetscCall(BVOrthonormalizeColumn(eps->V,nconv,PETSC_FALSE,NULL,&breakdown));
681 }
682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
7282 if (breakdown) {
683 /* Use random vector for restarting */
684 PetscCall(PetscInfo(eps,"Using random vector for restart\n"));
685 PetscCall(EPSGetStartVector(eps,nconv,&breakdown));
686 }
687
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
7282 if (PetscUnlikely(breakdown)) { /* give up */
688 eps->reason = EPS_DIVERGED_BREAKDOWN;
689
4/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
7862 PetscCall(PetscInfo(eps,"Unable to generate more start vectors\n"));
690 }
691 }
692 }
693 290 eps->nconv = nconv;
694
695
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
290 PetscCall(PetscFree4(ritz,bnd,perm,conv));
696
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.
72 PetscFunctionReturn(PETSC_SUCCESS);
697 }
698
699 146 static PetscErrorCode EPSSetFromOptions_Lanczos(EPS eps,PetscOptionItems PetscOptionsObject)
700 {
701 146 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
702 146 PetscBool flg;
703 146 EPSLanczosReorthogType reorthog=EPS_LANCZOS_REORTHOG_LOCAL,curval;
704
705
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
146 PetscFunctionBegin;
706
1/12
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
146 PetscOptionsHeadBegin(PetscOptionsObject,"EPS Lanczos Options");
707
708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
146 curval = (lanczos->reorthog==(EPSLanczosReorthogType)-1)? EPS_LANCZOS_REORTHOG_LOCAL: lanczos->reorthog;
709
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
146 PetscCall(PetscOptionsEnum("-eps_lanczos_reorthog","Lanczos reorthogonalization","EPSLanczosSetReorthog",EPSLanczosReorthogTypes,(PetscEnum)curval,(PetscEnum*)&reorthog,&flg));
710
5/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
146 if (flg) PetscCall(EPSLanczosSetReorthog(eps,reorthog));
711
712
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
146 PetscOptionsHeadEnd();
713
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.
36 PetscFunctionReturn(PETSC_SUCCESS);
714 }
715
716 154 static PetscErrorCode EPSLanczosSetReorthog_Lanczos(EPS eps,EPSLanczosReorthogType reorthog)
717 {
718 154 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
719
720
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
154 PetscFunctionBegin;
721
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
154 switch (reorthog) {
722 154 case EPS_LANCZOS_REORTHOG_LOCAL:
723 case EPS_LANCZOS_REORTHOG_FULL:
724 case EPS_LANCZOS_REORTHOG_DELAYED:
725 case EPS_LANCZOS_REORTHOG_SELECTIVE:
726 case EPS_LANCZOS_REORTHOG_PERIODIC:
727 case EPS_LANCZOS_REORTHOG_PARTIAL:
728
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
154 if (lanczos->reorthog != reorthog) {
729 154 lanczos->reorthog = reorthog;
730 154 eps->state = EPS_STATE_INITIAL;
731 }
732 38 break;
733 default:
734 SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid reorthogonalization type");
735 }
736
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.
38 PetscFunctionReturn(PETSC_SUCCESS);
737 }
738
739 /*@
740 EPSLanczosSetReorthog - Sets the type of reorthogonalization used during the Lanczos
741 iteration.
742
743 Logically Collective
744
745 Input Parameters:
746 + eps - the linear eigensolver context
747 - reorthog - the type of reorthogonalization, see `EPSLanczosReorthogType` for possible values
748
749 Options Database Key:
750 . -eps_lanczos_reorthog \<reorthog\> - sets the reorthogonalization type
751
752 Notes:
753 Details of the different reorthogonalization strategies can be found in
754 {cite:p}`Her06`.
755
756 This applies to `EPSLANCZOS`, not to `EPSKRYLOVSCHUR`.
757
758 Level: advanced
759
760 .seealso: [](ch:eps), `EPSLANCZOS`, `EPSLanczosGetReorthog()`, `EPSLanczosReorthogType`
761 @*/
762 154 PetscErrorCode EPSLanczosSetReorthog(EPS eps,EPSLanczosReorthogType reorthog)
763 {
764
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
154 PetscFunctionBegin;
765
3/16
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
154 PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
766
27/62
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 2 times.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✓ Branch 32 taken 2 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 2 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✓ Branch 41 taken 2 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 2 times.
✓ Branch 46 taken 2 times.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 2 times.
✓ Branch 50 taken 2 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 2 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 2 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✓ Branch 59 taken 2 times.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
154 PetscValidLogicalCollectiveEnum(eps,reorthog,2);
767
8/14
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
154 PetscTryMethod(eps,"EPSLanczosSetReorthog_C",(EPS,EPSLanczosReorthogType),(eps,reorthog));
768
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.
154 PetscFunctionReturn(PETSC_SUCCESS);
769 }
770
771 40 static PetscErrorCode EPSLanczosGetReorthog_Lanczos(EPS eps,EPSLanczosReorthogType *reorthog)
772 {
773 40 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
774
775
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
40 PetscFunctionBegin;
776 40 *reorthog = lanczos->reorthog;
777
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.
40 PetscFunctionReturn(PETSC_SUCCESS);
778 }
779
780 /*@
781 EPSLanczosGetReorthog - Gets the type of reorthogonalization used during
782 the Lanczos iteration.
783
784 Not Collective
785
786 Input Parameter:
787 . eps - the linear eigensolver context
788
789 Output Parameter:
790 . reorthog - the type of reorthogonalization
791
792 Level: advanced
793
794 .seealso: [](ch:eps), `EPSLANCZOS`, `EPSLanczosSetReorthog()`, `EPSLanczosReorthogType`
795 @*/
796 40 PetscErrorCode EPSLanczosGetReorthog(EPS eps,EPSLanczosReorthogType *reorthog)
797 {
798
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
40 PetscFunctionBegin;
799
3/16
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
40 PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
800
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40 PetscAssertPointer(reorthog,2);
801
9/16
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
40 PetscUseMethod(eps,"EPSLanczosGetReorthog_C",(EPS,EPSLanczosReorthogType*),(eps,reorthog));
802
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.
40 PetscFunctionReturn(PETSC_SUCCESS);
803 }
804
805 178 static PetscErrorCode EPSReset_Lanczos(EPS eps)
806 {
807 178 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
808
809
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
178 PetscFunctionBegin;
810
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
178 PetscCall(BVDestroy(&lanczos->AV));
811 178 lanczos->allocsize = 0;
812
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.
178 PetscFunctionReturn(PETSC_SUCCESS);
813 }
814
815 154 static PetscErrorCode EPSDestroy_Lanczos(EPS eps)
816 {
817
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
154 PetscFunctionBegin;
818
5/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
154 PetscCall(PetscFree(eps->data));
819
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
154 PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSLanczosSetReorthog_C",NULL));
820
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
154 PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSLanczosGetReorthog_C",NULL));
821
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.
38 PetscFunctionReturn(PETSC_SUCCESS);
822 }
823
824 static PetscErrorCode EPSView_Lanczos(EPS eps,PetscViewer viewer)
825 {
826 EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data;
827 PetscBool isascii;
828
829 PetscFunctionBegin;
830 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
831 if (isascii) {
832 if (lanczos->reorthog != (EPSLanczosReorthogType)-1) PetscCall(PetscViewerASCIIPrintf(viewer," %s reorthogonalization\n",EPSLanczosReorthogTypes[lanczos->reorthog]));
833 }
834 PetscFunctionReturn(PETSC_SUCCESS);
835 }
836
837 /*MC
838 EPSLANCZOS - EPSLANCZOS = "lanczos" - A basic Krylov method for Hermitian
839 problems, with explicit restart.
840
841 Notes:
842 This solver is very basic and is not recommended in general, since it
843 will not be competitive with respect to other solvers.
844
845 The implemented method is Lanczos with explicit restart and deflation.
846 Generally, it is much better to use Lanczos with implicit restart (also
847 known as thick-restart Lanczos) as implemented in `EPSKRYLOVSCHUR`.
848
849 Several reorthogonalization strategies can be selected with `EPSLanczosSetReorthog()`.
850 Some of them may result in a cheaper computation, but it will seldom be
851 enough to beat `EPSKRYLOVSCHUR`.
852
853 Level: beginner
854
855 .seealso: [](ch:eps), `EPS`, `EPSType`, `EPSSetType()`, `EPSLanczosSetReorthog()`
856 M*/
857 154 SLEPC_EXTERN PetscErrorCode EPSCreate_Lanczos(EPS eps)
858 {
859 154 EPS_LANCZOS *ctx;
860
861
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
154 PetscFunctionBegin;
862
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
154 PetscCall(PetscNew(&ctx));
863 154 eps->data = (void*)ctx;
864 154 ctx->reorthog = (EPSLanczosReorthogType)-1;
865
866 154 eps->useds = PETSC_TRUE;
867
868 154 eps->ops->solve = EPSSolve_Lanczos;
869 154 eps->ops->setup = EPSSetUp_Lanczos;
870 154 eps->ops->setupsort = EPSSetUpSort_Default;
871 154 eps->ops->setfromoptions = EPSSetFromOptions_Lanczos;
872 154 eps->ops->destroy = EPSDestroy_Lanczos;
873 154 eps->ops->reset = EPSReset_Lanczos;
874 154 eps->ops->view = EPSView_Lanczos;
875 154 eps->ops->backtransform = EPSBackTransform_Default;
876 154 eps->ops->computevectors = EPSComputeVectors_Hermitian;
877
878
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
154 PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSLanczosSetReorthog_C",EPSLanczosSetReorthog_Lanczos));
879
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
154 PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSLanczosGetReorthog_C",EPSLanczosGetReorthog_Lanczos));
880
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.
38 PetscFunctionReturn(PETSC_SUCCESS);
881 }
882