📄 dtgex2.c
字号:
/* lapack/double/dtgex2.f -- translated by f2c (version 20050501).
You must link the resulting object file with libf2c:
on Microsoft Windows system, link with libf2c.lib;
on Linux or Unix systems, link with .../path/to/libf2c.a -lm
or, if you install libf2c.a in a standard place, with -lf2c -lm
-- in that order, at the end of the command line, as in
cc *.o -lf2c -lm
Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
http://www.netlib.org/f2c/libf2c.zip
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "v3p_netlib.h"
/* Table of constant values */
static integer c__16 = 16;
static doublereal c_b3 = 0.;
static integer c__0 = 0;
static integer c__1 = 1;
static integer c__4 = 4;
static integer c__2 = 2;
static doublereal c_b38 = 1.;
static doublereal c_b44 = -1.;
/*< >*/
/* Subroutine */ int dtgex2_(logical *wantq, logical *wantz, integer *n,
doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
q, integer *ldq, doublereal *z__, integer *ldz, integer *j1, integer *
n1, integer *n2, doublereal *work, integer *lwork, integer *info)
{
/* System generated locals */
integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, z_dim1,
z_offset, i__1, i__2;
doublereal d__1;
/* Builtin functions */
double sqrt(doublereal);
/* Local variables */
doublereal f, g;
integer i__, m;
doublereal s[16] /* was [4][4] */, t[16] /* was [4][4] */, be[2], ai[2]
, ar[2], sa, sb, li[16] /* was [4][4] */, ir[16] /*
was [4][4] */, ss, ws, eps;
logical weak;
doublereal ddum;
integer idum;
doublereal taul[4], dsum;
extern /* Subroutine */ int drot_(integer *, doublereal *, integer *,
doublereal *, integer *, doublereal *, doublereal *);
doublereal taur[4], scpy[16] /* was [4][4] */, tcpy[16] /*
was [4][4] */;
extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *,
integer *);
doublereal scale, bqra21, brqa21;
extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *,
integer *, doublereal *, doublereal *, integer *, doublereal *,
integer *, doublereal *, doublereal *, integer *, ftnlen, ftnlen);
doublereal licop[16] /* was [4][4] */;
integer linfo;
doublereal ircop[16] /* was [4][4] */;
extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
doublereal *, integer *);
doublereal dnorm;
integer iwork[4];
extern /* Subroutine */ int dlagv2_(doublereal *, integer *, doublereal *,
integer *, doublereal *, doublereal *, doublereal *, doublereal *
, doublereal *, doublereal *, doublereal *), dgeqr2_(integer *,
integer *, doublereal *, integer *, doublereal *, doublereal *,
integer *), dgerq2_(integer *, integer *, doublereal *, integer *,
doublereal *, doublereal *, integer *), dorg2r_(integer *,
integer *, integer *, doublereal *, integer *, doublereal *,
doublereal *, integer *), dorgr2_(integer *, integer *, integer *,
doublereal *, integer *, doublereal *, doublereal *, integer *),
dorm2r_(char *, char *, integer *, integer *, integer *,
doublereal *, integer *, doublereal *, doublereal *, integer *,
doublereal *, integer *, ftnlen, ftnlen), dormr2_(char *, char *,
integer *, integer *, integer *, doublereal *, integer *,
doublereal *, doublereal *, integer *, doublereal *, integer *,
ftnlen, ftnlen), dtgsy2_(char *, integer *, integer *, integer *,
doublereal *, integer *, doublereal *, integer *, doublereal *,
integer *, doublereal *, integer *, doublereal *, integer *,
doublereal *, integer *, doublereal *, doublereal *, doublereal *,
integer *, integer *, integer *, ftnlen);
extern doublereal dlamch_(char *, ftnlen);
doublereal dscale;
extern /* Subroutine */ int dlacpy_(char *, integer *, integer *,
doublereal *, integer *, doublereal *, integer *, ftnlen),
dlartg_(doublereal *, doublereal *, doublereal *, doublereal *,
doublereal *), dlassq_(integer *, doublereal *, integer *,
doublereal *, doublereal *);
logical dtrong;
doublereal thresh, smlnum;
/* -- LAPACK auxiliary routine (version 3.0) -- */
/* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
/* Courant Institute, Argonne National Lab, and Rice University */
/* June 30, 1999 */
/* .. Scalar Arguments .. */
/*< LOGICAL WANTQ, WANTZ >*/
/*< INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, LWORK, N, N1, N2 >*/
/* .. */
/* .. Array Arguments .. */
/*< >*/
/* .. */
/* Purpose */
/* ======= */
/* DTGEX2 swaps adjacent diagonal blocks (A11, B11) and (A22, B22) */
/* of size 1-by-1 or 2-by-2 in an upper (quasi) triangular matrix pair */
/* (A, B) by an orthogonal equivalence transformation. */
/* (A, B) must be in generalized real Schur canonical form (as returned */
/* by DGGES), i.e. A is block upper triangular with 1-by-1 and 2-by-2 */
/* diagonal blocks. B is upper triangular. */
/* Optionally, the matrices Q and Z of generalized Schur vectors are */
/* updated. */
/* Q(in) * A(in) * Z(in)' = Q(out) * A(out) * Z(out)' */
/* Q(in) * B(in) * Z(in)' = Q(out) * B(out) * Z(out)' */
/* Arguments */
/* ========= */
/* WANTQ (input) LOGICAL */
/* .TRUE. : update the left transformation matrix Q; */
/* .FALSE.: do not update Q. */
/* WANTZ (input) LOGICAL */
/* .TRUE. : update the right transformation matrix Z; */
/* .FALSE.: do not update Z. */
/* N (input) INTEGER */
/* The order of the matrices A and B. N >= 0. */
/* A (input/output) DOUBLE PRECISION arrays, dimensions (LDA,N) */
/* On entry, the matrix A in the pair (A, B). */
/* On exit, the updated matrix A. */
/* LDA (input) INTEGER */
/* The leading dimension of the array A. LDA >= max(1,N). */
/* B (input/output) DOUBLE PRECISION arrays, dimensions (LDB,N) */
/* On entry, the matrix B in the pair (A, B). */
/* On exit, the updated matrix B. */
/* LDB (input) INTEGER */
/* The leading dimension of the array B. LDB >= max(1,N). */
/* Q (input/output) DOUBLE PRECISION array, dimension (LDZ,N) */
/* On entry, if WANTQ = .TRUE., the orthogonal matrix Q. */
/* On exit, the updated matrix Q. */
/* Not referenced if WANTQ = .FALSE.. */
/* LDQ (input) INTEGER */
/* The leading dimension of the array Q. LDQ >= 1. */
/* If WANTQ = .TRUE., LDQ >= N. */
/* Z (input/output) DOUBLE PRECISION array, dimension (LDZ,N) */
/* On entry, if WANTZ =.TRUE., the orthogonal matrix Z. */
/* On exit, the updated matrix Z. */
/* Not referenced if WANTZ = .FALSE.. */
/* LDZ (input) INTEGER */
/* The leading dimension of the array Z. LDZ >= 1. */
/* If WANTZ = .TRUE., LDZ >= N. */
/* J1 (input) INTEGER */
/* The index to the first block (A11, B11). 1 <= J1 <= N. */
/* N1 (input) INTEGER */
/* The order of the first block (A11, B11). N1 = 0, 1 or 2. */
/* N2 (input) INTEGER */
/* The order of the second block (A22, B22). N2 = 0, 1 or 2. */
/* WORK (workspace) DOUBLE PRECISION array, dimension (LWORK). */
/* LWORK (input) INTEGER */
/* The dimension of the array WORK. */
/* LWORK >= MAX( N*(N2+N1), (N2+N1)*(N2+N1)*2 ) */
/* INFO (output) INTEGER */
/* =0: Successful exit */
/* >0: If INFO = 1, the transformed matrix (A, B) would be */
/* too far from generalized Schur form; the blocks are */
/* not swapped and (A, B) and (Q, Z) are unchanged. */
/* The problem of swapping is too ill-conditioned. */
/* <0: If INFO = -16: LWORK is too small. Appropriate value */
/* for LWORK is returned in WORK(1). */
/* Further Details */
/* =============== */
/* Based on contributions by */
/* Bo Kagstrom and Peter Poromaa, Department of Computing Science, */
/* Umea University, S-901 87 Umea, Sweden. */
/* In the current code both weak and strong stability tests are */
/* performed. The user can omit the strong stability test by changing */
/* the internal logical parameter WANDS to .FALSE.. See ref. [2] for */
/* details. */
/* [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the */
/* Generalized Real Schur Form of a Regular Matrix Pair (A, B), in */
/* M.S. Moonen et al (eds), Linear Algebra for Large Scale and */
/* Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218. */
/* [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified */
/* Eigenvalues of a Regular Matrix Pair (A, B) and Condition */
/* Estimation: Theory, Algorithms and Software, */
/* Report UMINF - 94.04, Department of Computing Science, Umea */
/* University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working */
/* Note 87. To appear in Numerical Algorithms, 1996. */
/* ===================================================================== */
/* .. Parameters .. */
/*< DOUBLE PRECISION ZERO, ONE >*/
/*< PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) >*/
/*< DOUBLE PRECISION TEN >*/
/*< PARAMETER ( TEN = 1.0D+01 ) >*/
/*< INTEGER LDST >*/
/*< PARAMETER ( LDST = 4 ) >*/
/*< LOGICAL WANDS >*/
/*< PARAMETER ( WANDS = .TRUE. ) >*/
/* .. */
/* .. Local Scalars .. */
/*< LOGICAL DTRONG, WEAK >*/
/*< INTEGER I, IDUM, LINFO, M >*/
/*< >*/
/* .. */
/* .. Local Arrays .. */
/*< INTEGER IWORK( LDST ) >*/
/*< >*/
/* .. */
/* .. External Functions .. */
/*< DOUBLE PRECISION DLAMCH >*/
/*< EXTERNAL DLAMCH >*/
/* .. */
/* .. External Subroutines .. */
/*< >*/
/* .. */
/* .. Intrinsic Functions .. */
/*< INTRINSIC ABS, MAX, SQRT >*/
/* .. */
/* .. Executable Statements .. */
/*< INFO = 0 >*/
/* Parameter adjustments */
a_dim1 = *lda;
a_offset = 1 + a_dim1;
a -= a_offset;
b_dim1 = *ldb;
b_offset = 1 + b_dim1;
b -= b_offset;
q_dim1 = *ldq;
q_offset = 1 + q_dim1;
q -= q_offset;
z_dim1 = *ldz;
z_offset = 1 + z_dim1;
z__ -= z_offset;
--work;
/* Function Body */
*info = 0;
/* Quick return if possible */
/*< >*/
if (*n <= 1 || *n1 <= 0 || *n2 <= 0) {
return 0;
}
/*< >*/
if (*n1 > *n || *j1 + *n1 > *n) {
return 0;
}
/*< M = N1 + N2 >*/
m = *n1 + *n2;
/*< IF( LWORK.LT.MAX( N*M, M*M*2 ) ) THEN >*/
/* Computing MAX */
i__1 = *n * m, i__2 = m * m << 1;
if (*lwork < max(i__1,i__2)) {
/*< INFO = -16 >*/
*info = -16;
/*< WORK( 1 ) = MAX( N*M, M*M*2 ) >*/
/* Computing MAX */
i__1 = *n * m, i__2 = m * m << 1;
work[1] = (doublereal) max(i__1,i__2);
/*< RETURN >*/
return 0;
/*< END IF >*/
}
/*< WEAK = .FALSE. >*/
weak = FALSE_;
/*< DTRONG = .FALSE. >*/
dtrong = FALSE_;
/* Make a local copy of selected block */
/*< CALL DCOPY( LDST*LDST, ZERO, 0, LI, 1 ) >*/
dcopy_(&c__16, &c_b3, &c__0, li, &c__1);
/*< CALL DCOPY( LDST*LDST, ZERO, 0, IR, 1 ) >*/
dcopy_(&c__16, &c_b3, &c__0, ir, &c__1);
/*< CALL DLACPY( 'Full', M, M, A( J1, J1 ), LDA, S, LDST ) >*/
dlacpy_("Full", &m, &m, &a[*j1 + *j1 * a_dim1], lda, s, &c__4, (ftnlen)4);
/*< CALL DLACPY( 'Full', M, M, B( J1, J1 ), LDB, T, LDST ) >*/
dlacpy_("Full", &m, &m, &b[*j1 + *j1 * b_dim1], ldb, t, &c__4, (ftnlen)4);
/* Compute threshold for testing acceptance of swapping. */
/*< EPS = DLAMCH( 'P' ) >*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -