|
|
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: 33792 (0x8400)
Types: TextFile
Notes: RCSL-44-RT-900
Names: »nllprtx«
└─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ.
└─⟦4334b4c0b⟧
└─⟦this⟧ »nllprtx«
; gi nll procedures * page 1 5 09 77, 15.13;
; nll_pr
; ******
if listing.yes
char 10 12 10
nll_pr = set 1
nll_pr = algol
external integer procedure nll_pr
_________________________________
_ (z, t, exist);
zone z;
integer t;
boolean exist;
begin
integer q_proc;
real str;
nll_pr :=
q_proc := 10;
write(z, nl, 3, <:; :>, q_proc, <:_procedures:>, nl, 2,
_ <:; proc_name__________version:>, nl, 1);
for t := 1 step 1 until q_proc do
if exist then
begin
str := real (case t of (
<* 1 *> <:nll<95>pr:>,
<* 2 *> <:otn<95>gier:>,
<* 3 *> <:nll<95>gier:>,
<* 4 *> <:nll:>,
<* 5 *> <:nll1:>,
<* 6 *> <:nll<95>epu:>,
<* 7 *> <:otn<95>epu:>,
<* 8 *> <:epu<95>block:>,
<* 9 *> <:epu<95>print:>,
<* 10 *> <:nll<95>block:>,
<* *> <::>));
wr_date_time(z, proc_transla(string str)
+ 0*write(z, sp, 16 - write(z, nl, 1, string str, <:, :>)));
end;
end nll_pr;
end
if warning.yes
(mode 0.yes
message nll_pr not ok
lookup nll_pr)
\f
; gi nll procedures * page 2 5 09 77, 15.13;
; otn_gier
***********
if listing.yes
char 10 12 10
otn_gier = set 1
otngier = algol
external procedure otn_gier
__________________________
(B, NL, n);
value n;
array B, NL;
integer n;
comment
otn_gier (call) no type procedure
the procedure computes the contributions from
the product B**T times B to the triangular matrix
NL mapped as a linear array columnwize.
B (call) real array
a column of observation equations (for one observ.).
NL (call and return) real array
a triangular array of normals mapped on NL with
nl(1, 1)=NL(1), nl(1, 2)=NL(2), nl(2, 2)=NL(3), etc.
n (call) integer
the number of columns in B and the triagular NL;
begin integer I, r, c;
I:=0;
for r:=1 step 1 until n do
for c:=1 step 1 until r do
begin I:=I+1; NL(I):=NL(I)+B(r)*B(c) end
end otn_gier;
end
if warning.yes
(mode 0.yes
message otn_gier not ok
lookup otn_gier)
\f
; gi nll procedures * page 3 5 09 77, 15.13;
; nllgier
; *******
if listing.yes
char 10 12 10
nllgier = set 1 disc
nllgier = algol
external
real procedure nll(N, n, fr, fc, BS);
value n, fr, fc, BS; integer n, fr, fc; boolean BS; array N;
begin integer r, c, p, I, Ir, Ic; real sum;
for r:=fr+1 step 1 until n do
begin Ir:=r*(r-1)//2; I:=Ir+fc;
for c:=fc+1 step 1 until r do
begin sum:=0; Ic:=c*(c-1)//2; I:=I+1;
for p:=fc+1 step 1 until c-1 do
sum:=sum+N(Ir+p)*N(Ic+p);
N(I):=N(I)-sum; if r<>c then N(I):=N(I)/N(Ic+c)
end;
if r<>n then N(I):=sqrt(N(I))
else
begin nll:=N(I);
if BS then for c:=n-1 step -1 until 1 do
begin Ir:=I:=I-1; Ic:=c*(c+1)//2; N(I):=N(I)/N(Ic);
for p:=c-1 step -1 until 1 do
begin Ir:=Ir-1; Ic:=Ic-1;
N(Ir):=N(Ir)-N(I)*N(Ic)
end
end
end
end
end nll;
end
if warning.yes
(mode 0.yes
message nll_gier not ok
lookup nll_gier)
\f
; gi nll procedures * page 4 5 09 77, 15.13;
; nll
; ***
if listing.yes
char 10 12 10
nll = set 1 disc
nll = algol
external
real procedure nll(N, n, explim, maxlim, SING, KT);
value n, explim; integer n, explim;
array N; long array SING; real KT, maxlim;
begin integer r, t, tt, c, p, I, Ir, Ic, expNI, maxlim1, maxtest;
real sum, NI; boolean sing, BS;
tt:=0; t:=1; maxlim1:=-8338607;
explim:=explim shift 12;
BS:=n>0;
for r:=1 step 1 until n do
begin
I:=Ir:=r*(r-1)//2;
for c:=1 step 1 until r do
begin
sum:=0; Ic:=c*(c-1)//2; I:=I+1;
for p:=1 step 1 until c-1 do
sum:=sum-N(Ir+p)*N(Ic+p);
NI:=N(I);
if r<>c then N(I):=(NI+sum)/N(Ic+c)
else
if r<>n then
begin
tt:=tt+1; if tt=49 then begin t:=t+1; tt:=1; end;
SING(t):=SING(t) shift 1;
expNI:=(NI extract 12) shift 12; NI:=NI+sum;
maxtest:=expNI-((NI extract 12) shift 12);
sing:=maxtest>explim;
if -, sing & NI>0.0 then N(I):= sqrt(NI)
else begin N(I):='600; SING(t):=SING(t)+1; end;
if maxtest>maxlim1 then maxlim1:=maxtest;
end;
end;
end;
nll:=NI:=NI+sum;
KT:=mu*ln(-NI/sum)/2; maxlim:=maxlim1/4096;
if BS then for c:=n-1 step -1 until 1 do
begin
Ir:=I:=I-1; Ic:=c*(c+1)//2; N(I):=N(I)/N(Ic);
for p:=c-1 step -1 until 1 do
begin
Ir:=Ir-1; Ic:=Ic-1;
N(Ir):=N(Ir)-N(I)*N(Ic);
end;
end;
end nll;
end
if warning.yes
(mode 0.yes
message nll not ok
lookup nll)
\f
; gi nll procedures * page 5 5 09 77, 15.13;
; nll1
; ****
if listing.yes
char 10 12 10
nll1 = set 1 disc
nll1 = algol
external
real procedure nll(N, n, explim, maxloss, SING, KT);
value n, explim; integer n, explim, maxloss;
array N; long array SING; real KT;
begin integer r, t, tt, c, p, I, Ir, Ic, expNI, maxloss1, maxtest;
real sum, NI; boolean sing, BS;
tt:=0; t:=1; maxloss1:=0;
explim:=explim shift 12;
BS:=n>0; n := abs n;
for r:=1 step 1 until n do
begin
I:=Ir:=r*(r-1)//2;
for c:=1 step 1 until r do
begin
sum:=0; Ic:=c*(c-1)//2; I:=I+1;
for p:=1 step 1 until c-1 do
sum:=sum-N(Ir+p)*N(Ic+p);
NI:=N(I);
if r<>c then N(I):=(NI+sum)/N(Ic+c)
else
if r<>n then
begin
tt:=tt+1; if tt=49 then begin t:=t+1; tt:=1; end;
SING(t):=SING(t) shift 1;
expNI:=(NI extract 12) shift 12; NI:=NI+sum;
maxtest:=expNI-((NI extract 12) shift 12);
sing:=maxtest>explim;
if -,sing and NI>0.0 then N(I):= sqrt(NI)
else begin N(I):='600; SING(t):=SING(t)+1; end;
if maxtest>maxloss1 then maxloss1:=maxtest;
end;
end;
end;
comment TEST: :
write(out, <:<10>nll1:NI,sum= :>,
<< -d.ddd'-d>, NI, sum);
nll:=NI:=NI+sum;
KT:= if -sum>'-300 and NI>0 then mu*ln(-NI/sum)/2 else '-50;
maxloss := maxloss1 shift (-12);
if BS then for c:=n-1 step -1 until 1 do
begin
Ir:=I:=I-1; Ic:=c*(c+1)//2; N(I):=N(I)/N(Ic);
for p:=c-1 step -1 until 1 do
begin
Ir:=Ir-1; Ic:=Ic-1;
N(Ir):=N(Ir)-N(I)*N(Ic);
end;
end;
end nll;
end
if warning.yes
(mode 0.yes
message nll1 not ok
lookup nll1)
\f
; gi nll procedures * page 6 5 09 77, 15.13;
;
; n l l e p u
; ____________
;
if listing.yes
char 10 12 10
nllepu=set 36
nllepu=algol message.no
external
real procedure NLL(N, n, explim, maxlim, SING, KT);
___________________________________________________
value n, explim;
integer n, explim, maxlim;
array N;
long array SING;
real KT;
begin
comment
Solution of a system of linear equations with
positiv definit coefficient matrix. Choleski
decomposition and the aritmetic unit epu are
used.
Parameters.
NLL (real, return value). The pvv-sum
_ minus the square-sum of the inter-
_ mediate right side. The pvv-sum is
_ the square - sum of the original
_ right side.
N (real array, call and return value)
_ At call the coefficients and the
_ right side. Only the upper half is
_ stored, which is done column by
_ column, i.e. (1, 1), (1, 2), (2, 2),
_ (1, 3), (2, 3), (3, 3), (1, 4), ...,
_ (4, 4), ..., (1, n), ..., (n, n) is
_ stored in N(1) to N(n*(n+1)/2). The
_ last column is the right side and
_ the very last element (which is not
_ changed) ougth to be the pvv-sum.At
_ return the Choleski factor and the
_ solution is stored in the same way.
_ Double precision is used at call-
_ time. All the tails are stored in
_ the last part of N, that is from
_ element (n*(n+1)/2 + 1) to element
_ (n*(n+1)). At return single preci-
_ sion is used, i.e. the tails are un-
_ defined, exept the diagonal elements
_ which holds the status word and the
_ exponent loss from the epu-diagonal-
_ operation.
;
\f
comment gi nll procedures * page 7 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
comment
n (integer, call value). The order of
_ the system plus one. If sign is ne-
_ gativ the absolute value is used
_ and no back-substition is preformed.
explim (integer, call value). Maximum al-
_ lowed loss of digits in the subtrac-
_ tion which forms the square of the
_ new diagonal element. A value of 30
_ is a reasonable standard.
maxlim (integer, return value). The actual
_ maximum digit loss.
SING (long array, return value). Bit pat-
_ tern giving the singularities of
_ the matrix.
KT (real, return value). The Krarup
_ number 0.5*log(NLL/pvv).
External referances.
integer procedure abs_addr.
real procedure sub_double.
long prvers.
procedure epu_block (GI nr 75004).
process ympe.
GI program index nr 75006.
January 1975, WLW.
updated feb 77, WLW.
- -> o 0 o <- -
;
\f
comment gi nll procedures * page 8 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
integer r, t, tt, c, p, I, Ir, Ic, expNI, maxlim1,
_ add1, div1, str1, mla1,
_ zmls, stp, zadd1, mls, dia,
_ max_test, addr_sum, addr_sum1,
_ baseN, baseH, last_p, code_length,
_ n1;
real sum, sum1, NI, op_code;
zone epu((3*6*100+3)//4, 1, epu_block);
integer array field word;
boolean field byte;
integer field ord;
boolean sing, BS, epu_test, bs_test;
procedure code_dump;
begin
write(out, <:<10>epu code dump.:>);
for byte:= 1 step 1 until word do
write(out, false add 10,
if byte mod 6 = 1 then 1 else 0,
<< dddd>, epu.byte extract 12);
for ord:= 2 step 2 until word do
begin
byte:= ord -1;
if ord mod 6 = 2 then
begin
write(out, false add 10, 1,
if (epu.byte shift (-11) extract 1) = 1
then <:z :> else <: :>);
op_code:= real (
if (epu.byte extract 11 > 7)
then <:ill:> else ( case (epu.byte extract 7+1) of
(<:add:>, <:sub:>, <:mla:>, <:mls:>, <:str:>,
_<:div:>, <:sqr:>, <:dia:>, <:xxx:>)));
write(out, string op_code,
<< dddd>, epu.ord extract 12 <*count*>);
end
else write(out,
<<-ddd ddd ddd>,
(if (ord mod 6 = 4 and epu.ord <> addr_sum )
then ((epu.ord - baseN) // 4)
else (if (ord mod 6 = 0 and epu.ord <> addr_sum1)
_ then ((epu.ord - baseH) // 4)
_ else epu.ord)));
end for ord;
end epu_dump;
BS := n>0;
n := abs(n);
n1 := n - 1;
prvers:= 5 09 77 15 13;
comment index check in N;
r:= system(3)array_bounds:(c, N);
if r>1 or c<n*(n+1) then
begin
write(out, <:<10>***Coefficient matrix:>,
_ <:<10> in call of nllepu:>,
_ <:<10> is too small.:>,
_ <:<10> Bad bounds::>, r, c);
system(9)run_time_alarm:(n, <:<10>order___:>);
end if r>1;
word:= 0;
code_length:= 3*6*100;
open(epu, 14, <:ympe:>, 31 shift 18);
out_rec6(epu, code_length);
\f
comment gi nll procedures * page 9 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
add1 := 0 shift 23 + 1;
zadd1:= 1 shift 23 + 0 shift 12 + 1;
mla1 := 2 shift 12 + 1;
mls := 3 shift 12;
zmls := 1 shift 23 + 3 shift 12;
str1 := 4 shift 12 + 1;
div1 := 5 shift 12 + 1;
dia := 7 shift 12 + explim extract 12;
stp := 4095 shift 12 + 1;
addr_sum := abs_addr(sum);
addr_sum1:= abs_addr(sum1);
baseN := abs_addr(N);
baseH := baseN + (n*(n+1)*2);
epu_test := false;
bs_test := false;
if epu_test then
write(out, <:<10>adresser N, H:>, baseN, baseH,
<:<10>sum, sum1:>, addr_sum, addr_sum1);
for r:=1 step 1 until n do
begin
I:=Ir:=r*(r-1)*2;
for c:=1 step 1 until r do
begin
I:= I+4;
Ic:= c*(c-1)*2;
comment generate epu-code for
N(c, r) - summa (N(p, r)*N(p, c)),
p= 1, ..., c-1;
if epu_test then write(out, <:<10>mls r, c, word:>, r, c, word);
lastp:= if c=1 then 3 else 6;
for p:= 1 step 1 until lastp do
epu.word(p):= case p+6-lastp of (
zmls + (c-1),
baseN + 4 + Ir,
baseN + 4 + Ic,
(if c=1 then 1 shift 23 else 0) + add1,
baseN + I,
baseH + I);
word:= word + 2*last_p;
comment if c=1 the mls will work as a no-op, therefor
it is omitted and the clearing of the epu-accumulator
R is made by the 1 shift 23 in the add1.
;
\f
comment gi nll procedures * page 10 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
if word+24 >= code_length then
begin
comment start and wait for the epu-calculations. As
the epu-unit can't be reserved the contens of the
accumulator R must be saved before stop of the epu;
for p:= 1 step 1 until 6 do
epu.word(p):= case p of (
str1,
addr_sum,
addr_sum1,
stp,
0,
0);
if epu_test then
write(out, <:<10>fuld<10>:>);
word:= word + 12;
changerec6(epu, word);
outrec6(epu, code_length);
if epu_test then code_dump;
if epu_test then
for p:= 1 step 1 until I//4 do
write(out, nl, 1, <<dd>, p, << -d.ddd ddd'+d>, N(p));
word:= 0;
comment reload R from sum;
epu.word(1):= zadd1;
epu.word(2):= addr_sum;
epu.word(3):= addr_sum1;
word:= word+6;
end if word+18>= code_length;
\f
comment gi nll procedures * page 11 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
if r<>c then
begin
comment non-diagonal element;
epu.word(1):= div1;
epu.word(2) := baseN + I;
epu.word(3) := baseN + Ic + 4*c;
word:= word + 6;
comment Pay attention to the fact that both divisor and
the result are single precision. The divisor is a diagonal
element , i.e. the result of a sqrt . This operation must
therefor deliver a single precision result;
end non-diag
else
begin
comment diagonal element;
comment TEST: :
write(out, <:<10>nll epu dia::>, I);
if r = n then
begin
comment diagonal element of right hand side.
Start and wait for epu with save of sum;
for p:= 1 step 1 until 6 do
epu.word(p):= case p of (
str1,
addr_sum,
addr_sum1,
stp,
0,
0);
word:= word + 12;
comment start and wait for the epu-calculation;
if epu_test then write(out, <:<10>diag<10>:>, r, c, <:<10>:>);
if epu_test then
for p:= 1 step 1 until n*(n+1)//2 do
write(out, <:<10>:>, <<dd>, p, << -d.ddd ddd'+d>, N(p),
N(p + n*(n+1)//2) );
changerec6(epu, word);
if eputest then write(out, <:<10>changerec done, word:>, word);
if epu_test then code_dump;
outrec6(epu, code_length);
word:= 0;
end r = n
\f
<* gi nll procedures * page 12 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 *>
else
begin
comment computation of square root;
epu.word(1):= dia;
epu.word(2):= baseN + I <* sqrt *>;
epu.word(3):= baseH + I <* status shift 24 + exp_loss *>;
word := word + 6;
end if r<>n;
end diagonal element;
end for c, i.e. row no r clompleted;
end;
\f
comment gi nll procedures * page 13 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
comment the triangular choleski-factor is now
stored in N and the forward substitutio is
preformed. The new intermediate rigth sides,
which is the result of the forwart substitu-
tion, is stored in the last part of N;
if epu_test then
write(out, <:<10>Forlængs slut, I, sum, N(I):>,
<< -d.dd'd>, I, sum, N(I//4));
NLL:= NI:= sum + sum1 <* rounding, nll:= pvv - pww *>;
sub_double(sum, sum1, N(I//4), N(I//4 + n*(n+1)/2), sum, sum1);
comment TEST: :
write(out, <:<10>pww = :>, << -d.ddd'-ddd>,
sum, sum1, sum + sum1);
sum1:= sum + sum1 <* rounding, sum1 := -pww *>;
if abs(sum1) < '-100 then KT := - '300 else
if (-NI/sum1) < '-10 then KT := - '300 else
KT:=mu*ln(-NI/sum1)/2;
comment test of exponent losses;
max_lim1:= 0;
tt := 0 <* bit pointer *>;
t := 1 <* double word pointer *>;
c := n * (n + 1) // 2 <* base index of tail *>;
for p:= 1 step 1 until n1 do
begin
tt:= tt + 1;
if tt = 49 then
begin
tt:= 1;
t := t + 1;
end;
SING(t):= SING(t) shift 1;
r:= c + p * (p + 1) // 2 <* index of tail of diagonal element *>;
NI:= N(r);
if NI shift (-24) extract 24 <* status *> > 1 then
SING(t):= SING(t) add 1;
if NI extract 24 > max_lim1 then
max_lim1:= NI extract 24;
end for p;
max_lim:= max_lim_1;
\f
comment gi nll procedures * page 14 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
comment clear 2. part of rigth side;
c:= n*(n+1)//2 + n*(n-1)//2;
for p:= n-1 step -1 until 1 do
N(c+p):= 0;
if bs_test then
begin
write(out, <:<10>nll I:>, I);
write(out, <:<10>nll højre<10>:>);
for c:= n-1 step -1 until 1 do
write(out, false add 10,
if c mod 4 = 0 then 1 else 0,
<< -d.ddd ddd'+dd>, N(n*(n-1)//2 + c) );
end if bs_test;
if BS then
for c:= n-1 step -1 until 1 do
begin
comment compute solution no c and subtract
the effect on the rigth side;
Ir:= I:= I-4;
Ic:= c*(c+1)*2;
comment generate code for final solution
for unknown no c, x(c):= x(c)/diagonal(c);
if bs_test then
write(out, <:<10>nll div:>, << -d.ddd ddd'+dd>, N(I//4), N(Ic//4));
for p:= 1 step 1 until 6 do
epu.word(p):= case p of (
zadd1,
baseN + I,
baseH + I,
div1,
baseN + I,
baseN + Ic);
word:= word + 12;
\f
comment gi nll procedures * page 15 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
for r:= c-1 step -1 until 1 do
begin
comment subtract the influence of unknown no c
from the upper c-1 elements of the rigth side;
Ir:= Ir-4;
Ic:= Ic-4;
if word + 36 >= code_length then
begin comment start and wait for the epu;
epu.word(1):= stp;
epu.word(2):= 0;
epu.word(3):= 0;
word:= word + 6;
changerec6(epu, word);
out_rec6(epu, code_length);
word:= 0;
end if word + 30;
for p:= 1 step 1 until 9 do
epu.word(p):= case p of (
zadd1,
baseN + Ir,
baseH + Ir,
mls + 1,
baseN + I,
baseN + Ic,
str1,
baseN + Ir,
baseH + Ir);
word:= word + 18;
end for r;
end for c;
epu.word(1):= stp;
epu.word(2):= 0;
epu.word(3):= 0;
word:= word + 6;
changerec6(epu, word);
close(epu, true);
if bs_test then
begin
write(out, false add 10, 2);
for c:= n-1 step -1 until 1 do
write(out, false add 10,
if c mod 4 = 0 then 1 else 0,
<< -d.ddd ddd'+dd>, N(n*(n-1)//2 + c));
end if bs_test;
end NLL;
end
if warning.yes
(mode 0.yes
message nll_epu not ok
lookup nll_epu)
\f
; gi nll procedures * page 16 5 09 77, 15.13;
if listing.yes
char 10 12 10
otnepu=set 1
otnepu=algol
external procedure otn_epu(B, NL, n);
_____________________________________
value n;
integer n;
array B, NL;
begin
comment
The procedure add the contribution to the
normal equations from a single observation
equation. The arithemetic unit epu is used,
which give double precision results.
Parameters.
B (real array, call value). One row in the
_ observation equations, stored in the
_ elements B(1), ..., B(n).
NL (real array, call and return value). The
_ dobbel precision normal equations, in-
_ cluding the right-hand side. Only the
_ upper triangular part is stored, which
_ is done column by column. In the ele-
_ ments NL(1) to NL(n*(n+1)/2) the high
_ part of the coefficients are stored,
_ and in the last n*(n+1)/2 elements the
_ low part of the coefficients are stored.
n (integer, call value). The number of un-
_ knowns plus one.
External refrences.
integer procedure abs_addr
long prvers
procedure epu_block
process ympe
GI-program no 75005,
WW, jan. 1975.
;
\f
comment gi nll procedures * page 17 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
comment declarations;
integer z_add1, mla_1, str_1, stp_1,
_ head, tail, base, r, c, code_length;
integer array field word;
zone epu((100*18 + 6 + 3)//4, 1, epu_block);
prvers:= 5 09 77 15 13;
comment address constants for epu-calculations;
base:= abs_addr(B);
head:= abs_addr(NL);
tail:= head + (n*(n+1))*2;
n := 4 * n;
comment initialize epu-instruction nmenonics;
z_add_1:= 1 shift 23 + 0 shift 12 + 1;
_ mla_1:= 2 shift 12 + 1;
_ str_1:= 4 shift 12 + 1;
_ stp_1:= 4095 shift 12 + 1;
comment initialize the zone epu
and the associated variables;
word:= 0;
code_length:= 100*18;
open(epu, 14, <:ympe:>, 63 shift 17);
out_rec_6(epu, code_length + 6);
\f
comment gi nll procedures * page 18 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
for r:= 4 step 4 until n do
for c:= 4 step 4 until r do
begin
comment generate code for calculation of
the influence on element (c, r) in the
normal equations;
head:= head + 4;
tail:= tail + 4;
if word = code_length then
begin
comment empty the code-buffer;
epu.word(1):= stp_1;
epu.word(2):=
epu.word(3):= 0;
out_rec_6(epu, code_length + 6);
word:= 0;
end;
epu.word(1):= z_add_1;
epu.word(2):= head;
epu.word(3):= tail;
epu.word(4):= mla_1;
epu.word(5):= base + r;
epu.word(6):= base + c;
epu.word(7):= str_1;
epu.word(8):= head;
epu.word(9):= tail;
word:= word + 18;
end for r and c;
epu.word(1):= stp_1;
epu.word(2):=
epu.word(3):= 0;
word:= word + 6;
change_rec_6(epu, word);
close(epu, true);
end otn_epu;
end
if warning.yes
(mode 0.yes
message otn_epu not ok
lookup otn_epu)
\f
; gi nll procedures * page 19 5 09 77, 15.13;
if listing.yes
char 10 12 10
epublock=set 1
epublock=algol list.no
external procedure epublock(z, s, b);
_____________________________________
zone z;
integer s, b;
begin
comment
Block procedure for the arithmetic unit epu.
The status bit 6 = 1 shift 17 = underflow
is handeled by applying the z-modif to the
following instruction and restarting
the unit.
If the procedure is called with b < 0 it will
return imediately with b=no of underflows
and this underflow counter will
be cleared.
GI program no 75004,
WW, jan 1975.
;
integer bit, share, record_base,
_ result, buffer_address,
_ new_status;
integer array descriptor(1:20),
_ answer(1:8);
own integer underflows;
boolean first, test, old_z;
boolean field byte;
\f
comment gi nll procedures * page 20 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
if b >= 0 then
begin
comment block procedure part;
first:= true;
test := false;
byte := 1;
getzone6(z, descriptor);
record_base:= descriptor(14);
share:= descriptor(17);
getshare6(z, descriptor, share);
if test then
begin
write(out, <:<10>epu block proc:>, s, s extract 12, b,
<:<10>share no :>, share,
<:<10>record base :>, record_base,
<:<10>share state:>, descriptor(1),
<:<10>first shared:>, descriptor(2),
<:<10>last shared:>, descriptor(3),
<:<10>first instru:>, descriptor(5),
<:<10>last instru:>, descriptor(6),
<:<10>R1, R2 :>, << -d.ddd ddd ddd'-dd>,
descriptor(7), descriptor(8));
end if test;
for bit:= 16 step 1 until 22 do
if s shift (-bit) extract 1 = 1 then
begin
comment status bit no bit is on;
if bit <> 17 then
begin
write(out, if first then
<:<10>***epu status::> else
<:<10>______________:>,
case bit-15 of (
<:16:>,
<:underflow:>,
<:overflow:>,
<:address fault:>,
<:20:>,
<:21:>,
<:illegal instruction:>));
first:= false;
end bit <>17;
\f
comment gi nll procedures * page 21 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
case bit - 15 of
begin
;
begin
comment 1 shift 17: underflow;
if byte > 1 and test then
write(out, <:<10>epu-extra:>, byte, b);
byte:= b + byte;
underflows:= underflows + 1;
if test then write(out, <:<10>uf:>, byte, z.byte extract 12);
comment modify the operation and start for the rest;
old_z := z.byte;
z.byte:= false add (old_z extract 11) add (1 shift 11);
descriptor(5):= descriptor(5) + b;
descriptor(4):= 5 shift 12;
setshare6(z, descriptor, share);
buffer_address:= monitor(16)send_message:(z, share, descriptor);
if buffer_address = 0 then
system(9)run_time_alarm:(0, <:<10>buf_claim:>);
result:= monitor(18)wait_answer:(z, share, answer);
if result <> 1 then
system(9)run_time_alarm:(result, <:<10>epu-ans.:>);
comment reset the modified instruction and
the status word;
z.byte:= old_z;
new_status:= answer(1);
b:= answer(2);
s:= logand(exor(-1, 1 shift 17 + 1 shift 8 + 1), s) extract 24;
s:= logor(s, new_status shift (-12) shift 12) extract 24;
bit:= 16;
if test then write(out, <:<10>***epu-new status::>,
new_status shift (-12), new_status extract 12,
s shift (-12), s extract 12);
end case underflow;
;
;
;
;
;
end case bit of;
end if s;
\f
comment gi nll procedures * page 22 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
if -, first then write(out, <:<10>:>);
if s <> 1 shift 1 then stderror(z, s, b);
end block-procedure part
else
begin
comment return the underflowcounter;
b:= underflows;
underflows:= 0;
end;
end;
end
if warning.yes
(mode 0.yes
message epu_block not ok
lookup epu_block)
\f
; gi nll procedures * page 23 5 09 77, 15.13;
; epu_print
; *********
if listing.yes
char 10 12 10
epuprint=set 1 disc
epuprint=algol
external procedure epu_print
____________________________
_ (epu, code_length);
value code_length;
zone epu;
integer code_length;
begin
integer instr;
boolean z;
integer array field word;
codelength:= (codelength//6)*6 - 1;
write(out, <:<10><10>epu-instruktioner<10>:>);
for word := 0 step 6 until codelength do
begin
z := epu.word(1)<0;
write(out, false add 10, if z then 2 else 1);
instr := epu.word(1) shift (-12) extract 11;
if z and instr=2047 then
write(out, <:__stp:>)
else
begin
write(out, if z then <:z:> else <:_:>);
if instr < 9 then
write(out, <:_:>,
case instr + 1 of (
<:add:>, <:sub:>, <:mla:>, <:mls:>, <:str:>,
<:div:>, <:sqr:>, <:dia:>, <:chl:>))
else write(out, <<dddd>, instr);
end;
write(out, <:__:>, <<dddd>, epu.word(1) extract 12);
z := z and instr=2047;
if -, z then
write(out, <:, ___:>, <<-d_ddd_ddd>, epu.word(2));
if instr <> 6 and -, z then
write(out, <:, ___:>, <<-d_ddd_ddd>, epu.word(3));
end word-loop;
write(out, false add 10, 2);
end;
end
if warning.yes
(mode 0.yes
message epu_print not ok
lookup epu_print)
\f
; gi nll procedures * page 24 5 09 77, 15.13;
; nll_block
; *********
if listing.yes
char 12 10
nllblock=set 1
nllblock=algol list.no
external procedure nllblock(z, s, b);
_____________________________________
zone z;
integer s, b;
begin
comment
Simple block procedure for the arithmetic unit epu (RC 4090).
The procedure write on current output the name (ref a, page 11)
or the no (algol equivalent, ref b, p 6-11) of the 12 hardware
status bits of the epu status-word s.
References:
(a) P. Koch Andersson:
Functional Description for the RC4090,
External Processing Unit.
RCSL 44-RT 900.
(b) Hans Dinesen Hansen:
Algol 6 User's Manual.
RCSL 31-D 322.
nll_pr procedure lib no 10.
Willy Lehmann Weng, nov 1976.
;
\f
comment gi nll procedures * page 25 5 09 77, 15.13
0 1 2 3 4 5 6 7 8 9 ;
integer bit;
boolean first;
first:= true;
for bit:= 12 step 1 until 23 do
if s shift (-bit) extract 1 = 1 then
begin
comment status bit no bit is on;
write(out, if first then
<:<10>***epu status::> else
<:<10>______________:>,
case bit-11 of (
<:12:>,
<:13:>,
<:14:>,
<:15:>,
<:16:>,
<*17*> <:underflow:>,
<*18*> <:overflow:>,
<*19*> <:address fault:>,
<:20:>,
<*21*> <:time out:>,
<*22*> <:illegal instruction:>,
<:23:>));
first:= false;
end if s;
if -, first then
begin
write(out, <:<10>:>);
epu_print(z, b);
end;
if s <> 1 shift 1 then
begin
case epumode+1 of
begin
stderror(z, s, b);
system(9)alarm:(s, <:nllblock:>);
system(9)alarm:(s, <:nllblock:>);
end;
end;
end;
end
if warning.yes
(
mode 0.yes
message syntax fejl i nllblock
)
\f
; gi nll procedures * page 26 5 09 77, 15.13;
if 0.no
(
if listing.yes
char 10 12 10
nll_pr = compresslib ,
otn_gier,
nll_gier,
nll,
nll1,
nll_epu,
otn_epu,
epu_block,
epu_print,
nll_block,
if 2.no
scope project ,
nll_pr,
otn_gier,
nll_gier,
nll,
nll1,
nll_epu,
otn_epu,
epu_block,
epu_print,
nll_block,
lookup ,
nll_pr,
otn_gier,
nll_gier,
nll,
nll1,
nll_epu,
otn_epu,
epu_block,
epu_print,
nll_block,
)
if 10.no
end
if 10.no
finis
\f
; gi nll procedures * page 27 5 09 77, 15.13;
; test of nll_1 and nll_epu
; *************************
if 0.yes
end
if 0.yes
finis
mode 0.no ; clear error flag
pie_test = set 1
pie_test = algol list.no message.no
begin
comment
Test progran for the procedures nll_1 and nll_epu.
The matrix of case 4 from appendix C of Westlake
'A Handbook of Numerical Matrix Inversion
and Solutions of Linear Equations'
is used as test matrix.
The order of the matrix is read from current input.
A negativ value means single precision solution and
a positiv value means double precison sulution.
This order reading is repeated until order zero
is read.
Willy Weng, jan 1977.
;
integer i, j, n1, n, max, exp_lim, max_los;
real dia, non_dia, kt;
boolean double;
exp_lim:= 30;
for i:= read(in, n) while n <> 0 do
begin
double:= n > 0;
n := abs(n);
n1 := n - 1;
max := if double then n*(n+1) else n*(n+1)/2;
begin
long array sing(1:(n+47)//48);
real array A(1:max);
write(out, nl, 2, <:Pie-test of order :>, n1);
dia := 2/(2*n1-1);
non_dia:= - 1/((n1 - 1)*(2*n1 - 1));
for i := 1 step 1 until n1 do
for j := 1 step 1 until i do
A(i*(i-1)/2 + j) :=
if i=j then dia else non_dia;
i := n * (n - 1) / 2 + 1;
A(i) := 1;
for i := i + 1 step 1 until max do
A(i) := 0;
A(n*(n+1)/2) := 1;
if double then
write(out, <:<10>Double nll = :>,
nll_epu(A, n, exp_lim, max_los, sing, kt))
else
write(out, <:<10>Single nll = :>,
nll_1(A, n, exp_lim, max_los, sing, kt));
write(out, <:<10>kt = :>, kt,
_ <:<10>los= :>, max_los,
_ <:<10>:>);
max := n*(n+1)/2;
j := n*(n-1)/2 + 1;
for i:= j step 1 until max do
write(out, << -d.ddd'-dd>, nl,
if (i-j) mod 5 = 0 then 1 else 0,
if i=j then ((A(i) - n1) / n1) else (A(i) - 1));
end array decl block;
end read block;
end
if warning.yes
(mode 0.yes
o c
message pie test not ok
end)
if 0.yes
finis
pie_test
4 10 -4 -10 0
; 3 ; 10 ; 20 ; 50 ;
; -3 ; -10 ; -20 ; -50 ; 0 ;
end
finis
▶EOF◀