Coverage Report

Created: 2023-06-07 06:06

/src/igraph/vendor/lapack/dnapps.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 doublereal c_b5 = 0.;
18
static doublereal c_b6 = 1.;
19
static integer c__1 = 1;
20
static doublereal c_b43 = -1.;
21
22
/* -----------------------------------------------------------------------   
23
   \BeginDoc   
24
25
   \Name: dnapps   
26
27
   \Description:   
28
    Given the Arnoldi factorization   
29
30
       A*V_{k} - V_{k}*H_{k} = r_{k+p}*e_{k+p}^T,   
31
32
    apply NP implicit shifts resulting in   
33
34
       A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q   
35
36
    where Q is an orthogonal matrix which is the product of rotations   
37
    and reflections resulting from the NP bulge chage sweeps.   
38
    The updated Arnoldi factorization becomes:   
39
40
       A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T.   
41
42
   \Usage:   
43
    call dnapps   
44
       ( N, KEV, NP, SHIFTR, SHIFTI, V, LDV, H, LDH, RESID, Q, LDQ,   
45
         WORKL, WORKD )   
46
47
   \Arguments   
48
    N       Integer.  (INPUT)   
49
            Problem size, i.e. size of matrix A.   
50
51
    KEV     Integer.  (INPUT/OUTPUT)   
52
            KEV+NP is the size of the input matrix H.   
53
            KEV is the size of the updated matrix HNEW.  KEV is only   
54
            updated on ouput when fewer than NP shifts are applied in   
55
            order to keep the conjugate pair together.   
56
57
    NP      Integer.  (INPUT)   
58
            Number of implicit shifts to be applied.   
59
60
    SHIFTR, Double precision array of length NP.  (INPUT)   
61
    SHIFTI  Real and imaginary part of the shifts to be applied.   
62
            Upon, entry to dnapps, the shifts must be sorted so that the   
63
            conjugate pairs are in consecutive locations.   
64
65
    V       Double precision N by (KEV+NP) array.  (INPUT/OUTPUT)   
66
            On INPUT, V contains the current KEV+NP Arnoldi vectors.   
67
            On OUTPUT, V contains the updated KEV Arnoldi vectors   
68
            in the first KEV columns of V.   
69
70
    LDV     Integer.  (INPUT)   
71
            Leading dimension of V exactly as declared in the calling   
72
            program.   
73
74
    H       Double precision (KEV+NP) by (KEV+NP) array.  (INPUT/OUTPUT)   
75
            On INPUT, H contains the current KEV+NP by KEV+NP upper   
76
            Hessenber matrix of the Arnoldi factorization.   
77
            On OUTPUT, H contains the updated KEV by KEV upper Hessenberg   
78
            matrix in the KEV leading submatrix.   
79
80
    LDH     Integer.  (INPUT)   
81
            Leading dimension of H exactly as declared in the calling   
82
            program.   
83
84
    RESID   Double precision array of length N.  (INPUT/OUTPUT)   
85
            On INPUT, RESID contains the the residual vector r_{k+p}.   
86
            On OUTPUT, RESID is the update residual vector rnew_{k}   
87
            in the first KEV locations.   
88
89
    Q       Double precision KEV+NP by KEV+NP work array.  (WORKSPACE)   
90
            Work array used to accumulate the rotations and reflections   
91
            during the bulge chase sweep.   
92
93
    LDQ     Integer.  (INPUT)   
94
            Leading dimension of Q exactly as declared in the calling   
95
            program.   
96
97
    WORKL   Double precision work array of length (KEV+NP).  (WORKSPACE)   
98
            Private (replicated) array on each PE or array allocated on   
99
            the front end.   
100
101
    WORKD   Double precision work array of length 2*N.  (WORKSPACE)   
102
            Distributed array used in the application of the accumulated   
103
            orthogonal matrix Q.   
104
105
   \EndDoc   
106
107
   -----------------------------------------------------------------------   
108
109
   \BeginLib   
110
111
   \Local variables:   
112
       xxxxxx  real   
113
114
   \References:   
115
    1. D.C. Sorensen, "Implicit Application of Polynomial Filters in   
116
       a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),   
117
       pp 357-385.   
118
119
   \Routines called:   
120
       ivout   ARPACK utility routine that prints integers.   
121
       second  ARPACK utility routine for timing.   
122
       dmout   ARPACK utility routine that prints matrices.   
123
       dvout   ARPACK utility routine that prints vectors.   
124
       dlabad  LAPACK routine that computes machine constants.   
125
       dlacpy  LAPACK matrix copy routine.   
126
       dlamch  LAPACK routine that determines machine constants.   
127
       dlanhs  LAPACK routine that computes various norms of a matrix.   
128
       dlapy2  LAPACK routine to compute sqrt(x**2+y**2) carefully.   
129
       dlarf   LAPACK routine that applies Householder reflection to   
130
               a matrix.   
131
       dlarfg  LAPACK Householder reflection construction routine.   
132
       dlartg  LAPACK Givens rotation construction routine.   
133
       dlaset  LAPACK matrix initialization routine.   
134
       dgemv   Level 2 BLAS routine for matrix vector multiplication.   
135
       daxpy   Level 1 BLAS that computes a vector triad.   
136
       dcopy   Level 1 BLAS that copies one vector to another .   
137
       dscal   Level 1 BLAS that scales a vector.   
138
139
   \Author   
140
       Danny Sorensen               Phuong Vu   
141
       Richard Lehoucq              CRPC / Rice University   
142
       Dept. of Computational &     Houston, Texas   
143
       Applied Mathematics   
144
       Rice University   
145
       Houston, Texas   
146
147
   \Revision history:   
148
       xx/xx/92: Version ' 2.1'   
149
150
   \SCCS Information: @(#)   
151
   FILE: napps.F   SID: 2.3   DATE OF SID: 4/20/96   RELEASE: 2   
152
153
   \Remarks   
154
    1. In this version, each shift is applied to all the sublocks of   
155
       the Hessenberg matrix H and not just to the submatrix that it   
156
       comes from. Deflation as in LAPACK routine dlahqr (QR algorithm   
157
       for upper Hessenberg matrices ) is used.   
158
       The subdiagonals of H are enforced to be non-negative.   
159
160
   \EndLib   
161
162
   -----------------------------------------------------------------------   
163
164
   Subroutine */ int igraphdnapps_(integer *n, integer *kev, integer *np, 
165
  doublereal *shiftr, doublereal *shifti, doublereal *v, integer *ldv, 
166
  doublereal *h__, integer *ldh, doublereal *resid, doublereal *q, 
167
  integer *ldq, doublereal *workl, doublereal *workd)
