GCC Code Coverage Report


Directory: ./
File: src/svd/impls/lanczos/gklanczos.c
Date: 2026-10-22 02:08:06
Exec Total Coverage
Lines: 239 265 90.2%
Functions: 12 13 92.3%
Branches: 688 1260 54.6%

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 singular value solver: "lanczos"
12
13 Method: Explicitly restarted Lanczos
14
15 Algorithm:
16
17 Golub-Kahan-Lanczos bidiagonalization with explicit restart.
18
19 References:
20
21 [1] G.H. Golub and W. Kahan, "Calculating the singular values
22 and pseudo-inverse of a matrix", SIAM J. Numer. Anal. Ser.
23 B 2:205-224, 1965.
24
25 [2] V. Hernandez, J.E. Roman, and A. Tomas, "A robust and
26 efficient parallel SVD solver based on restarted Lanczos
27 bidiagonalization", Elec. Trans. Numer. Anal. 31:68-85,
28 2008.
29 */
30
31 #include <slepc/private/svdimpl.h> /*I "slepcsvd.h" I*/
32
33 typedef struct {
34 PetscBool oneside;
35 } SVD_LANCZOS;
36
37 204 static PetscErrorCode SVDSetUp_Lanczos(SVD svd)
38 {
39 204 SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
40 204 PetscInt N;
41
42
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
204 PetscFunctionBegin;
43
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
204 SVDCheckStandard(svd);
44
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
204 SVDCheckDefinite(svd);
45
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.
204 PetscCall(MatGetSize(svd->A,NULL,&N));
46
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.
204 PetscCall(SVDSetDimensions_Default(svd));
47
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
204 PetscCheck(svd->ncv<=svd->nsv+svd->mpd,PetscObjectComm((PetscObject)svd),PETSC_ERR_USER_INPUT,"The value of ncv must not be larger than nev+mpd");
48
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5 times.
303 if (svd->max_it==PETSC_DETERMINE) svd->max_it = PetscMax(N/svd->ncv,100)*((svd->stop==SVD_STOP_THRESHOLD)?10:1);
49 204 svd->leftbasis = PetscNot(lanczos->oneside);
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.
204 PetscCall(SVDAllocateSolution(svd,1));
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.
204 PetscCall(DSSetType(svd->ds,DSSVD));
52
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.
204 PetscCall(DSSetCompact(svd->ds,PETSC_TRUE));
53
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.
204 PetscCall(DSSetExtraRow(svd->ds,PETSC_TRUE));
54
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.
204 PetscCall(DSAllocate(svd->ds,svd->ncv+1));
55
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
38 PetscFunctionReturn(PETSC_SUCCESS);
56 }
57
58 13760 PetscErrorCode SVDTwoSideLanczos(SVD svd,PetscReal *alpha,PetscReal *beta,BV V,BV U,PetscInt k,PetscInt *n,PetscBool *breakdown)
59 {
60 13760 PetscInt i;
61 13760 Vec u,v;
62 13760 PetscBool lindep=PETSC_FALSE;
63
64
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
13760 PetscFunctionBegin;
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.
13760 PetscCall(BVGetColumn(svd->V,k,&v));
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.
13760 PetscCall(BVGetColumn(svd->U,k,&u));
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.
13760 PetscCall(MatMult(svd->A,v,u));
68
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.
13760 PetscCall(BVRestoreColumn(svd->V,k,&v));
69
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.
13760 PetscCall(BVRestoreColumn(svd->U,k,&u));
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.
13760 PetscCall(BVOrthonormalizeColumn(svd->U,k,PETSC_FALSE,alpha+k,&lindep));
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
13760 if (PetscUnlikely(lindep)) {
72 ✗ *n = k;
73 ✗ if (breakdown) *breakdown = lindep;
74 ✗ PetscFunctionReturn(PETSC_SUCCESS);
75 }
76
77
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
96165 for (i=k+1;i<*n;i++) {
78
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.
82405 PetscCall(BVGetColumn(svd->V,i,&v));
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.
82405 PetscCall(BVGetColumn(svd->U,i-1,&u));
80
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.
82405 PetscCall(MatMult(svd->AT,u,v));
81
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.
82405 PetscCall(BVRestoreColumn(svd->V,i,&v));
82
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.
82405 PetscCall(BVRestoreColumn(svd->U,i-1,&u));
83
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.
82405 PetscCall(BVOrthonormalizeColumn(svd->V,i,PETSC_FALSE,beta+i-1,&lindep));
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
82405 if (PetscUnlikely(lindep)) {
85 ✗ *n = i;
86 ✗ break;
87 }
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.
82405 PetscCall(BVGetColumn(svd->V,i,&v));
89
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.
82405 PetscCall(BVGetColumn(svd->U,i,&u));
90
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.
82405 PetscCall(MatMult(svd->A,v,u));
91
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.
82405 PetscCall(BVRestoreColumn(svd->V,i,&v));
92
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.
82405 PetscCall(BVRestoreColumn(svd->U,i,&u));
93
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.
82405 PetscCall(BVOrthonormalizeColumn(svd->U,i,PETSC_FALSE,alpha+i,&lindep));
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
82405 if (PetscUnlikely(lindep)) {
95 ✗ *n = i;
96 ✗ break;
97 }
98 }
99
100
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
13760 if (!lindep) {
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.
13760 PetscCall(BVGetColumn(svd->V,*n,&v));
102
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.
13760 PetscCall(BVGetColumn(svd->U,*n-1,&u));
103
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.
13760 PetscCall(MatMult(svd->AT,u,v));
104
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.
13760 PetscCall(BVRestoreColumn(svd->V,*n,&v));
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.
13760 PetscCall(BVRestoreColumn(svd->U,*n-1,&u));
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.
13760 PetscCall(BVOrthogonalizeColumn(svd->V,*n,NULL,beta+*n-1,&lindep));
107 }
108
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
13760 if (breakdown) *breakdown = lindep;
109
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
2396 PetscFunctionReturn(PETSC_SUCCESS);
110 }
111
112 688 static PetscErrorCode SVDOneSideLanczos(SVD svd,PetscReal *alpha,PetscReal *beta,BV V,Vec u,Vec u_1,PetscInt k,PetscInt n,PetscScalar* work)
113 {
114 688 PetscInt i,bvl,bvk;
115 688 PetscReal a,b;
116 688 Vec z,temp;
117
118
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
688 PetscFunctionBegin;
119
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.
688 PetscCall(BVGetActiveColumns(V,&bvl,&bvk));
120
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.
688 PetscCall(BVGetColumn(V,k,&z));
121
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.
688 PetscCall(MatMult(svd->A,z,u));
122
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.
688 PetscCall(BVRestoreColumn(V,k,&z));
123
124
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
5980 for (i=k+1;i<n;i++) {
125
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.
5292 PetscCall(BVGetColumn(V,i,&z));
126
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.
5292 PetscCall(MatMult(svd->AT,u,z));
127
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.
5292 PetscCall(BVRestoreColumn(V,i,&z));
128
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.
5292 PetscCall(VecNormBegin(u,NORM_2,&a));
129
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.
5292 PetscCall(BVSetActiveColumns(V,0,i));
130
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.
5292 PetscCall(BVDotColumnBegin(V,i,work));
131
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.
5292 PetscCall(VecNormEnd(u,NORM_2,&a));
132
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.
5292 PetscCall(BVDotColumnEnd(V,i,work));
133
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.
5292 PetscCall(VecScale(u,1.0/a));
134
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.
5292 PetscCall(BVMultColumn(V,-1.0/a,1.0/a,i,work));
135
136 /* h = V^* z, z = z - V h */
137
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.
5292 PetscCall(BVDotColumn(V,i,work));
138
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.
5292 PetscCall(BVMultColumn(V,-1.0,1.0,i,work));
139
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.
5292 PetscCall(BVNormColumn(V,i,NORM_2,&b));
140
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5292 PetscCheck(PetscAbsReal(b)>10*PETSC_MACHINE_EPSILON,PetscObjectComm((PetscObject)svd),PETSC_ERR_PLIB,"Recurrence generated a zero vector; use a two-sided variant");
141
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.
5292 PetscCall(BVScaleColumn(V,i,1.0/b));
142
143
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.
5292 PetscCall(BVGetColumn(V,i,&z));
144
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.
5292 PetscCall(MatMult(svd->A,z,u_1));
145
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.
5292 PetscCall(BVRestoreColumn(V,i,&z));
146
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.
5292 PetscCall(VecAXPY(u_1,-b,u));
147 5292 alpha[i-1] = a;
148 5292 beta[i-1] = b;
149 5292 temp = u;
150 5292 u = u_1;
151 5292 u_1 = temp;
152 }
153
154
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.
688 PetscCall(BVGetColumn(V,n,&z));
155
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.
688 PetscCall(MatMult(svd->AT,u,z));
156
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.
688 PetscCall(BVRestoreColumn(V,n,&z));
157
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.
688 PetscCall(VecNormBegin(u,NORM_2,&a));
158
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.
688 PetscCall(BVDotColumnBegin(V,n,work));
159
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.
688 PetscCall(VecNormEnd(u,NORM_2,&a));
160
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.
688 PetscCall(BVDotColumnEnd(V,n,work));
161
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.
688 PetscCall(VecScale(u,1.0/a));
162
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.
688 PetscCall(BVMultColumn(V,-1.0/a,1.0/a,n,work));
163
164 /* h = V^* z, z = z - V h */
165
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.
688 PetscCall(BVDotColumn(V,n,work));
166
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.
688 PetscCall(BVMultColumn(V,-1.0,1.0,n,work));
167
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.
688 PetscCall(BVNormColumn(V,i,NORM_2,&b));
168
169 688 alpha[n-1] = a;
170 688 beta[n-1] = b;
171
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.
688 PetscCall(BVSetActiveColumns(V,bvl,bvk));
172
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
108 PetscFunctionReturn(PETSC_SUCCESS);
173 }
174
175 /*
176 SVDKrylovConvergence - Implements the loop that checks for convergence
177 in Krylov methods.
178
179 Input Parameters:
180 svd - the solver; some error estimates are updated in svd->errest
181 getall - whether all residuals must be computed
182 kini - initial value of k (the loop variable)
183 nits - number of iterations of the loop
184 normr - norm of triangular factor of qr([A;B]), used only in GSVD
185
186 Output Parameter:
187 kout - the first index where the convergence test failed
188 */
189 25876 PetscErrorCode SVDKrylovConvergence(SVD svd,PetscBool getall,PetscInt kini,PetscInt nits,PetscReal normr,PetscInt *kout)
190 {
191 25876 PetscInt k,marker,ld;
192 25876 PetscReal *alpha,*beta,*betah,resnorm;
193 25876 PetscBool extra;
194
195
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
25876 PetscFunctionBegin;
196
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
25876 if (PetscUnlikely(svd->conv == SVD_CONV_MAXIT && svd->its >= svd->max_it)) *kout = svd->nsv;
197 else {
198
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.
25876 PetscCall(DSGetLeadingDimension(svd->ds,&ld));
199
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.
25876 PetscCall(DSGetExtraRow(svd->ds,&extra));
200
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
25876 PetscCheck(extra,PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"Only implemented for DS with extra row");
201 25876 marker = -1;
202
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
25876 if (svd->trackall) getall = PETSC_TRUE;
203
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.
25876 PetscCall(DSGetArrayReal(svd->ds,DS_MAT_T,&alpha));
204 25876 beta = alpha + ld;
205 25876 betah = alpha + 2*ld;
206
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
32637 for (k=kini;k<kini+nits;k++) {
207
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
32588 if (svd->isgeneralized) resnorm = SlepcAbs(beta[k],betah[k])*normr;
208 21416 else resnorm = PetscAbsReal(beta[k]);
209
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.
32588 PetscCall((*svd->converged)(svd,svd->sigma[k],resnorm,&svd->errest[k],svd->convergedctx));
210
3/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 10 times.
32588 if (marker==-1 && svd->errest[k] >= svd->tol) marker = k;
211
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
32588 if (marker!=-1 && !getall) break;
212 }
213
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.
25876 PetscCall(DSRestoreArrayReal(svd->ds,DS_MAT_T,&alpha));
214
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
25876 if (marker!=-1) k = marker;
215 25876 *kout = k;
216 }
217
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
4830 PetscFunctionReturn(PETSC_SUCCESS);
218 }
219
220 204 static PetscErrorCode SVDSolve_Lanczos(SVD svd)
221 {
222 204 SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
223 204 PetscReal *alpha,*beta;
224 204 PetscScalar *swork,*w,*P,*aux1,*aux2;
225 204 PetscInt i,k,j,nv,ld;
226 204 Vec u=NULL,u_1=NULL;
227 204 Mat U,V;
228
229
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
204 PetscFunctionBegin;
230 /* allocate working space */
231
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.
204 PetscCall(DSGetLeadingDimension(svd->ds,&ld));
232
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.
204 PetscCall(PetscMalloc2(ld,&w,svd->ncv,&swork));
233
234
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
204 if (lanczos->oneside) {
235
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.
24 PetscCall(MatCreateVecs(svd->A,NULL,&u));
236
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.
24 PetscCall(MatCreateVecs(svd->A,NULL,&u_1));
237 }
238
239 /* normalize start vector */
240
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
204 if (!svd->nini) {
241
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.
156 PetscCall(BVSetRandomColumn(svd->V,0));
242
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.
156 PetscCall(BVOrthonormalizeColumn(svd->V,0,PETSC_TRUE,NULL,NULL));
243 }
244
245 6462 while (svd->reason == SVD_CONVERGED_ITERATING) {
246 6258 svd->its++;
247
248 /* inner loop */
249 6258 nv = PetscMin(svd->nconv+svd->mpd,svd->ncv);
250
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.
6258 PetscCall(DSGetArrayReal(svd->ds,DS_MAT_T,&alpha));
251 6258 beta = alpha + ld;
252
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.
6258 if (lanczos->oneside) PetscCall(SVDOneSideLanczos(svd,alpha,beta,svd->V,u,u_1,svd->nconv,nv,swork));
253 else {
254
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.
5570 PetscCall(SVDTwoSideLanczos(svd,alpha,beta,svd->V,svd->U,svd->nconv,&nv,NULL));
255
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.
5570 PetscCall(BVSetActiveColumns(svd->U,svd->nconv,nv));
256 }
257
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.
6258 PetscCall(DSRestoreArrayReal(svd->ds,DS_MAT_T,&alpha));
258
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.
6258 PetscCall(BVSetActiveColumns(svd->V,svd->nconv,nv));
259
260 /* compute SVD of bidiagonal matrix */
261
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.
6258 PetscCall(DSSetDimensions(svd->ds,nv,svd->nconv,0));
262
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.
6258 PetscCall(DSSVDSetDimensions(svd->ds,nv));
263
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.
6258 PetscCall(DSSetState(svd->ds,DS_STATE_INTERMEDIATE));
264
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.
6258 PetscCall(DSSolve(svd->ds,w,NULL));
265
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.
6258 PetscCall(DSSort(svd->ds,w,NULL,NULL,NULL,NULL));
266
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.
6258 PetscCall(DSUpdateExtraRow(svd->ds));
267
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.
6258 PetscCall(DSSynchronize(svd->ds,w,NULL));
268
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
65625 for (i=svd->nconv;i<nv;i++) svd->sigma[i] = PetscRealPart(w[i]);
269
270 /* check convergence */
271
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.
6258 PetscCall(SVDKrylovConvergence(svd,PETSC_FALSE,svd->nconv,nv-svd->nconv,1.0,&k));
272
5/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
6258 SVDSetCtxThreshold(svd,svd->sigma,svd->errest,k,nv);
273
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.
6258 PetscCall((*svd->stopping)(svd,svd->its,svd->max_it,k,svd->nsv,&svd->reason,svd->stoppingctx));
274
275 /* compute restart vector */
276
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
6258 if (svd->reason == SVD_CONVERGED_ITERATING) {
277
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
6054 if (k<nv) {
278
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.
6054 PetscCall(DSGetArray(svd->ds,DS_MAT_V,&P));
279
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
63617 for (j=svd->nconv;j<nv;j++) swork[j-svd->nconv] = PetscConj(P[j+k*ld]);
280
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.
6054 PetscCall(DSRestoreArray(svd->ds,DS_MAT_V,&P));
281
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.
6054 PetscCall(BVMultColumn(svd->V,1.0,0.0,nv,swork));
282 } else {
283 /* all approximations have converged, generate a new initial vector */
284 ✗ PetscCall(BVSetRandomColumn(svd->V,nv));
285 ✗ PetscCall(BVOrthonormalizeColumn(svd->V,nv,PETSC_FALSE,NULL,NULL));
286 }
287 }
288
289 /* compute converged singular vectors */
290
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.
6258 PetscCall(DSGetMat(svd->ds,DS_MAT_V,&V));
291
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.
6258 PetscCall(BVMultInPlace(svd->V,V,svd->nconv,k));
292
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.
6258 PetscCall(DSRestoreMat(svd->ds,DS_MAT_V,&V));
293
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
6258 if (!lanczos->oneside) {
294
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.
5570 PetscCall(DSGetMat(svd->ds,DS_MAT_U,&U));
295
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.
5570 PetscCall(BVMultInPlace(svd->U,U,svd->nconv,k));
296
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.
5570 PetscCall(DSRestoreMat(svd->ds,DS_MAT_U,&U));
297 }
298
299
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
6258 if (svd->reason == SVD_CONVERGED_ITERATING) {
300
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.
6054 PetscCall(BVCopyColumn(svd->V,nv,k)); /* copy restart vector from the last column */
301
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
6054 if (svd->stop==SVD_STOP_THRESHOLD && nv-k<5) { /* reallocate */
302 ✗ svd->ncv = svd->mpd+k;
303 ✗ PetscCall(SVDReallocateSolution(svd,svd->ncv+1));
304 ✗ for (i=nv;i<svd->ncv;i++) svd->perm[i] = i;
305 ✗ PetscCall(DSReallocate(svd->ds,svd->ncv+1));
306 ✗ aux1 = w;
307 ✗ aux2 = swork;
308 ✗ PetscCall(PetscMalloc2(svd->ncv+1,&w,svd->ncv,&swork));
309 ✗ PetscCall(PetscArraycpy(w,aux1,ld));
310 ✗ PetscCall(PetscFree2(aux1,aux2));
311 ✗ PetscCall(DSGetLeadingDimension(svd->ds,&ld));
312 }
313 }
314
315 6258 svd->nconv = k;
316
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.
6462 PetscCall(SVDMonitor(svd,svd->its,svd->nconv,svd->sigma,svd->errest,nv));
317 }
318
319 /* free working space */
320
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.
204 PetscCall(VecDestroy(&u));
321
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.
204 PetscCall(VecDestroy(&u_1));
322
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.
204 PetscCall(PetscFree2(w,swork));
323
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
38 PetscFunctionReturn(PETSC_SUCCESS);
324 }
325
326 144 static PetscErrorCode SVDSetFromOptions_Lanczos(SVD svd,PetscOptionItems PetscOptionsObject)
327 {
328 144 PetscBool set,val;
329 144 SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
330
331
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
144 PetscFunctionBegin;
332
1/12
✗ Branch 0 not taken.
✓ Branch 1 taken 10 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.
144 PetscOptionsHeadBegin(PetscOptionsObject,"SVD Lanczos Options");
333
334
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.
144 PetscCall(PetscOptionsBool("-svd_lanczos_oneside","Use one-side reorthogonalization","SVDLanczosSetOneSide",lanczos->oneside,&val,&set));
335
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.
144 if (set) PetscCall(SVDLanczosSetOneSide(svd,val));
336
337
1/16
✗ 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.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
144 PetscOptionsHeadEnd();
338
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
26 PetscFunctionReturn(PETSC_SUCCESS);
339 }
340
341 24 static PetscErrorCode SVDLanczosSetOneSide_Lanczos(SVD svd,PetscBool oneside)
342 {
343 24 SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
344
345
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
24 PetscFunctionBegin;
346
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
24 if (lanczos->oneside != oneside) {
347 24 lanczos->oneside = oneside;
348 24 svd->state = SVD_STATE_INITIAL;
349 }
350
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
24 PetscFunctionReturn(PETSC_SUCCESS);
351 }
352
353 /*@
354 SVDLanczosSetOneSide - Indicate if the variant of the Lanczos method
355 to be used is one-sided or two-sided.
356
357 Logically Collective
358
359 Input Parameters:
360 + svd - the singular value solver context
361 - oneside - boolean flag indicating if the method is one-sided or not
362
363 Options Database Key:
364 . -svd_lanczos_oneside (true|false) - enable the one-sided variant
365
366 Note:
367 By default, a two-sided variant is selected, which is sometimes slightly
368 more robust. However, the one-sided variant is faster because it avoids
369 the orthogonalization associated to left singular vectors. It also saves
370 the memory required for storing such vectors. See more details in
371 {cite:p}`Her07c,Her08`.
372
373 Level: advanced
374
375 .seealso: [](ch:svd), `SVDTRLANCZOS`, `SVDTRLanczosSetOneSide()`
376 @*/
377 24 PetscErrorCode SVDLanczosSetOneSide(SVD svd,PetscBool oneside)
378 {
379
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
24 PetscFunctionBegin;
380
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.
24 PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
381
31/70
✓ 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 not taken.
✓ Branch 9 taken 2 times.
✓ 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.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ 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 not taken.
✓ Branch 35 taken 2 times.
✓ Branch 36 taken 2 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 2 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 2 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 2 times.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✓ Branch 47 taken 2 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 2 times.
✓ Branch 52 taken 2 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 2 times.
✓ Branch 56 taken 2 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 2 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 2 times.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✓ Branch 63 taken 2 times.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 67 taken 2 times.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
24 PetscValidLogicalCollectiveBool(svd,oneside,2);
382
8/14
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 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.
24 PetscTryMethod(svd,"SVDLanczosSetOneSide_C",(SVD,PetscBool),(svd,oneside));
383
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
24 PetscFunctionReturn(PETSC_SUCCESS);
384 }
385
386 20 static PetscErrorCode SVDLanczosGetOneSide_Lanczos(SVD svd,PetscBool *oneside)
387 {
388 20 SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
389
390
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
20 PetscFunctionBegin;
391 20 *oneside = lanczos->oneside;
392
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
20 PetscFunctionReturn(PETSC_SUCCESS);
393 }
394
395 /*@
396 SVDLanczosGetOneSide - Gets if the variant of the Lanczos method
397 to be used is one-sided or two-sided.
398
399 Not Collective
400
401 Input Parameter:
402 . svd - the singular value solver context
403
404 Output Parameter:
405 . oneside - boolean flag indicating if the method is one-sided or not
406
407 Level: advanced
408
409 .seealso: [](ch:svd), `SVDTRLANCZOS`, `SVDLanczosSetOneSide()`
410 @*/
411 20 PetscErrorCode SVDLanczosGetOneSide(SVD svd,PetscBool *oneside)
412 {
413
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
20 PetscFunctionBegin;
414
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.
20 PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
415
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.
20 PetscAssertPointer(oneside,2);
416
9/16
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 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.
20 PetscUseMethod(svd,"SVDLanczosGetOneSide_C",(SVD,PetscBool*),(svd,oneside));
417
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
20 PetscFunctionReturn(PETSC_SUCCESS);
418 }
419
420 164 static PetscErrorCode SVDDestroy_Lanczos(SVD svd)
421 {
422
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
164 PetscFunctionBegin;
423
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 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.
164 PetscCall(PetscFree(svd->data));
424
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.
164 PetscCall(PetscObjectComposeFunction((PetscObject)svd,"SVDLanczosSetOneSide_C",NULL));
425
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.
164 PetscCall(PetscObjectComposeFunction((PetscObject)svd,"SVDLanczosGetOneSide_C",NULL));
426
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
30 PetscFunctionReturn(PETSC_SUCCESS);
427 }
428
429 ✗ static PetscErrorCode SVDView_Lanczos(SVD svd,PetscViewer viewer)
430 {
431 ✗ SVD_LANCZOS *lanczos = (SVD_LANCZOS*)svd->data;
432 ✗ PetscBool isascii;
433
434 ✗ PetscFunctionBegin;
435 ✗ PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
436 ✗ if (isascii) PetscCall(PetscViewerASCIIPrintf(viewer," %s-sided reorthogonalization\n",lanczos->oneside? "one": "two"));
437 ✗ PetscFunctionReturn(PETSC_SUCCESS);
438 }
439
440 /*MC
441 SVDLANCZOS - SVDLANCZOS = "lanczos" - A basic Golub-Kahan-Lanczos
442 bidiagonalization method with explicit restart.
443
444 Notes:
445 Only available for standard SVD problems.
446
447 This solver is very basic and is not recommended in general, since it
448 will not be competitive with respect to other solvers.
449
450 The implemented method is Lanczos bidiagonalization with explicit restart
451 and deflation. Generally, it is much better to use Lanczos with implicit
452 restart (also known as thick-restart Lanczos) as implemented in `SVDTRLANCZOS`.
453
454 The implementation includes a one-sided orthogonalization option, and
455 efficient parallel orthogonalization, see the details in {cite:p}`Her07c,Her08`.
456
457 Level: beginner
458
459 .seealso: [](ch:svd), [](#sec:svdback), `SVD`, `SVDType`, `SVDSetType()`, `SVDSetProblemType()`, `SVDTRLANCZOS`
460 M*/
461 164 SLEPC_EXTERN PetscErrorCode SVDCreate_Lanczos(SVD svd)
462 {
463 164 SVD_LANCZOS *ctx;
464
465
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
164 PetscFunctionBegin;
466
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.
164 PetscCall(PetscNew(&ctx));
467 164 svd->data = (void*)ctx;
468
469 164 svd->ops->setup = SVDSetUp_Lanczos;
470 164 svd->ops->solve = SVDSolve_Lanczos;
471 164 svd->ops->destroy = SVDDestroy_Lanczos;
472 164 svd->ops->setfromoptions = SVDSetFromOptions_Lanczos;
473 164 svd->ops->view = SVDView_Lanczos;
474 164 svd->ops->computevectors = SVDComputeVectors_Left;
475
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.
164 PetscCall(PetscObjectComposeFunction((PetscObject)svd,"SVDLanczosSetOneSide_C",SVDLanczosSetOneSide_Lanczos));
476
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.
164 PetscCall(PetscObjectComposeFunction((PetscObject)svd,"SVDLanczosGetOneSide_C",SVDLanczosGetOneSide_Lanczos));
477
7/14
✓ 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 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
30 PetscFunctionReturn(PETSC_SUCCESS);
478 }
479