1
subroutine scaleg (n,ma,a,mb,b,low,igh,cscale,cperm,wk)
4
integer igh,low,ma,mb,n
5
double precision a(ma,n),b(mb,n),cperm(n),cscale(n),wk(n,6)
7
c *****local variables:
8
integer i,ir,it,j,jc,kount,nr,nrp2
9
double precision alpha,basl,beta,cmax,coef,coef2,coef5,cor,
10
* ew,ewc,fi,fj,gamma,pgamma,sum,t,ta,tb,tc
12
c *****fortran functions:
13
double precision dabs, dlog10, dsign
16
c *****subroutines called:
19
c ---------------------------------------------------------------
22
c scales the matrices a and b in the generalized eigenvalue
23
c problem a*x = (lambda)*b*x such that the magnitudes of the
24
c elements of the submatrices of a and b (as specified by low
25
c and igh) are close to unity in the least squares sense.
26
c ref.: ward, r. c., balancing the generalized eigenvalue
27
c problem, siam j. sci. stat. comput., vol. 2, no. 2, june 1981,
30
c *****parameter description:
35
c row dimensions of the arrays containing matrices
36
c a and b respectively, as declared in the main calling
37
c program dimension statement;
40
c order of the matrices a and b;
43
c contains the a matrix of the generalized eigenproblem
47
c contains the b matrix of the generalized eigenproblem
51
c specifies the beginning -1 for the rows and
52
c columns of a and b to be scaled;
55
c specifies the ending -1 for the rows and columns
56
c of a and b to be scaled;
59
c work array. only locations low through igh are
60
c referenced and altered by this subroutine;
63
c work array that must contain at least 6*n locations.
64
c only locations low through igh, n+low through n+igh,
65
c ..., 5*n+low through 5*n+igh are referenced and
66
c altered by this subroutine.
70
c a,b contain the scaled a and b matrices;
73
c contains in its low through igh locations the integer
74
c exponents of 2 used for the column scaling factors.
75
c the other locations are not referenced;
77
c wk contains in its low through igh locations the integer
78
c exponents of 2 used for the row scaling factors.
80
c *****algorithm notes:
84
c written by r. c. ward.......
85
c modified 8/86 by bobby bodenheimer so that if
86
c sum = 0 (corresponding to the case where the matrix
87
c doesn't need to be scaled) the routine returns.
89
c ---------------------------------------------------------------
91
if (low .eq. igh) go to 410
103
c compute right side vector in resulting linear equations
110
if (ta .eq. 0.0d0) go to 220
111
ta = dlog10(dabs(ta)) / basl
113
if (tb .eq. 0.0d0) go to 230
114
tb = dlog10(dabs(tb)) / basl
116
wk(i,5) = wk(i,5) - ta - tb
117
wk(j,6) = wk(j,6) - ta - tb
120
coef = 1.0d0/float(2*nr)
127
c start generalized conjugate gradient iteration
134
gamma = gamma + wk(i,5)*wk(i,5) + wk(i,6)*wk(i,6)
138
gamma = coef*gamma - coef2*(ew**2 + ewc**2)
139
+ - coef5*(ew - ewc)**2
140
if (it .ne. 1) beta = gamma / pgamma
141
t = coef5*(ewc - 3.0d0*ew)
142
tc = coef5*(ew - 3.0d0*ewc)
144
wk(i,2) = beta*wk(i,2) + coef*wk(i,5) + t
145
cperm(i) = beta*cperm(i) + coef*wk(i,6) + tc
148
c apply matrix to vector
154
if (a(i,j) .eq. 0.0d0) go to 280
158
if (b(i,j) .eq. 0.0d0) go to 290
162
wk(i,3) = float(kount)*wk(i,2) + sum
168
if (a(i,j) .eq. 0.0d0) go to 310
172
if (b(i,j) .eq. 0.0d0) go to 320
176
wk(j,4) = float(kount)*cperm(j) + sum
180
sum = sum + wk(i,2)*wk(i,3) + cperm(i)*wk(i,4)
182
if(sum.eq.0.0d0) return
185
c determine correction to current iterate
189
cor = alpha * wk(i,2)
190
if (dabs(cor) .gt. cmax) cmax = dabs(cor)
191
wk(i,1) = wk(i,1) + cor
192
cor = alpha * cperm(i)
193
if (dabs(cor) .gt. cmax) cmax = dabs(cor)
194
cscale(i) = cscale(i) + cor
196
if (cmax .lt. 0.5d0) go to 370
198
wk(i,5) = wk(i,5) - alpha*wk(i,3)
199
wk(i,6) = wk(i,6) - alpha*wk(i,4)
203
if (it .le. nrp2) go to 250
205
c end generalized conjugate gradient iteration
209
ir = wk(i,1) + dsign(0.5d0,wk(i,1))
211
jc = cscale(i) + dsign(0.5d0,cscale(i))
220
if (i .lt. low) fi = 1.0d0
224
if (j .le. igh) go to 390
225
if (i .lt. low) go to 400
228
a(i,j) = a(i,j)*fi*fj
229
b(i,j) = b(i,j)*fi*fj
234
c last line of scaleg