~ubuntu-branches/ubuntu/lucid/igraph/lucid

« back to all changes in this revision

Viewing changes to src/arpack/dsapps.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Malaterre
  • Date: 2009-11-16 18:12:42 UTC
  • Revision ID: james.westby@ubuntu.com-20091116181242-mzv9p5fz9uj57xd1
Tags: upstream-0.5.3
ImportĀ upstreamĀ versionĀ 0.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  -- translated by f2c (version 20050501).
 
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 "config.h"
 
14
#include "arpack_internal.h"
 
15
#include "f2c.h"
 
16
 
 
17
/* Common Block Declarations */
 
18
 
 
19
static struct {
 
20
    integer logfil, ndigit, mgetv0, msaupd, msaup2, msaitr, mseigt, msapps, 
 
21
            msgets, mseupd, mnaupd, mnaup2, mnaitr, mneigh, mnapps, mngets, 
 
22
            mneupd, mcaupd, mcaup2, mcaitr, mceigh, mcapps, mcgets, mceupd;
 
23
} debug_;
 
24
 
 
25
#define debug_1 debug_
 
26
 
 
27
static struct {
 
28
    integer nopx, nbx, nrorth, nitref, nrstrt;
 
29
    real tsaupd, tsaup2, tsaitr, tseigt, tsgets, tsapps, tsconv, tnaupd, 
 
30
            tnaup2, tnaitr, tneigh, tngets, tnapps, tnconv, tcaupd, tcaup2, 
 
31
            tcaitr, tceigh, tcgets, tcapps, tcconv, tmvopx, tmvbx, tgetv0, 
 
32
            titref, trvec;
 
33
} timing_;
 
34
 
 
35
#define timing_1 timing_
 
36
 
 
37
/* Table of constant values */
 
38
 
 
39
static doublereal c_b4 = 0.;
 
40
static doublereal c_b5 = 1.;
 
41
static integer c__1 = 1;
 
42
static doublereal c_b20 = -1.;
 
43
 
 
44
/* ----------------------------------------------------------------------- */
 
45
/* \BeginDoc */
 
46
 
 
47
/* \Name: dsapps */
 
48
 
 
49
/* \Description: */
 
50
/*  Given the Arnoldi factorization */
 
51
 
 
52
/*     A*V_{k} - V_{k}*H_{k} = r_{k+p}*e_{k+p}^T, */
 
53
 
 
54
/*  apply NP shifts implicitly resulting in */
 
55
 
 
56
/*     A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q */
 
57
 
 
58
/*  where Q is an orthogonal matrix of order KEV+NP. Q is the product of */
 
59
/*  rotations resulting from the NP bulge chasing sweeps.  The updated Arnoldi */
 
60
/*  factorization becomes: */
 
61
 
 
62
/*     A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T. */
 
63
 
 
64
/* \Usage: */
 
65
/*  call dsapps */
 
66
/*     ( N, KEV, NP, SHIFT, V, LDV, H, LDH, RESID, Q, LDQ, WORKD ) */
 
67
 
 
68
/* \Arguments */
 
69
/*  N       Integer.  (INPUT) */
 
70
/*          Problem size, i.e. dimension of matrix A. */
 
71
 
 
72
/*  KEV     Integer.  (INPUT) */
 
73
/*          INPUT: KEV+NP is the size of the input matrix H. */
 
74
/*          OUTPUT: KEV is the size of the updated matrix HNEW. */
 
75
 
 
76
/*  NP      Integer.  (INPUT) */
 
77
/*          Number of implicit shifts to be applied. */
 
78
 
 
79
/*  SHIFT   Double precision array of length NP.  (INPUT) */
 
80
/*          The shifts to be applied. */
 
81
 
 
82
/*  V       Double precision N by (KEV+NP) array.  (INPUT/OUTPUT) */
 
83
/*          INPUT: V contains the current KEV+NP Arnoldi vectors. */
 
84
/*          OUTPUT: VNEW = V(1:n,1:KEV); the updated Arnoldi vectors */
 
