~ubuntu-branches/ubuntu/saucy/igraph/saucy

« back to all changes in this revision

Viewing changes to src/arpack/dnaup2.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
/* igraphdnaup2.f -- 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_b3 = .66666666666666663;
 
40
static integer c__1 = 1;
 
41
static integer c__0 = 0;
 
42
static integer c__4 = 4;
 
43
static logical c_true = TRUE_;
 
44
static integer c__2 = 2;
 
45
 
 
46
/* \BeginDoc */
 
47
 
 
48
/* \Name: igraphdnaup2 */
 
49
 
 
50
/* \Description: */
 
51
/*  Intermediate level interface called by igraphdnaupd . */
 
52
 
 
53
/* \Usage: */
 
54
/*  call igraphdnaup2 */
 
55
/*     ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD, */
 
56
/*       ISHIFT, MXITER, V, LDV, H, LDH, RITZR, RITZI, BOUNDS, */
 
57
/*       Q, LDQ, WORKL, IPNTR, WORKD, INFO ) */
 
58
 
 
59
/* \Arguments */
 
60
 
 
61
/*  IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in igraphdnaupd . */
 
62
/*  MODE, ISHIFT, MXITER: see the definition of IPARAM in igraphdnaupd . */
 
63
 
 
64
/*  NP      Integer.  (INPUT/OUTPUT) */
 
65
/*          Contains the number of implicit shifts to apply during */
 
66
/*          each Arnoldi iteration. */
 
67
/*          If ISHIFT=1, NP is adjusted dynamically at each iteration */
 
68
/*          to accelerate convergence and prevent stagnation. */
 
69
/*          This is also roughly equal to the number of matrix-vector */
 
70
/*          products (involving the operator OP) per Arnoldi iteration. */
 
71
/*          The logic for adjusting is contained within the current */
 
72
/*          subroutine. */
 
73
/*          If ISHIFT=0, NP is the number of shifts the user needs */
 
74
/*          to provide via reverse comunication. 0 < NP < NCV-NEV. */
 
75
/*          NP may be less than NCV-NEV for two reasons. The first, is */
 
76
/*          to keep complex conjugate pairs of "wanted" Ritz values */
 
77
/*          together. The second, is that a leading block of the current */
 
78
/*          upper Hessenberg matrix has split off and contains "unwanted" */
 
79
/*          Ritz values. */
 
80
/*          Upon termination of the IRA iteration, NP contains the number */
 
81
/*          of "converged" wanted Ritz values. */
 
82
 
 
83
/*  IUPD    Integer.  (INPUT) */
 
84
/*          IUPD .EQ. 0: use explicit restart instead implicit update. */
 
85
/*          IUPD .NE. 0: use implicit update. */
 
86
 
 
87
/*  V       Double precision  N by (NEV+NP) array.  (INPUT/OUTPUT) */
 
88
/*          The Arnoldi basis vectors are returned in the first NEV */
 
89
/*          columns of V. */
 
90
 
 
91
/*  LDV     Integer.  (INPUT) */
 
92
/*          Leading dimension of V exactly as declared in the calling */
 
93
/*          program. */
 
94
 
 
95
/*  H       Double precision  (NEV+NP) by (NEV+NP) array.  (OUTPUT) */
 
96
/*          H is used to store the generated upper Hessenberg matrix */
 
97
 
 
98
/*  LDH     Integer.  (INPUT) */
 
99
/*          Leading dimension of H exactly as declared in the calling */
 
100
/*          program. */
 
101
 
 
102
/*  RITZR,  Double precision  arrays of length NEV+NP.  (OUTPUT) */
 
103
/*  RITZI   RITZR(1:NEV) (resp. RITZI(1:NEV)) contains the real (resp. */
 
104
/*          imaginary) part of the computed Ritz values of OP. */
 
105
 
 
106
/*  BOUNDS  Double precision  array of length NEV+NP.  (OUTPUT) */
 
107
/*          BOUNDS(1:NEV) contain the error bounds corresponding to */
 
108
/*          the computed Ritz values. */
 
109
 
 
110
/*  Q       Double precision  (NEV+NP) by (NEV+NP) array.  (WORKSPACE) */
 
111
/*          Private (replicated) work array used to accumulate the */
 
112
/*          rotation in the shift application step. */
 
113
 
 
114
/*  LDQ     Integer.  (INPUT) */
 
115
/*          Leading dimension of Q exactly as declared in the calling */
 
116
/*          program. */
 
117
 
 
118
/*  WORKL   Double precision  work array of length at least */
 
119
/*          (NEV+NP)**2 + 3*(NEV+NP).  (INPUT/WORKSPACE) */
 
120
/*          Private (replicated) array on each PE or array allocated on */
 
121
/*          the front end.  It is used in shifts calculation, shifts */
 
122
/*          application and convergence checking. */
 
123
 
 
124
/*          On exit, the last 3*(NEV+NP) locations of WORKL contain */
 
125
/*          the Ritz values (real,imaginary) and associated Ritz */
 
126
/*          estimates of the current Hessenberg matrix.  They are */
 
127
/*          listed in the same order as returned from dneigh . */
 
128
 
 
129
/*          If ISHIFT .EQ. O and IDO .EQ. 3, the first 2*NP locations */
 
130
/*          of WORKL are used in reverse communication to hold the user */
 
131
/*          supplied shifts. */
 
132
 
 
133
/*  IPNTR   Integer array of length 3.  (OUTPUT) */
 
134
/*          Pointer to mark the starting locations in the WORKD for */
 
135
/*          vectors used by the Arnoldi iteration. */
 
136
/*          ------------------------------------------------------------- */
 
137
/*          IPNTR(1): pointer to the current operand vector X. */
 
138
/*          IPNTR(2): pointer to the current result vector Y. */
 
139
/*          IPNTR(3): pointer to the vector B * X when used in the */
 
140
/*                    shift-and-invert mode.  X is the current operand. */
 
141
/*          ------------------------------------------------------------- */
 
142
 
 
143
/*  WORKD   Double precision  work array of length 3*N.  (WORKSPACE) */
 
144
/*          Distributed array to be used in the basic Arnoldi iteration */
 
