1 /* arpack/dgetv0.f -- translated by f2c (version 20090411).
2 You must link the resulting object file with libf2c:
3 on Microsoft Windows system, link with libf2c.lib;
4 on Linux or Unix systems, link with .../path/to/libf2c.a -lm
5 or, if you install libf2c.a in a standard place, with -lf2c -lm
6 -- in that order, at the end of the command line, as in
7 cc *.o -lf2c -lm
8 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
9
10 http://www.netlib.org/f2c/libf2c.zip
11 */
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 #include "v3p_netlib.h"
17
18 /* Common Block Declarations */
19
20 /*Extern struct { */
21 /* integer logfil, ndigit, mgetv0, msaupd, msaup2, msaitr, mseigt, msapps, */
22 /* msgets, mseupd, mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, */
23 /* mneupd, mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd; */
24 /*} debug_; */
25
26 /*#define debug_1 debug_ */
27
28 /*Extern struct { */
29 /* integer nopx, nbx, nrorth, nitref, nrstrt; */
30 /* real tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv, tnaupd, */
31 /* tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv, tcaupd, tcaup2, */
32 /* tcaitr, tceigh, tcgets, tcapps, tcconv, tmvopx, tmvbx, tgetv0, */
33 /* titref, trvec; */
34 /*} timing_; */
35
36 /*#define timing_1 timing_ */
37
38 /* Table of constant values */
39
40 static integer c__1 = 1;
41 static doublereal c_b24 = 1.;
42 static doublereal c_b26 = 0.;
43 static doublereal c_b29 = -1.;
44
45 /* ----------------------------------------------------------------------- */
46 /* \BeginDoc */
47
48 /* \Name: dgetv0 */
49
50 /* \Description: */
51 /* Generate a random initial residual vector for the Arnoldi process. */
52 /* Force the residual vector to be in the range of the operator OP. */
53
54 /* \Usage: */
55 /* call dgetv0 */
56 /* ( IDO, BMAT, ITRY, INITV, N, J, V, LDV, RESID, RNORM, */
57 /* IPNTR, WORKD, IERR ) */
58
59 /* \Arguments */
60 /* IDO Integer. (INPUT/OUTPUT) */
61 /* Reverse communication flag. IDO must be zero on the first */
62 /* call to dgetv0. */
63 /* ------------------------------------------------------------- */
64 /* IDO = 0: first call to the reverse communication interface */
65 /* IDO = -1: compute Y = OP * X where */
66 /* IPNTR(1) is the pointer into WORKD for X, */
67 /* IPNTR(2) is the pointer into WORKD for Y. */
68 /* This is for the initialization phase to force the */
69 /* starting vector into the range of OP. */
70 /* IDO = 2: compute Y = B * X where */
71 /* IPNTR(1) is the pointer into WORKD for X, */
72 /* IPNTR(2) is the pointer into WORKD for Y. */
73 /* IDO = 99: done */
74 /* ------------------------------------------------------------- */
75
76 /* BMAT Character*1. (INPUT) */
77 /* BMAT specifies the type of the matrix B in the (generalized) */
78 /* eigenvalue problem A*x = lambda*B*x. */
79 /* B = 'I' -> standard eigenvalue problem A*x = lambda*x */
80 /* B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x */
81
82 /* ITRY Integer. (INPUT) */
83 /* ITRY counts the number of times that dgetv0 is called. */
84 /* It should be set to 1 on the initial call to dgetv0. */
85
86 /* INITV Logical variable. (INPUT) */
87 /* .TRUE. => the initial residual vector is given in RESID. */
88 /* .FALSE. => generate a random initial residual vector. */
89
90 /* N Integer. (INPUT) */
91 /* Dimension of the problem. */
92
93 /* J Integer. (INPUT) */
94 /* Index of the residual vector to be generated, with respect to */
95 /* the Arnoldi process. J > 1 in case of a "restart". */
96
97 /* V Double precision N by J array. (INPUT) */
98 /* The first J-1 columns of V contain the current Arnoldi basis */
99 /* if this is a "restart". */
100
101 /* LDV Integer. (INPUT) */
102 /* Leading dimension of V exactly as declared in the calling */
103 /* program. */
104
105 /* RESID Double precision array of length N. (INPUT/OUTPUT) */
106 /* Initial residual vector to be generated. If RESID is */
107 /* provided, force RESID into the range of the operator OP. */
108
109 /* RNORM Double precision scalar. (OUTPUT) */
110 /* B-norm of the generated residual. */
111
112 /* IPNTR Integer array of length 3. (OUTPUT) */
113
114 /* WORKD Double precision work array of length 2*N. (REVERSE COMMUNICATION). */
115 /* On exit, WORK(1:N) = B*RESID to be used in SSAITR. */
116
117 /* IERR Integer. (OUTPUT) */
118 /* = 0: Normal exit. */
119 /* = -1: Cannot generate a nontrivial restarted residual vector */
120 /* in the range of the operator OP. */
121
122 /* \EndDoc */
123
124 /* ----------------------------------------------------------------------- */
125
126 /* \BeginLib */
127
128 /* \Local variables: */
129 /* xxxxxx real */
130
131 /* \References: */
132 /* 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in */
133 /* a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), */
134 /* pp 357-385. */
135 /* 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly */
136 /* Restarted Arnoldi Iteration", Rice University Technical Report */
137 /* TR95-13, Department of Computational and Applied Mathematics. */
138
139 /* \Routines called: */
140 /* second ARPACK utility routine for timing. */
141 /* dlarnv LAPACK routine for generating a random vector. */
142 /* dgemv Level 2 BLAS routine for matrix vector multiplication. */
143 /* dcopy Level 1 BLAS that copies one vector to another. */
144 /* ddot Level 1 BLAS that computes the scalar product of two vectors. */
145 /* dnrm2 Level 1 BLAS that computes the norm of a vector. */
146
147 /* \Author */
148 /* Danny Sorensen Phuong Vu */
149 /* Richard Lehoucq CRPC / Rice University */
150 /* Dept. of Computational & Houston, Texas */
151 /* Applied Mathematics */
152 /* Rice University */
153 /* Houston, Texas */
154
155 /* \SCCS Information: @(#) */
156 /* FILE: getv0.F SID: 2.6 DATE OF SID: 8/27/96 RELEASE: 2 */
157
158 /* \EndLib */
159
160 /* ----------------------------------------------------------------------- */
161
162 /*< >*/
dgetv0_(integer * ido,char * bmat,integer * itry,logical * initv,integer * n,integer * j,doublereal * v,integer * ldv,doublereal * resid,doublereal * rnorm,integer * ipntr,doublereal * workd,integer * ierr,ftnlen bmat_len)163 /* Subroutine */ int dgetv0_(integer *ido, char *bmat, integer *itry, logical
164 *initv, integer *n, integer *j, doublereal *v, integer *ldv,
165 doublereal *resid, doublereal *rnorm, integer *ipntr, doublereal *
166 workd, integer *ierr, ftnlen bmat_len)
167 {
168 /* Initialized data */
169
170 static logical inits = TRUE_;
171
172 /* System generated locals */
173 integer v_dim1, v_offset, i__1;
174
175 /* Builtin functions */
176 double sqrt(doublereal);
177
178 /* Local variables */
179 /* static real t0, t1, t2, t3; */
180 integer jj;
181 extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
182 integer *);
183 static integer iter;
184 static logical orth;
185 extern doublereal dnrm2_(integer *, doublereal *, integer *);
186 static integer iseed[4];
187 extern /* Subroutine */ int dgemv_(char *, integer *, integer *,
188 doublereal *, doublereal *, integer *, doublereal *, integer *,
189 doublereal *, doublereal *, integer *, ftnlen);
190 integer idist;
191 extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
192 doublereal *, integer *);
193 static logical first;
194 static doublereal rnorm0;
195 /* static integer msglvl; */
196 extern /* Subroutine */ int dlarnv_(integer *, integer *, integer *,
197 doublereal *);
198
199
200 /* %----------------------------------------------------% */
201 /* | Include files for debugging and timing information | */
202 /* %----------------------------------------------------% */
203
204 /*< include 'debug.h' >*/
205 /*< include 'stat.h' >*/
206
207 /* \SCCS Information: @(#) */
208 /* FILE: debug.h SID: 2.3 DATE OF SID: 11/16/95 RELEASE: 2 */
209
210 /* %---------------------------------% */
211 /* | See debug.doc for documentation | */
212 /* %---------------------------------% */
213 /*< >*/
214 /*< character bmat*1 >*/
215
216 /* %------------------% */
217 /* | Scalar Arguments | */
218 /* %------------------% */
219
220 /* %--------------------------------% */
221 /* | See stat.doc for documentation | */
222 /* %--------------------------------% */
223
224 /* \SCCS Information: @(#) */
225 /* FILE: stat.h SID: 2.2 DATE OF SID: 11/16/95 RELEASE: 2 */
226
227 /*< save t0, t1, t2, t3, t4, t5 >*/
228
229 /*< integer nopx, nbx, nrorth, nitref, nrstrt >*/
230 /*< >*/
231 /*< >*/
232 /*< logical initv >*/
233 /*< integer ido, ierr, itry, j, ldv, n >*/
234 /*< >*/
235
236 /* %-----------------% */
237 /* | Array Arguments | */
238 /* %-----------------% */
239
240 /*< integer ipntr(3) >*/
241 /*< >*/
242
243 /* %------------% */
244 /* | Parameters | */
245 /* %------------% */
246
247 /*< >*/
248 /*< parameter (one = 1.0D+0, zero = 0.0D+0) >*/
249
250 /* %------------------------% */
251 /* | Local Scalars & Arrays | */
252 /* %------------------------% */
253
254 /*< logical first, inits, orth >*/
255 /*< integer idist, iseed(4), iter, msglvl, jj >*/
256 /*< >*/
257 /*< save first, iseed, inits, iter, msglvl, orth, rnorm0 >*/
258
259 /* %----------------------% */
260 /* | External Subroutines | */
261 /* %----------------------% */
262
263 /*< external dlarnv, dcopy, dgemv, second >*/
264
265 /* %--------------------% */
266 /* | External Functions | */
267 /* %--------------------% */
268
269 /*< >*/
270 /*< external ddot, dnrm2 >*/
271
272 /* %---------------------% */
273 /* | Intrinsic Functions | */
274 /* %---------------------% */
275
276 /*< intrinsic abs, sqrt >*/
277
278 /* %-----------------% */
279 /* | Data Statements | */
280 /* %-----------------% */
281
282 /*< data inits /.true./ >*/
283 /* Parameter adjustments */
284 --workd;
285 --resid;
286 v_dim1 = *ldv;
287 v_offset = 1 + v_dim1;
288 v -= v_offset;
289 --ipntr;
290
291 /* Function Body */
292
293 /* %-----------------------% */
294 /* | Executable Statements | */
295 /* %-----------------------% */
296
297
298 /* %-----------------------------------% */
299 /* | Initialize the seed of the LAPACK | */
300 /* | random number generator | */
301 /* %-----------------------------------% */
302
303 /*< if (inits) then >*/
304 if (inits) {
305 /*< iseed(1) = 1 >*/
306 iseed[0] = 1;
307 /*< iseed(2) = 3 >*/
308 iseed[1] = 3;
309 /*< iseed(3) = 5 >*/
310 iseed[2] = 5;
311 /*< iseed(4) = 7 >*/
312 iseed[3] = 7;
313 /*< inits = .false. >*/
314 inits = FALSE_;
315 /*< end if >*/
316 }
317
318 /*< if (ido .eq. 0) then >*/
319 if (*ido == 0) {
320
321 /* %-------------------------------% */
322 /* | Initialize timing statistics | */
323 /* | & message level for debugging | */
324 /* %-------------------------------% */
325
326 /*< call second (t0) >*/
327 /* second_(&t0); */
328 /*< msglvl = mgetv0 >*/
329 /* msglvl = debug_1.mgetv0; */
330
331 /*< ierr = 0 >*/
332 *ierr = 0;
333 /*< iter = 0 >*/
334 iter = 0;
335 /*< first = .FALSE. >*/
336 first = FALSE_;
337 /*< orth = .FALSE. >*/
338 orth = FALSE_;
339
340 /* %-----------------------------------------------------% */
341 /* | Possibly generate a random starting vector in RESID | */
342 /* | Use a LAPACK random number generator used by the | */
343 /* | matrix generation routines. | */
344 /* | idist = 1: uniform (0,1) distribution; | */
345 /* | idist = 2: uniform (-1,1) distribution; | */
346 /* | idist = 3: normal (0,1) distribution; | */
347 /* %-----------------------------------------------------% */
348
349 /*< if (.not.initv) then >*/
350 if (! (*initv)) {
351 /*< idist = 2 >*/
352 idist = 2;
353 /*< call dlarnv (idist, iseed, n, resid) >*/
354 dlarnv_(&idist, iseed, n, &resid[1]);
355 /*< end if >*/
356 }
357
358 /* %----------------------------------------------------------% */
359 /* | Force the starting vector into the range of OP to handle | */
360 /* | the generalized problem when B is possibly (singular). | */
361 /* %----------------------------------------------------------% */
362
363 /*< call second (t2) >*/
364 /* second_(&t2); */
365 /*< if (bmat .eq. 'G') then >*/
366 if (*(unsigned char *)bmat == 'G') {
367 /*< nopx = nopx + 1 >*/
368 /* ++timing_1.nopx; */
369 /*< ipntr(1) = 1 >*/
370 ipntr[1] = 1;
371 /*< ipntr(2) = n + 1 >*/
372 ipntr[2] = *n + 1;
373 /*< call dcopy (n, resid, 1, workd, 1) >*/
374 dcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
375 /*< ido = -1 >*/
376 *ido = -1;
377 /*< go to 9000 >*/
378 goto L9000;
379 /*< end if >*/
380 }
381 /*< end if >*/
382 }
383
384 /* %-----------------------------------------% */
385 /* | Back from computing OP*(initial-vector) | */
386 /* %-----------------------------------------% */
387
388 /*< if (first) go to 20 >*/
389 if (first) {
390 goto L20;
391 }
392
393 /* %-----------------------------------------------% */
394 /* | Back from computing B*(orthogonalized-vector) | */
395 /* %-----------------------------------------------% */
396
397 /*< if (orth) go to 40 >*/
398 if (orth) {
399 goto L40;
400 }
401
402 /*< if (bmat .eq. 'G') then >*/
403 if (*(unsigned char *)bmat == 'G') {
404 /*< call second (t3) >*/
405 /* second_(&t3); */
406 /*< tmvopx = tmvopx + (t3 - t2) >*/
407 /* timing_1.tmvopx += t3 - t2; */
408 /*< end if >*/
409 }
410
411 /* %------------------------------------------------------% */
412 /* | Starting vector is now in the range of OP; r = OP*r; | */
413 /* | Compute B-norm of starting vector. | */
414 /* %------------------------------------------------------% */
415
416 /*< call second (t2) >*/
417 /* second_(&t2); */
418 /*< first = .TRUE. >*/
419 first = TRUE_;
420 /*< if (bmat .eq. 'G') then >*/
421 if (*(unsigned char *)bmat == 'G') {
422 /*< nbx = nbx + 1 >*/
423 /* ++timing_1.nbx; */
424 /*< call dcopy (n, workd(n+1), 1, resid, 1) >*/
425 dcopy_(n, &workd[*n + 1], &c__1, &resid[1], &c__1);
426 /*< ipntr(1) = n + 1 >*/
427 ipntr[1] = *n + 1;
428 /*< ipntr(2) = 1 >*/
429 ipntr[2] = 1;
430 /*< ido = 2 >*/
431 *ido = 2;
432 /*< go to 9000 >*/
433 goto L9000;
434 /*< else if (bmat .eq. 'I') then >*/
435 } else if (*(unsigned char *)bmat == 'I') {
436 /*< call dcopy (n, resid, 1, workd, 1) >*/
437 dcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
438 /*< end if >*/
439 }
440
441 /*< 20 continue >*/
442 L20:
443
444 /*< if (bmat .eq. 'G') then >*/
445 if (*(unsigned char *)bmat == 'G') {
446 /*< call second (t3) >*/
447 /* second_(&t3); */
448 /*< tmvbx = tmvbx + (t3 - t2) >*/
449 /* timing_1.tmvbx += t3 - t2; */
450 /*< end if >*/
451 }
452
453 /*< first = .FALSE. >*/
454 first = FALSE_;
455 /*< if (bmat .eq. 'G') then >*/
456 if (*(unsigned char *)bmat == 'G') {
457 /*< rnorm0 = ddot (n, resid, 1, workd, 1) >*/
458 rnorm0 = ddot_(n, &resid[1], &c__1, &workd[1], &c__1);
459 /*< rnorm0 = sqrt(abs(rnorm0)) >*/
460 rnorm0 = sqrt((abs(rnorm0)));
461 /*< else if (bmat .eq. 'I') then >*/
462 } else if (*(unsigned char *)bmat == 'I') {
463 /*< rnorm0 = dnrm2(n, resid, 1) >*/
464 rnorm0 = dnrm2_(n, &resid[1], &c__1);
465 /*< end if >*/
466 }
467 /*< rnorm = rnorm0 >*/
468 *rnorm = rnorm0;
469
470 /* %---------------------------------------------% */
471 /* | Exit if this is the very first Arnoldi step | */
472 /* %---------------------------------------------% */
473
474 /*< if (j .eq. 1) go to 50 >*/
475 if (*j == 1) {
476 goto L50;
477 }
478
479 /* %---------------------------------------------------------------- */
480 /* | Otherwise need to B-orthogonalize the starting vector against | */
481 /* | the current Arnoldi basis using Gram-Schmidt with iter. ref. | */
482 /* | This is the case where an invariant subspace is encountered | */
483 /* | in the middle of the Arnoldi factorization. | */
484 /* | | */
485 /* | s = V^{T}*B*r; r = r - V*s; | */
486 /* | | */
487 /* | Stopping criteria used for iter. ref. is discussed in | */
488 /* | Parlett's book, page 107 and in Gragg & Reichel TOMS paper. | */
489 /* %---------------------------------------------------------------% */
490
491 /*< orth = .TRUE. >*/
492 orth = TRUE_;
493 /*< 30 continue >*/
494 L30:
495
496 /*< >*/
497 i__1 = *j - 1;
498 dgemv_("T", n, &i__1, &c_b24, &v[v_offset], ldv, &workd[1], &c__1, &c_b26,
499 &workd[*n + 1], &c__1, (ftnlen)1);
500 /*< >*/
501 i__1 = *j - 1;
502 dgemv_("N", n, &i__1, &c_b29, &v[v_offset], ldv, &workd[*n + 1], &c__1, &
503 c_b24, &resid[1], &c__1, (ftnlen)1);
504
505 /* %----------------------------------------------------------% */
506 /* | Compute the B-norm of the orthogonalized starting vector | */
507 /* %----------------------------------------------------------% */
508
509 /*< call second (t2) >*/
510 /* second_(&t2); */
511 /*< if (bmat .eq. 'G') then >*/
512 if (*(unsigned char *)bmat == 'G') {
513 /*< nbx = nbx + 1 >*/
514 /* ++timing_1.nbx; */
515 /*< call dcopy (n, resid, 1, workd(n+1), 1) >*/
516 dcopy_(n, &resid[1], &c__1, &workd[*n + 1], &c__1);
517 /*< ipntr(1) = n + 1 >*/
518 ipntr[1] = *n + 1;
519 /*< ipntr(2) = 1 >*/
520 ipntr[2] = 1;
521 /*< ido = 2 >*/
522 *ido = 2;
523 /*< go to 9000 >*/
524 goto L9000;
525 /*< else if (bmat .eq. 'I') then >*/
526 } else if (*(unsigned char *)bmat == 'I') {
527 /*< call dcopy (n, resid, 1, workd, 1) >*/
528 dcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
529 /*< end if >*/
530 }
531
532 /*< 40 continue >*/
533 L40:
534
535 /*< if (bmat .eq. 'G') then >*/
536 if (*(unsigned char *)bmat == 'G') {
537 /*< call second (t3) >*/
538 /* second_(&t3); */
539 /*< tmvbx = tmvbx + (t3 - t2) >*/
540 /* timing_1.tmvbx += t3 - t2; */
541 /*< end if >*/
542 }
543
544 /*< if (bmat .eq. 'G') then >*/
545 if (*(unsigned char *)bmat == 'G') {
546 /*< rnorm = ddot (n, resid, 1, workd, 1) >*/
547 *rnorm = ddot_(n, &resid[1], &c__1, &workd[1], &c__1);
548 /*< rnorm = sqrt(abs(rnorm)) >*/
549 *rnorm = sqrt((abs(*rnorm)));
550 /*< else if (bmat .eq. 'I') then >*/
551 } else if (*(unsigned char *)bmat == 'I') {
552 /*< rnorm = dnrm2(n, resid, 1) >*/
553 *rnorm = dnrm2_(n, &resid[1], &c__1);
554 /*< end if >*/
555 }
556
557 /* %--------------------------------------% */
558 /* | Check for further orthogonalization. | */
559 /* %--------------------------------------% */
560
561 /* if (msglvl .gt. 2) then */
562 /* call dvout (logfil, 1, rnorm0, ndigit, */
563 /* & '_getv0: re-orthonalization ; rnorm0 is') */
564 /* call dvout (logfil, 1, rnorm, ndigit, */
565 /* & '_getv0: re-orthonalization ; rnorm is') */
566 /* end if */
567
568 /*< if (rnorm .gt. 0.717*rnorm0) go to 50 >*/
569 if (*rnorm > rnorm0 * (float).717) {
570 goto L50;
571 }
572
573 /*< iter = iter + 1 >*/
574 ++iter;
575 /*< if (iter .le. 1) then >*/
576 if (iter <= 1) {
577
578 /* %-----------------------------------% */
579 /* | Perform iterative refinement step | */
580 /* %-----------------------------------% */
581
582 /*< rnorm0 = rnorm >*/
583 rnorm0 = *rnorm;
584 /*< go to 30 >*/
585 goto L30;
586 /*< else >*/
587 } else {
588
589 /* %------------------------------------% */
590 /* | Iterative refinement step "failed" | */
591 /* %------------------------------------% */
592
593 /*< do 45 jj = 1, n >*/
594 i__1 = *n;
595 for (jj = 1; jj <= i__1; ++jj) {
596 /*< resid(jj) = zero >*/
597 resid[jj] = 0.;
598 /*< 45 continue >*/
599 /* L45: */
600 }
601 /*< rnorm = zero >*/
602 *rnorm = 0.;
603 /*< ierr = -1 >*/
604 *ierr = -1;
605 /*< end if >*/
606 }
607
608 /*< 50 continue >*/
609 L50:
610
611 /* if (msglvl .gt. 0) then */
612 /* call dvout (logfil, 1, rnorm, ndigit, */
613 /* & '_getv0: B-norm of initial / restarted starting vector') */
614 /* end if */
615 /* if (msglvl .gt. 2) then */
616 /* call dvout (logfil, n, resid, ndigit, */
617 /* & '_getv0: initial / restarted starting vector') */
618 /* end if */
619 /*< ido = 99 >*/
620 *ido = 99;
621
622 /*< call second (t1) >*/
623 /* second_(&t1); */
624 /*< tgetv0 = tgetv0 + (t1 - t0) >*/
625 /* timing_1.tgetv0 += t1 - t0; */
626
627 /*< 9000 continue >*/
628 L9000:
629 /*< return >*/
630 return 0;
631
632 /* %---------------% */
633 /* | End of dgetv0 | */
634 /* %---------------% */
635
636 /*< end >*/
637 } /* dgetv0_ */
638
639 #ifdef __cplusplus
640 }
641 #endif
642