85
/*          are in the first KEV columns of V. */
 
86
 
 
87
/*  LDV     Integer.  (INPUT) */
 
88
/*          Leading dimension of V exactly as declared in the calling */
 
89
/*          program. */
 
90
 
 
91
/*  H       Double precision (KEV+NP) by 2 array.  (INPUT/OUTPUT) */
 
92
/*          INPUT: H contains the symmetric tridiagonal matrix of the */
 
93
/*          Arnoldi factorization with the subdiagonal in the 1st column */
 
94
/*          starting at H(2,1) and the main diagonal in the 2nd column. */
 
95
/*          OUTPUT: H contains the updated tridiagonal matrix in the */
 
96
/*          KEV leading submatrix. */
 
97
 
 
98
/*  LDH     Integer.  (INPUT) */
 
99
/*          Leading dimension of H exactly as declared in the calling */
 
100
/*          program. */
 
101
 
 
102
/*  RESID   Double precision array of length (N).  (INPUT/OUTPUT) */
 
103
/*          INPUT: RESID contains the the residual vector r_{k+p}. */
 
104
/*          OUTPUT: RESID is the updated residual vector rnew_{k}. */
 
105
 
 
106
/*  Q       Double precision KEV+NP by KEV+NP work array.  (WORKSPACE) */
 
107
/*          Work array used to accumulate the rotations during the bulge */
 
108
/*          chase sweep. */
 
109
 
 
110
/*  LDQ     Integer.  (INPUT) */
 
111
/*          Leading dimension of Q exactly as declared in the calling */
 
112
/*          program. */
 
113
 
 
114
/*  WORKD   Double precision work array of length 2*N.  (WORKSPACE) */
 
115
/*          Distributed array used in the application of the accumulated */
 
116
/*          orthogonal matrix Q. */
 
117
 
 
118
/* \EndDoc */
 
119
 
 
120
/* ----------------------------------------------------------------------- */
 
121
 
 
122
/* \BeginLib */
 
123
 
 
124
/* \Local variables: */
 
125
/*     xxxxxx  real */
 
126
 
 
127
/* \References: */
 
128
/*  1. D.C. Sorensen, "Implicit Application of Polynomial Filters in */
 
129
/*     a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), */
 
130
/*     pp 357-385. */
 
131
/*  2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly */
 
132
/*     Restarted Arnoldi Iteration", Rice University Technical Report */
 
133
/*     TR95-13, Department of Computational and Applied Mathematics. */
 
134
 
 
135
/* \Routines called: */
 
136
/*     ivout   ARPACK utility routine that prints integers. */
 
137
/*     second  ARPACK utility routine for timing. */
 
138
/*     dvout   ARPACK utility routine that prints vectors. */
 
139
/*     dlamch  LAPACK routine that determines machine constants. */
 
140
/*     dlartg  LAPACK Givens rotation construction routine. */
 
141
/*     dlacpy  LAPACK matrix copy routine. */
 
142
/*     dlaset  LAPACK matrix initialization routine. */
 
143
/*     dgemv   Level 2 BLAS routine for matrix vector multiplication. */
 
144
/*     daxpy   Level 1 BLAS that computes a vector triad. */
 
145
/*     dcopy   Level 1 BLAS that copies one vector to another. */
 
146
/*     dscal   Level 1 BLAS that scales a vector. */
 
147
 
 
148
/* \Author */
 
149
/*     Danny Sorensen               Phuong Vu */
 
150
/*     Richard Lehoucq              CRPC / Rice University */
 
151
/*     Dept. of Computational &     Houston, Texas */
 
152
/*     Applied Mathematics */
 
153
/*     Rice University */
 
154
/*     Houston, Texas */
 
155
 
 
156
/* \Revision history: */
 
157
/*     12/16/93: Version ' 2.4' */
 
158
 
 
159
/* \SCCS Information: @(#) */
 
160
/* FILE: sapps.F   SID: 2.6   DATE OF SID: 3/28/97   RELEASE: 2 */
 
161
 
 
162
/* \Remarks */
 
