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