Coverage Report

Created: 2023-06-07 06:06

/src/igraph/vendor/lapack/dgetv0.c
Line
Count
Source (jump to first uncovered line)
1
/*  -- translated by f2c (version 20191129).
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
#include "f2c.h"
14
15
/* Table of constant values */
16
17
static integer c__1 = 1;
18
static doublereal c_b24 = 1.;
19
static doublereal c_b26 = 0.;
20
static doublereal c_b29 = -1.;
21
22
/* -----------------------------------------------------------------------   
23
   \BeginDoc   
24
25
   \Name: dgetv0   
26
27
   \Description:   
28
    Generate a random initial residual vector for the Arnoldi process.   
29
    Force the residual vector to be in the range of the operator OP.   
30
31
   \Usage:   
32
    call dgetv0   
33
       ( IDO, BMAT, ITRY, INITV, N, J, V, LDV, RESID, RNORM,   
34
         IPNTR, WORKD, IERR )   
35
36
   \Arguments   
37
    IDO     Integer.  (INPUT/OUTPUT)   
38
            Reverse communication flag.  IDO must be zero on the first   
39
            call to dgetv0.   
40
            -------------------------------------------------------------   
41
            IDO =  0: first call to the reverse communication interface   
42
            IDO = -1: compute  Y = OP * X  where   
43
                      IPNTR(1) is the pointer into WORKD for X,   
44
                      IPNTR(2) is the pointer into WORKD for Y.   
45
                      This is for the initialization phase to force the   
46
                      starting vector into the range of OP.   
47
            IDO =  2: compute  Y = B * X  where   
48
                      IPNTR(1) is the pointer into WORKD for X,   
49
                      IPNTR(2) is the pointer into WORKD for Y.   
50
            IDO = 99: done   
51
            -------------------------------------------------------------   
52
53
    BMAT    Character*1.  (INPUT)   
54
            BMAT specifies the type of the matrix B in the (generalized)   
55
            eigenvalue problem A*x = lambda*B*x.   
56
            B = 'I' -> standard eigenvalue problem A*x = lambda*x   
57
            B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x   
58
59
    ITRY    Integer.  (INPUT)   
60
            ITRY counts the number of times that dgetv0 is called.   
61
            It should be set to 1 on the initial call to dgetv0.   
62
63
    INITV   Logical variable.  (INPUT)   
64
            .TRUE.  => the initial residual vector is given in RESID.   
65
            .FALSE. => generate a random initial residual vector.   
66
67
    N       Integer.  (INPUT)   
68
            Dimension of the problem.   
69
70
    J       Integer.  (INPUT)   
71
            Index of the residual vector to be generated, with respect to   
72
            the Arnoldi process.  J > 1 in case of a "restart".   
73
74
    V       Double precision N by J array.  (INPUT)   
75
            The first J-1 columns of V contain the current Arnoldi basis   
76
            if this is a "restart".   
77
78
    LDV     Integer.  (INPUT)   
79
            Leading dimension of V exactly as declared in the calling   
80
            program.   
81
82
    RESID   Double precision array of length N.  (INPUT/OUTPUT)   
83
            Initial residual vector to be generated.  If RESID is   
84
            provided, force RESID into the range of the operator OP.   
85
86
    RNORM   Double precision scalar.  (OUTPUT)   
87
            B-norm of the generated residual.   
88
89
    IPNTR   Integer array of length 3.  (OUTPUT)   
90
91
    WORKD   Double precision work array of length 2*N.  (REVERSE COMMUNICATION).   
92
            On exit, WORK(1:N) = B*RESID to be used in SSAITR.   
93
94
    IERR    Integer.  (OUTPUT)   
95
            =  0: Normal exit.   
96
            = -1: Cannot generate a nontrivial restarted residual vector   
97
                  in the range of the operator OP.   
98
99
   \EndDoc   
100
101
   -----------------------------------------------------------------------   
102
103
   \BeginLib   
104
105
   \Local variables:   
106
       xxxxxx  real   
107
108
   \References:   
109
    1. D.C. Sorensen, "Implicit Application of Polynomial Filters in   
110
       a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),   
111
       pp 357-385.   
112
    2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly   
113
       Restarted Arnoldi Iteration", Rice University Technical Report   
114
       TR95-13, Department of Computational and Applied Mathematics.   
115
116
   \Routines called:   
117
       second  ARPACK utility routine for timing.   
118
       dvout   ARPACK utility routine for vector output.   
119
       dlarnv  LAPACK routine for generating a random vector.   
120
       dgemv   Level 2 BLAS routine for matrix vector multiplication.   
121
       dcopy   Level 1 BLAS that copies one vector to another.   
122
       ddot    Level 1 BLAS that computes the scalar product of two vectors.   
123
       dnrm2   Level 1 BLAS that computes the norm of a vector.   
124
125
   \Author   
126
       Danny Sorensen               Phuong Vu   
127
       Richard Lehoucq              CRPC / Rice University   
128
       Dept. of Computational &     Houston, Texas   
129
       Applied Mathematics   
130
       Rice University   
131
       Houston, Texas   
132
133
   \SCCS Information: @(#)   
134
   FILE: getv0.F   SID: 2.6   DATE OF SID: 8/27/96   RELEASE: 2   
135
136
   \EndLib   
137
138
   -----------------------------------------------------------------------   
139
140
   Subroutine */ int igraphdgetv0_(integer *ido, char *bmat, integer *itry, logical 
141
  *initv, integer *n, integer *j, doublereal *v, integer *ldv, 
142
  doublereal *resid, doublereal *rnorm, integer *ipntr, doublereal *
143
  workd, integer *ierr)
