|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 6144 (0x1800)
Types: TextFile
Names: »extcptridql«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt.
└─⟦0364f57e3⟧
└─⟦58ca399f1⟧ »extbib«
└─⟦this⟧
cptridql=algol list.yes index.no
external
procedure cptridql(n,c,a,x);
value n; integer n; array c,a,x;
comment The procedure diagonalizes a hermitian matrix of
order n. The upper triangular part of this is stored
with the real part on and below the diagonal and the
imaginary part above the diagonal in the quadratic
array c(1:n,1:n). The eigenvalues in ascending order
are formed in a(1:n), and the unitary transformation
matrix ( a = x c x' ) is formed with the real part
in c and the imaginary part in the array x(1:n,1:n).
First part of the procedure is a modified Householder
tridiagonalization;
begin
integer i,j,k,l,m;
real f,g,h,br,bi,qr,qi,q,s,t,macheps;
array b,pr,pi(1:n);
macheps:= 3'-11; q:= 0;
for i:=1 step 1 until n do
for j:=1 step 1 until n do q:= q+abs(c(i,j));
q:= macheps*q/(n*n);
for i:=n step -1 until 3 do begin
a(i):= c(i,i); l:= i-1; qr:= c(i,l); qi:= c(l,i);
s:= f:= qr*qr+qi*qi;
for j:=i-2 step -1 until 1 do s:= s+c(i,j)**2+c(j,i)**2;
b(l):= s:= sqrt(s);
if s>q then begin
f:= sqrt(f); c(i,i):= h:= (s+f)*s;
if f>0 then begin
pr(i):= br:= -qr/f; pi(i):= bi:= qi/f;
c(i,l):= qr-s*br; c(l,i):= qi+s*bi
end else begin
c(i,l):= s; pi(i):= c(l,i):= bi:= 0; pr(i):= br:= -1 end;
comment the elements c(i,1) - c(i,i-1) and c(1,i) - c(i-1,i)
contain real and imaginary parts of u(1) - u(i-1).
h was stored in c(i,i). p = c*u/h is calculated
in pr and pi. g = u'*p/2h is formed as well;
g:= 0;
for j:=1 step 1 until l do begin
qr:= c(j,j)*c(i,j); qi:= c(j,j)*c(j,i);
for k:=j-1 step -1 until 1 do begin
qr:= qr+c(j,k)*c(i,k)+c(k,j)*c(k,i);
qi:= qi-c(k,j)*c(i,k)+c(j,k)*c(k,i)
end;
for k:= j+1 step 1 until l do begin
qr:= qr+c(k,j)*c(i,k)-c(j,k)*c(k,i);
qi:= qi+c(j,k)*c(i,k)+c(k,j)*c(k,i)
end;
pr(j):= qr:= qr/h; pi(j):= qi:= qi/h;
g:= g+qr*c(i,j)+qi*c(j,i);
end j;
g:= g/(h+h);
comment the elements of p - g*u is calculated in p, and
finally c is transformed;
for j:=1 step 1 until l do begin
pr(j):= pr(j)-c(i,j)*g;
pi(j):= pi(j)-c(j,i)*g
end;
for j:=1 step 1 until l do
for k:=1 step 1 until j do begin
c(j,k):= c(j,k)-pr(j)*c(i,k)-pi(j)*c(k,i)
-pr(k)*c(i,j)-pi(k)*c(j,i);
if j>k then
c(k,j):= c(k,j)-pr(j)*c(k,i)+pi(j)*c(i,k)
+pr(k)*c(j,i)-pi(k)*c(i,j)
end;
comment exp(i*delta(i)) used to make b(i-1) positive
was evaluated and stored in p(i). The elements of
c with index (i-1) are transformed accordingly;
for j:=l-1 step -1 until 1 do begin
qr:= c(l,j); qi:= c(j,l);
c(l,j):= br*qr+bi*qi; c(j,l):= br*qi-bi*qr
end end sigma>q
end i, tridiagonalization;
a(1):= c(1,1); c(1,1):= 1; x(1,1):= b(n):= 0;
if n>1 then begin
a(2):= c(2,2); br:= c(2,1); bi:= c(1,2);
b(1):= f:= sqrt(br*br+bi*bi);
if f>0 then begin c(1,1):= br/f; x(1,1):= -bi/f
end end;
m:= n+1;
for i:=3 step 1 until m do begin
l:= i-1;
if b(l)<=q then begin
c(l,l):= 1; x(l,l):= 0;
for j:=l-1 step -1 until 1 do
c(j,l):= c(l,j):= x(j,l):= x(l,j):= 0
end else begin
h:= c(i,i);
comment u is transferred to p;
for j:=1 step 1 until l do begin
pr(j):= c(i,j); pi(j):= c(j,i)
end;
g:= 1/b(l); g:= h*g*g; qr:= pr(i); qi:= pi(i);
c(l,l):= qr-qr*g;
x(l,l):= qi-qi*g;
br:= (qr*pr(l)-qi*pi(l))/h;
bi:= (qi*pr(l)+qr*pi(l))/h;
for j:=i-2 step -1 until 1 do begin
qr:= qi:= 0;
for k:=i-2 step -1 until 1 do begin
qr:= qr+c(j,k)*pr(k)-x(j,k)*pi(k);
qi:= qi+c(j,k)*pi(k)+x(j,k)*pr(k)
end;
c(j,l):= x(j,l):= 0; qr:= qr/h; qi:= qi/h;
for k:=1 step 1 until l do begin
c(j,k):= c(j,k)-qr*pr(k)-qi*pi(k);
x(j,k):= x(j,k)-qi*pr(k)+qr*pi(k)
end;
c(l,j):= -br*pr(j)-bi*pi(j);
x(l,j):= -bi*pr(j)+br*pi(j)
end end j end i;
comment Now we find the eigenvalues and eigenvectors of the
tridiagonal matrix given with its diagonal elements
in the array a(1:n) and its subdiagonal elements in
the first n-1 stores of the array b(1:n), using QL
transformations. The eigenvalues are overwritten in
the array a in ascending order. The eigenvectors are
formed in the array x(1:n,1:n), overwritting the
accumulated transformations supplied by the tridia-
gonalization above (Numer. Math. 11, 293-306 (1968));
br:= f:= 0;
for l:=1 step 1 until n do begin
j:= 0; h:= macheps*(abs a(l) + abs b(l));
if br<h then br:= h;
comment look for small sub-diagonal elements;
for m:= l step 1 until n do
if abs b(m)<=br then goto cont;
cont:
if m=l then goto root;
nextit:
if j=30 then goto fail;
j:= j+1;
comment form shift;
t:= (a(l+1)-a(l))/(2*b(l)); q:= sqrt(t*t+1);
h:= a(l)-b(l)/(if t<0 then t-q else t+q);
for i:=l step 1 until n do a(i):= a(i)-h;
f:= f+h;
comment QL transformation;
t:= a(m); bi:= 1; s:= 0;
for i:= m-1 step -1 until l do begin
g:= bi*b(i); h:= bi*t;
if abs t>=abs b(i) then begin
bi:= b(i)/t; q:= sqrt(bi*bi+1);
b(i+1):= s*t*q; s:= bi/q; bi:= 1/q
end else begin
bi:= t/b(i); q:= sqrt(bi*bi+1);
b(i+1):= s*b(i)*q; s:= 1/q; bi:= bi/q
end;
t:= bi*a(i)-s*g;
a(i+1):= h+s*(bi*g+s*a(i));
comment form vector;
for k:=1 step 1 until n do begin
qr:= x(i,k); qi:= x(i+1,k);
x(i+1,k):= s*qr+bi*qi;
x(i,k) := bi*qr-s*qi;
qr:= c(i,k); qi:= c(i+1,k);
c(i+1,k):= s*qr+bi*qi;
c(i,k) := bi*qr-s*qi
end k
end i;
b(l):= s*t; a(l):= bi*t;
if abs b(l)>br then goto nextit;
root:
a(l):= a(l)+f
end l;
comment order eigenvalues and eigenvectors;
for i:=1 step 1 until n do begin
k:= i; t:= a(i);
for j:=i+1 step 1 until n do if a(j)<t then
begin k:= j; t:= a(j) end;
if k<>i then begin
a(k):= a(i); a(i):= t;
for j:=1 step 1 until n do begin
t:= x(i,j); x(i,j):= x(k,j); x(k,j):= t;
t:= c(i,j); c(i,j):= c(k,j); c(k,j):= t
end j
end end;
fail:
end;
end
▶EOF◀