168
0
{
169
    /* Initialized data */
170
171
0
    IGRAPH_F77_SAVE logical first = TRUE_;
172
173
    /* System generated locals */
174
0
    integer h_dim1, h_offset, v_dim1, v_offset, q_dim1, q_offset, i__1, i__2, 
175
0
      i__3, i__4;
176
0
    doublereal d__1, d__2;
177
178
    /* Local variables */
179
0
    doublereal c__, f, g;
180
0
    integer i__, j;
181
0
    doublereal r__, s, t, u[3];
182
0
    IGRAPH_F77_SAVE real t0, t1;
183
0
    doublereal h11, h12, h21, h22, h32;
184
0
    integer jj, ir, nr;
185
0
    doublereal tau;
186
0
    IGRAPH_F77_SAVE doublereal ulp;
187
0
    doublereal tst1;
188
0
    integer iend;
189
0
    IGRAPH_F77_SAVE doublereal unfl, ovfl;
190
0
    extern /* Subroutine */ int igraphdscal_(integer *, doublereal *, doublereal *, 
191
0
      integer *), igraphdlarf_(char *, integer *, integer *, doublereal *, 
192
0
      integer *, doublereal *, doublereal *, integer *, doublereal *);
193
0
    logical cconj;
194
0
    extern /* Subroutine */ int igraphdgemv_(char *, integer *, integer *, 
195
0
      doublereal *, doublereal *, integer *, doublereal *, integer *, 
196
0
      doublereal *, doublereal *, integer *), igraphdcopy_(integer *, 
197
0
      doublereal *, integer *, doublereal *, integer *), igraphdaxpy_(integer 
198
0
      *, doublereal *, doublereal *, integer *, doublereal *, integer *)
199
0
      , igraphdmout_(integer *, integer *, integer *, doublereal *, integer *,
200
0
       integer *, char *, ftnlen), igraphdvout_(integer *, integer *, 
201
0
      doublereal *, integer *, char *, ftnlen), igraphivout_(integer *, 
202
0
      integer *, integer *, integer *, char *, ftnlen);
203
0
    extern doublereal igraphdlapy2_(doublereal *, doublereal *);
204
0
    extern /* Subroutine */ int igraphdlabad_(doublereal *, doublereal *);
205
0
    extern doublereal igraphdlamch_(char *);
206
0
    extern /* Subroutine */ int igraphdlarfg_(integer *, doublereal *, doublereal *,
207
0
       integer *, doublereal *);
208
0
    doublereal sigmai;
209
0
    extern doublereal igraphdlanhs_(char *, integer *, doublereal *, integer *, 
210
0
      doublereal *);
211
0
    extern /* Subroutine */ int igraphsecond_(real *), igraphdlacpy_(char *, integer *, 
212
0
      integer *, doublereal *, integer *, doublereal *, integer *), igraphdlaset_(char *, integer *, integer *, doublereal *, 
213
0
      doublereal *, doublereal *, integer *), igraphdlartg_(
214
0
      doublereal *, doublereal *, doublereal *, doublereal *, 
215
0
      doublereal *);
216
0
    integer logfil, ndigit;
217
0
    doublereal sigmar;
218
0
    integer mnapps = 0, msglvl;
219
0
    real tnapps = 0.;
220
0
    integer istart;
221
0
    IGRAPH_F77_SAVE doublereal smlnum;
222
0
    integer kplusp;
223
224
225
/*     %----------------------------------------------------%   
226
       | Include files for debugging and timing information |   
227
       %----------------------------------------------------%   
228
229
230
       %------------------%   
231
       | Scalar Arguments |   
232
       %------------------%   
233
234
235
       %-----------------%   
236
       | Array Arguments |   
237
       %-----------------%   
238
239
240
       %------------%   
241
       | Parameters |   
242
       %------------%   
243
244
245
       %------------------------%   
246
       | Local Scalars & Arrays |   
247
       %------------------------%   
248
249
250
       %----------------------%   
251
       | External Subroutines |   
252
       %----------------------%   
253
254
255
       %--------------------%   
256
       | External Functions |   
257
       %--------------------%   
258
259
260
       %----------------------%   
261
       | Intrinsics Functions |   
262
       %----------------------%   
263
264
265
       %----------------%   
266
       | Data statments |   
267
       %----------------%   
268
269
       Parameter adjustments */
270
0
    --workd;
271
0
    --resid;
272
0
    --workl;
273
0
    --shifti;
274
0
    --shiftr;
275
0
    v_dim1 = *ldv;
276
0
    v_offset = 1 + v_dim1;
277
0
    v -= v_offset;
278
0
    h_dim1 = *ldh;
279
0
    h_offset = 1 + h_dim1;
280
0
    h__ -= h_offset;
281
0
    q_dim1 = *ldq;
282
0
    q_offset = 1 + q_dim1;
283
0
    q -= q_offset;
284
285
    /* Function Body   
286
287
       %-----------------------%   
288
       | Executable Statements |   
289
       %-----------------------% */
290
291
0
    if (first) {
292
293
/*        %-----------------------------------------------%   
294
          | Set machine-dependent constants for the       |   
295
          | stopping criterion. If norm(H) <= sqrt(OVFL), |   
296
          | overflow should not occur.                    |   
297
          | REFERENCE: LAPACK subroutine dlahqr           |   
298
          %-----------------------------------------------% */
299
300
0
  unfl = igraphdlamch_("safe minimum");
301
0
  ovfl = 1. / unfl;
302
0
  igraphdlabad_(&unfl, &ovfl);
303
0
  ulp = igraphdlamch_("precision");
304
0
  smlnum = unfl * (*n / ulp);
305
0
  first = FALSE_;
306
0
    }
307
308
/*     %-------------------------------%   
309
       | Initialize timing statistics  |   
310
       | & message level for debugging |   
311
       %-------------------------------% */
312
313
0
    igraphsecond_(&t0);
314
0
    msglvl = mnapps;
315
0
    kplusp = *kev + *np;
316
317
/*     %--------------------------------------------%   
318
       | Initialize Q to the identity to accumulate |   
319
       | the rotations and reflections              |   
320
       %--------------------------------------------% */
321
322
0
    igraphdlaset_("All", &kplusp, &kplusp, &c_b5, &c_b6, &q[q_offset], ldq);
323
324
/*     %----------------------------------------------%   
325
       | Quick return if there are no shifts to apply |   
326
       %----------------------------------------------% */
327
328
0
    if (*np == 0) {
329
0
  goto L9000;
330
0
    }
331
332
/*     %----------------------------------------------%   
333
       | Chase the bulge with the application of each |   
334
       | implicit shift. Each shift is applied to the |   
335
       | whole matrix including each block.           |   
336
       %----------------------------------------------% */
337
338
0
    cconj = FALSE_;
339
0
    i__1 = *np;
340
0
    for (jj = 1; jj <= i__1; ++jj) {
341
0
  sigmar = shiftr[jj];
342
0
  sigmai = shifti[jj];
343
344
0
  if (msglvl > 2) {
345
0
      igraphivout_(&logfil, &c__1, &jj, &ndigit, "_napps: shift number.", (
346
0
        ftnlen)21);
347
0
      igraphdvout_(&logfil, &c__1, &sigmar, &ndigit, "_napps: The real part "
348
0
        "of the shift ", (ftnlen)35);
349
0
      igraphdvout_(&logfil, &c__1, &sigmai, &ndigit, "_napps: The imaginary "
350
0
        "part of the shift ", (ftnlen)40);
351
0
  }
352
353
/*        %-------------------------------------------------%   
354
          | The following set of conditionals is necessary  |   
355
          | in order that complex conjugate pairs of shifts |   
356
          | are applied together or not at all.             |   
357
          %-------------------------------------------------% */
358
359
0
  if (cconj) {
360
361
/*           %-----------------------------------------%   
362
             | cconj = .true. means the previous shift |   
363
             | had non-zero imaginary part.            |   
364
             %-----------------------------------------% */
365
366
0
      cconj = FALSE_;
367
0
      goto L110;
368
0
  } else if (jj < *np && abs(sigmai) > 0.) {
369
370
/*           %------------------------------------%   
371
             | Start of a complex conjugate pair. |   
372
             %------------------------------------% */
373
374
0
      cconj = TRUE_;
375
0
  } else if (jj == *np && abs(sigmai) > 0.) {
376
377
/*           %----------------------------------------------%   
378
             | The last shift has a nonzero imaginary part. |   
379
             | Don't apply it; thus the order of the        |   
380
             | compressed H is order KEV+1 since only np-1  |   
381
             | were applied.                                |   
382
             %----------------------------------------------% */
383
384
0
      ++(*kev);
385
0
      goto L110;
386
0
  }
387
0
  istart = 1;
388
0
L20:
389
390
/*        %--------------------------------------------------%   
391
          | if sigmai = 0 then                               |   
392
          |    Apply the jj-th shift ...                     |   
393
          | else                                             |   
394
          |    Apply the jj-th and (jj+1)-th together ...    |   
395
          |    (Note that jj < np at this point in the code) |   
396
          | end                                              |   
397
          | to the current block of H. The next do loop      |   
398
          | determines the current block ;                   |   
399
          %--------------------------------------------------% */
400
401
0
  i__2 = kplusp - 1;
402
0
  for (i__ = istart; i__ <= i__2; ++i__) {
403
404
/*           %----------------------------------------%   
405
             | Check for splitting and deflation. Use |   
406
             | a standard test as in the QR algorithm |   
407
             | REFERENCE: LAPACK subroutine dlahqr    |   
408
             %----------------------------------------% */
409
410
0
      tst1 = (d__1 = h__[i__ + i__ * h_dim1], abs(d__1)) + (d__2 = h__[
411
0
        i__ + 1 + (i__ + 1) * h_dim1], abs(d__2));
412
0
      if (tst1 == 0.) {
413
0
    i__3 = kplusp - jj + 1;
414
0
    tst1 = igraphdlanhs_("1", &i__3, &h__[h_offset], ldh, &workl[1]);
415
0
      }
416
/* Computing MAX */
417
0
      d__2 = ulp * tst1;
418
0
      if ((d__1 = h__[i__ + 1 + i__ * h_dim1], abs(d__1)) <= max(d__2,
419
0
        smlnum)) {
420
0
    if (msglvl > 0) {
421
0
        igraphivout_(&logfil, &c__1, &i__, &ndigit, "_napps: matrix sp"
422
0
          "litting at row/column no.", (ftnlen)42);
423
0
        igraphivout_(&logfil, &c__1, &jj, &ndigit, "_napps: matrix spl"
424
0
          "itting with shift number.", (ftnlen)43);
425
0
        igraphdvout_(&logfil, &c__1, &h__[i__ + 1 + i__ * h_dim1], &
426
0
          ndigit, "_napps: off diagonal element.", (ftnlen)
427
0
          29);
428
0
    }
429
0
    iend = i__;
430
0
    h__[i__ + 1 + i__ * h_dim1] = 0.;
431
0
    goto L40;
432
0
      }
433
/* L30: */
434
0
  }
435
0
  iend = kplusp;
436
0
L40:
437
438
0
  if (msglvl > 2) {
439
0
      igraphivout_(&logfil, &c__1, &istart, &ndigit, "_napps: Start of curre"
440
0
        "nt block ", (ftnlen)31);
441
0
      igraphivout_(&logfil, &c__1, &iend, &ndigit, "_napps: End of current b"
442
0
        "lock ", (ftnlen)29);
443
0
  }
444
445
/*        %------------------------------------------------%   
446
          | No reason to apply a shift to block of order 1 |   
447
          %------------------------------------------------% */
448
449
0
  if (istart == iend) {
450
0
      goto L100;
451
0
  }
452
453
/*        %------------------------------------------------------%   
454
          | If istart + 1 = iend then no reason to apply a       |   
455
          | complex conjugate pair of shifts on a 2 by 2 matrix. |   
456
          %------------------------------------------------------% */
457
458
0
  if (istart + 1 == iend && abs(sigmai) > 0.) {
459
0
      goto L100;
460
0
  }
461
462
0
  h11 = h__[istart + istart * h_dim1];
463
0
  h21 = h__[istart + 1 + istart * h_dim1];
464
0
  if (abs(sigmai) <= 0.) {
465
466
/*           %---------------------------------------------%   
467
             | Real-valued shift ==> apply single shift QR |   
468
             %---------------------------------------------% */
469
470
0
      f = h11 - sigmar;
471
0
      g = h21;
472
473
0
      i__2 = iend - 1;
474
0
      for (i__ = istart; i__ <= i__2; ++i__) {
475
476
/*              %-----------------------------------------------------%   
477
                | Contruct the plane rotation G to zero out the bulge |   
478
                %-----------------------------------------------------% */
479
480
0
    igraphdlartg_(&f, &g, &c__, &s, &r__);
481
0
    if (i__ > istart) {
482
483
/*                 %-------------------------------------------%   
484
                   | The following ensures that h(1:iend-1,1), |   
485
                   | the first iend-2 off diagonal of elements |   
486
                   | H, remain non negative.                   |   
487
                   %-------------------------------------------% */
488
489
0
        if (r__ < 0.) {
490
0
      r__ = -r__;
491
0
      c__ = -c__;
492
0
      s = -s;
493
0
        }
494
0
        h__[i__ + (i__ - 1) * h_dim1] = r__;
495
0
        h__[i__ + 1 + (i__ - 1) * h_dim1] = 0.;
496
0
    }
497
498
/*              %---------------------------------------------%   
499
                | Apply rotation to the left of H;  H <- G'*H |   
500
                %---------------------------------------------% */
501
502
0
    i__3 = kplusp;
503
0
    for (j = i__; j <= i__3; ++j) {
504
0
        t = c__ * h__[i__ + j * h_dim1] + s * h__[i__ + 1 + j * 
505
0
          h_dim1];
506
0
        h__[i__ + 1 + j * h_dim1] = -s * h__[i__ + j * h_dim1] + 
507
0
          c__ * h__[i__ + 1 + j * h_dim1];
508
0
        h__[i__ + j * h_dim1] = t;
509
/* L50: */
510
0
    }
511
512
/*              %---------------------------------------------%   
513
                | Apply rotation to the right of H;  H <- H*G |   
514
                %---------------------------------------------%   
515
516
   Computing MIN */
517
0
    i__4 = i__ + 2;
518
0
    i__3 = min(i__4,iend);
519
0
    for (j = 1; j <= i__3; ++j) {
520
0
        t = c__ * h__[j + i__ * h_dim1] + s * h__[j + (i__ + 1) * 
521
0
          h_dim1];
522
0
        h__[j + (i__ + 1) * h_dim1] = -s * h__[j + i__ * h_dim1] 
523
0
          + c__ * h__[j + (i__ + 1) * h_dim1];
524
0
        h__[j + i__ * h_dim1] = t;
525
/* L60: */
526
0
    }
527
528
/*              %----------------------------------------------------%   
529
                | Accumulate the rotation in the matrix Q;  Q <- Q*G |   
530
                %----------------------------------------------------%   
531
532
   Computing MIN */
533
0
    i__4 = j + jj;
534
0
    i__3 = min(i__4,kplusp);
535
0
    for (j = 1; j <= i__3; ++j) {
536
0
        t = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * 
537
0
          q_dim1];
538
0
        q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + 
539
0
          c__ * q[j + (i__ + 1) * q_dim1];
540
0
        q[j + i__ * q_dim1] = t;
541
/* L70: */
542
0
    }
543
544
/*              %---------------------------%   
545
                | Prepare for next rotation |   
546
                %---------------------------% */
547
548
0
    if (i__ < iend - 1) {
549
0
        f = h__[i__ + 1 + i__ * h_dim1];
550
0
        g = h__[i__ + 2 + i__ * h_dim1];
551
0
    }
552
/* L80: */
553
0
      }
554
555
/*           %-----------------------------------%   
556
             | Finished applying the real shift. |   
557
             %-----------------------------------% */
558
559
0
  } else {
560
561
/*           %----------------------------------------------------%   
562
             | Complex conjugate shifts ==> apply double shift QR |   
563
             %----------------------------------------------------% */
564
565
0
      h12 = h__[istart + (istart + 1) * h_dim1];
566
0
      h22 = h__[istart + 1 + (istart + 1) * h_dim1];
567
0
      h32 = h__[istart + 2 + (istart + 1) * h_dim1];
568
569
/*           %---------------------------------------------------------%   
570
             | Compute 1st column of (H - shift*I)*(H - conj(shift)*I) |   
571
             %---------------------------------------------------------% */
572
573
0
      s = sigmar * 2.f;
574
0
      t = igraphdlapy2_(&sigmar, &sigmai);
575
0
      u[0] = (h11 * (h11 - s) + t * t) / h21 + h12;
576
0
      u[1] = h11 + h22 - s;
577
0
      u[2] = h32;
578
579
0
      i__2 = iend - 1;
580
0
      for (i__ = istart; i__ <= i__2; ++i__) {
581
582
/* Computing MIN */
583
0
    i__3 = 3, i__4 = iend - i__ + 1;
584
0
    nr = min(i__3,i__4);
585
586
/*              %-----------------------------------------------------%   
587
                | Construct Householder reflector G to zero out u(1). |   
588
                | G is of the form I - tau*( 1 u )' * ( 1 u' ).       |   
589
                %-----------------------------------------------------% */
590
591
0
    igraphdlarfg_(&nr, u, &u[1], &c__1, &tau);
592
593
0
    if (i__ > istart) {
594
0
        h__[i__ + (i__ - 1) * h_dim1] = u[0];
595
0
        h__[i__ + 1 + (i__ - 1) * h_dim1] = 0.;
596
0
        if (i__ < iend - 1) {
597
0
      h__[i__ + 2 + (i__ - 1) * h_dim1] = 0.;
598
0
        }
599
0
    }
600
0
    u[0] = 1.;
601
602
/*              %--------------------------------------%   
603
                | Apply the reflector to the left of H |   
604
                %--------------------------------------% */
605
606
0
    i__3 = kplusp - i__ + 1;
607
0
    igraphdlarf_("Left", &nr, &i__3, u, &c__1, &tau, &h__[i__ + i__ * 
608
0
      h_dim1], ldh, &workl[1]);
609
610
/*              %---------------------------------------%   
611
                | Apply the reflector to the right of H |   
612
                %---------------------------------------%   
613
614
   Computing MIN */
615
0
    i__3 = i__ + 3;
616
0
    ir = min(i__3,iend);
617
0
    igraphdlarf_("Right", &ir, &nr, u, &c__1, &tau, &h__[i__ * h_dim1 + 
618
0
      1], ldh, &workl[1]);
619
620
/*              %-----------------------------------------------------%   
621
                | Accumulate the reflector in the matrix Q;  Q <- Q*G |   
622
                %-----------------------------------------------------% */
623
624
0
    igraphdlarf_("Right", &kplusp, &nr, u, &c__1, &tau, &q[i__ * q_dim1 
625
0
      + 1], ldq, &workl[1]);
626
627
/*              %----------------------------%   
628
                | Prepare for next reflector |   
629
                %----------------------------% */
630
631
0
    if (i__ < iend - 1) {
632
0
        u[0] = h__[i__ + 1 + i__ * h_dim1];
633
0
        u[1] = h__[i__ + 2 + i__ * h_dim1];
634
0
        if (i__ < iend - 2) {
635
0
      u[2] = h__[i__ + 3 + i__ * h_dim1];
636
0
        }
637
0
    }
638
639
/* L90: */
640
0
      }
641
642
/*           %--------------------------------------------%   
643
             | Finished applying a complex pair of shifts |   
644
             | to the current block                       |   
645
             %--------------------------------------------% */
646
647
0
  }
648
649
0
L100:
650
651
/*        %---------------------------------------------------------%   
652
          | Apply the same shift to the next block if there is any. |   
653
          %---------------------------------------------------------% */
654
655
0
  istart = iend + 1;
656
0
  if (iend < kplusp) {
657
0
      goto L20;
658
0
  }
659
660
/*        %---------------------------------------------%   
661
          | Loop back to the top to get the next shift. |   
662
          %---------------------------------------------% */
663
664
0
L110:
665
0
  ;
666
0
    }