144
0
{
145
    /* Initialized data */
146
147
0
    IGRAPH_F77_SAVE logical inits = TRUE_;
148
149
    /* System generated locals */
150
0
    integer v_dim1, v_offset, i__1;
151
152
    /* Builtin functions */
153
0
    double sqrt(doublereal);
154
155
    /* Local variables */
156
0
    IGRAPH_F77_SAVE real t0, t1, t2, t3;
157
0
    integer jj, nbx = 0;
158
0
    extern doublereal igraphddot_(integer *, doublereal *, integer *, doublereal *, 
159
0
      integer *);
160
0
    IGRAPH_F77_SAVE integer iter;
161
0
    IGRAPH_F77_SAVE logical orth;
162
0
    integer nopx = 0;
163
0
    extern doublereal igraphdnrm2_(integer *, doublereal *, integer *);
164
0
    IGRAPH_F77_SAVE integer iseed[4];
165
0
    extern /* Subroutine */ int igraphdgemv_(char *, integer *, integer *, 
166
0
      doublereal *, doublereal *, integer *, doublereal *, integer *, 
167
0
      doublereal *, doublereal *, integer *);
168
0
    integer idist;
169
0
    extern /* Subroutine */ int igraphdcopy_(integer *, doublereal *, integer *, 
170
0
      doublereal *, integer *);
171
0
    IGRAPH_F77_SAVE logical first;
172
0
    real tmvbx = 0;
173
0
    extern /* Subroutine */ int igraphdvout_(integer *, integer *, doublereal *, 
174
0
      integer *, char *, ftnlen);
175
0
    integer mgetv0 = 0;
176
0
    real tgetv0 = 0;
177
0
    IGRAPH_F77_SAVE doublereal rnorm0;
178
0
    extern /* Subroutine */ int igraphsecond_(real *);
179
0
    integer logfil, ndigit;
180
0
    extern /* Subroutine */ int igraphdlarnv_(integer *, integer *, integer *, 
181
0
      doublereal *);
182
0
    IGRAPH_F77_SAVE integer msglvl;
183
0
    real tmvopx = 0;
184
185
186
/*     %----------------------------------------------------%   
187
       | Include files for debugging and timing information |   
188
       %----------------------------------------------------%   
189
190
191
       %------------------%   
192
       | Scalar Arguments |   
193
       %------------------%   
194
195
196
       %-----------------%   
197
       | Array Arguments |   
198
       %-----------------%   
199
200
201
       %------------%   
202
       | Parameters |   
203
       %------------%   
204
205
206
       %------------------------%   
207
       | Local Scalars & Arrays |   
208
       %------------------------%   
209
210
211
       %----------------------%   
212
       | External Subroutines |   
213
       %----------------------%   
214
215
216
       %--------------------%   
217
       | External Functions |   
218
       %--------------------%   
219
220
221
       %---------------------%   
222
       | Intrinsic Functions |   
223
       %---------------------%   
224
225
226
       %-----------------%   
227
       | Data Statements |   
228
       %-----------------%   
229
230
       Parameter adjustments */
231
0
    --workd;
232
0
    --resid;
233
0
    v_dim1 = *ldv;
234
0
    v_offset = 1 + v_dim1;
235
0
    v -= v_offset;
236
0
    --ipntr;
237
238
    /* Function Body   
239
240
       %-----------------------%   
241
       | Executable Statements |   
242
       %-----------------------%   
243
244
245
       %-----------------------------------%   
246
       | Initialize the seed of the LAPACK |   
247
       | random number generator           |   
248
       %-----------------------------------% */
249
250
0
    if (inits) {
251
0
  iseed[0] = 1;
252
0
  iseed[1] = 3;
253
0
  iseed[2] = 5;
254
0
  iseed[3] = 7;
255
0
  inits = FALSE_;
256
0
    }
257
258
0
    if (*ido == 0) {
259
260
/*        %-------------------------------%   
261
          | Initialize timing statistics  |   
262
          | & message level for debugging |   
263
          %-------------------------------% */
264
265
0
  igraphsecond_(&t0);
266
0
  msglvl = mgetv0;
267
268
0
  *ierr = 0;
269
0
  iter = 0;
270
0
  first = FALSE_;
271
0
  orth = FALSE_;
272
273
/*        %-----------------------------------------------------%   
274
          | Possibly generate a random starting vector in RESID |   
275
          | Use a LAPACK random number generator used by the    |   
276
          | matrix generation routines.                         |   
277
          |    idist = 1: uniform (0,1)  distribution;          |   
278
          |    idist = 2: uniform (-1,1) distribution;          |   
279
          |    idist = 3: normal  (0,1)  distribution;          |   
280
          %-----------------------------------------------------% */
281
282
0
  if (! (*initv)) {
283
0
      idist = 2;
284
0
      igraphdlarnv_(&idist, iseed, n, &resid[1]);
285
0
  }
286
287
/*        %----------------------------------------------------------%   
288
          | Force the starting vector into the range of OP to handle |   
289
          | the generalized problem when B is possibly (singular).   |   
290
          %----------------------------------------------------------% */
291
292
0
  igraphsecond_(&t2);
293
0
  if (*(unsigned char *)bmat == 'G') {
294
0
      ++nopx;
295
0
      ipntr[1] = 1;
296
0
      ipntr[2] = *n + 1;
297
0
      igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
298
0
      *ido = -1;
299
0
      goto L9000;
300
0
  }
301
0
    }
302
303
/*     %-----------------------------------------%   
304
       | Back from computing OP*(initial-vector) |   
305
       %-----------------------------------------% */
306
307
0
    if (first) {
308
0
  goto L20;
309
0
    }
310
311
/*     %-----------------------------------------------%   
312
       | Back from computing B*(orthogonalized-vector) |   
313
       %-----------------------------------------------% */
314
315
0
    if (orth) {
316
0
  goto L40;
317
0
    }
318
319
0
    if (*(unsigned char *)bmat == 'G') {
320
0
  igraphsecond_(&t3);
321
0
  tmvopx += t3 - t2;
322
0
    }
323
324
/*     %------------------------------------------------------%   
325
       | Starting vector is now in the range of OP; r = OP*r; |   
326
       | Compute B-norm of starting vector.                   |   
327
       %------------------------------------------------------% */
328
329
0
    igraphsecond_(&t2);
330
0
    first = TRUE_;
331
0
    if (*(unsigned char *)bmat == 'G') {
332
0
  ++nbx;
333
0
  igraphdcopy_(n, &workd[*n + 1], &c__1, &resid[1], &c__1);
334
0
  ipntr[1] = *n + 1;
335
0
  ipntr[2] = 1;
336
0
  *ido = 2;
337
0
  goto L9000;
338
0
    } else if (*(unsigned char *)bmat == 'I') {
339
0
  igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
340
0
    }
341
342
0
L20:
343
344
0
    if (*(unsigned char *)bmat == 'G') {
345
0
  igraphsecond_(&t3);
346
0
  tmvbx += t3 - t2;
347
0
    }
348
349
0
    first = FALSE_;
350
0
    if (*(unsigned char *)bmat == 'G') {
351
0
  rnorm0 = igraphddot_(n, &resid[1], &c__1, &workd[1], &c__1);
352
0
  rnorm0 = sqrt((abs(rnorm0)));
353
0
    } else if (*(unsigned char *)bmat == 'I') {
354
0
  rnorm0 = igraphdnrm2_(n, &resid[1], &c__1);
355
0
    }
356
0
    *rnorm = rnorm0;
357
358
/*     %---------------------------------------------%   
359
       | Exit if this is the very first Arnoldi step |   
360
       %---------------------------------------------% */
361
362
0
    if (*j == 1) {
363
0
  goto L50;
364
0
    }
365
366
/*     %----------------------------------------------------------------   
367
       | Otherwise need to B-orthogonalize the starting vector against |   
368
       | the current Arnoldi basis using Gram-Schmidt with iter. ref.  |   
369
       | This is the case where an invariant subspace is encountered   |   
370
       | in the middle of the Arnoldi factorization.                   |   
371
       |                                                               |   
372
       |       s = V^{T}*B*r;   r = r - V*s;                           |   
373
       |                                                               |   
374
       | Stopping criteria used for iter. ref. is discussed in         |   
375
       | Parlett's book, page 107 and in Gragg & Reichel TOMS paper.   |   
376
       %---------------------------------------------------------------% */
377
378
0
    orth = TRUE_;
379
0
L30:
380
381
0
    i__1 = *j - 1;
382
0
    igraphdgemv_("T", n, &i__1, &c_b24, &v[v_offset], ldv, &workd[1], &c__1, &c_b26,
383
0
       &workd[*n + 1], &c__1);
384
0
    i__1 = *j - 1;
385
0
    igraphdgemv_("N", n, &i__1, &c_b29, &v[v_offset], ldv, &workd[*n + 1], &c__1, &
386
0
      c_b24, &resid[1], &c__1);
387
388
/*     %----------------------------------------------------------%   
389
       | Compute the B-norm of the orthogonalized starting vector |   
390
       %----------------------------------------------------------% */
391
392
0
    igraphsecond_(&t2);
393
0
    if (*(unsigned char *)bmat == 'G') {
394
0
  ++nbx;
395
0
  igraphdcopy_(n, &resid[1], &c__1, &workd[*n + 1], &c__1);
396
0
  ipntr[1] = *n + 1;
397
0
  ipntr[2] = 1;
398
0
  *ido = 2;
399
0
  goto L9000;
400
0
    } else if (*(unsigned char *)bmat == 'I') {
401
0
  igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
402
0
    }
403
404
0
L40:
405
406
0
    if (*(unsigned char *)bmat == 'G') {
407
0
  igraphsecond_(&t3);
408
0
  tmvbx += t3 - t2;
409
0
    }
410
411
0
    if (*(unsigned char *)bmat == 'G') {
412
0
  *rnorm = igraphddot_(n, &resid[1], &c__1, &workd[1], &c__1);
413
0
  *rnorm = sqrt((abs(*rnorm)));
414
0
    } else if (*(unsigned char *)bmat == 'I') {
415
0
  *rnorm = igraphdnrm2_(n, &resid[1], &c__1);
416
0
    }
417
418
/*     %--------------------------------------%   
419
       | Check for further orthogonalization. |   
420
       %--------------------------------------% */
421
422
0
    if (msglvl > 2) {
423
0
  igraphdvout_(&logfil, &c__1, &rnorm0, &ndigit, "_getv0: re-orthonalization"
424
0
    " ; rnorm0 is", (ftnlen)38);
425
0
  igraphdvout_(&logfil, &c__1, rnorm, &ndigit, "_getv0: re-orthonalization ;"
426
0
    " rnorm is", (ftnlen)37);
427
0
    }
428
429
0
    if (*rnorm > rnorm0 * .717f) {
430
0
  goto L50;
431
0
    }
432
433
0
    ++iter;
434
0
    if (iter <= 1) {
435
436
/*        %-----------------------------------%   
437
          | Perform iterative refinement step |   
438
          %-----------------------------------% */
439
440
0
  rnorm0 = *rnorm;
441
0
  goto L30;
442
0
    } else {
443
444
/*        %------------------------------------%   
445
          | Iterative refinement step "failed" |   
446
          %------------------------------------% */
447
448
0
  i__1 = *n;
449
0
  for (jj = 1; jj <= i__1; ++jj) {
450
0
      resid[jj] = 0.;
451
/* L45: */
452
0
  }
453
0
  *rnorm = 0.;
454
0
  *ierr = -1;
455
0
    }
456
457
0
L50:
458
459
0
    if (msglvl > 0) {
460
0
  igraphdvout_(&logfil, &c__1, rnorm, &ndigit, "_getv0: B-norm of initial / "
461
0
    "restarted starting vector", (ftnlen)53);
462
0
    }
463
0
    if (msglvl > 2) {
464
0
  igraphdvout_(&logfil, n, &resid[1], &ndigit, "_getv0: initial / restarted "
465
0
    "starting vector", (ftnlen)43);
466
0
    }
467
0
    *ido = 99;
468
469
0
    igraphsecond_(&t1);
470
0
    tgetv0 += t1 - t0;
471
472
0
L9000:
473
0
    return 0;
474
475
/*     %---------------%   
476
       | End of dgetv0 |   
477
       %---------------% */
478
479
0
} /* igraphdgetv0_ */
480