zggbal.c
来自「算断裂的」· C语言 代码 · 共 612 行 · 第 1/2 页
C
612 行
#include "f2c.h"
/* Subroutine */ int zggbal_(char *job, integer *n, doublecomplex *a, integer
*lda, doublecomplex *b, integer *ldb, integer *ilo, integer *ihi,
doublereal *lscale, doublereal *rscale, doublereal *work, integer *
info)
{
/* -- LAPACK routine (version 2.0) --
Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
Courant Institute, Argonne National Lab, and Rice University
September 30, 1994
Purpose
=======
ZGGBAL balances a pair of general complex matrices (A,B). This
involves, first, permuting A and B by similarity transformations to
isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
elements on the diagonal; and second, applying a diagonal similarity
transformation to rows and columns ILO to IHI to make the rows
and columns as close in norm as possible. Both steps are optional.
Balancing may reduce the 1-norm of the matrices, and improve the
accuracy of the computed eigenvalues and/or eigenvectors in the
generalized eigenvalue problem A*x = lambda*B*x.
Arguments
=========
JOB (input) CHARACTER*1
Specifies the operations to be performed on A and B:
= 'N': none: simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
and RSCALE(I) = 1.0 for i=1,...,N;
= 'P': permute only;
= 'S': scale only;
= 'B': both permute and scale.
N (input) INTEGER
The order of the matrices A and B. N >= 0.
A (input/output) COMPLEX*16 array, dimension (LDA,N)
On entry, the input matrix A.
On exit, A is overwritten by the balanced matrix.
If JOB = 'N', A is not referenced.
LDA (input) INTEGER
The leading dimension of the array A. LDA >= max(1,N).
B (input/output) COMPLEX*16 array, dimension (LDB,N)
On entry, the input matrix B.
On exit, B is overwritten by the balanced matrix.
If JOB = 'N', B is not referenced.
LDB (input) INTEGER
The leading dimension of the array B. LDB >= max(1,N).
ILO (output) INTEGER
IHI (output) INTEGER
ILO and IHI are set to integers such that on exit
A(i,j) = 0 and B(i,j) = 0 if i > j and
j = 1,...,ILO-1 or i = IHI+1,...,N.
If JOB = 'N' or 'S', ILO = 1 and IHI = N.
LSCALE (output) DOUBLE PRECISION array, dimension (N)
Details of the permutations and scaling factors applied
to the left side of A and B. If P(j) is the index of the
row interchanged with row j, and D(j) is the scaling factor
applied to row j, then
LSCALE(j) = P(j) for J = 1,...,ILO-1
= D(j) for J = ILO,...,IHI
= P(j) for J = IHI+1,...,N.
The order in which the interchanges are made is N to IHI+1,
then 1 to ILO-1.
RSCALE (output) DOUBLE PRECISION array, dimension (N)
Details of the permutations and scaling factors applied
to the right side of A and B. If P(j) is the index of the
column interchanged with column j, and D(j) is the scaling
factor applied to column j, then
RSCALE(j) = P(j) for J = 1,...,ILO-1
= D(j) for J = ILO,...,IHI
= P(j) for J = IHI+1,...,N.
The order in which the interchanges are made is N to IHI+1,
then 1 to ILO-1.
WORK (workspace) DOUBLE PRECISION array, dimension (6*N)
INFO (output) INTEGER
= 0: successful exit
< 0: if INFO = -i, the i-th argument had an illegal value.
Further Details
===============
See R.C. WARD, Balancing the generalized eigenvalue problem,
SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
=====================================================================
Test the input parameters
Parameter adjustments
Function Body */
/* Table of constant values */
static integer c__1 = 1;
static doublereal c_b35 = 10.;
static doublereal c_b71 = .5;
/* System generated locals */
integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3, i__4;
doublereal d__1, d__2, d__3;
/* Builtin functions */
double d_lg10(doublereal *), d_imag(doublecomplex *), z_abs(doublecomplex
*), d_sign(doublereal *, doublereal *), pow_di(doublereal *,
integer *);
/* Local variables */
static integer lcab;
static doublereal beta, coef;
static integer irab, lrab;
static doublereal basl, cmax;
extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
integer *);
static doublereal coef2, coef5;
static integer i, j, k, l, m;
static doublereal gamma, t, alpha;
extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *,
integer *);
extern logical lsame_(char *, char *);
static doublereal sfmin, sfmax;
static integer iflow;
extern /* Subroutine */ int daxpy_(integer *, doublereal *, doublereal *,
integer *, doublereal *, integer *);
static integer kount;
extern /* Subroutine */ int zswap_(integer *, doublecomplex *, integer *,
doublecomplex *, integer *);
static integer jc;
static doublereal ta, tb, tc;
extern doublereal dlamch_(char *);
static integer ir, it;
static doublereal ew;
static integer nr;
static doublereal pgamma;
extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_(
integer *, doublereal *, doublecomplex *, integer *);
static integer lsfmin;
extern integer izamax_(integer *, doublecomplex *, integer *);
static integer lsfmax, ip1, jp1, lm1;
static doublereal cab, rab, ewc, cor, sum;
static integer nrp2, icab;
#define LSCALE(I) lscale[(I)-1]
#define RSCALE(I) rscale[(I)-1]
#define WORK(I) work[(I)-1]
#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)]
#define B(I,J) b[(I)-1 + ((J)-1)* ( *ldb)]
*info = 0;
if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(
job, "S") && ! lsame_(job, "B")) {
*info = -1;
} else if (*n < 0) {
*info = -2;
} else if (*lda < max(1,*n)) {
*info = -4;
} else if (*ldb < max(1,*n)) {
*info = -5;
}
if (*info != 0) {
i__1 = -(*info);
xerbla_("ZGGBAL", &i__1);
return 0;
}
k = 1;
l = *n;
/* Quick return if possible */
if (*n == 0) {
return 0;
}
if (lsame_(job, "N")) {
*ilo = 1;
*ihi = *n;
i__1 = *n;
for (i = 1; i <= *n; ++i) {
LSCALE(i) = 1.;
RSCALE(i) = 1.;
/* L10: */
}
return 0;
}
if (k == l) {
*ilo = 1;
*ihi = 1;
LSCALE(1) = 1.;
RSCALE(1) = 1.;
return 0;
}
if (lsame_(job, "S")) {
goto L190;
}
goto L30;
/* Permute the matrices A and B to isolate the eigenvalues.
Find row with one nonzero in columns 1 through L */
L20:
l = lm1;
if (l != 1) {
goto L30;
}
RSCALE(1) = 1.;
LSCALE(1) = 1.;
goto L190;
L30:
lm1 = l - 1;
for (i = l; i >= 1; --i) {
i__1 = lm1;
for (j = 1; j <= lm1; ++j) {
jp1 = j + 1;
i__2 = i + j * a_dim1;
i__3 = i + j * b_dim1;
if (A(i,j).r != 0. || A(i,j).i != 0. || (B(i,j).r != 0. || B(i,j).i != 0.)) {
goto L50;
}
/* L40: */
}
j = l;
goto L70;
L50:
i__1 = l;
for (j = jp1; j <= l; ++j) {
i__2 = i + j * a_dim1;
i__3 = i + j * b_dim1;
if (A(i,j).r != 0. || A(i,j).i != 0. || (B(i,j).r != 0. || B(i,j).i != 0.)) {
goto L80;
}
/* L60: */
}
j = jp1 - 1;
L70:
m = l;
iflow = 1;
goto L160;
L80:
;
}
goto L100;
/* Find column with one nonzero in rows K through N */
L90:
++k;
L100:
i__1 = l;
for (j = k; j <= l; ++j) {
i__2 = lm1;
for (i = k; i <= lm1; ++i) {
ip1 = i + 1;
i__3 = i + j * a_dim1;
i__4 = i + j * b_dim1;
if (A(i,j).r != 0. || A(i,j).i != 0. || (B(i,j).r != 0. || B(i,j).i != 0.)) {
goto L120;
}
/* L110: */
}
i = l;
goto L140;
L120:
i__2 = l;
for (i = ip1; i <= l; ++i) {
i__3 = i + j * a_dim1;
i__4 = i + j * b_dim1;
if (A(i,j).r != 0. || A(i,j).i != 0. || (B(i,j).r != 0. || B(i,j).i != 0.)) {
goto L150;
}
/* L130: */
}
i = ip1 - 1;
L140:
m = k;
iflow = 2;
goto L160;
L150:
;
}
goto L190;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?