667
668
/*     %--------------------------------------------------%   
669
       | Perform a similarity transformation that makes   |   
670
       | sure that H will have non negative sub diagonals |   
671
       %--------------------------------------------------% */
672
673
0
    i__1 = *kev;
674
0
    for (j = 1; j <= i__1; ++j) {
675
0
  if (h__[j + 1 + j * h_dim1] < 0.) {
676
0
      i__2 = kplusp - j + 1;
677
0
      igraphdscal_(&i__2, &c_b43, &h__[j + 1 + j * h_dim1], ldh);
678
/* Computing MIN */
679
0
      i__3 = j + 2;
680
0
      i__2 = min(i__3,kplusp);
681
0
      igraphdscal_(&i__2, &c_b43, &h__[(j + 1) * h_dim1 + 1], &c__1);
682
/* Computing MIN */
683
0
      i__3 = j + *np + 1;
684
0
      i__2 = min(i__3,kplusp);
685
0
      igraphdscal_(&i__2, &c_b43, &q[(j + 1) * q_dim1 + 1], &c__1);
686
0
  }
687
/* L120: */
688
0
    }
689
690
0
    i__1 = *kev;
691
0
    for (i__ = 1; i__ <= i__1; ++i__) {
692
693
/*        %--------------------------------------------%   
694
          | Final check for splitting and deflation.   |   
695
          | Use a standard test as in the QR algorithm |   
696
          | REFERENCE: LAPACK subroutine dlahqr        |   
697
          %--------------------------------------------% */
698
699
0
  tst1 = (d__1 = h__[i__ + i__ * h_dim1], abs(d__1)) + (d__2 = h__[i__ 
700
0
    + 1 + (i__ + 1) * h_dim1], abs(d__2));
701
0
  if (tst1 == 0.) {
702
0
      tst1 = igraphdlanhs_("1", kev, &h__[h_offset], ldh, &workl[1]);
703
0
  }
704
/* Computing MAX */
705
0
  d__1 = ulp * tst1;
706
0
  if (h__[i__ + 1 + i__ * h_dim1] <= max(d__1,smlnum)) {
707
0
      h__[i__ + 1 + i__ * h_dim1] = 0.;
708
0
  }
709
/* L130: */
710
0
    }
