MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
arptest.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbwrap/arptest.cc,v 1.12 2017/01/12 14:44:25 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
33 
34 #include <iostream>
35 #include <iomanip>
36 
37 #include <vector>
38 
39 #include "ac/f2c.h"
40 #include "ac/arpack.h"
41 
42 #include "solman.h"
43 #include "naivewrap.h"
44 
45 /* from dnaupd.f distributed with arpack:
46 
47 c\Description:
48 c Reverse communication interface for the Implicitly Restarted Arnoldi
49 c iteration. This subroutine computes approximations to a few eigenpairs
50 c of a linear operator "OP" with respect to a semi-inner product defined by
51 c a symmetric positive semi-definite real matrix B. B may be the identity
52 c matrix. NOTE: If the linear operator "OP" is real and symmetric
53 c with respect to the real positive semi-definite symmetric matrix B,
54 c i.e. B*OP = (OP`)*B, then subroutine dsaupd should be used instead.
55 c
56 c The computed approximate eigenvalues are called Ritz values and
57 c the corresponding approximate eigenvectors are called Ritz vectors.
58 c
59 c dnaupd is usually called iteratively to solve one of the
60 c following problems:
61 c
62 c Mode 1: A*x = lambda*x.
63 c ===> OP = A and B = I.
64 c
65 c Mode 2: A*x = lambda*M*x, M symmetric positive definite
66 c ===> OP = inv[M]*A and B = M.
67 c ===> (If M can be factored see remark 3 below)
68 c
69 c Mode 3: A*x = lambda*M*x, M symmetric semi-definite
70 c ===> OP = Real_Part{ inv[A - sigma*M]*M } and B = M.
71 c ===> shift-and-invert mode (in real arithmetic)
72 c If OP*x = amu*x, then
73 c amu = 1/2 * [ 1/(lambda-sigma) + 1/(lambda-conjg(sigma)) ].
74 c Note: If sigma is real, i.e. imaginary part of sigma is zero;
75 c Real_Part{ inv[A - sigma*M]*M } == inv[A - sigma*M]*M
76 c amu == 1/(lambda-sigma).
77 c
78 c Mode 4: A*x = lambda*M*x, M symmetric semi-definite
79 c ===> OP = Imaginary_Part{ inv[A - sigma*M]*M } and B = M.
80 c ===> shift-and-invert mode (in real arithmetic)
81 c If OP*x = amu*x, then
82 c amu = 1/2i * [ 1/(lambda-sigma) - 1/(lambda-conjg(sigma)) ].
83 c
84 c Both mode 3 and 4 give the same enhancement to eigenvalues close to
85 c the (complex) shift sigma. However, as lambda goes to infinity,
86 c the operator OP in mode 4 dampens the eigenvalues more strongly than
87 c does OP defined in mode 3.
88 c
89 c NOTE: The action of w <- inv[A - sigma*M]*v or w <- inv[M]*v
90 c should be accomplished either by a direct method
91 c using a sparse matrix factorization and solving
92 c
93 c [A - sigma*M]*w = v or M*w = v,
94 c
95 c or through an iterative method for solving these
96 c systems. If an iterative method is used, the
97 c convergence test must be more stringent than
98 c the accuracy requirements for the eigenvalue
99 c approximations.
100 c
101 c\Usage:
102 c call dnaupd
103 c ( IDO, BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM,
104 c IPNTR, WORKD, WORKL, LWORKL, INFO )
105 c
106 c\Arguments
107 c IDO Integer. (INPUT/OUTPUT)
108 c Reverse communication flag. IDO must be zero on the first
109 c call to dnaupd . IDO will be set internally to
110 c indicate the type of operation to be performed. Control is
111 c then given back to the calling routine which has the
112 c responsibility to carry out the requested operation and call
113 c dnaupd with the result. The operand is given in
114 c WORKD(IPNTR(1)), the result must be put in WORKD(IPNTR(2)).
115 c -------------------------------------------------------------
116 c IDO = 0: first call to the reverse communication interface
117 c IDO = -1: compute Y = OP * X where
118 c IPNTR(1) is the pointer into WORKD for X,
119 c IPNTR(2) is the pointer into WORKD for Y.
120 c This is for the initialization phase to force the
121 c starting vector into the range of OP.
122 c IDO = 1: compute Y = OP * X where
123 c IPNTR(1) is the pointer into WORKD for X,
124 c IPNTR(2) is the pointer into WORKD for Y.
125 c In mode 3 and 4, the vector B * X is already
126 c available in WORKD(ipntr(3)). It does not
127 c need to be recomputed in forming OP * X.
128 c IDO = 2: compute Y = B * X where
129 c IPNTR(1) is the pointer into WORKD for X,
130 c IPNTR(2) is the pointer into WORKD for Y.
131 c IDO = 3: compute the IPARAM(8) real and imaginary parts
132 c of the shifts where INPTR(14) is the pointer
133 c into WORKL for placing the shifts. See Remark
134 c 5 below.
135 c IDO = 99: done
136 c -------------------------------------------------------------
137 c
138 c BMAT Character*1. (INPUT)
139 c BMAT specifies the type of the matrix B that defines the
140 c semi-inner product for the operator OP.
141 c BMAT = 'I' -> standard eigenvalue problem A*x = lambda*x
142 c BMAT = 'G' -> generalized eigenvalue problem A*x = lambda*B*x
143 c
144 c N Integer. (INPUT)
145 c Dimension of the eigenproblem.
146 c
147 c WHICH Character*2. (INPUT)
148 c 'LM' -> want the NEV eigenvalues of largest magnitude.
149 c 'SM' -> want the NEV eigenvalues of smallest magnitude.
150 c 'LR' -> want the NEV eigenvalues of largest real part.
151 c 'SR' -> want the NEV eigenvalues of smallest real part.
152 c 'LI' -> want the NEV eigenvalues of largest imaginary part.
153 c 'SI' -> want the NEV eigenvalues of smallest imaginary part.
154 c
155 c NEV Integer. (INPUT)
156 c Number of eigenvalues of OP to be computed. 0 < NEV < N-1.
157 c
158 c TOL Double precision scalar. (INPUT)
159 c Stopping criterion: the relative accuracy of the Ritz value
160 c is considered acceptable if BOUNDS(I) .LE. TOL*ABS(RITZ(I))
161 c where ABS(RITZ(I)) is the magnitude when RITZ(I) is complex.
162 c DEFAULT = DLAMCH ('EPS') (machine precision as computed
163 c by the LAPACK auxiliary subroutine DLAMCH ).
164 c
165 c RESID Double precision array of length N. (INPUT/OUTPUT)
166 c On INPUT:
167 c If INFO .EQ. 0, a random initial residual vector is used.
168 c If INFO .NE. 0, RESID contains the initial residual vector,
169 c possibly from a previous run.
170 c On OUTPUT:
171 c RESID contains the final residual vector.
172 c
173 c NCV Integer. (INPUT)
174 c Number of columns of the matrix V. NCV must satisfy the two
175 c inequalities 2 <= NCV-NEV and NCV <= N.
176 c This will indicate how many Arnoldi vectors are generated
177 c at each iteration. After the startup phase in which NEV
178 c Arnoldi vectors are generated, the algorithm generates
179 c approximately NCV-NEV Arnoldi vectors at each subsequent update
180 c iteration. Most of the cost in generating each Arnoldi vector is
181 c in the matrix-vector operation OP*x.
182 c NOTE: 2 <= NCV-NEV in order that complex conjugate pairs of Ritz
183 c values are kept together. (See remark 4 below)
184 c
185 c V Double precision array N by NCV. (OUTPUT)
186 c Contains the final set of Arnoldi basis vectors.
187 c
188 c LDV Integer. (INPUT)
189 c Leading dimension of V exactly as declared in the calling program.
190 c
191 c IPARAM Integer array of length 11. (INPUT/OUTPUT)
192 c IPARAM(1) = ISHIFT: method for selecting the implicit shifts.
193 c The shifts selected at each iteration are used to restart
194 c the Arnoldi iteration in an implicit fashion.
195 c -------------------------------------------------------------
196 c ISHIFT = 0: the shifts are provided by the user via
197 c reverse communication. The real and imaginary
198 c parts of the NCV eigenvalues of the Hessenberg
199 c matrix H are returned in the part of the WORKL
200 c array corresponding to RITZR and RITZI. See remark
201 c 5 below.
202 c ISHIFT = 1: exact shifts with respect to the current
203 c Hessenberg matrix H. This is equivalent to
204 c restarting the iteration with a starting vector
205 c that is a linear combination of approximate Schur
206 c vectors associated with the "wanted" Ritz values.
207 c -------------------------------------------------------------
208 c
209 c IPARAM(2) = No longer referenced.
210 c
211 c IPARAM(3) = MXITER
212 c On INPUT: maximum number of Arnoldi update iterations allowed.
213 c On OUTPUT: actual number of Arnoldi update iterations taken.
214 c
215 c IPARAM(4) = NB: blocksize to be used in the recurrence.
216 c The code currently works only for NB = 1.
217 c
218 c IPARAM(5) = NCONV: number of "converged" Ritz values.
219 c This represents the number of Ritz values that satisfy
220 c the convergence criterion.
221 c
222 c IPARAM(6) = IUPD
223 c No longer referenced. Implicit restarting is ALWAYS used.
224 c
225 c IPARAM(7) = MODE
226 c On INPUT determines what type of eigenproblem is being solved.
227 c Must be 1,2,3,4; See under \Description of dnaupd for the
228 c four modes available.
229 c
230 c IPARAM(8) = NP
231 c When ido = 3 and the user provides shifts through reverse
232 c communication (IPARAM(1)=0), dnaupd returns NP, the number
233 c of shifts the user is to provide. 0 < NP <=NCV-NEV. See Remark
234 c 5 below.
235 c
236 c IPARAM(9) = NUMOP, IPARAM(10) = NUMOPB, IPARAM(11) = NUMREO,
237 c OUTPUT: NUMOP = total number of OP*x operations,
238 c NUMOPB = total number of B*x operations if BMAT='G',
239 c NUMREO = total number of steps of re-orthogonalization.
240 c
241 c IPNTR Integer array of length 14. (OUTPUT)
242 c Pointer to mark the starting locations in the WORKD and WORKL
243 c arrays for matrices/vectors used by the Arnoldi iteration.
244 c -------------------------------------------------------------
245 c IPNTR(1): pointer to the current operand vector X in WORKD.
246 c IPNTR(2): pointer to the current result vector Y in WORKD.
247 c IPNTR(3): pointer to the vector B * X in WORKD when used in
248 c the shift-and-invert mode.
249 c IPNTR(4): pointer to the next available location in WORKL
250 c that is untouched by the program.
251 c IPNTR(5): pointer to the NCV by NCV upper Hessenberg matrix
252 c H in WORKL.
253 c IPNTR(6): pointer to the real part of the ritz value array
254 c RITZR in WORKL.
255 c IPNTR(7): pointer to the imaginary part of the ritz value array
256 c RITZI in WORKL.
257 c IPNTR(8): pointer to the Ritz estimates in array WORKL associated
258 c with the Ritz values located in RITZR and RITZI in WORKL.
259 c
260 c IPNTR(14): pointer to the NP shifts in WORKL. See Remark 5 below.
261 c
262 c Note: IPNTR(9:13) is only referenced by dneupd . See Remark 2 below.
263 c
264 c IPNTR(9): pointer to the real part of the NCV RITZ values of the
265 c original system.
266 c IPNTR(10): pointer to the imaginary part of the NCV RITZ values of
267 c the original system.
268 c IPNTR(11): pointer to the NCV corresponding error bounds.
269 c IPNTR(12): pointer to the NCV by NCV upper quasi-triangular
270 c Schur matrix for H.
271 c IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors
272 c of the upper Hessenberg matrix H. Only referenced by
273 c dneupd if RVEC = .TRUE. See Remark 2 below.
274 c -------------------------------------------------------------
275 c
276 c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION)
277 c Distributed array to be used in the basic Arnoldi iteration
278 c for reverse communication. The user should not use WORKD
279 c as temporary workspace during the iteration. Upon termination
280 c WORKD(1:N) contains B*RESID(1:N). If an invariant subspace
281 c associated with the converged Ritz values is desired, see remark
282 c 2 below, subroutine dneupd uses this output.
283 c See Data Distribution Note below.
284 c
285 c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE)
286 c Private (replicated) array on each PE or array allocated on
287 c the front end. See Data Distribution Note below.
288 c
289 c LWORKL Integer. (INPUT)
290 c LWORKL must be at least 3*NCV**2 + 6*NCV.
291 c
292 c INFO Integer. (INPUT/OUTPUT)
293 c If INFO .EQ. 0, a randomly initial residual vector is used.
294 c If INFO .NE. 0, RESID contains the initial residual vector,
295 c possibly from a previous run.
296 c Error flag on output.
297 c = 0: Normal exit.
298 c = 1: Maximum number of iterations taken.
299 c All possible eigenvalues of OP has been found. IPARAM(5)
300 c returns the number of wanted converged Ritz values.
301 c = 2: No longer an informational error. Deprecated starting
302 c with release 2 of ARPACK.
303 c = 3: No shifts could be applied during a cycle of the
304 c Implicitly restarted Arnoldi iteration. One possibility
305 c is to increase the size of NCV relative to NEV.
306 c See remark 4 below.
307 c = -1: N must be positive.
308 c = -2: NEV must be positive.
309 c = -3: NCV-NEV >= 2 and less than or equal to N.
310 c = -4: The maximum number of Arnoldi update iteration
311 c must be greater than zero.
312 c = -5: WHICH must be one of 'LM', 'SM', 'LR', 'SR', 'LI', 'SI'
313 c = -6: BMAT must be one of 'I' or 'G'.
314 c = -7: Length of private work array is not sufficient.
315 c = -8: Error return from LAPACK eigenvalue calculation;
316 c = -9: Starting vector is zero.
317 c = -10: IPARAM(7) must be 1,2,3,4.
318 c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatable.
319 c = -12: IPARAM(1) must be equal to 0 or 1.
320 c = -9999: Could not build an Arnoldi factorization.
321 c IPARAM(5) returns the size of the current Arnoldi
322 c factorization.
323 c
324 c\Remarks
325 c 1. The computed Ritz values are approximate eigenvalues of OP. The
326 c selection of WHICH should be made with this in mind when
327 c Mode = 3 and 4. After convergence, approximate eigenvalues of the
328 c original problem may be obtained with the ARPACK subroutine dneupd .
329 c
330 c 2. If a basis for the invariant subspace corresponding to the converged Ritz
331 c values is needed, the user must call dneupd immediately following
332 c completion of dnaupd . This is new starting with release 2 of ARPACK.
333 c
334 c 3. If M can be factored into a Cholesky factorization M = LL`
335 c then Mode = 2 should not be selected. Instead one should use
336 c Mode = 1 with OP = inv(L)*A*inv(L`). Appropriate triangular
337 c linear systems should be solved with L and L` rather
338 c than computing inverses. After convergence, an approximate
339 c eigenvector z of the original problem is recovered by solving
340 c L`z = x where x is a Ritz vector of OP.
341 c
342 c 4. At present there is no a-priori analysis to guide the selection
343 c of NCV relative to NEV. The only formal requrement is that NCV > NEV + 2.
344 c However, it is recommended that NCV .ge. 2*NEV+1. If many problems of
345 c the same type are to be solved, one should experiment with increasing
346 c NCV while keeping NEV fixed for a given test problem. This will
347 c usually decrease the required number of OP*x operations but it
348 c also increases the work and storage required to maintain the orthogonal
349 c basis vectors. The optimal "cross-over" with respect to CPU time
350 c is problem dependent and must be determined empirically.
351 c See Chapter 8 of Reference 2 for further information.
352 c
353 c 5. When IPARAM(1) = 0, and IDO = 3, the user needs to provide the
354 c NP = IPARAM(8) real and imaginary parts of the shifts in locations
355 c real part imaginary part
356 c ----------------------- --------------
357 c 1 WORKL(IPNTR(14)) WORKL(IPNTR(14)+NP)
358 c 2 WORKL(IPNTR(14)+1) WORKL(IPNTR(14)+NP+1)
359 c . .
360 c . .
361 c . .
362 c NP WORKL(IPNTR(14)+NP-1) WORKL(IPNTR(14)+2*NP-1).
363 c
364 c Only complex conjugate pairs of shifts may be applied and the pairs
365 c must be placed in consecutive locations. The real part of the
366 c eigenvalues of the current upper Hessenberg matrix are located in
367 c WORKL(IPNTR(6)) through WORKL(IPNTR(6)+NCV-1) and the imaginary part
368 c in WORKL(IPNTR(7)) through WORKL(IPNTR(7)+NCV-1). They are ordered
369 c according to the order defined by WHICH. The complex conjugate
370 c pairs are kept together and the associated Ritz estimates are located in
371 c WORKL(IPNTR(8)), WORKL(IPNTR(8)+1), ... , WORKL(IPNTR(8)+NCV-1).
372 c
373 c-----------------------------------------------------------------------
374 c
375 c\Data Distribution Note:
376 c
377 c Fortran-D syntax:
378 c ================
379 c Double precision resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
380 c decompose d1(n), d2(n,ncv)
381 c align resid(i) with d1(i)
382 c align v(i,j) with d2(i,j)
383 c align workd(i) with d1(i) range (1:n)
384 c align workd(i) with d1(i-n) range (n+1:2*n)
385 c align workd(i) with d1(i-2*n) range (2*n+1:3*n)
386 c distribute d1(block), d2(block,:)
387 c replicated workl(lworkl)
388 c
389 c Cray MPP syntax:
390 c ===============
391 c Double precision resid(n), v(ldv,ncv), workd(n,3), workl(lworkl)
392 c shared resid(block), v(block,:), workd(block,:)
393 c replicated workl(lworkl)
394 c
395 c CM2/CM5 syntax:
396 c ==============
397 c
398 c-----------------------------------------------------------------------
399 c
400 c include 'ex-nonsym.doc'
401 c
402 c-----------------------------------------------------------------------
403 c
404 c\BeginLib
405 c
406 c\Local variables:
407 c xxxxxx real
408 c
409 c\References:
410 c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
411 c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
412 c pp 357-385.
413 c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
414 c Restarted Arnoldi Iteration", Rice University Technical Report
415 c TR95-13, Department of Computational and Applied Mathematics.
416 c 3. B.N. Parlett & Y. Saad, "Complex Shift and Invert Strategies for
417 c Real Matrices", Linear Algebra and its Applications, vol 88/89,
418 c pp 575-595, (1987).
419 c
420 c\Routines called:
421 c dnaup2 ARPACK routine that implements the Implicitly Restarted
422 c Arnoldi Iteration.
423 c ivout ARPACK utility routine that prints integers.
424 c second ARPACK utility routine for timing.
425 c dvout ARPACK utility routine that prints vectors.
426 c dlamch LAPACK routine that determines machine constants.
427 c
428 c\Author
429 c Danny Sorensen Phuong Vu
430 c Richard Lehoucq CRPC / Rice University
431 c Dept. of Computational & Houston, Texas
432 c Applied Mathematics
433 c Rice University
434 c Houston, Texas
435 c
436 c\Revision history:
437 c 12/16/93: Version '1.1'
438 c
439 c\SCCS Information: @(#)
440 c FILE: naupd.F SID: 2.8 DATE OF SID: 04/10/01 RELEASE: 2
441  */
442 
443 /* from dneupd.f distributed with arpack:
444 c\Name: dneupd
445 c
446 c\Description:
447 c
448 c This subroutine returns the converged approximations to eigenvalues
449 c of A*z = lambda*B*z and (optionally):
450 c
451 c (1) The corresponding approximate eigenvectors;
452 c
453 c (2) An orthonormal basis for the associated approximate
454 c invariant subspace;
455 c
456 c (3) Both.
457 c
458 c There is negligible additional cost to obtain eigenvectors. An orthonormal
459 c basis is always computed. There is an additional storage cost of n*nev
460 c if both are requested (in this case a separate array Z must be supplied).
461 c
462 c The approximate eigenvalues and eigenvectors of A*z = lambda*B*z
463 c are derived from approximate eigenvalues and eigenvectors of
464 c of the linear operator OP prescribed by the MODE selection in the
465 c call to DNAUPD . DNAUPD must be called before this routine is called.
466 c These approximate eigenvalues and vectors are commonly called Ritz
467 c values and Ritz vectors respectively. They are referred to as such
468 c in the comments that follow. The computed orthonormal basis for the
469 c invariant subspace corresponding to these Ritz values is referred to as a
470 c Schur basis.
471 c
472 c See documentation in the header of the subroutine DNAUPD for
473 c definition of OP as well as other terms and the relation of computed
474 c Ritz values and Ritz vectors of OP with respect to the given problem
475 c A*z = lambda*B*z. For a brief description, see definitions of
476 c IPARAM(7), MODE and WHICH in the documentation of DNAUPD .
477 c
478 c\Usage:
479 c call dneupd
480 c ( RVEC, HOWMNY, SELECT, DR, DI, Z, LDZ, SIGMAR, SIGMAI, WORKEV, BMAT,
481 c N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR, WORKD, WORKL,
482 c LWORKL, INFO )
483 c
484 c\Arguments:
485 c RVEC LOGICAL (INPUT)
486 c Specifies whether a basis for the invariant subspace corresponding
487 c to the converged Ritz value approximations for the eigenproblem
488 c A*z = lambda*B*z is computed.
489 c
490 c RVEC = .FALSE. Compute Ritz values only.
491 c
492 c RVEC = .TRUE. Compute the Ritz vectors or Schur vectors.
493 c See Remarks below.
494 c
495 c HOWMNY Character*1 (INPUT)
496 c Specifies the form of the basis for the invariant subspace
497 c corresponding to the converged Ritz values that is to be computed.
498 c
499 c = 'A': Compute NEV Ritz vectors;
500 c = 'P': Compute NEV Schur vectors;
501 c = 'S': compute some of the Ritz vectors, specified
502 c by the logical array SELECT.
503 c
504 c SELECT Logical array of dimension NCV. (INPUT)
505 c If HOWMNY = 'S', SELECT specifies the Ritz vectors to be
506 c computed. To select the Ritz vector corresponding to a
507 c Ritz value (DR(j), DI(j)), SELECT(j) must be set to .TRUE..
508 c If HOWMNY = 'A' or 'P', SELECT is used as internal workspace.
509 c
510 c DR Double precision array of dimension NEV+1. (OUTPUT)
511 c If IPARAM(7) = 1,2 or 3 and SIGMAI=0.0 then on exit: DR contains
512 c the real part of the Ritz approximations to the eigenvalues of
513 c A*z = lambda*B*z.
514 c If IPARAM(7) = 3, 4 and SIGMAI is not equal to zero, then on exit:
515 c DR contains the real part of the Ritz values of OP computed by
516 c DNAUPD . A further computation must be performed by the user
517 c to transform the Ritz values computed for OP by DNAUPD to those
518 c of the original system A*z = lambda*B*z. See remark 3 below.
519 c
520 c DI Double precision array of dimension NEV+1. (OUTPUT)
521 c On exit, DI contains the imaginary part of the Ritz value
522 c approximations to the eigenvalues of A*z = lambda*B*z associated
523 c with DR.
524 c
525 c NOTE: When Ritz values are complex, they will come in complex
526 c conjugate pairs. If eigenvectors are requested, the
527 c corresponding Ritz vectors will also come in conjugate
528 c pairs and the real and imaginary parts of these are
529 c represented in two consecutive columns of the array Z
530 c (see below).
531 c
532 c Z Double precision N by NEV+1 array if RVEC = .TRUE. and HOWMNY = 'A'. (OUTPUT)
533 c On exit, if RVEC = .TRUE. and HOWMNY = 'A', then the columns of
534 c Z represent approximate eigenvectors (Ritz vectors) corresponding
535 c to the NCONV=IPARAM(5) Ritz values for eigensystem
536 c A*z = lambda*B*z.
537 c
538 c The complex Ritz vector associated with the Ritz value
539 c with positive imaginary part is stored in two consecutive
540 c columns. The first column holds the real part of the Ritz
541 c vector and the second column holds the imaginary part. The
542 c Ritz vector associated with the Ritz value with negative
543 c imaginary part is simply the complex conjugate of the Ritz vector
544 c associated with the positive imaginary part.
545 c
546 c If RVEC = .FALSE. or HOWMNY = 'P', then Z is not referenced.
547 c
548 c NOTE: If if RVEC = .TRUE. and a Schur basis is not required,
549 c the array Z may be set equal to first NEV+1 columns of the Arnoldi
550 c basis array V computed by DNAUPD . In this case the Arnoldi basis
551 c will be destroyed and overwritten with the eigenvector basis.
552 c
553 c LDZ Integer. (INPUT)
554 c The leading dimension of the array Z. If Ritz vectors are
555 c desired, then LDZ >= max( 1, N ). In any case, LDZ >= 1.
556 c
557 c SIGMAR Double precision (INPUT)
558 c If IPARAM(7) = 3 or 4, represents the real part of the shift.
559 c Not referenced if IPARAM(7) = 1 or 2.
560 c
561 c SIGMAI Double precision (INPUT)
562 c If IPARAM(7) = 3 or 4, represents the imaginary part of the shift.
563 c Not referenced if IPARAM(7) = 1 or 2. See remark 3 below.
564 c
565 c WORKEV Double precision work array of dimension 3*NCV. (WORKSPACE)
566 c
567 c **** The remaining arguments MUST be the same as for the ****
568 c **** call to DNAUPD that was just completed. ****
569 c
570 c NOTE: The remaining arguments
571 c
572 c BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM, IPNTR,
573 c WORKD, WORKL, LWORKL, INFO
574 c
575 c must be passed directly to DNEUPD following the last call
576 c to DNAUPD . These arguments MUST NOT BE MODIFIED between
577 c the the last call to DNAUPD and the call to DNEUPD .
578 c
579 c Three of these parameters (V, WORKL, INFO) are also output parameters:
580 c
581 c V Double precision N by NCV array. (INPUT/OUTPUT)
582 c
583 c Upon INPUT: the NCV columns of V contain the Arnoldi basis
584 c vectors for OP as constructed by DNAUPD .
585 c
586 c Upon OUTPUT: If RVEC = .TRUE. the first NCONV=IPARAM(5) columns
587 c contain approximate Schur vectors that span the
588 c desired invariant subspace. See Remark 2 below.
589 c
590 c NOTE: If the array Z has been set equal to first NEV+1 columns
591 c of the array V and RVEC=.TRUE. and HOWMNY= 'A', then the
592 c Arnoldi basis held by V has been overwritten by the desired
593 c Ritz vectors. If a separate array Z has been passed then
594 c the first NCONV=IPARAM(5) columns of V will contain approximate
595 c Schur vectors that span the desired invariant subspace.
596 c
597 c WORKL Double precision work array of length LWORKL. (OUTPUT/WORKSPACE)
598 c WORKL(1:ncv*ncv+3*ncv) contains information obtained in
599 c dnaupd . They are not changed by dneupd .
600 c WORKL(ncv*ncv+3*ncv+1:3*ncv*ncv+6*ncv) holds the
601 c real and imaginary part of the untransformed Ritz values,
602 c the upper quasi-triangular matrix for H, and the
603 c associated matrix representation of the invariant subspace for H.
604 c
605 c Note: IPNTR(9:13) contains the pointer into WORKL for addresses
606 c of the above information computed by dneupd .
607 c -------------------------------------------------------------
608 c IPNTR(9): pointer to the real part of the NCV RITZ values of the
609 c original system.
610 c IPNTR(10): pointer to the imaginary part of the NCV RITZ values of
611 c the original system.
612 c IPNTR(11): pointer to the NCV corresponding error bounds.
613 c IPNTR(12): pointer to the NCV by NCV upper quasi-triangular
614 c Schur matrix for H.
615 c IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors
616 c of the upper Hessenberg matrix H. Only referenced by
617 c dneupd if RVEC = .TRUE. See Remark 2 below.
618 c -------------------------------------------------------------
619 c
620 c INFO Integer. (OUTPUT)
621 c Error flag on output.
622 c
623 c = 0: Normal exit.
624 c
625 c = 1: The Schur form computed by LAPACK routine dlahqr
626 c could not be reordered by LAPACK routine dtrsen .
627 c Re-enter subroutine dneupd with IPARAM(5)=NCV and
628 c increase the size of the arrays DR and DI to have
629 c dimension at least dimension NCV and allocate at least NCV
630 c columns for Z. NOTE: Not necessary if Z and V share
631 c the same space. Please notify the authors if this error
632 c occurs.
633 c
634 c = -1: N must be positive.
635 c = -2: NEV must be positive.
636 c = -3: NCV-NEV >= 2 and less than or equal to N.
637 c = -5: WHICH must be one of 'LM', 'SM', 'LR', 'SR', 'LI', 'SI'
638 c = -6: BMAT must be one of 'I' or 'G'.
639 c = -7: Length of private work WORKL array is not sufficient.
640 c = -8: Error return from calculation of a real Schur form.
641 c Informational error from LAPACK routine dlahqr .
642 c = -9: Error return from calculation of eigenvectors.
643 c Informational error from LAPACK routine dtrevc .
644 c = -10: IPARAM(7) must be 1,2,3,4.
645 c = -11: IPARAM(7) = 1 and BMAT = 'G' are incompatible.
646 c = -12: HOWMNY = 'S' not yet implemented
647 c = -13: HOWMNY must be one of 'A' or 'P' if RVEC = .true.
648 c = -14: DNAUPD did not find any eigenvalues to sufficient
649 c accuracy.
650 c = -15: DNEUPD got a different count of the number of converged
651 c Ritz values than DNAUPD got. This indicates the user
652 c probably made an error in passing data from DNAUPD to
653 c DNEUPD or that the data was modified before entering
654 c DNEUPD
655 c
656 c\BeginLib
657 c
658 c\References:
659 c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
660 c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
661 c pp 357-385.
662 c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
663 c Restarted Arnoldi Iteration", Rice University Technical Report
664 c TR95-13, Department of Computational and Applied Mathematics.
665 c 3. B.N. Parlett & Y. Saad, "Complex Shift and Invert Strategies for
666 c Real Matrices", Linear Algebra and its Applications, vol 88/89,
667 c pp 575-595, (1987).
668 c
669 c\Routines called:
670 c ivout ARPACK utility routine that prints integers.
671 c dmout ARPACK utility routine that prints matrices
672 c dvout ARPACK utility routine that prints vectors.
673 c dgeqr2 LAPACK routine that computes the QR factorization of
674 c a matrix.
675 c dlacpy LAPACK matrix copy routine.
676 c dlahqr LAPACK routine to compute the real Schur form of an
677 c upper Hessenberg matrix.
678 c dlamch LAPACK routine that determines machine constants.
679 c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
680 c dlaset LAPACK matrix initialization routine.
681 c dorm2r LAPACK routine that applies an orthogonal matrix in
682 c factored form.
683 c dtrevc LAPACK routine to compute the eigenvectors of a matrix
684 c in upper quasi-triangular form.
685 c dtrsen LAPACK routine that re-orders the Schur form.
686 c dtrmm Level 3 BLAS matrix times an upper triangular matrix.
687 c dger Level 2 BLAS rank one update to a matrix.
688 c dcopy Level 1 BLAS that copies one vector to another .
689 c ddot Level 1 BLAS that computes the scalar product of two vectors.
690 c dnrm2 Level 1 BLAS that computes the norm of a vector.
691 c dscal Level 1 BLAS that scales a vector.
692 c
693 c\Remarks
694 c
695 c 1. Currently only HOWMNY = 'A' and 'P' are implemented.
696 c
697 c Let trans(X) denote the transpose of X.
698 c
699 c 2. Schur vectors are an orthogonal representation for the basis of
700 c Ritz vectors. Thus, their numerical properties are often superior.
701 c If RVEC = .TRUE. then the relationship
702 c A * V(:,1:IPARAM(5)) = V(:,1:IPARAM(5)) * T, and
703 c trans(V(:,1:IPARAM(5))) * V(:,1:IPARAM(5)) = I are approximately
704 c satisfied. Here T is the leading submatrix of order IPARAM(5) of the
705 c real upper quasi-triangular matrix stored workl(ipntr(12)). That is,
706 c T is block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
707 c each 2-by-2 diagonal block has its diagonal elements equal and its
708 c off-diagonal elements of opposite sign. Corresponding to each 2-by-2
709 c diagonal block is a complex conjugate pair of Ritz values. The real
710 c Ritz values are stored on the diagonal of T.
711 c
712 c 3. If IPARAM(7) = 3 or 4 and SIGMAI is not equal zero, then the user must
713 c form the IPARAM(5) Rayleigh quotients in order to transform the Ritz
714 c values computed by DNAUPD for OP to those of A*z = lambda*B*z.
715 c Set RVEC = .true. and HOWMNY = 'A', and
716 c compute
717 c trans(Z(:,I)) * A * Z(:,I) if DI(I) = 0.
718 c If DI(I) is not equal to zero and DI(I+1) = - D(I),
719 c then the desired real and imaginary parts of the Ritz value are
720 c trans(Z(:,I)) * A * Z(:,I) + trans(Z(:,I+1)) * A * Z(:,I+1),
721 c trans(Z(:,I)) * A * Z(:,I+1) - trans(Z(:,I+1)) * A * Z(:,I),
722 c respectively.
723 c Another possibility is to set RVEC = .true. and HOWMNY = 'P' and
724 c compute trans(V(:,1:IPARAM(5))) * A * V(:,1:IPARAM(5)) and then an upper
725 c quasi-triangular matrix of order IPARAM(5) is computed. See remark
726 c 2 above.
727 c
728 c\Authors
729 c Danny Sorensen Phuong Vu
730 c Richard Lehoucq CRPC / Rice University
731 c Chao Yang Houston, Texas
732 c Dept. of Computational &
733 c Applied Mathematics
734 c Rice University
735 c Houston, Texas
736 c
737 c\SCCS Information: @(#)
738 c FILE: neupd.F SID: 2.7 DATE OF SID: 09/20/00 RELEASE: 2
739  */
740 
741 int
742 main(void)
743 {
744  // matrix
745  NaiveMatrixHandler mh(5);
746  mh(1, 1) = 2.;
747  mh(1, 2) = 1.;
748  mh(2, 1) = 1.;
749  mh(2, 2) = 2.;
750  mh(2, 3) = 1.;
751  mh(3, 2) = 1.;
752  mh(3, 3) = 2.;
753  mh(3, 4) = 1.;
754  mh(4, 3) = 1.;
755  mh(4, 4) = 2.;
756  mh(4, 5) = 1.;
757  mh(5, 4) = 1.;
758  mh(5, 5) = 2.;
759 
760  // shift
761  doublereal SIGMA = 1.;
762  doublereal SIGMAR = 0.;
763  doublereal SIGMAI = 0.;
764 
765  // arpack-related vars
766  integer IDO; // 0 at first iteration; then set by dnaupd
767  const char *BMAT; // 'I' for standard problem
768  integer N; // size of problem
769  const char *WHICH; // "SM" to request smallest eigenvalues
770  integer NEV; // number of eigenvalues
771  doublereal TOL; // -1 to use machine precision
772  std::vector<doublereal> RESID; // residual vector (ignored if IDO==0)
773  integer NCV; // number of vectors in subspace
774  std::vector<doublereal> V; // Schur basis
775  integer LDV; // leading dimension of V (==N!)
776  integer IPARAM[11] = { 0 };
777  integer IPNTR[14] = { 0 };
778  std::vector<doublereal> WORKD;
779  std::vector<doublereal> WORKL;
780  integer LWORKL;
781  integer INFO;
782 
783  IDO = 0;
784  BMAT = "I";
785  N = mh.iGetNumRows();
786  WHICH = "SM";
787  NEV = 2;
788  TOL = 0.;
789  RESID.resize(N, 0.);
790  NCV = 4;
791  V.resize(N*NCV, 0.);
792  LDV = N;
793  IPARAM[0] = 1;
794  IPARAM[2] = 300;
795  IPARAM[3] = 1;
796  IPARAM[6] = 1; // mode...
797  WORKD.resize(3*N, 0.);
798  LWORKL = 3*NCV*NCV + 6*NCV;
799  WORKL.resize(LWORKL, 0.);
800  INFO = 0;
801 
802  int cnt = 0;
803  do {
804  std::cout << "before:" << std::endl
805  << "IDO=" << IDO << std::endl
806  << "BMAT=" << BMAT << std::endl
807  << "N=" << N << std::endl
808  << "WHICH=" << WHICH << std::endl
809  << "NEV=" << NEV << std::endl
810  << "TOL=" << TOL << std::endl
811  << "&RESID[0]=" << &RESID[0] << std::endl
812  << "NCV=" << NCV << std::endl
813  << "&V[0]=" << &V[0] << std::endl
814  << "LDV=" << LDV << std::endl
815  << "IPARAM=" << IPARAM[0]
816  << "," << IPARAM[1]
817  << "," << IPARAM[2]
818  << "," << IPARAM[3]
819  << "," << IPARAM[4]
820  << "," << IPARAM[5]
821  << "," << IPARAM[6]
822  << "," << IPARAM[7]
823  << "," << IPARAM[8]
824  << "," << IPARAM[9]
825  << "," << IPARAM[10]
826  << std::endl
827  << "IPNTR=" << IPNTR[0]
828  << "," << IPNTR[1]
829  << "," << IPNTR[2]
830  << "," << IPNTR[3]
831  << "," << IPNTR[4]
832  << "," << IPNTR[5]
833  << "," << IPNTR[6]
834  << "," << IPNTR[7]
835  << "," << IPNTR[8]
836  << "," << IPNTR[9]
837  << "," << IPNTR[10]
838  << "," << IPNTR[11]
839  << "," << IPNTR[12]
840  << "," << IPNTR[13]
841  << std::endl
842  << "&WORKD[0]=" << &WORKD[0] << std::endl
843  << "&WORKL[0]=" << &WORKL[0] << std::endl
844  << "LWORKL=" << LWORKL << std::endl
845  << "INFO=" << INFO << std::endl
846  << std::endl;
847 
848  __FC_DECL__(dnaupd)(&IDO, &BMAT[0], &N, &WHICH[0], &NEV,
849  &TOL, &RESID[0], &NCV, &V[0], &LDV, &IPARAM[0], &IPNTR[0],
850  &WORKD[0], &WORKL[0], &LWORKL, &INFO);
851 
852  std::cout << "after:" << std::endl
853  << "IDO=" << IDO << std::endl
854  << "BMAT=" << BMAT << std::endl
855  << "N=" << N << std::endl
856  << "WHICH=" << WHICH << std::endl
857  << "NEV=" << NEV << std::endl
858  << "TOL=" << TOL << std::endl
859  << "&RESID[0]=" << &RESID[0] << std::endl
860  << "NCV=" << NCV << std::endl
861  << "&V[0]=" << &V[0] << std::endl
862  << "LDV=" << LDV << std::endl
863  << "IPARAM=" << IPARAM[0]
864  << "," << IPARAM[1]
865  << "," << IPARAM[2]
866  << "," << IPARAM[3]
867  << "," << IPARAM[4]
868  << "," << IPARAM[5]
869  << "," << IPARAM[6]
870  << "," << IPARAM[7]
871  << "," << IPARAM[8]
872  << "," << IPARAM[9]
873  << "," << IPARAM[10]
874  << std::endl
875  << "IPNTR=" << IPNTR[0]
876  << "," << IPNTR[1]
877  << "," << IPNTR[2]
878  << "," << IPNTR[3]
879  << "," << IPNTR[4]
880  << "," << IPNTR[5]
881  << "," << IPNTR[6]
882  << "," << IPNTR[7]
883  << "," << IPNTR[8]
884  << "," << IPNTR[9]
885  << "," << IPNTR[10]
886  << "," << IPNTR[11]
887  << "," << IPNTR[12]
888  << "," << IPNTR[13]
889  << std::endl
890  << "&WORKD[0]=" << &WORKD[0] << std::endl
891  << "&WORKL[0]=" << &WORKL[0] << std::endl
892  << "LWORKL=" << LWORKL << std::endl
893  << "INFO=" << INFO << std::endl
894  << std::endl;
895 
896  std::cout << "cnt=" << cnt << ": IDO=" << IDO << ", INFO=" << INFO << std::endl;
897 
898  // compute Y = OP*X
899  MyVectorHandler X(N, &WORKD[IPNTR[0] - 1]);
900  MyVectorHandler Y(N, &WORKD[IPNTR[1] - 1]);
901 
902  Y = X;
903  Y *= -SIGMA;
904  mh.MatVecIncMul(Y, X);
905 
906  std::cout << "X:" << std::endl << X << std::endl;
907  std::cout << "Y:" << std::endl << Y << std::endl;
908 
909  cnt++;
910  } while (IDO == 1 || IDO == -1);
911 
912  if (INFO < 0) {
913  std::cerr << "error" << std::endl;
914  return 1;
915  }
916 
917  logical RVEC = true;
918  const char *HOWMNY = "A";
919  std::vector<logical> SELECT(NCV);
920  std::vector<doublereal> DR(NEV + 1);
921  std::vector<doublereal> DI(NEV + 1);
922  std::vector<doublereal> Z(N*(NEV + 1));
923  integer LDZ = N;
924  std::vector<doublereal> WORKEV(3*NCV);
925 
926  __FC_DECL__(dneupd)(&RVEC, &HOWMNY[0], &SELECT[0], &DR[0], &DI[0],
927  &Z[0], &LDZ, &SIGMAR, &SIGMAI, &WORKEV[0],
928  &BMAT[0], &N, &WHICH[0], &NEV,
929  &TOL, &RESID[0], &NCV, &V[0], &LDV, &IPARAM[0], &IPNTR[0],
930  &WORKD[0], &WORKL[0], &LWORKL, &INFO);
931 
932  bool bCmplx = false;
933  bool bFirst;
934  for (integer nv = 0; nv < NEV; nv++) {
935  std::cout << "value " << std::setw(8) << nv << ":"
936  << std::setw(16) << DR[nv] + SIGMA
937  << (DI[nv] >= 0. ? " + " : " - ")
938  << std::setw(16) << std::abs(DI[nv]) << " i" << std::endl;
939 
940  std::cout << "vector " << std::setw(8) << nv << ":"
941  << std::endl;
942  if (!bCmplx) {
943  if (DI[nv] != 0.) {
944  bCmplx = true;
945  bFirst = true;
946  }
947  }
948 
949  if (!bCmplx) {
950  for (integer idx = 0; idx < N; idx++) {
951  std::cout
952  << std::setw(8) << idx << ":"
953  << std::setw(16) << Z[N*nv + idx]
954  << std::endl;
955  }
956 
957  } else if (bFirst) {
958  bFirst = false;
959 
960  for (integer idx = 0; idx < N; idx++) {
961  doublereal d = Z[N*(nv + 1) + idx];
962  std::cout
963  << std::setw(8) << idx << ":"
964  << std::setw(16) << Z[N*nv + idx]
965  << (d > 0. ? " + " : " - " )
966  << std::setw(16) << std::abs(d) << " i"
967  << std::endl;
968  }
969 
970  } else {
971  bCmplx = false;
972 
973  for (integer idx = 0; idx < N; idx++) {
974  doublereal d = Z[N*nv + idx];
975  std::cout
976  << std::setw(8) << idx << ":"
977  << std::setw(16) << Z[N*(nv - 1) + idx]
978  << (d > 0. ? " + " : " - " )
979  << std::setw(16) << std::abs(d) << " i"
980  << std::endl;
981  }
982  }
983  }
984 
985  return 0;
986 }
integer iGetNumRows(void) const
Definition: naivemh.h:111
virtual VectorHandler & MatVecIncMul(VectorHandler &out, const VectorHandler &in) const
Definition: mh.cc:350
int main(void)
Definition: arptest.cc:742
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51