163
/*  1. In this version, each shift is applied to all the subblocks of */
 
164
/*     the tridiagonal matrix H and not just to the submatrix that it */
 
165
/*     comes from. This routine assumes that the subdiagonal elements */
 
166
/*     of H that are stored in h(1:kev+np,1) are nonegative upon input */
 
167
/*     and enforce this condition upon output. This version incorporates */
 
168
/*     deflation. See code for documentation. */
 
169
 
 
170
/* \EndLib */
 
171
 
 
172
/* ----------------------------------------------------------------------- */
 
173
 
 
174
/* Subroutine */ int igraphdsapps_(integer *n, integer *kev, integer *np, 
 
175
        doublereal *shift, doublereal *v, integer *ldv, doublereal *h__, 
 
176
        integer *ldh, doublereal *resid, doublereal *q, integer *ldq, 
 
177
        doublereal *workd)
 
178
{
 
179
    /* Initialized data */
 
180
 
 
181
    static logical first = TRUE_;
 
182
 
 
183
    /* System generated locals */
 
184
    integer h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, 
 
185
            i__3, i__4;
 
186
    doublereal d__1, d__2;
 
187
 
 
188
    /* Local variables */
 
189
    static doublereal c__, f, g;
 
190
    static integer i__, j;
 
191
    static doublereal r__, s, a1, a2, a3, a4;
 
192
    static real t0, t1;
 
193
    static integer jj;
 
194
    static doublereal big;
 
195
    extern /* Subroutine */ int igraphdscal_(integer *, doublereal *, 
 
196
            doublereal *, integer *), igraphdgemv_(char *, integer *, integer 
 
197
            *, doublereal *, doublereal *, integer *, doublereal *, integer *,
 
198
             doublereal *, doublereal *, integer *), igraphdcopy_(
 
199
            integer *, doublereal *, integer *, doublereal *, integer *), 
 
200
            igraphdaxpy_(integer *, doublereal *, doublereal *, integer *, 
 
201
            doublereal *, integer *), igraphdvout_(integer *, integer *, 
 
202
            doublereal *, integer *, char *), igraphivout_(integer *, 
 
203
            integer *, integer *, integer *, char *);
 
204
    static integer iend, itop;
 
205
    extern doublereal igraphdlamch_(char *);
 
206
    extern /* Subroutine */ int igraphsecond_(real *), igraphdlacpy_(char *, 
 
207
            integer *, integer *, doublereal *, integer *, doublereal *, 
 
208
            integer *), igraphdlartg_(doublereal *, doublereal *, 
 
209
            doublereal *, doublereal *, doublereal *), igraphdlaset_(char *, 
 
210
            integer *, integer *, doublereal *, doublereal *, doublereal *, 
 
211
            integer *);
 
212
    static doublereal epsmch;
 
213
    static integer istart, kplusp, msglvl;
 
214
 
 
215
 
 
216
/*     %----------------------------------------------------% */
 
217
/*     | Include files for debugging and timing information | */
 
218
/*     %----------------------------------------------------% */
 
219
 
 
220
 
 
221
/* \SCCS Information: @(#) */
 
222
/* FILE: debug.h   SID: 2.3   DATE OF SID: 11/16/95   RELEASE: 2 */
 
223
 
 
224
/*     %---------------------------------% */
 
225
/*     | See debug.doc for documentation | */
 
226
/*     %---------------------------------% */
 
227
 
 
228
/*     %------------------% */
 
229
/*     | Scalar Arguments | */
 
230
/*     %------------------% */
 
231
 
 
232
/*     %--------------------------------% */
 
233
/*     | See stat.doc for documentation | */
 
234
/*     %--------------------------------% */
 
235
 
 
236
/* \SCCS Information: @(#) */
 
237
/* FILE: stat.h   SID: 2.2   DATE OF SID: 11/16/95   RELEASE: 2 */
 
238
 
 
239
 
 
240
 
 
241
/*     %-----------------% */
 
242
/*     | Array Arguments | */
 
243
/*     %-----------------% */
 
244
 
 
245
 
 
246
/*     %------------% */
 
247
/*     | Parameters | */
 
248
/*     %------------% */
 
249
 
 
250
 
 
251
/*     %---------------% */
 
252
/*     | Local Scalars | */
 
253
/*     %---------------% */
 
254
 
 
255
 
 
256
 
 
257
/*     %----------------------% */
 
258
/*     | External Subroutines | */
 
259
/*     %----------------------% */
 
260
 
 
261
 
 
262
/*     %--------------------% */
 
263
/*     | External Functions | */
 
264
/*     %--------------------% */
 
265
 
 
266
 
 
267
/*     %----------------------% */
 
268
/*     | Intrinsics Functions | */
 
269
/*     %----------------------% */
 
270
 
 
271
 
 
272
/*     %----------------% */
 
273
/*     | Data statments | */
 
274
/*     %----------------% */
 
275
 
 
276
    /* Parameter adjustments */
 
277
    --workd;
 
278
    --resid;
 
279
    --shift;
 
280
    v_dim1 = *ldv;
 
281
    v_offset = 1 + v_dim1;
 
282
    v -= v_offset;
 
283
    h_dim1 = *ldh;
 
284
    h_offset = 1 + h_dim1;
 
285
    h__ -= h_offset;
 
286
    q_dim1 = *ldq;
 
287
    q_offset = 1 + q_dim1;
 
288
    q -= q_offset;
 
289
 
 
290
    /* Function Body */
 
291
 
 
292
/*     %-----------------------% */
 
293
/*     | Executable Statements | */
 
294
/*     %-----------------------% */
 
295
 
 
296
    if (first) {
 
297
        epsmch = igraphdlamch_("Epsilon-Machine");
 
298
        first = FALSE_;
 
299
    }
 
300
    itop = 1;
 
301
 
 
302
/*     %-------------------------------% */
 
303
/*     | Initialize timing statistics  | */
 
304
/*     | & message level for debugging | */
 
305
/*     %-------------------------------% */
 
306
 
 
307
    igraphsecond_(&t0);
 
308
    msglvl = debug_1.msapps;
 
309
 
 
310
    kplusp = *kev + *np;
 
311
 
 
312
/*     %----------------------------------------------% */
 
313
/*     | Initialize Q to the identity matrix of order | */
 
314
/*     | kplusp used to accumulate the rotations.     | */
 
315
/*     %----------------------------------------------% */
 
316
 
 
317
    igraphdlaset_("All", &kplusp, &kplusp, &c_b4, &c_b5, &q[q_offset], ldq);
 
318
 
 
319
/*     %----------------------------------------------% */
 
320
/*     | Quick return if there are no shifts to apply | */
 
321
/*     %----------------------------------------------% */
 
322
 
 
323
    if (*np == 0) {
 
324
        goto L9000;
 
325
    }
 
326
 
 
327
/*     %----------------------------------------------------------% */
 
328
/*     | Apply the np shifts implicitly. Apply each shift to the  | */
 
329
/*     | whole matrix and not just to the submatrix from which it | */
 
330
/*     | comes.                                                   | */
 
331
/*     %----------------------------------------------------------% */
 
332
 
 
333
    i__1 = *np;
 
334
    for (jj = 1; jj <= i__1; ++jj) {
 
335
 
 
336
        istart = itop;
 
337
 
 
338
/*        %----------------------------------------------------------% */
 
339
/*        | Check for splitting and deflation. Currently we consider | */
 
340
/*        | an off-diagonal element h(i+1,1) negligible if           | */
 
341
/*        |         h(i+1,1) .le. epsmch*( |h(i,2)| + |h(i+1,2)| )   | */
 
342
/*        | for i=1:KEV+NP-1.                                        | */
 
343
/*        | If above condition tests true then we set h(i+1,1) = 0.  | */
 
344
/*        | Note that h(1:KEV+NP,1) are assumed to be non negative.  | */
 
345
/*        %----------------------------------------------------------% */
 
346
 
 
347
L20:
 
348
 
 
349
/*        %------------------------------------------------% */
 
350
/*        | The following loop exits early if we encounter | */
 
351
/*        | a negligible off diagonal element.             | */
 
352
/*        %------------------------------------------------% */
 
353
 
 
354
        i__2 = kplusp - 1;
 
355
        for (i__ = istart; i__ <= i__2; ++i__) {
 
356
            big = (d__1 = h__[i__ + (h_dim1 << 1)], abs(d__1)) + (d__2 = h__[
 
357
                    i__ + 1 + (h_dim1 << 1)], abs(d__2));
 
358
            if (h__[i__ + 1 + h_dim1] <= epsmch * big) {
 
359
                if (msglvl > 0) {
 
360
                    igraphivout_(&debug_1.logfil, &c__1, &i__, &
 
361
                            debug_1.ndigit, "_sapps: deflation at row/column"
 
362
                            " no.");
 
363
                    igraphivout_(&debug_1.logfil, &c__1, &jj, &debug_1.ndigit,
 
364
                             "_sapps: occured before shift number.");
 
365
                    igraphdvout_(&debug_1.logfil, &c__1, &h__[i__ + 1 + 
 
366
                            h_dim1], &debug_1.ndigit, "_sapps: the correspon"
 
367
                            "ding off diagonal element");
 
368
                }
 
369
                h__[i__ + 1 + h_dim1] = 0.;
 
370
                iend = i__;
 
371
                goto L40;
 
372
            }
 
373
/* L30: */
 
374
        }
 
375
        iend = kplusp;
 
376
L40:
 
377
 
 
378
        if (istart < iend) {
 
379
 
 
380
/*           %--------------------------------------------------------% */
 
381
/*           | Construct the plane rotation G'(istart,istart+1,theta) | */
 
382
/*           | that attempts to drive h(istart+1,1) to zero.          | */
 
383
/*           %--------------------------------------------------------% */
 
384
 
 
385
            f = h__[istart + (h_dim1 << 1)] - shift[jj];
 
386
            g = h__[istart + 1 + h_dim1];
 
387
            igraphdlartg_(&f, &g, &c__, &s, &r__);
 
388
 
 
389
/*            %-------------------------------------------------------% */
 
390
/*            | Apply rotation to the left and right of H;            | */
 
391
/*            | H <- G' * H * G,  where G = G(istart,istart+1,theta). | */
 
392
/*            | This will create a "bulge".                           | */
 
393
/*            %-------------------------------------------------------% */
 
394
 
 
395
            a1 = c__ * h__[istart + (h_dim1 << 1)] + s * h__[istart + 1 + 
 
396
                    h_dim1];
 
397
            a2 = c__ * h__[istart + 1 + h_dim1] + s * h__[istart + 1 + (
 
398
                    h_dim1 << 1)];
 
399
            a4 = c__ * h__[istart + 1 + (h_dim1 << 1)] - s * h__[istart + 1 + 
 
400
                    h_dim1];
 
401
            a3 = c__ * h__[istart + 1 + h_dim1] - s * h__[istart + (h_dim1 << 
 
402
                    1)];
 
403
            h__[istart + (h_dim1 << 1)] = c__ * a1 + s * a2;
 
404
            h__[istart + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3;
 
405
            h__[istart + 1 + h_dim1] = c__ * a3 + s * a4;
 
406
 
 
407
/*            %----------------------------------------------------% */
 
408
/*            | Accumulate the rotation in the matrix Q;  Q <- Q*G | */
 
409
/*            %----------------------------------------------------% */
 
410
 
 
411
/* Computing MIN */
 
412
            i__3 = istart + jj;
 
413
            i__2 = min(i__3,kplusp);
 
414
            for (j = 1; j <= i__2; ++j) {
 
415
                a1 = c__ * q[j + istart * q_dim1] + s * q[j + (istart + 1) * 
 
416
                        q_dim1];
 
417
                q[j + (istart + 1) * q_dim1] = -s * q[j + istart * q_dim1] + 
 
418
                        c__ * q[j + (istart + 1) * q_dim1];
 
419
                q[j + istart * q_dim1] = a1;
 
420
/* L60: */
 
421
            }
 
422
 
 
423
 
 
424
/*            %----------------------------------------------% */
 
425
/*            | The following loop chases the bulge created. | */
 
426
/*            | Note that the previous rotation may also be  | */
 
427
/*            | done within the following loop. But it is    | */
 
428
/*            | kept separate to make the distinction among  | */
 
429
/*            | the bulge chasing sweeps and the first plane | */
 
430
/*            | rotation designed to drive h(istart+1,1) to  | */
 
431
/*            | zero.                                        | */
 
432
/*            %----------------------------------------------% */
 
433
 
 
434
            i__2 = iend - 1;
 
435
            for (i__ = istart + 1; i__ <= i__2; ++i__) {
 
436
 
 
437
/*               %----------------------------------------------% */
 
438
/*               | Construct the plane rotation G'(i,i+1,theta) | */
 
439
/*               | that zeros the i-th bulge that was created   | */
 
440
/*               | by G(i-1,i,theta). g represents the bulge.   | */
 
441
/*               %----------------------------------------------% */
 
442
 
 
443
                f = h__[i__ + h_dim1];
 
444
                g = s * h__[i__ + 1 + h_dim1];
 
445
 
 
446
/*               %----------------------------------% */
 
447
/*               | Final update with G(i-1,i,theta) | */
 
448
/*               %----------------------------------% */
 
449
 
 
450
                h__[i__ + 1 + h_dim1] = c__ * h__[i__ + 1 + h_dim1];
 
451
                igraphdlartg_(&f, &g, &c__, &s, &r__);
 
452
 
 
453
/*               %-------------------------------------------% */
 
454
/*               | The following ensures that h(1:iend-1,1), | */
 
455
/*               | the first iend-2 off diagonal of elements | */
 
456
/*               | H, remain non negative.                   | */
 
457
/*               %-------------------------------------------% */
 
458
 
 
459
                if (r__ < 0.) {
 
460
                    r__ = -r__;
 
461
                    c__ = -c__;
 
462
                    s = -s;
 
463
                }
 
464
 
 
465
/*               %--------------------------------------------% */
 
466
/*               | Apply rotation to the left and right of H; | */
 
467
/*               | H <- G * H * G',  where G = G(i,i+1,theta) | */
 
468
/*               %--------------------------------------------% */
 
469
 
 
470
                h__[i__ + h_dim1] = r__;
 
471
 
 
472
                a1 = c__ * h__[i__ + (h_dim1 << 1)] + s * h__[i__ + 1 + 
 
473
                        h_dim1];
 
474
                a2 = c__ * h__[i__ + 1 + h_dim1] + s * h__[i__ + 1 + (h_dim1 
 
475
                        << 1)];
 
476
                a3 = c__ * h__[i__ + 1 + h_dim1] - s * h__[i__ + (h_dim1 << 1)
 
477
                        ];
 
478
                a4 = c__ * h__[i__ + 1 + (h_dim1 << 1)] - s * h__[i__ + 1 + 
 
479
                        h_dim1];
 
480
 
 
481
                h__[i__ + (h_dim1 << 1)] = c__ * a1 + s * a2;
 
482
                h__[i__ + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3;
 
483
                h__[i__ + 1 + h_dim1] = c__ * a3 + s * a4;
 
484
 
 
485
/*               %----------------------------------------------------% */
 
486
/*               | Accumulate the rotation in the matrix Q;  Q <- Q*G | */
 
487
/*               %----------------------------------------------------% */
 
488
 
 
489
/* Computing MIN */
 
490
                i__4 = i__ + jj;
 
491
                i__3 = min(i__4,kplusp);
 
492
                for (j = 1; j <= i__3; ++j) {
 
493
                    a1 = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * 
 
494
                            q_dim1];
 
495
                    q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + 
 
496
                            c__ * q[j + (i__ + 1) * q_dim1];
 
497
                    q[j + i__ * q_dim1] = a1;
 
498
/* L50: */
 
499
                }
 
500
 
 
501
/* L70: */
 
502
            }
 
503
 
 
504
        }
 
505
 
 
506
/*        %--------------------------% */
 
507
/*        | Update the block pointer | */
 
508
/*        %--------------------------% */
 
509
 
 
510
        istart = iend + 1;
 
511
 
 
512
/*        %------------------------------------------% */
 
513
/*        | Make sure that h(iend,1) is non-negative | */
 
514
/*        | If not then set h(iend,1) <-- -h(iend,1) | */
 
515
/*        | and negate the last column of Q.         | */
 
516
/*        | We have effectively carried out a        | */
 
517
/*        | similarity on transformation H           | */
 
518
/*        %------------------------------------------% */
 
519
 
 
520
        if (h__[iend + h_dim1] < 0.) {
 
521
            h__[iend + h_dim1] = -h__[iend + h_dim1];
 
522
            igraphdscal_(&kplusp, &c_b20, &q[iend * q_dim1 + 1], &c__1);
 
523
        }
 
524
 
 
525
/*        %--------------------------------------------------------% */
 
526
/*        | Apply the same shift to the next block if there is any | */
 
527
/*        %--------------------------------------------------------% */
 
528
 
 
529
        if (iend < kplusp) {
 
530
            goto L20;
 
531
        }
 
532
 
 
533
/*        %-----------------------------------------------------% */
 
534
/*        | Check if we can increase the the start of the block | */
 
535
/*        %-----------------------------------------------------% */
 
536
 
 
537
        i__2 = kplusp - 1;
 
538
        for (i__ = itop; i__ <= i__2; ++i__) {
 
539
            if (h__[i__ + 1 + h_dim1] > 0.) {
 
540
                goto L90;
 
541
            }
 
542
            ++itop;
 
543
/* L80: */
 
544
        }
 
545
 
 
546
/*        %-----------------------------------% */
 
547
/*        | Finished applying the jj-th shift | */
 
548
/*        %-----------------------------------% */
 
549
 
 
550
L90:
 
551
        ;
 
552
    }
 
553
 
 
554
/*     %------------------------------------------% */
 
555
/*     | All shifts have been applied. Check for  | */
 
556
/*     | more possible deflation that might occur | */
 
557
/*     | after the last shift is applied.         | */
 
558
/*     %------------------------------------------% */
 
559
 
 
560
    i__1 = kplusp - 1;
 
561
    for (i__ = itop; i__ <= i__1; ++i__) {
 
562
        big = (d__1 = h__[i__ + (h_dim1 << 1)], abs(d__1)) + (d__2 = h__[i__ 
 
563
                + 1 + (h_dim1 << 1)], abs(d__2));
 
564
        if (h__[i__ + 1 + h_dim1] <= epsmch * big) {
 
565
            if (msglvl > 0) {
 
566
                igraphivout_(&debug_1.logfil, &c__1, &i__, &debug_1.ndigit, 
 
567
                        "_sapps: deflation at row/column no.");
 
568
                igraphdvout_(&debug_1.logfil, &c__1, &h__[i__ + 1 + h_dim1], &
 
569
                        debug_1.ndigit, "_sapps: the corresponding off diago"
 
570
                        "nal element");
 
571
            }
 
572
            h__[i__ + 1 + h_dim1] = 0.;
 
573
        }
 
574
/* L100: */
 
575
    }
 
576
 
 
577
/*     %-------------------------------------------------% */
 
578
/*     | Compute the (kev+1)-st column of (V*Q) and      | */
 
579
/*     | temporarily store the result in WORKD(N+1:2*N). | */
 
580
/*     | This is not necessary if h(kev+1,1) = 0.         | */
 
581
/*     %-------------------------------------------------% */
 
582
 
 
583
    if (h__[*kev + 1 + h_dim1] > 0.) {
 
584
        igraphdgemv_("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) 
 
585
                * q_dim1 + 1], &c__1, &c_b4, &workd[*n + 1], &c__1)
 
586
                ;
 
587
    }
 
588
 
 
589
/*     %-------------------------------------------------------% */
 
590
/*     | Compute column 1 to kev of (V*Q) in backward order    | */
 
591
/*     | taking advantage that Q is an upper triangular matrix | */
 
592
/*     | with lower bandwidth np.                              | */
 
593
/*     | Place results in v(:,kplusp-kev:kplusp) temporarily.  | */
 
594
/*     %-------------------------------------------------------% */
 
595
 
 
596
    i__1 = *kev;
 
597
    for (i__ = 1; i__ <= i__1; ++i__) {
 
598
        i__2 = kplusp - i__ + 1;
 
599
        igraphdgemv_("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ 
 
600
                + 1) * q_dim1 + 1], &c__1, &c_b4, &workd[1], &c__1)
 