145
/*          for reverse communication.  The user should not use WORKD */
 
146
/*          as temporary workspace during the iteration !!!!!!!!!! */
 
147
/*          See Data Distribution Note in DNAUPD. */
 
148
 
 
149
/*  INFO    Integer.  (INPUT/OUTPUT) */
 
150
/*          If INFO .EQ. 0, a randomly initial residual vector is used. */
 
151
/*          If INFO .NE. 0, RESID contains the initial residual vector, */
 
152
/*                          possibly from a previous run. */
 
153
/*          Error flag on output. */
 
154
/*          =     0: Normal return. */
 
155
/*          =     1: Maximum number of iterations taken. */
 
156
/*                   All possible eigenvalues of OP has been found. */
 
157
/*                   NP returns the number of converged Ritz values. */
 
158
/*          =     2: No shifts could be applied. */
 
159
/*          =    -8: Error return from LAPACK eigenvalue calculation; */
 
160
/*                   This should never happen. */
 
161
/*          =    -9: Starting vector is zero. */
 
162
/*          = -9999: Could not build an Arnoldi factorization. */
 
163
/*                   Size that was built in returned in NP. */
 
164
 
 
165
/* \EndDoc */
 
166
 
 
167
/* ----------------------------------------------------------------------- */
 
168
 
 
169
/* \BeginLib */
 
170
 
 
171
/* \Local variables: */
 
172
/*     xxxxxx  real */
 
173
 
 
174
/* \References: */
 
175
/*  1. D.C. Sorensen, "Implicit Application of Polynomial Filters in */
 
176
/*     a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992), */
 
177
/*     pp 357-385. */
 
178
/*  2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly */
 
179
/*     Restarted Arnoldi Iteration", Rice University Technical Report */
 
180
/*     TR95-13, Department of Computational and Applied Mathematics. */
 
181
 
 
182
/* \Routines called: */
 
183
/*     dgetv0   ARPACK initial vector generation routine. */
 
184
/*     igraphdnaitr   ARPACK Arnoldi factorization routine. */
 
185
/*     igraphdnapps   ARPACK application of implicit shifts routine. */
 
186
/*     igraphdnconv   ARPACK convergence of Ritz values routine. */
 
187
/*     dneigh   ARPACK compute Ritz values and error bounds routine. */
 
188
/*     dngets   ARPACK reorder Ritz values and error bounds routine. */
 
189
/*     dsortc   ARPACK sorting routine. */
 
190
/*     ivout   ARPACK utility routine that prints integers. */
 
191
/*     second  ARPACK utility routine for timing. */
 
192
/*     dmout    ARPACK utility routine that prints matrices */
 
193
/*     dvout    ARPACK utility routine that prints vectors. */
 
194
/*     dlamch   LAPACK routine that determines machine constants. */
 
195
/*     dlapy2   LAPACK routine to compute sqrt(x**2+y**2) carefully. */
 
196
/*     dcopy    Level 1 BLAS that copies one vector to another . */
 
197
/*     ddot     Level 1 BLAS that computes the scalar product of two vectors. */
 
198
/*     dnrm2    Level 1 BLAS that computes the norm of a vector. */
 
199
/*     dswap    Level 1 BLAS that swaps two vectors. */
 
200
 
 
201
/* \Author */
 
202
/*     Danny Sorensen               Phuong Vu */
 
203
/*     Richard Lehoucq              CRPC / Rice University */
 
204
/*     Dept. of Computational &     Houston, Texas */
 
205
/*     Applied Mathematics */
 
206
/*     Rice University */
 
207
/*     Houston, Texas */
 
208
 
 
209
/* \SCCS Information: @(#) */
 
210
/* FILE: naup2.F   SID: 2.8   DATE OF SID: 10/17/00   RELEASE: 2 */
 
211
 
 
212
/* \Remarks */
 
213
/*     1. None */
 
214
 
 
215
/* \EndLib */
 
216
 
 
217
/* ----------------------------------------------------------------------- */
 
218
 
 
219
/* Subroutine */ int igraphdnaup2_(integer *ido, char *bmat, integer *n, char *
 
220
        which, integer *nev, integer *np, doublereal *tol, doublereal *resid, 
 
221
        integer *mode, integer *iupd, integer *ishift, integer *mxiter, 
 
222
        doublereal *v, integer *ldv, doublereal *h__, integer *ldh, 
 
223
        doublereal *ritzr, doublereal *ritzi, doublereal *bounds, doublereal *
 
224
        q, integer *ldq, doublereal *workl, integer *ipntr, doublereal *workd,
 
225
         integer *info)
 