711
712
/*     %-------------------------------------------------%   
713
       | Compute the (kev+1)-st column of (V*Q) and      |   
714
       | temporarily store the result in WORKD(N+1:2*N). |   
715
       | This is needed in the residual update since we  |   
716
       | cannot GUARANTEE that the corresponding entry   |   
717
       | of H would be zero as in exact arithmetic.      |   
718
       %-------------------------------------------------% */
719
720
0
    if (h__[*kev + 1 + *kev * h_dim1] > 0.) {
721
0
  igraphdgemv_("N", n, &kplusp, &c_b6, &v[v_offset], ldv, &q[(*kev + 1) * 
722
0
    q_dim1 + 1], &c__1, &c_b5, &workd[*n + 1], &c__1);
723
0
    }
724
725
/*     %----------------------------------------------------------%   
726
       | Compute column 1 to kev of (V*Q) in backward order       |   
727
       | taking advantage of the upper Hessenberg structure of Q. |   
728
       %----------------------------------------------------------% */
729
730
0
    i__1 = *kev;
731
0
    for (i__ = 1; i__ <= i__1; ++i__) {
732
0
  i__2 = kplusp - i__ + 1;
733
0
  igraphdgemv_("N", n, &i__2, &c_b6, &v[v_offset], ldv, &q[(*kev - i__ + 1) * 
734
0
    q_dim1 + 1], &c__1, &c_b5, &workd[1], &c__1);
735
0
  igraphdcopy_(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], &
736
0
    c__1);
