/* -- translated by f2c (version 20191129). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib; on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */ #include "f2c.h" /* Table of constant values */ static integer c__1 = 1; static doublereal c_b24 = 1.; static doublereal c_b26 = 0.; static doublereal c_b29 = -1.; /* ----------------------------------------------------------------------- \BeginDoc \Name: dgetv0 \Description: Generate a random initial residual vector for the Arnoldi process. Force the residual vector to be in the range of the operator OP. \Usage: call dgetv0 ( IDO, BMAT, ITRY, INITV, N, J, V, LDV, RESID, RNORM, IPNTR, WORKD, IERR ) \Arguments IDO Integer. (INPUT/OUTPUT) Reverse communication flag. IDO must be zero on the first call to dgetv0. ------------------------------------------------------------- IDO = 0: first call to the reverse communication interface IDO = -1: compute Y = OP * X where IPNTR(1) is the pointer into WORKD for X, IPNTR(2) is the pointer into WORKD for Y. This is for the initialization phase to force the starting vector into the range of OP. IDO = 2: compute Y = B * X where IPNTR(1) is the pointer into WORKD for X, IPNTR(2) is the pointer into WORKD for Y. IDO = 99: done ------------------------------------------------------------- BMAT Character*1. (INPUT) BMAT specifies the type of the matrix B in the (generalized) eigenvalue problem A*x = lambda*B*x. B = 'I' -> standard eigenvalue problem A*x = lambda*x B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x ITRY Integer. (INPUT) ITRY counts the number of times that dgetv0 is called. It should be set to 1 on the initial call to dgetv0. INITV Logical variable. (INPUT) .TRUE. => the initial residual vector is given in RESID. .FALSE. => generate a random initial residual vector. N Integer. (INPUT) Dimension of the problem. J Integer. (INPUT) Index of the residual vector to be generated, with respect to the Arnoldi process. J > 1 in case of a "restart". V Double precision N by J array. (INPUT) The first J-1 columns of V contain the current Arnoldi basis if this is a "restart". LDV Integer. (INPUT) Leading dimension of V exactly as declared in the calling program. RESID Double precision array of length N. (INPUT/OUTPUT) Initial residual vector to be generated. If RESID is provided, force RESID into the range of the operator OP. RNORM Double precision scalar. (OUTPUT) B-norm of the generated residual. IPNTR Integer array of length 3. (OUTPUT) WORKD Double precision work array of length 2*N. (REVERSE COMMUNICATION). On exit, WORK(1:N) = B*RESID to be used in SSAITR. IERR Integer. (OUTPUT) = 0: Normal exit. = -1: Cannot generate a nontrivial restarted residual vector in the range of the operator OP. \EndDoc ----------------------------------------------------------------------- \BeginLib \Local variables: xxxxxx real \References: 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), pp 357-385. 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly Restarted Arnoldi Iteration", Rice University Technical Report TR95-13, Department of Computational and Applied Mathematics. \Routines called: second ARPACK utility routine for timing. dvout ARPACK utility routine for vector output. dlarnv LAPACK routine for generating a random vector. dgemv Level 2 BLAS routine for matrix vector multiplication. dcopy Level 1 BLAS that copies one vector to another. ddot Level 1 BLAS that computes the scalar product of two vectors. dnrm2 Level 1 BLAS that computes the norm of a vector. \Author Danny Sorensen Phuong Vu Richard Lehoucq CRPC / Rice University Dept. of Computational & Houston, Texas Applied Mathematics Rice University Houston, Texas \SCCS Information: @(#) FILE: getv0.F SID: 2.6 DATE OF SID: 8/27/96 RELEASE: 2 \EndLib ----------------------------------------------------------------------- Subroutine */ int igraphdgetv0_(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) { /* Initialized data */ IGRAPH_F77_SAVE logical inits = TRUE_; /* System generated locals */ integer v_dim1, v_offset, i__1; /* Builtin functions */ double sqrt(doublereal); /* Local variables */ IGRAPH_F77_SAVE real t0, t1, t2, t3; integer jj, nbx = 0; extern doublereal igraphddot_(integer *, doublereal *, integer *, doublereal *, integer *); IGRAPH_F77_SAVE integer iter; IGRAPH_F77_SAVE logical orth; integer nopx = 0; extern doublereal igraphdnrm2_(integer *, doublereal *, integer *); IGRAPH_F77_SAVE integer iseed[4]; extern /* Subroutine */ int igraphdgemv_(char *, integer *, integer *, doublereal *, doublereal *, integer *, doublereal *, integer *, doublereal *, doublereal *, integer *); integer idist; extern /* Subroutine */ int igraphdcopy_(integer *, doublereal *, integer *, doublereal *, integer *); IGRAPH_F77_SAVE logical first; real tmvbx = 0; extern /* Subroutine */ int igraphdvout_(integer *, integer *, doublereal *, integer *, char *, ftnlen); integer mgetv0 = 0; real tgetv0 = 0; IGRAPH_F77_SAVE doublereal rnorm0; extern /* Subroutine */ int igraphsecond_(real *); integer logfil, ndigit; extern /* Subroutine */ int igraphdlarnv_(integer *, integer *, integer *, doublereal *); IGRAPH_F77_SAVE integer msglvl; real tmvopx = 0; /* %----------------------------------------------------% | Include files for debugging and timing information | %----------------------------------------------------% %------------------% | Scalar Arguments | %------------------% %-----------------% | Array Arguments | %-----------------% %------------% | Parameters | %------------% %------------------------% | Local Scalars & Arrays | %------------------------% %----------------------% | External Subroutines | %----------------------% %--------------------% | External Functions | %--------------------% %---------------------% | Intrinsic Functions | %---------------------% %-----------------% | Data Statements | %-----------------% Parameter adjustments */ --workd; --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; v -= v_offset; --ipntr; /* Function Body %-----------------------% | Executable Statements | %-----------------------% %-----------------------------------% | Initialize the seed of the LAPACK | | random number generator | %-----------------------------------% */ if (inits) { iseed[0] = 1; iseed[1] = 3; iseed[2] = 5; iseed[3] = 7; inits = FALSE_; } if (*ido == 0) { /* %-------------------------------% | Initialize timing statistics | | & message level for debugging | %-------------------------------% */ igraphsecond_(&t0); msglvl = mgetv0; *ierr = 0; iter = 0; first = FALSE_; orth = FALSE_; /* %-----------------------------------------------------% | Possibly generate a random starting vector in RESID | | Use a LAPACK random number generator used by the | | matrix generation routines. | | idist = 1: uniform (0,1) distribution; | | idist = 2: uniform (-1,1) distribution; | | idist = 3: normal (0,1) distribution; | %-----------------------------------------------------% */ if (! (*initv)) { idist = 2; igraphdlarnv_(&idist, iseed, n, &resid[1]); } /* %----------------------------------------------------------% | Force the starting vector into the range of OP to handle | | the generalized problem when B is possibly (singular). | %----------------------------------------------------------% */ igraphsecond_(&t2); if (*(unsigned char *)bmat == 'G') { ++nopx; ipntr[1] = 1; ipntr[2] = *n + 1; igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1); *ido = -1; goto L9000; } } /* %-----------------------------------------% | Back from computing OP*(initial-vector) | %-----------------------------------------% */ if (first) { goto L20; } /* %-----------------------------------------------% | Back from computing B*(orthogonalized-vector) | %-----------------------------------------------% */ if (orth) { goto L40; } if (*(unsigned char *)bmat == 'G') { igraphsecond_(&t3); tmvopx += t3 - t2; } /* %------------------------------------------------------% | Starting vector is now in the range of OP; r = OP*r; | | Compute B-norm of starting vector. | %------------------------------------------------------% */ igraphsecond_(&t2); first = TRUE_; if (*(unsigned char *)bmat == 'G') { ++nbx; igraphdcopy_(n, &workd[*n + 1], &c__1, &resid[1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; goto L9000; } else if (*(unsigned char *)bmat == 'I') { igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1); } L20: if (*(unsigned char *)bmat == 'G') { igraphsecond_(&t3); tmvbx += t3 - t2; } first = FALSE_; if (*(unsigned char *)bmat == 'G') { rnorm0 = igraphddot_(n, &resid[1], &c__1, &workd[1], &c__1); rnorm0 = sqrt((abs(rnorm0))); } else if (*(unsigned char *)bmat == 'I') { rnorm0 = igraphdnrm2_(n, &resid[1], &c__1); } *rnorm = rnorm0; /* %---------------------------------------------% | Exit if this is the very first Arnoldi step | %---------------------------------------------% */ if (*j == 1) { goto L50; } /* %---------------------------------------------------------------- | Otherwise need to B-orthogonalize the starting vector against | | the current Arnoldi basis using Gram-Schmidt with iter. ref. | | This is the case where an invariant subspace is encountered | | in the middle of the Arnoldi factorization. | | | | s = V^{T}*B*r; r = r - V*s; | | | | Stopping criteria used for iter. ref. is discussed in | | Parlett's book, page 107 and in Gragg & Reichel TOMS paper. | %---------------------------------------------------------------% */ orth = TRUE_; L30: i__1 = *j - 1; igraphdgemv_("T", n, &i__1, &c_b24, &v[v_offset], ldv, &workd[1], &c__1, &c_b26, &workd[*n + 1], &c__1); i__1 = *j - 1; igraphdgemv_("N", n, &i__1, &c_b29, &v[v_offset], ldv, &workd[*n + 1], &c__1, & c_b24, &resid[1], &c__1); /* %----------------------------------------------------------% | Compute the B-norm of the orthogonalized starting vector | %----------------------------------------------------------% */ igraphsecond_(&t2); if (*(unsigned char *)bmat == 'G') { ++nbx; igraphdcopy_(n, &resid[1], &c__1, &workd[*n + 1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; goto L9000; } else if (*(unsigned char *)bmat == 'I') { igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1); } L40: if (*(unsigned char *)bmat == 'G') { igraphsecond_(&t3); tmvbx += t3 - t2; } if (*(unsigned char *)bmat == 'G') { *rnorm = igraphddot_(n, &resid[1], &c__1, &workd[1], &c__1); *rnorm = sqrt((abs(*rnorm))); } else if (*(unsigned char *)bmat == 'I') { *rnorm = igraphdnrm2_(n, &resid[1], &c__1); } /* %--------------------------------------% | Check for further orthogonalization. | %--------------------------------------% */ if (msglvl > 2) { igraphdvout_(&logfil, &c__1, &rnorm0, &ndigit, "_getv0: re-orthonalization" " ; rnorm0 is", (ftnlen)38); igraphdvout_(&logfil, &c__1, rnorm, &ndigit, "_getv0: re-orthonalization ;" " rnorm is", (ftnlen)37); } if (*rnorm > rnorm0 * .717f) { goto L50; } ++iter; if (iter <= 1) { /* %-----------------------------------% | Perform iterative refinement step | %-----------------------------------% */ rnorm0 = *rnorm; goto L30; } else { /* %------------------------------------% | Iterative refinement step "failed" | %------------------------------------% */ i__1 = *n; for (jj = 1; jj <= i__1; ++jj) { resid[jj] = 0.; /* L45: */ } *rnorm = 0.; *ierr = -1; } L50: if (msglvl > 0) { igraphdvout_(&logfil, &c__1, rnorm, &ndigit, "_getv0: B-norm of initial / " "restarted starting vector", (ftnlen)53); } if (msglvl > 2) { igraphdvout_(&logfil, n, &resid[1], &ndigit, "_getv0: initial / restarted " "starting vector", (ftnlen)43); } *ido = 99; igraphsecond_(&t1); tgetv0 += t1 - t0; L9000: return 0; /* %---------------% | End of dgetv0 | %---------------% */ } /* igraphdgetv0_ */