226
{
 
227
    /* System generated locals */
 
228
    integer h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2;
 
229
    doublereal d__1, d__2;
 
230
 
 
231
    /* Builtin functions */
 
232
    double igraphpow_dd(doublereal *, doublereal *);
 
233
    integer igraphs_cmp(char *, char *, ftnlen, ftnlen);
 
234
    /* Subroutine */ int igraphs_copy(char *, char *, ftnlen, ftnlen);
 
235
    double sqrt(doublereal);
 
236
 
 
237
    /* Local variables */
 
238
    static integer j;
 
239
    static real t0, t1, t2, t3;
 
240
    static integer kp[4], np0, nev0;
 
241
    extern doublereal igraphddot_(integer *, doublereal *, integer *, doublereal *, 
 
242
            integer *);
 
243
    static doublereal eps23;
 
244
    static integer ierr, iter;
 
245
    static doublereal temp;
 
246
    extern doublereal igraphdnrm2_(integer *, doublereal *, integer *);
 
247
    static logical getv0, cnorm;
 
248
    extern /* Subroutine */ int igraphdcopy_(integer *, doublereal *, integer *, 
 
249
            doublereal *, integer *);
 
250
    static integer nconv;
 
251
    extern /* Subroutine */ int igraphdmout_(integer *, integer *, integer *, 
 
252
            doublereal *, integer *, integer *, char *);
 
253
    static logical initv;
 
254
    static doublereal rnorm;
 
255
    extern /* Subroutine */ int igraphdvout_(integer *, integer *, doublereal *, 
 
256
            integer *, char *), igraphivout_(integer *, integer *, integer *
 
257
            , integer *, char *), igraphdgetv0_(integer *, char *, integer *
 
258
            , logical *, integer *, integer *, doublereal *, integer *, 
 
259
            doublereal *, doublereal *, integer *, doublereal *, integer *);
 
260
    extern doublereal igraphdlapy2_(doublereal *, doublereal *), igraphdlamch_(char *);
 
261
    extern /* Subroutine */ int igraphdneigh_(doublereal *, integer *, doublereal *,
 
262
             integer *, doublereal *, doublereal *, doublereal *, doublereal *
 
263
            , integer *, doublereal *, integer *);
 
264
    static integer nevbef;
 
265
    extern /* Subroutine */ int igraphsecond_(real *);
 
266
    static logical update;
 
267
    static char wprime[2];
 
268
    static logical ushift;
 
269
    static integer kplusp, msglvl, nptemp, numcnv;
 
270
    extern /* Subroutine */ int igraphdnaitr_(integer *, char *, integer *, integer 
 
271
            *, integer *, integer *, doublereal *, doublereal *, doublereal *,
 
272
             integer *, doublereal *, integer *, integer *, doublereal *, 
 
273
            integer *), igraphdnconv_(integer *, doublereal *, doublereal *,
 
274
             doublereal *, doublereal *, integer *), igraphdngets_(integer *, char *
 
275
            , integer *, integer *, doublereal *, doublereal *, doublereal *, 
 
276
            doublereal *, doublereal *), igraphdnapps_(integer *, integer *,
 
277
             integer *, doublereal *, doublereal *, doublereal *, integer *, 
 
278
            doublereal *, integer *, doublereal *, doublereal *, integer *, 
 
279
            doublereal *, doublereal *), igraphdsortc_(char *, logical *, integer *,
 
280
             doublereal *, doublereal *, doublereal *);
 
281
 
 
282
 
 
283
/*     %----------------------------------------------------% */
 
284
/*     | Include files for debugging and timing information | */
 
285
/*     %----------------------------------------------------% */
 
286
 
 
287
 
 
288
/* \SCCS Information: @(#) */
 
289
/* FILE: debug.h   SID: 2.3   DATE OF SID: 11/16/95   RELEASE: 2 */
 
290
 
 
291
/*     %---------------------------------% */
 
292
/*     | See debug.doc for documentation | */
 
293
/*     %---------------------------------% */
 
294
 
 
295
/*     %------------------% */
 
296
/*     | Scalar Arguments | */
 
297
/*     %------------------% */
 
298
 
 
299
/*     %--------------------------------% */
 
300
/*     | See stat.doc for documentation | */
 
301
/*     %--------------------------------% */
 
302
 
 
303
/* \SCCS Information: @(#) */
 
304
/* FILE: stat.h   SID: 2.2   DATE OF SID: 11/16/95   RELEASE: 2 */
 
305
 
 
306
 
 
307
 
 
308
/*     %-----------------% */
 
309
/*     | Array Arguments | */
 
310
/*     %-----------------% */
 
311
 
 
312
 
 
313
/*     %------------% */
 
314
/*     | Parameters | */
 
315
/*     %------------% */
 
316
 
 
317
 
 
318
/*     %---------------% */
 
319
/*     | Local Scalars | */
 
320
/*     %---------------% */
 
321
 
 
322
 
 
323
/*     %-----------------------% */
 
324
/*     | Local array arguments | */
 
325
/*     %-----------------------% */
 
326
 
 
327
 
 
328
/*     %----------------------% */
 
329
/*     | External Subroutines | */
 
330
/*     %----------------------% */
 
331
 
 
332
 
 
333
/*     %--------------------% */
 
334
/*     | External Functions | */
 
335
/*     %--------------------% */
 
336
 
 
337
 
 
338
/*     %---------------------% */
 
339
/*     | Intrinsic Functions | */
 
340
/*     %---------------------% */
 
341
 
 
342
 
 
343
/*     %-----------------------% */
 
344
/*     | Executable Statements | */
 
345
/*     %-----------------------% */
 
346
 
 
347
    /* Parameter adjustments */
 
348
    --workd;
 
349
    --resid;
 
350
    --workl;
 
351
    --bounds;
 
352
    --ritzi;
 
353
    --ritzr;
 
354
    v_dim1 = *ldv;
 
355
    v_offset = 1 + v_dim1;
 
356
    v -= v_offset;
 
357
    h_dim1 = *ldh;
 
358
    h_offset = 1 + h_dim1;
 
359
    h__ -= h_offset;
 
360
    q_dim1 = *ldq;
 
361
    q_offset = 1 + q_dim1;
 
362
    q -= q_offset;
 
363
    --ipntr;
 
364
 
 
365
    /* Function Body */
 
366
    if (*ido == 0) {
 
367
 
 
368
        igraphsecond_(&t0);
 
369
 
 
370
        msglvl = debug_1.mnaup2;
 
371
 
 
372
/*        %-------------------------------------% */
 
373
/*        | Get the machine dependent constant. | */
 
374
/*        %-------------------------------------% */
 
375
 
 
376
        eps23 = igraphdlamch_("Epsilon-Machine");
 
377
        eps23 = igraphpow_dd(&eps23, &c_b3);
 
378
 
 
379
        nev0 = *nev;
 
380
        np0 = *np;
 
381
 
 
382
/*        %-------------------------------------% */
 
383
/*        | kplusp is the bound on the largest  | */
 
384
/*        |        Lanczos factorization built. | */
 
385
/*        | nconv is the current number of      | */
 
386
/*        |        "converged" eigenvlues.      | */
 
387
/*        | iter is the counter on the current  | */
 
388
/*        |      iteration step.                | */
 
389
/*        %-------------------------------------% */
 
390
 
 
391
        kplusp = *nev + *np;
 
392
        nconv = 0;
 
393
        iter = 0;
 
394
 
 
395
/*        %---------------------------------------% */
 
396
/*        | Set flags for computing the first NEV | */
 
397
/*        | steps of the Arnoldi factorization.   | */
 
398
/*        %---------------------------------------% */
 
399
 
 
400
        getv0 = TRUE_;
 
401
        update = FALSE_;
 
402
        ushift = FALSE_;
 
403
        cnorm = FALSE_;
 
404
 
 
405
        if (*info != 0) {
 
406
 
 
407
/*           %--------------------------------------------% */
 
408
/*           | User provides the initial residual vector. | */
 
409
/*           %--------------------------------------------% */
 
410
 
 
411
            initv = TRUE_;
 
412
            *info = 0;
 
413
        } else {
 
414
            initv = FALSE_;
 
415
        }
 
416
    }
 
417
 
 
418
/*     %---------------------------------------------% */
 
419
/*     | Get a possibly random starting vector and   | */
 
420
/*     | force it into the range of the operator OP. | */
 
421
/*     %---------------------------------------------% */
 
422
 
 
423
/* L10: */
 
424
 
 
425
    if (getv0) {
 
426
        igraphdgetv0_(ido, bmat, &c__1, &initv, n, &c__1, &v[v_offset], ldv, &resid[
 
427
                1], &rnorm, &ipntr[1], &workd[1], info);
 
428
 
 
429
        if (*ido != 99) {
 
430
            goto L9000;
 
431
        }
 
432
 
 
433
        if (rnorm == 0.) {
 
434
 
 
435
/*           %-----------------------------------------% */
 
436
/*           | The initial vector is zero. Error exit. | */
 
437
/*           %-----------------------------------------% */
 
438
 
 
439
            *info = -9;
 
440
            goto L1100;
 
441
        }
 
442
        getv0 = FALSE_;
 
443
        *ido = 0;
 
444
    }
 
445
 
 
446
/*     %-----------------------------------% */
 
447
/*     | Back from reverse communication : | */
 
448
/*     | continue with update step         | */
 
449
/*     %-----------------------------------% */
 
450
 
 
451
    if (update) {
 
452
        goto L20;
 
453
    }
 
454
 
 
455
/*     %-------------------------------------------% */
 
456
/*     | Back from computing user specified shifts | */
 
457
/*     %-------------------------------------------% */
 
458
 
 
459
    if (ushift) {
 
460
        goto L50;
 
461
    }
 
462
 
 
463
/*     %-------------------------------------% */
 
464
/*     | Back from computing residual norm   | */
 
465
/*     | at the end of the current iteration | */
 
466
/*     %-------------------------------------% */
 
467
 
 
468
    if (cnorm) {
 
469
        goto L100;
 
470
    }
 
471
 
 
472
/*     %----------------------------------------------------------% */
 
473
/*     | Compute the first NEV steps of the Arnoldi factorization | */
 
474
/*     %----------------------------------------------------------% */
 
475
 
 
476
    igraphdnaitr_(ido, bmat, n, &c__0, nev, mode, &resid[1], &rnorm, &v[v_offset], 
 
477
            ldv, &h__[h_offset], ldh, &ipntr[1], &workd[1], info);
 
478
 
 
479
/*     %---------------------------------------------------% */
 
480
/*     | ido .ne. 99 implies use of reverse communication  | */
 
481
/*     | to compute operations involving OP and possibly B | */
 
482
/*     %---------------------------------------------------% */
 
483
 
 
484
    if (*ido != 99) {
 
485
        goto L9000;
 
486
    }
 
487
 
 
488
    if (*info > 0) {
 
489
        *np = *info;
 
490
        *mxiter = iter;
 
491
        *info = -9999;
 
492
        goto L1200;
 
493
    }
 
494
 
 
495
/*     %--------------------------------------------------------------% */
 
496
/*     |                                                              | */
 
497
/*     |           M A I N  ARNOLDI  I T E R A T I O N  L O O P       | */
 
498
/*     |           Each iteration implicitly restarts the Arnoldi     | */
 
499
/*     |           factorization in place.                            | */
 
500
/*     |                                                              | */
 
501
/*     %--------------------------------------------------------------% */
 
502
 
 
503
L1000:
 
504
 
 
505
    ++iter;
 
506
 
 
507
    if (msglvl > 0) {
 
508
        igraphivout_(&debug_1.logfil, &c__1, &iter, &debug_1.ndigit, "_naup2: ****"
 
509
                " Start of major iteration number ****");
 
510
    }
 
511
 
 
512
/*        %-----------------------------------------------------------% */
 
513
/*        | Compute NP additional steps of the Arnoldi factorization. | */
 
514
/*        | Adjust NP since NEV might have been updated by last call  | */
 
515
/*        | to the shift application routine igraphdnapps .                  | */
 
516
/*        %-----------------------------------------------------------% */
 
517
 
 
518
    *np = kplusp - *nev;
 
519
 
 
520
    if (msglvl > 1) {
 
521
        igraphivout_(&debug_1.logfil, &c__1, nev, &debug_1.ndigit, "_naup2: The le"
 
522
                "ngth of the current Arnoldi factorization");
 
523
        igraphivout_(&debug_1.logfil, &c__1, np, &debug_1.ndigit, "_naup2: Extend "
 
524
                "the Arnoldi factorization by");
 
525
    }
 
526
 
 
527
/*        %-----------------------------------------------------------% */
 
528
/*        | Compute NP additional steps of the Arnoldi factorization. | */
 
529
/*        %-----------------------------------------------------------% */
 
530
 
 
531
    *ido = 0;
 
532
L20:
 
533
    update = TRUE_;
 
534
 
 
535
    igraphdnaitr_(ido, bmat, n, nev, np, mode, &resid[1], &rnorm, &v[v_offset], ldv,
 
536
             &h__[h_offset], ldh, &ipntr[1], &workd[1], info);
 
537
 
 
538
/*        %---------------------------------------------------% */
 
539
/*        | ido .ne. 99 implies use of reverse communication  | */
 
540
/*        | to compute operations involving OP and possibly B | */
 
541
/*        %---------------------------------------------------% */
 
542
 
 
543
    if (*ido != 99) {
 
544
        goto L9000;
 
545
    }
 
546
 
 
547
    if (*info > 0) {
 
548
        *np = *info;
 
549
        *mxiter = iter;
 
550
        *info = -9999;
 
551
        goto L1200;
 
552
    }
 
553
    update = FALSE_;
 
554
 
 
555
    if (msglvl > 1) {
 
556
        igraphdvout_(&debug_1.logfil, &c__1, &rnorm, &debug_1.ndigit, "_naup2: Cor"
 
557
                "responding B-norm of the residual");
 
558
    }
 
559
 
 
560
/*        %--------------------------------------------------------% */
 
561
/*        | Compute the eigenvalues and corresponding error bounds | */
 
562
/*        | of the current upper Hessenberg matrix.                | */
 
563
/*        %--------------------------------------------------------% */
 
564
 
 
565
    igraphdneigh_(&rnorm, &kplusp, &h__[h_offset], ldh, &ritzr[1], &ritzi[1], &
 
566
            bounds[1], &q[q_offset], ldq, &workl[1], &ierr);
 
567
 
 
568
    if (ierr != 0) {
 
569
        *info = -8;
 
570
        goto L1200;
 
571
    }
 
572
 
 
573
/*        %----------------------------------------------------% */
 
574
/*        | Make a copy of eigenvalues and corresponding error | */
 
575
/*        | bounds obtained from dneigh .                       | */
 
576
/*        %----------------------------------------------------% */
 
577
 
 
578
/* Computing 2nd power */
 
579
    i__1 = kplusp;
 
580
    igraphdcopy_(&kplusp, &ritzr[1], &c__1, &workl[i__1 * i__1 + 1], &c__1);
 
581
/* Computing 2nd power */
 
582
    i__1 = kplusp;
 
583
    igraphdcopy_(&kplusp, &ritzi[1], &c__1, &workl[i__1 * i__1 + kplusp + 1], &c__1)
 
584
            ;
 
585
/* Computing 2nd power */
 
586
    i__1 = kplusp;
 
587
    igraphdcopy_(&kplusp, &bounds[1], &c__1, &workl[i__1 * i__1 + (kplusp << 1) + 1]
 
588
            , &c__1);
 
589
 
 
590
/*        %---------------------------------------------------% */
 
591
/*        | Select the wanted Ritz values and their bounds    | */
 
592
/*        | to be used in the convergence test.               | */
 
593
/*        | The wanted part of the spectrum and corresponding | */
 
594
/*        | error bounds are in the last NEV loc. of RITZR,   | */
 
595
/*        | RITZI and BOUNDS respectively. The variables NEV  | */
 
596
/*        | and NP may be updated if the NEV-th wanted Ritz   | */
 
597
/*        | value has a non zero imaginary part. In this case | */
 
598
/*        | NEV is increased by one and NP decreased by one.  | */
 
599
/*        | NOTE: The last two arguments of dngets  are no     | */
 
600
/*        | longer used as of version 2.1.                    | */
 
601
/*        %---------------------------------------------------% */
 
602
 
 
603
    *nev = nev0;
 
604
    *np = np0;
 
605
    numcnv = *nev;
 
606
    igraphdngets_(ishift, which, nev, np, &ritzr[1], &ritzi[1], &bounds[1], &workl[
 
607
            1], &workl[*np + 1]);
 
608
    if (*nev == nev0 + 1) {
 
609
        numcnv = nev0 + 1;
 
610
    }
 
611
 
 
612
/*        %-------------------% */
 
613
/*        | Convergence test. | */
 
614
/*        %-------------------% */
 
615
 
 
616
    igraphdcopy_(nev, &bounds[*np + 1], &c__1, &workl[(*np << 1) + 1], &c__1);
 
617
    igraphdnconv_(nev, &ritzr[*np + 1], &ritzi[*np + 1], &workl[(*np << 1) + 1], 
 
618
            tol, &nconv);
 
619
 
 
620
    if (msglvl > 2) {
 
621
        kp[0] = *nev;
 
622
        kp[1] = *np;
 
623
        kp[2] = numcnv;
 
624
        kp[3] = nconv;
 
625
        igraphivout_(&debug_1.logfil, &c__4, kp, &debug_1.ndigit, "_naup2: NEV, NP"
 
626
                ", NUMCNV, NCONV are");
 
627
        igraphdvout_(&debug_1.logfil, &kplusp, &ritzr[1], &debug_1.ndigit, "_naup2"
 
628
                ": Real part of the eigenvalues of H");
 
629
        igraphdvout_(&debug_1.logfil, &kplusp, &ritzi[1], &debug_1.ndigit, "_naup2"
 
630
                ": Imaginary part of the eigenvalues of H");
 
631
        igraphdvout_(&debug_1.logfil, &kplusp, &bounds[1], &debug_1.ndigit, "_naup"
 
632
                "2: Ritz estimates of the current NCV Ritz values")
 
633
                ;
 
634
    }
 
635
 
 
636
/*        %---------------------------------------------------------% */
 
637
/*        | Count the number of unwanted Ritz values that have zero | */
 
638
/*        | Ritz estimates. If any Ritz estimates are equal to zero | */
 
639
/*        | then a leading block of H of order equal to at least    | */
 
640
/*        | the number of Ritz values with zero Ritz estimates has  | */
 
641
/*        | split off. None of these Ritz values may be removed by  | */
 
642
/*        | shifting. Decrease NP the number of shifts to apply. If | */
 
643
/*        | no shifts may be applied, then prepare to exit          | */
 
644
/*        %---------------------------------------------------------% */
 
645
 
 
646
    nptemp = *np;
 
647
    i__1 = nptemp;
 
648
    for (j = 1; j <= i__1; ++j) {
 
649
        if (bounds[j] == 0.) {
 
650
            --(*np);
 
651
            ++(*nev);
 
652
        }
 
653
/* L30: */
 
654
    }
 
655
 
 
656
    if (nconv >= numcnv || iter > *mxiter || *np == 0) {
 
657
 
 
658
        if (msglvl > 4) {
 
659
/* Computing 2nd power */
 
660
            i__1 = kplusp;
 
661
            igraphdvout_(&debug_1.logfil, &kplusp, &workl[i__1 * i__1 + 1], &
 
662
                    debug_1.ndigit, "_naup2: Real part of the eig computed b"
 
663
                    "y _neigh:");
 
664
/* Computing 2nd power */
 
665
            i__1 = kplusp;
 
666
            igraphdvout_(&debug_1.logfil, &kplusp, &workl[i__1 * i__1 + kplusp + 1],
 
667
                     &debug_1.ndigit, "_naup2: Imag part of the eig computed"
 
668
                    " by _neigh:");
 
669
/* Computing 2nd power */
 
670
            i__1 = kplusp;
 
671
            igraphdvout_(&debug_1.logfil, &kplusp, &workl[i__1 * i__1 + (kplusp << 
 
672
                    1) + 1], &debug_1.ndigit, "_naup2: Ritz eistmates comput"
 
673
                    "ed by _neigh:");
 
674
        }
 
675
 
 
676
/*           %------------------------------------------------% */
 
677
/*           | Prepare to exit. Put the converged Ritz values | */
 
678
/*           | and corresponding bounds in RITZ(1:NCONV) and  | */
 
679
/*           | BOUNDS(1:NCONV) respectively. Then sort. Be    | */
 
680
/*           | careful when NCONV > NP                        | */
 
681
/*           %------------------------------------------------% */
 
682
 
 
683
/*           %------------------------------------------% */
 
684
/*           |  Use h( 3,1 ) as storage to communicate  | */
 
685
/*           |  rnorm to _neupd if needed               | */
 
686
/*           %------------------------------------------% */
 
687
        h__[h_dim1 + 3] = rnorm;
 
688
 
 
689
/*           %----------------------------------------------% */
 
690
/*           | To be consistent with dngets , we first do a  | */
 
691
/*           | pre-processing sort in order to keep complex | */
 
692
/*           | conjugate pairs together.  This is similar   | */
 
693
/*           | to the pre-processing sort used in dngets     | */
 
694
/*           | except that the sort is done in the opposite | */
 
695
/*           | order.                                       | */
 
696
/*           %----------------------------------------------% */
 
697
 
 
698
        if (igraphs_cmp(which, "LM", (ftnlen)2, (ftnlen)2) == 0) {
 
699
            igraphs_copy(wprime, "SR", (ftnlen)2, (ftnlen)2);
 
700
        }
 
701
        if (igraphs_cmp(which, "SM", (ftnlen)2, (ftnlen)2) == 0) {
 
702
            igraphs_copy(wprime, "LR", (ftnlen)2, (ftnlen)2);
 
703
        }
 
704
        if (igraphs_cmp(which, "LR", (ftnlen)2, (ftnlen)2) == 0) {
 
705
            igraphs_copy(wprime, "SM", (ftnlen)2, (ftnlen)2);
 
706
        }
 
707
        if (igraphs_cmp(which, "SR", (ftnlen)2, (ftnlen)2) == 0) {
 
708
            igraphs_copy(wprime, "LM", (ftnlen)2, (ftnlen)2);
 
709
        }
 
710
        if (igraphs_cmp(which, "LI", (ftnlen)2, (ftnlen)2) == 0) {
 
711
            igraphs_copy(wprime, "SM", (ftnlen)2, (ftnlen)2);
 
712
        }
 
713
        if (igraphs_cmp(which, "SI", (ftnlen)2, (ftnlen)2) == 0) {
 
714
            igraphs_copy(wprime, "LM", (ftnlen)2, (ftnlen)2);
 
715
        }
 
716
 
 
717
        igraphdsortc_(wprime, &c_true, &kplusp, &ritzr[1], &ritzi[1], &bounds[1]);
 
718
 
 
719
/*           %----------------------------------------------% */
 
720
/*           | Now sort Ritz values so that converged Ritz  | */
 
721
/*           | values appear within the first NEV locations | */
 
722
/*           | of ritzr, ritzi and bounds, and the most     | */
 
723
/*           | desired one appears at the front.            | */
 
724
/*           %----------------------------------------------% */
 
725
 
 
726
        if (igraphs_cmp(which, "LM", (ftnlen)2, (ftnlen)2) == 0) {
 
727
            igraphs_copy(wprime, "SM", (ftnlen)2, (ftnlen)2);
 
728
        }
 
729
        if (igraphs_cmp(which, "SM", (ftnlen)2, (ftnlen)2) == 0) {
 
730
            igraphs_copy(wprime, "LM", (ftnlen)2, (ftnlen)2);
 
731
        }
 
732
        if (igraphs_cmp(which, "LR", (ftnlen)2, (ftnlen)2) == 0) {
 
733
            igraphs_copy(wprime, "SR", (ftnlen)2, (ftnlen)2);
 
734
        }
 
735
        if (igraphs_cmp(which, "SR", (ftnlen)2, (ftnlen)2) == 0) {
 
736
            igraphs_copy(wprime, "LR", (ftnlen)2, (ftnlen)2);
 
737
        }
 
738
        if (igraphs_cmp(which, "LI", (ftnlen)2, (ftnlen)2) == 0) {
 
739
            igraphs_copy(wprime, "SI", (ftnlen)2, (ftnlen)2);
 
740
        }
 
741
        if (igraphs_cmp(which, "SI", (ftnlen)2, (ftnlen)2) == 0) {
 
742
            igraphs_copy(wprime, "LI", (ftnlen)2, (ftnlen)2);
 
743
        }
 
744
 
 
745
        igraphdsortc_(wprime, &c_true, &kplusp, &ritzr[1], &ritzi[1], &bounds[1]);
 
746
 
 
747
/*           %--------------------------------------------------% */
 
748
/*           | Scale the Ritz estimate of each Ritz value       | */
 
749
/*           | by 1 / max(eps23,magnitude of the Ritz value).   | */
 
750
/*           %--------------------------------------------------% */
 
751
 
 
752
        i__1 = numcnv;
 
753
        for (j = 1; j <= i__1; ++j) {
 
754
/* Computing MAX */
 
755
            d__1 = eps23, d__2 = igraphdlapy2_(&ritzr[j], &ritzi[j]);
 
756
            temp = max(d__1,d__2);
 
757
            bounds[j] /= temp;
 
758
/* L35: */
 
759
        }
 
760
 
 
761
/*           %----------------------------------------------------% */
 
762
/*           | Sort the Ritz values according to the scaled Ritz  | */
 
763
/*           | esitmates.  This will push all the converged ones  | */
 
764
/*           | towards the front of ritzr, ritzi, bounds          | */
 
765
/*           | (in the case when NCONV < NEV.)                    | */
 
766
/*           %----------------------------------------------------% */
 
767
 
 
768
        igraphs_copy(wprime, "LR", (ftnlen)2, (ftnlen)2);
 
769
        igraphdsortc_(wprime, &c_true, &numcnv, &bounds[1], &ritzr[1], &ritzi[1]);
 
770
 
 
771
/*           %----------------------------------------------% */
 
772
/*           | Scale the Ritz estimate back to its original | */
 
773
/*           | value.                                       | */
 
774
/*           %----------------------------------------------% */
 
775
 
 
776
        i__1 = numcnv;
 
777
        for (j = 1; j <= i__1; ++j) {
 
778
/* Computing MAX */
 
779
            d__1 = eps23, d__2 = igraphdlapy2_(&ritzr[j], &ritzi[j]);
 
780
            temp = max(d__1,d__2);
 
781
            bounds[j] *= temp;
 
782
/* L40: */
 
783
        }
 
784
 
 
785
/*           %------------------------------------------------% */
 
786
/*           | Sort the converged Ritz values again so that   | */
 
787
/*           | the "threshold" value appears at the front of  | */
 
788
/*           | ritzr, ritzi and bound.                        | */
 
789
/*           %------------------------------------------------% */
 
790
 
 
791
        igraphdsortc_(which, &c_true, &nconv, &ritzr[1], &ritzi[1], &bounds[1]);
 
792
 
 
793
        if (msglvl > 1) {
 
794
            igraphdvout_(&debug_1.logfil, &kplusp, &ritzr[1], &debug_1.ndigit, 
 
795
                    "_naup2: Sorted real part of the eigenvalues");
 
796
            igraphdvout_(&debug_1.logfil, &kplusp, &ritzi[1], &debug_1.ndigit, 
 
797
                    "_naup2: Sorted imaginary part of the eigenvalues");
 
798
            igraphdvout_(&debug_1.logfil, &kplusp, &bounds[1], &debug_1.ndigit, 
 
799
                    "_naup2: Sorted ritz estimates.");
 
800
        }
 
801
 
 
802
/*           %------------------------------------% */
 
803
/*           | Max iterations have been exceeded. | */
 
804
/*           %------------------------------------% */
 
805
 
 
806
        if (iter > *mxiter && nconv < numcnv) {
 
807
            *info = 1;
 
808
        }
 
809
 
 
810
/*           %---------------------% */
 
811
/*           | No shifts to apply. | */
 
812
/*           %---------------------% */
 
813
 
 
814
        if (*np == 0 && nconv < numcnv) {
 
815
            *info = 2;
 
816
        }
 
817
 
 
818
        *np = nconv;
 
819
        goto L1100;
 
820
 
 
821
    } else if (nconv < numcnv && *ishift == 1) {
 
822
 
 
823
/*           %-------------------------------------------------% */
 
824
/*           | Do not have all the requested eigenvalues yet.  | */
 
825
/*           | To prevent possible stagnation, adjust the size | */
 
826
/*           | of NEV.                                         | */
 
827
/*           %-------------------------------------------------% */
 
828
 
 
829
        nevbef = *nev;
 
830
/* Computing MIN */
 
831
        i__1 = nconv, i__2 = *np / 2;
 
832
        *nev += min(i__1,i__2);
 
833
        if (*nev == 1 && kplusp >= 6) {
 
834
            *nev = kplusp / 2;
 
835
        } else if (*nev == 1 && kplusp > 3) {
 
836
            *nev = 2;
 
837
        }
 
838
        *np = kplusp - *nev;
 
839
 
 
840
/*           %---------------------------------------% */
 
841
/*           | If the size of NEV was just increased | */
 
842
/*           | resort the eigenvalues.               | */
 
843
/*           %---------------------------------------% */
 
844
 
 
845
        if (nevbef < *nev) {
 
846
            igraphdngets_(ishift, which, nev, np, &ritzr[1], &ritzi[1], &bounds[1], 
 
847
                          &workl[1], &workl[*np + 1]);
 
848
        }
 
849
 
 
850
    }
 
851
 
 
852
    if (msglvl > 0) {
 
853
        igraphivout_(&debug_1.logfil, &c__1, &nconv, &debug_1.ndigit, "_naup2: no."
 
854
                " of \"converged\" Ritz values at this iter.");
 
855
        if (msglvl > 1) {
 
856
            kp[0] = *nev;
 
857
            kp[1] = *np;
 
858
            igraphivout_(&debug_1.logfil, &c__2, kp, &debug_1.ndigit, "_naup2: NEV"
 
859
                    " and NP are");
 
860
            igraphdvout_(&debug_1.logfil, nev, &ritzr[*np + 1], &debug_1.ndigit, 
 
861
                    "_naup2: \"wanted\" Ritz values -- real part");
 
862
            igraphdvout_(&debug_1.logfil, nev, &ritzi[*np + 1], &debug_1.ndigit, 
 
863
                    "_naup2: \"wanted\" Ritz values -- imag part")
 
864
                    ;
 
865
            igraphdvout_(&debug_1.logfil, nev, &bounds[*np + 1], &debug_1.ndigit, 
 
866
                    "_naup2: Ritz estimates of the \"wanted\" values ");
 
867
        }
 
868
    }
 
869
 
 
870
    if (*ishift == 0) {
 
871
 
 
872
/*           %-------------------------------------------------------% */
 
873
/*           | User specified shifts: reverse comminucation to       | */
 
874
/*           | compute the shifts. They are returned in the first    | */
 
875
/*           | 2*NP locations of WORKL.                              | */
 
876
/*           %-------------------------------------------------------% */
 
877
 
 
878
        ushift = TRUE_;
 
879
        *ido = 3;
 
880
        goto L9000;
 
881
    }
 
882
 
 
883
L50:
 
884
 
 
885
/*        %------------------------------------% */
 
886
/*        | Back from reverse communication;   | */
 
887
/*        | User specified shifts are returned | */
 
888
/*        | in WORKL(1:2*NP)                   | */
 
889
/*        %------------------------------------% */
 
890
 
 
891
    ushift = FALSE_;
 
892
 
 
893
    if (*ishift == 0) {
 
894
 
 
895
/*            %----------------------------------% */
 
896
/*            | Move the NP shifts from WORKL to | */
 
897
/*            | RITZR, RITZI to free up WORKL    | */
 
898
/*            | for non-exact shift case.        | */
 
899
/*            %----------------------------------% */
 
900
 
 
901
        igraphdcopy_(np, &workl[1], &c__1, &ritzr[1], &c__1);
 
902
        igraphdcopy_(np, &workl[*np + 1], &c__1, &ritzi[1], &c__1);
 
903
    }
 
904
 
 
905
    if (msglvl > 2) {
 
906
        igraphivout_(&debug_1.logfil, &c__1, np, &debug_1.ndigit, "_naup2: The num"
 
907
                "ber of shifts to apply ");
 
908
        igraphdvout_(&debug_1.logfil, np, &ritzr[1], &debug_1.ndigit, "_naup2: Rea"
 
909
                "l part of the shifts");
 
910
        igraphdvout_(&debug_1.logfil, np, &ritzi[1], &debug_1.ndigit, "_naup2: Ima"
 
911
                "ginary part of the shifts");
 
912
        if (*ishift == 1) {
 
913
            igraphdvout_(&debug_1.logfil, np, &bounds[1], &debug_1.ndigit, "_naup2"
 
914
                    ": Ritz estimates of the shifts");
 
915
        }
 
916
    }
 
917
 
 
918
/*        %---------------------------------------------------------% */
 
919
/*        | Apply the NP implicit shifts by QR bulge chasing.       | */
 
920
/*        | Each shift is applied to the whole upper Hessenberg     | */
 
921
/*        | matrix H.                                               | */
 
922
/*        | The first 2*N locations of WORKD are used as workspace. | */
 
923
/*        %---------------------------------------------------------% */
 
924
 
 
925
    igraphdnapps_(n, nev, np, &ritzr[1], &ritzi[1], &v[v_offset], ldv, &h__[
 
926
            h_offset], ldh, &resid[1], &q[q_offset], ldq, &workl[1], &workd[1]
 
927
            );
 
928
 
 
929
/*        %---------------------------------------------% */
 
930
/*        | Compute the B-norm of the updated residual. | */
 
931
/*        | Keep B*RESID in WORKD(1:N) to be used in    | */
 
932
/*        | the first step of the next call to igraphdnaitr .  | */
 
933
/*        %---------------------------------------------% */
 
934
 
 
935
    cnorm = TRUE_;
 
936
    igraphsecond_(&t2);
 
937
    if (*(unsigned char *)bmat == 'G') {
 
938
        ++timing_1.nbx;
 
939
        igraphdcopy_(n, &resid[1], &c__1, &workd[*n + 1], &c__1);
 
940
        ipntr[1] = *n + 1;
 
941
        ipntr[2] = 1;
 
942
        *ido = 2;
 
943
 
 
944
/*           %----------------------------------% */
 
945
/*           | Exit in order to compute B*RESID | */
 
946
/*           %----------------------------------% */
 
947
 
 
948
        goto L9000;
 
949
    } else if (*(unsigned char *)bmat == 'I') {
 
950
        igraphdcopy_(n, &resid[1], &c__1, &workd[1], &c__1);
 
951
    }
 
952
 
 
953
L100:
 
954
 
 
955
/*        %----------------------------------% */
 
956
/*        | Back from reverse communication; | */
 
957
/*        | WORKD(1:N) := B*RESID            | */
 
958
/*        %----------------------------------% */
 
959
 
 
960
    if (*(unsigned char *)bmat == 'G') {
 
961
        igraphsecond_(&t3);
 
962
        timing_1.tmvbx += t3 - t2;
 
963
    }
 
964
 
 
965
    if (*(unsigned char *)bmat == 'G') {
 
966
        rnorm = igraphddot_(n, &resid[1], &c__1, &workd[1], &c__1);
 
967
        rnorm = sqrt((abs(rnorm)));
 
968
    } else if (*(unsigned char *)bmat == 'I') {
 
969
        rnorm = igraphdnrm2_(n, &resid[1], &c__1);
 
970
    }
 
971
    cnorm = FALSE_;
 
972
 
 
973
    if (msglvl > 2) {
 
974
        igraphdvout_(&debug_1.logfil, &c__1, &rnorm, &debug_1.ndigit, "_naup2: B-n"
 
975
                "orm of residual for compressed factorization");
 
976
        igraphdmout_(&debug_1.logfil, nev, nev, &h__[h_offset], ldh, &
 
977
                     debug_1.ndigit, "_naup2: Compressed upper Hessenberg matrix H");
 
978
    }
 
979
 
 
980
    goto L1000;
 
981
 
 
982
/*     %---------------------------------------------------------------% */
 
983
/*     |                                                               | */
 
984
/*     |  E N D     O F     M A I N     I T E R A T I O N     L O O P  | */
 
985
/*     |                                                               | */
 
986
/*     %---------------------------------------------------------------% */
 
987
 
 
988
L1100:
 
989
 
 
990
    *mxiter = iter;
 
991
    *nev = numcnv;
 
992
 
 
993
L1200:
 
994
    *ido = 99;
 
995
 
 
996
/*     %------------% */
 
997
/*     | Error Exit | */
 
998
/*     %------------% */
 
999
 
 
1000
    igraphsecond_(&t1);
 
1001
    timing_1.tnaup2 = t1 - t0;
 
1002
 
 
1003
L9000:
 
1004
 
 
1005
/*     %---------------% */
 
1006
/*     | End of igraphdnaup2  | */
 
1007
/*     %---------------% */
 
1008
 
 
1009
    return 0;
 
1010
} /* igraphdnaup2_ */
 
1011