601
                ;
 
602
        igraphdcopy_(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1],
 
603
                 &c__1);
 
604
/* L130: */
 
605
    }
 
606
 
 
607
/*     %-------------------------------------------------% */
 
608
/*     |  Move v(:,kplusp-kev+1:kplusp) into v(:,1:kev). | */
 
609
/*     %-------------------------------------------------% */
 
610
 
 
611
    igraphdlacpy_("All", n, kev, &v[(*np + 1) * v_dim1 + 1], ldv, &v[v_offset]
 
612
            , ldv);
 
613
 
 
614
/*     %--------------------------------------------% */
 
615
/*     | Copy the (kev+1)-st column of (V*Q) in the | */
 
616
/*     | appropriate place if h(kev+1,1) .ne. zero. | */
 
617
/*     %--------------------------------------------% */
 
618
 
 
619
    if (h__[*kev + 1 + h_dim1] > 0.) {
 
620
        igraphdcopy_(n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &
 
621
                c__1);
 
622
    }
 
623
 
 
624
/*     %-------------------------------------% */
 
625
/*     | Update the residual vector:         | */
 
626
/*     |    r <- sigmak*r + betak*v(:,kev+1) | */
 
627
/*     | where                               | */
 
628
/*     |    sigmak = (e_{kev+p}'*Q)*e_{kev}  | */
 
