Actual source code: cgeig.c
1: /*
2: Code for calculating extreme eigenvalues via the Lanczos method
3: running with CG. Note this only works for symmetric real and Hermitian
4: matrices (not complex matrices that are symmetric).
5: */
6: #include <../src/ksp/ksp/impls/cg/cgimpl.h>
7: #include <../include/petscblaslapack.h>
9: PetscErrorCode KSPComputeEigenvalues_CG(KSP ksp, PetscInt nmax, PetscReal *r, PetscReal *c, PetscInt *neig)
10: {
11: KSP_CG *cgP = (KSP_CG *)ksp->data;
12: PetscScalar *d, *e;
13: PetscReal *ee;
14: PetscInt n = ksp->its;
15: PetscBLASInt bn, ldz = 1;
17: PetscFunctionBegin;
18: PetscCheck(nmax >= n, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_SIZ, "Not enough room in work space r and c for eigenvalues");
19: *neig = n;
21: PetscCall(PetscArrayzero(c, nmax));
22: if (!n) PetscFunctionReturn(PETSC_SUCCESS);
23: d = cgP->d;
24: e = cgP->e;
25: ee = cgP->ee;
27: /* copy tridiagonal matrix to work space */
28: for (PetscInt j = 0; j < n; j++) {
29: r[j] = PetscRealPart(d[j]);
30: ee[j] = PetscRealPart(e[j + 1]);
31: }
33: PetscCall(PetscBLASIntCast(n, &bn));
34: PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
35: PetscCallLAPACKInfo("LAPACKREALstev", LAPACKREALstev_("N", &bn, r, ee, NULL, &ldz, NULL, &info));
36: PetscCall(PetscFPTrapPop());
37: PetscCall(PetscSortReal(n, r));
38: PetscFunctionReturn(PETSC_SUCCESS);
39: }
41: PetscErrorCode KSPComputeExtremeSingularValues_CG(KSP ksp, PetscReal *emax, PetscReal *emin)
42: {
43: KSP_CG *cgP = (KSP_CG *)ksp->data;
44: PetscScalar *d, *e;
45: PetscReal *dd, *ee;
46: PetscInt n = ksp->its;
47: PetscBLASInt bn, ldz = 1;
49: PetscFunctionBegin;
50: if (!n) {
51: *emax = *emin = 1.0;
52: PetscFunctionReturn(PETSC_SUCCESS);
53: }
54: d = cgP->d;
55: e = cgP->e;
56: dd = cgP->dd;
57: ee = cgP->ee;
59: /* copy tridiagonal matrix to work space */
60: for (PetscInt j = 0; j < n; j++) {
61: dd[j] = PetscRealPart(d[j]);
62: ee[j] = PetscRealPart(e[j + 1]);
63: }
65: PetscCall(PetscBLASIntCast(n, &bn));
66: PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
67: PetscCallLAPACKInfo("LAPACKREALstev", LAPACKREALstev_("N", &bn, dd, ee, NULL, &ldz, NULL, &info));
68: PetscCall(PetscFPTrapPop());
69: *emin = dd[0];
70: *emax = dd[n - 1];
71: PetscFunctionReturn(PETSC_SUCCESS);
72: }