737
/* L140: */
738
0
    }
739
740
/*     %-------------------------------------------------%   
741
       |  Move v(:,kplusp-kev+1:kplusp) into v(:,1:kev). |   
742
       %-------------------------------------------------% */
743
744
0
    igraphdlacpy_("A", n, kev, &v[(kplusp - *kev + 1) * v_dim1 + 1], ldv, &v[
745
0
      v_offset], ldv);
746
747
/*     %--------------------------------------------------------------%   
748
       | Copy the (kev+1)-st column of (V*Q) in the appropriate place |   
749
       %--------------------------------------------------------------% */
750
751
0
    if (h__[*kev + 1 + *kev * h_dim1] > 0.) {
752
0
  igraphdcopy_(n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &c__1);
753
0
    }
754
755
/*     %-------------------------------------%   
756
       | Update the residual vector:         |   
757
       |    r <- sigmak*r + betak*v(:,kev+1) |   
758
       | where                               |   
759
       |    sigmak = (e_{kplusp}'*Q)*e_{kev} |   
760
       |    betak = e_{kev+1}'*H*e_{kev}     |   
761
       %-------------------------------------% */
762
763
0
    igraphdscal_(n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1);
764
0
    if (h__[*kev + 1 + *kev * h_dim1] > 0.) {
765
0
  igraphdaxpy_(n, &h__[*kev + 1 + *kev * h_dim1], &v[(*kev + 1) * v_dim1 + 1],
766
0
     &c__1, &resid[1], &c__1);
767
0
    }