629
/*     |    betak = e_{kev+1}'*H*e_{kev}     | */
 
630
/*     %-------------------------------------% */
 
631
 
 
632
    igraphdscal_(n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1);
 
633
    if (h__[*kev + 1 + h_dim1] > 0.) {
 
634
        igraphdaxpy_(n, &h__[*kev + 1 + h_dim1], &v[(*kev + 1) * v_dim1 + 1], 
 
635
                &c__1, &resid[1], &c__1);
 
636
    }
 
637
 
 
638
    if (msglvl > 1) {
 
639
        igraphdvout_(&debug_1.logfil, &c__1, &q[kplusp + *kev * q_dim1], &
 
640
                debug_1.ndigit, "_sapps: sigmak of the updated residual vect"
 
641
                "or");
 
642
        igraphdvout_(&debug_1.logfil, &c__1, &h__[*kev + 1 + h_dim1], &
 
643
                debug_1.ndigit, "_sapps: betak of the updated residual vector"
 
644
                );
 
645
        igraphdvout_(&debug_1.logfil, kev, &h__[(h_dim1 << 1) + 1], &
 
646
                debug_1.ndigit, "_sapps: updated main diagonal of H for next"
 
647
                " iteration");
 
648
        if (*kev > 1) {
 
649
            i__1 = *kev - 1;
 
650
            igraphdvout_(&debug_1.logfil, &i__1, &h__[h_dim1 + 2], &
 
651
                    debug_1.ndigit, "_sapps: updated sub diagonal of H for n"
 
652
                    "ext iteration");
 
653
        }
 
654
    }
 
655
 
 
656
    igraphsecond_(&t1);
 
657
    timing_1.tsapps += t1 - t0;
 
658
 
 
659
L9000:
 
660
    return 0;
 
661
 
 
662
/*     %---------------% */
 
663
/*     | End of dsapps | */
 
664
/*     %---------------% */
 
665
 
 
666
} /* igraphdsapps_ */
 
667