1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
subroutine cbal(nm,n,ar,ai,low,igh,scale)
c
integer i,j,k,l,m,n,jj,nm,igh,low,iexc
double precision ar(nm,n),ai(nm,n),scale(n)
double precision c,f,g,r,s,b2,radix
logical noconv
c
c!purpose
c
c this subroutine balances a complex matrix and isolates
c eigenvalues whenever possible.
c
c!calling sequence
c subroutine cbal(nm,n,ar,ai,low,igh,scale)
c
c integer n,nm,igh,low
c double precision ar(nm,n),ai(nm,n),scale(n)
c logical noconv
c
c on input:
c
c nm must be set to the row dimension of two-dimensional
c array parameters as declared in the calling program
c dimension statement;
c
c n is the order of the matrix;
c
c ar and ai contain the real and imaginary parts,
c respectively, of the complex matrix to be balanced.
c
c on output:
c
c ar and ai contain the real and imaginary parts,
c respectively, of the balanced matrix;
c
c low and igh are two integers such that ar(i,j) and ai(i,j)
c are equal to zero if
c (1) i is greater than j and
c (2) j=1,...,low-1 or i=igh+1,...,n;
c
c scale contains information determining the
c permutations and scaling factors used.
c
c suppose that the principal submatrix in rows low through igh
c has been balanced, that p(j) denotes the index interchanged
c with j during the permutation step, and that the elements
c of the diagonal matrix used are denoted by d(i,j). then
c scale(j) = p(j), for j = 1,...,low-1
c = d(j,j) j = low,...,igh
c = p(j) j = igh+1,...,n.
c the order in which the interchanges are made is n to igh+1,
c then 1 to low-1.
c
c note that 1 is returned for igh if igh is zero formally.
c
c the algol procedure exc contained in cbalance appears in
c cbal in line. (note that the algol roles of identifiers
c k,l have been reversed.)
c
c arithmetic is real throughout.
c
c!originator
c this subroutine is a translation of the algol procedure
c cbalance, which is a complex version of balance,
c num. math. 13, 293-304(1969) by parlett and reinsch.
c handbook for auto. comp., vol.ii-linear algebra, 315-326(1971).
c questions and comments should be directed to b. s. garbow,
c applied mathematics division, argonne national laboratory
c
c!
c ------------------------------------------------------------------
c
c :::::::::: radix is a machine dependent parameter specifying
c the base of the machine floating point representation.
c radix = 16.0d+0 for long form arithmetic
c on s360 ::::::::::
data radix/2.0d+0/
c
b2 = radix * radix
k = 1
l = n
go to 100
c :::::::::: in-line procedure for row and
c column exchange ::::::::::
20 scale(m) = j
if (j .eq. m) go to 50
c
do 30 i = 1, l
f = ar(i,j)
ar(i,j) = ar(i,m)
ar(i,m) = f
f = ai(i,j)
ai(i,j) = ai(i,m)
ai(i,m) = f
30 continue
c
do 40 i = k, n
f = ar(j,i)
ar(j,i) = ar(m,i)
ar(m,i) = f
f = ai(j,i)
ai(j,i) = ai(m,i)
ai(m,i) = f
40 continue
c
50 go to (80,130), iexc
c :::::::::: search for rows isolating an eigenvalue
c and push them down ::::::::::
80 if (l .eq. 1) go to 280
l = l - 1
c :::::::::: for j=l step -1 until 1 do -- ::::::::::
100 do 120 jj = 1, l
j = l + 1 - jj
c
do 110 i = 1, l
if (i .eq. j) go to 110
if (ar(j,i) .ne. 0.0d+0 .or. ai(j,i) .ne. 0.0d+0) go to 120
110 continue
c
m = l
iexc = 1
go to 20
120 continue
c
go to 140
c :::::::::: search for columns isolating an eigenvalue
c and push them left ::::::::::
130 k = k + 1
c
140 do 170 j = k, l
c
do 150 i = k, l
if (i .eq. j) go to 150
if (ar(i,j) .ne. 0.0d+0 .or. ai(i,j) .ne. 0.0d+0) go to 170
150 continue
c
m = k
iexc = 2
go to 20
170 continue
c :::::::::: now balance the submatrix in rows k to l ::::::::::
do 180 i = k, l
180 scale(i) = 1.0d+0
c :::::::::: iterative loop for norm reduction ::::::::::
190 noconv = .false.
c
do 270 i = k, l
c = 0.0d+0
r = 0.0d+0
c
do 200 j = k, l
if (j .eq. i) go to 200
c = c + abs(ar(j,i)) + abs(ai(j,i))
r = r + abs(ar(i,j)) + abs(ai(i,j))
200 continue
c :::::::::: guard against zero c or r due to underflow ::::::::::
if (c .eq. 0.0d+0 .or. r .eq. 0.0d+0) go to 270
g = r / radix
f = 1.0d+0
s = c + r
210 if (c .ge. g) go to 220
f = f * radix
c = c * b2
go to 210
220 g = r * radix
230 if (c .lt. g) go to 240
f = f / radix
c = c / b2
go to 230
c :::::::::: now balance ::::::::::
240 if ((c + r) / f .ge. 0.950d+0 * s) go to 270
g = 1.0d+0 / f
scale(i) = scale(i) * f
noconv = .true.
c
do 250 j = k, n
ar(i,j) = ar(i,j) * g
ai(i,j) = ai(i,j) * g
250 continue
c
do 260 j = 1, l
ar(j,i) = ar(j,i) * f
ai(j,i) = ai(j,i) * f
260 continue
c
270 continue
c
if (noconv) go to 190
c
280 low = k
igh = l
return
c :::::::::: last card of cbal ::::::::::
end
|