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