768
769
0
    if (msglvl > 1) {
770
0
  igraphdvout_(&logfil, &c__1, &q[kplusp + *kev * q_dim1], &ndigit, "_napps:"
771
0
    " sigmak = (e_{kev+p}^T*Q)*e_{kev}", (ftnlen)40);
772
0
  igraphdvout_(&logfil, &c__1, &h__[*kev + 1 + *kev * h_dim1], &ndigit, "_na"
773
0
    "pps: betak = e_{kev+1}^T*H*e_{kev}", (ftnlen)37);
774
0
  igraphivout_(&logfil, &c__1, kev, &ndigit, "_napps: Order of the final Hes"
775
0
    "senberg matrix ", (ftnlen)45);
776
0
  if (msglvl > 2) {
777
0
      igraphdmout_(&logfil, kev, kev, &h__[h_offset], ldh, &ndigit, "_napps:"
778
0
        " updated Hessenberg matrix H for next iteration", (ftnlen)
779
0
        54);
780
0
  }
781
782
0
    }
783
784
0
L9000:
785
0
    igraphsecond_(&t1);
786
0
    tnapps += t1 - t0;
787
788
0
    return 0;
789
790
/*     %---------------%   
791
       | End of dnapps |   
792
       %---------------% */
793
794
0
} /* igraphdnapps_ */
795