38 int LanTrbounds(
int lanm,
int maxit,
double tol,
double *vinit,
40 double *lammin,
double *lammax, FILE *fstats) {
42 double lmin=0.0, lmax=0.0, t, t1, t2;
56 maxit =
min(maxit, n);
58 size_t lanm1_l = lanm1;
63 double done=1.0, dmone=-1.0, dzero=0.0;
69 fprintf(fstats,
" LanTR for bounds: dim %d, maxits %d\n", lanm, maxit);
74 int min_inner_step = 5;
79 Malloc(V, n_l*lanm1,
double);
83 Malloc(Z, n_l*lanm1,
double);
88 Calloc(T, lanm1_l*lanm1_l,
double);
92 double *Rval, *Rvec, *BRvec=NULL;
93 Malloc(Rval, lanm,
double);
95 Malloc(Rvec, n_l*2,
double);
97 Malloc(BRvec, n_l*2,
double);
101 Malloc(EvecT, lanm1_l*lanm1_l,
double);
106 size_t work_size = 2*n_l;
107 Malloc(work, work_size,
double);
109 DCOPY(&n, vinit, &one, V, &one);
114 t = 1.0 / sqrt(
DDOT(&n, V, &one, Z, &one));
116 DSCAL(&n, &t, Z, &one);
119 t = 1.0 /
DNRM2(&n, V, &one);
122 DSCAL(&n, &t, V, &one);
131 int k = trlen > 0 ? trlen + 1 : 0;
134 if (k+min_inner_step > lanm1) {
135 fprintf(stderr,
"Krylov dim too small for this problem. Try a larger dim\n");
142 double *v = &V[k1*n_l];
143 double *z = &Z[k1*n_l];
145 double *vnew = v + n;
146 double *znew = z + n;
151 for (i=0; i<trlen; i++) {
152 T[i*lanm1_l+i] = Rval[i];
156 s[k1] =
DDOT(&n, v, &one, znew, &one);
158 DGEMV(&cN, &n, &k, &dmone, Z, &n, s, &one, &done, znew, &one);
161 for (i=0; i<k1; i++) {
162 T[trlen*lanm1_l+i] = s[i];
163 T[i*lanm1_l+trlen] = s[i];
164 wn += 2.0 * fabs(s[i]);
166 T[trlen*lanm1_l+trlen] = s[k1];
172 beta = sqrt(
DDOT(&n, vnew, &one, znew, &one));
175 beta =
DNRM2(&n, vnew, &one);
185 matvec_B(vnew, znew);
186 beta = sqrt(
DDOT(&n, vnew, &one, znew, &one));
187 double ibeta = 1.0 / beta;
188 DSCAL(&n, &ibeta, vnew, &one);
189 DSCAL(&n, &ibeta, znew, &one);
195 double ibeta = 1.0 / beta;
196 DSCAL(&n, &ibeta, vnew, &one);
201 double ibeta = 1.0 / beta;
202 DSCAL(&n, &ibeta, vnew, &one);
204 DSCAL(&n, &ibeta, znew, &one);
208 T[k1*lanm1_l+k] = beta;
209 T[k*lanm1_l+k1] = beta;
215 double *zold = k > 0 ? Z+(k-1)*n_l : NULL;
219 while (k < lanm && it < maxit) {
222 double *v = &V[(k-1)*n_l];
223 double *z = &Z[(k-1)*n_l];
225 double *vnew = v + n;
226 double *znew = z + n;
232 double nbeta = -beta;
233 DAXPY(&n, &nbeta, zold, &one, znew, &one);
236 double alpha =
DDOT(&n, v, &one, znew, &one);
238 T[(k-1)*lanm1_l+(k-1)] = alpha;
241 double nalpha = -alpha;
242 DAXPY(&n, &nalpha, z, &one, znew, &one);
250 beta = sqrt(
DDOT(&n, vnew, &one, znew, &one));
263 fprintf(fstats,
"it %4d: Lucky breakdown, beta = %.15e\n", it, beta);
270 matvec_B(vnew, znew);
271 beta = sqrt(
DDOT(&n, vnew, &one, znew, &one));
272 double ibeta = 1.0 / beta;
273 DSCAL(&n, &ibeta, vnew, &one);
274 DSCAL(&n, &ibeta, znew, &one);
280 double ibeta = 1.0 / beta;
281 DSCAL(&n, &ibeta, vnew, &one);
286 double ibeta = 1.0 / beta;
287 DSCAL(&n, &ibeta, vnew, &one);
290 DSCAL(&n, &ibeta, znew, &one);
294 T[k*lanm1_l+(k-1)] = beta;
295 T[(k-1)*lanm1_l+k] = beta;
306 s[0] = beta * EvecT[k-1];
307 s[1] = beta * EvecT[(k-1)*lanm1_l+(k-1)];
315 t1 = 2.0*s[0]*s[0] / (Rval[1] - Rval[0]);
316 t2 = 2.0*s[1]*s[1] / (Rval[k-1] - Rval[k-2]);
319 lmax = Rval[k-1] + t2;
323 DGEMV(&cN, &n, &k, &done, V, &n, EvecT, &one, &dzero, Rvec, &one);
324 DGEMV(&cN, &n, &k, &done, V, &n, EvecT+(k-1)*lanm1_l, &one, &dzero, Rvec+n, &one);
326 DGEMV(&cN, &n, &k, &done, Z, &n, EvecT, &one, &dzero, BRvec, &one);
327 DGEMV(&cN, &n, &k, &done, Z, &n, EvecT+(k-1)*lanm1_l, &one, &dzero, BRvec+n, &one);
331 for (i=0; i<2; i++) {
332 double *y = Rvec + i*n_l;
333 DCOPY(&n, y, &one, V+i*n_l, &one);
335 double *By = BRvec + i*n_l;
336 DCOPY(&n, By, &one, Z+i*n_l, &one);
344 double *w2 = work + n;
346 for (i=0; i<2; i++) {
347 double *y = Rvec + i*n_l;
348 double nt = -Rval[i];
352 DAXPY(&n, &nt, w2, &one, w1, &one);
354 rr[i] = sqrt(
DDOT(&n, w1, &one, w2, &one));
356 DAXPY(&n, &nt, y, &one, w1, &one);
357 rr[i] =
DNRM2(&n, w1, &one);
361 fprintf(fstats,
"it %4d, k %3d: ritz %.15e %.15e, t1,t2 %e %e, res %.15e %.15e, comp res %.15e %.15e\n",
362 it, k, Rval[0], Rval[1], t1, t2, fabs(s[0]), fabs(s[1]), rr[0], rr[1]);
366 fprintf(fstats,
"it %4d, k %3d: ritz %.15e %.15e, t1,t2 %e %e, res %.15e %.15e\n",
367 it, k, Rval[0], Rval[1], t1, t2, fabs(s[0]), fabs(s[1]));
371 if (t1+t2 < tol*(fabs(lmin)+fabs(lmax))) {
375 memset(T, 0, lanm1_l*lanm1_l*
sizeof(
double));
377 DCOPY(&n, V+k*n_l, &one, V+trlen*n_l, &one);
379 DCOPY(&n, Z+k*n_l, &one, Z+trlen*n_l, &one);
void SymEigenSolver(int n, double *A, int lda, double *Q, int ldq, double *lam)
interface to LAPACK SYMMETRIC EIGEN-SOLVER
double DDOT(int *n, double *x, int *incx, double *y, int *incy)
void rand_double(int n, double *v)
void CGS_DGKS(int n, int k, int i_max, double *Q, double *v, double *nrmv, double *w)
Classical GS reortho with Daniel, Gragg, Kaufman, Stewart test.
int LanTrbounds(int lanm, int maxit, double tol, double *vinit, int bndtype, double *lammin, double *lammax, FILE *fstats)
Lanczos process for eigenvalue bounds [Thick restart version].
void DSCAL(int *n, double *a, double *x, int *incx)
#define Calloc(base, nmem, type)
This file contains function prototypes and constant definitions internally used in EVSL...
#define Malloc(base, nmem, type)
void DGEMV(char *trans, int *m, int *n, double *alpha, double *a, int *lda, double *x, int *incx, double *beta, double *y, int *incy)
void CGS_DGKS2(int n, int k, int i_max, double *Z, double *Q, double *v, double *w)
Classical GS reortho. No test. just do i_max times used in generalized ev problems.
void DAXPY(int *n, double *alpha, double *x, int *incx, double *y, int *incy)
double DNRM2(int *n, double *x, int *incx)
Defs for blaslapack routines.
evslData evsldata
global variable of EVSL
void DCOPY(int *n, double *dx, int *incx, double *dy, int *incy)