(* ----------------------------------------------------------------------------
* $Id: MASC.mi,v 1.3 1992/10/15 16:28:10 kredel Exp $
* ----------------------------------------------------------------------------
* This file is part of MAS.
* ----------------------------------------------------------------------------
* Copyright (c) 1989 - 1992 Universitaet Passau
* ----------------------------------------------------------------------------
* $Log: MASC.mi,v $
* Revision 1.3 1992/10/15 16:28:10 kredel
* Changed rcsid variable
*
* Revision 1.2 1992/09/28 18:34:51 kredel
* Updated revision string.
*
* Revision 1.1 1992/09/28 17:29:12 kredel
* Initial revision
*
* ----------------------------------------------------------------------------
*)
IMPLEMENTATION MODULE MASC;
(* MAS Complex Number Implementation Module. *)
(* Import lists and declarations. *)
FROM MASBIOS IMPORT SWRITE, CWRITE, CREADB, MASORD, BKSP, BLINES;
FROM MASSTOR IMPORT LIST, ADV, COMP, FIRST, SIL;
FROM MASERR IMPORT severe, ERROR;
FROM SACLIST IMPORT OWRITE, SECOND, FIRST2, LIST2, COMP2,
AWRITE, EQUAL;
FROM SACRN IMPORT RNSUM, RNPROD, RNCOMP, RNNEG, RNDIF,
RNQ, RNINT, RNREAD, RNWRIT, RNRAND;
FROM MASRN IMPORT RNDWR, RNDRD, RNONE;
CONST rcsidi = "$Id: MASC.mi,v 1.3 1992/10/15 16:28:10 kredel Exp $";
CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau";
(* Representation of a + i b, with a, b rational numbers, is
0 if a=0 and b=0
(a,b) else *)
PROCEDURE CABS(R: LIST): LIST;
(*Complex number absolute value. R is a complex number. S is the
absolute value of R, a rational number. *)
VAR S, r, i: LIST;
BEGIN
(*1*) IF R = 0 THEN S:=R; RETURN(S) END;
(*2*) FIRST2(R,r,i);
S:=RNSUM(RNPROD(r,r),RNPROD(i,i));
RETURN(S);
(*4*) END CABS;
PROCEDURE CCON(R: LIST): LIST;
(*Complex number conjugate. R is a complex number. S is the
complex conjugate of R. *)
VAR S, r, i: LIST;
BEGIN
(*1*) IF R = 0 THEN RETURN(0) END;
(*2*) FIRST2(R,r,i);
S:=COMP2(r,RNNEG(i),SIL);
RETURN(S);
(*4*) END CCON;
PROCEDURE CCOMP(R,S: LIST): LIST;
(*Complex number comparison. R and S are complex numbers.
t=0 if R=S, t=1 else. *)
VAR t: LIST;
BEGIN
(*1*) t:=EQUAL(R,S);
IF t = 1 THEN t:=0 ELSE t:=1 END;
RETURN(t);
(*4*) END CCOMP;
PROCEDURE CDIF(R,S: LIST): LIST;
(*Complex number difference. R and S are complex numbers. T=R-S. *)
VAR T, r1, i1, r2, i2: LIST;
BEGIN
(*1*) IF R = 0 THEN T:=CNEG(S); RETURN(T) END;
IF S = 0 THEN T:=R; RETURN(T) END;
(*2*) FIRST2(R,r1,i1); FIRST2(S,r2,i2);
r1:=RNDIF(r1,r2); i1:=RNDIF(i1,i2);
IF (r1 = 0) AND (i1 = 0) THEN T:=0; RETURN(T) END;
T:=COMP2(r1,i1,SIL);
RETURN(T);
(*4*) END CDIF;
PROCEDURE CDREAD(): LIST;
(*Complex number decimal read. The complex number R is read
from the input stream. Any preceding blanks are skipped. *)
VAR R, r, i, c: LIST;
BEGIN
(*1*) r:=RNDRD(); i:=0;
c:=CREADB();
IF c = MASORD("i") THEN i:=RNDRD(); ELSE BKSP; END;
IF (r = 0) AND (i = 0) THEN RETURN(0) END;
R:=COMP2(r,i,SIL);
RETURN(R);
(*4*) END CDREAD;
PROCEDURE CDWRITE(R,NL: LIST);
(*Complex number decimal write. R is a complex number. n is a
non-negative integer. R is approximated by a decimal fraction D with
n decimal digits following the decimal point and D is written in the
output stream. The inaccuracy of the approximation is at most
(1/2)*10**-n. *)
VAR r, i: LIST;
BEGIN
(*1*) IF R = 0 THEN AWRITE(R); RETURN END;
(*2*) FIRST2(R,r,i);
RNDWR(r,NL);
IF i <> 0 THEN SWRITE(" i "); RNDWR(i,NL) END;
(*4*) END CDWRITE;
PROCEDURE CEXP(A,NL: LIST): LIST;
(*Complex number exponentiation. A is a complex number,
n is a non-negative beta-integer. B=A**n. *)
VAR B, KL: LIST;
BEGIN
(*1*) (*n less than or equal to 1.*)
IF NL = 0 THEN B:=CINT(1); RETURN(B); END;
IF NL = 1 THEN B:=A; RETURN(B); END;
(*2*) (*recursion.*) KL:=NL DIV 2; B:=CEXP(A,KL); B:=CPROD(B,B);
IF NL > 2*KL THEN B:=CPROD(B,A); END;
RETURN(B);
(*5*) END CEXP;
PROCEDURE CIM(R: LIST): LIST;
(*Complex number imaginary part. R is a complex number. b is the
imaginary part of R, a rational number. *)
BEGIN
(*1*) IF R = 0 THEN RETURN(0) END;
(*2*) RETURN(SECOND(R));
(*4*) END CIM;
PROCEDURE CINT(A: LIST): LIST;
(*Complex number from integer. A is an integer. R is the complex
number with real part A/1 and imaginary part 0. *)
VAR R: LIST;
BEGIN
(*1*) IF A = 0 THEN R:=A; RETURN(R) END;
(*2*) R:=COMP2(RNINT(A),0,SIL);
RETURN(R);
(*4*) END CINT;
PROCEDURE CRE(R: LIST): LIST;
(*Complex number real part. R is a complex number. b is the
real part of R, a rational number. *)
BEGIN
(*1*) IF R = 0 THEN RETURN(0) END;
(*2*) RETURN(FIRST(R));
(*4*) END CRE;
PROCEDURE CRN(A: LIST): LIST;
(*Complex number from rational number. A is a rational number.
R is the complex number with real part A and imaginary part 0. *)
VAR R: LIST;
BEGIN
(*1*) IF A = 0 THEN RETURN(0) END;
(*2*) R:=COMP2(A,0,SIL);
RETURN(R);
(*4*) END CRN;
PROCEDURE CRNP(A, B: LIST): LIST;
(*Complex number from pair of rational numbers. A and B are
rational numbers. R is the complex number with real part A
and imaginary part B. *)
VAR R: LIST;
BEGIN
(*1*) IF (A = 0) AND (B = 0) THEN RETURN(0) END;
(*2*) R:=COMP2(A,B,SIL);
RETURN(R);
(*4*) END CRNP;
PROCEDURE CNINV(R: LIST): LIST;
(*Complex number inverse. R is a non-zero complex number. S R=1. *)
VAR S, r, i, a: LIST;
BEGIN
(*1*) IF R = 0 THEN ERROR(severe,"CINV: division by zero."); END;
(*2*) FIRST2(R,r,i);
a:=RNSUM(RNPROD(r,r),RNPROD(i,i));
r:=RNQ(r,a); i:=RNQ(RNNEG(i),a);
S:=COMP2(r,i,SIL);
RETURN(S);
(*4*) END CNINV;
PROCEDURE CNEG(R: LIST): LIST;
(*Complex number negative. R is a complex number. S=-R. *)
VAR S, r, i: LIST;
BEGIN
(*1*) IF R = 0 THEN RETURN(0) END;
(*2*) FIRST2(R,r,i);
S:=COMP2(RNNEG(r),RNNEG(i),SIL);
RETURN(S);
(*4*) END CNEG;
PROCEDURE CONE(R: LIST): LIST;
(*Complex number one. R is a complex number. s=1 if R=1,
s=0 else. *)
VAR r, i, t: LIST;
BEGIN
(*1*) IF R = 0 THEN RETURN(0) END;
(*2*) FIRST2(R,r,i);
IF i <> 0 THEN RETURN(0) END;
t:=RNONE(r);
RETURN(t);
(*4*) END CONE;
PROCEDURE CPROD(R,S: LIST): LIST;
(*Complex number product. R and S are complex numbers. T=R*S. *)
VAR T, r1, i1, r2, i2, r, i: LIST;
BEGIN
(*1*) IF (R = 0) OR (S = 0) THEN RETURN(0) END;
(*2*) FIRST2(R,r1,i1); FIRST2(S,r2,i2);
r:=RNDIF(RNPROD(r1,r2),RNPROD(i1,i2));
i:=RNSUM(RNPROD(r1,i2),RNPROD(i1,r2));
IF (r = 0) AND (i = 0) THEN RETURN(0) END;
T:=COMP2(r,i,SIL);
RETURN(T);
(*4*) END CPROD;
PROCEDURE CQ(R,S: LIST): LIST;
(*Complex number quotient. R and S are complex numbers, S non-zero.
T=R/S. *)
VAR T: LIST;
BEGIN
(*1*) T:=CPROD(R,CNINV(S));
RETURN(T);
(*4*) END CQ;
PROCEDURE CRAND(NL: LIST): LIST;
(*Complex number, random. n is a positive beta-integer. Random
rational numbers A and B are generated using RNRAND(n). Then
R is the complex number with real part A and imaginary part B. *)
VAR T, r, i: LIST;
BEGIN
(*1*) r:=RNRAND(NL); i:=RNRAND(NL);
IF (r = 0) AND (i = 0) THEN RETURN(0) END;
T:=COMP2(r,i,SIL);
RETURN(T);
(*4*) END CRAND;
PROCEDURE CNREAD(): LIST;
(*Complex number read. The complex number R is read from the input
stream. Any preceding blanks are skipped. *)
VAR R, r, i, c: LIST;
BEGIN
(*1*) r:=RNREAD(); i:=0;
c:=CREADB();
IF c = MASORD("i") THEN i:=RNREAD(); ELSE BKSP; END;
IF (r = 0) AND (i = 0) THEN RETURN(0) END;
R:=COMP2(r,i,SIL);
RETURN(R);
(*4*) END CNREAD;
PROCEDURE CSUM(R,S: LIST): LIST;
(*Complex number sum. R and S are complex numbers. T=R+S. *)
VAR T, r1, i1, r2, i2: LIST;
BEGIN
(*1*) IF R = 0 THEN T:=S; RETURN(T) END;
IF S = 0 THEN T:=R; RETURN(T) END;
(*2*) FIRST2(R,r1,i1); FIRST2(S,r2,i2);
r1:=RNSUM(r1,r2); i1:=RNSUM(i1,i2);
IF (r1 = 0) AND (i1 = 0) THEN T:=0; RETURN(T) END;
T:=COMP2(r1,i1,SIL);
RETURN(T);
(*4*) END CSUM;
PROCEDURE CNWRITE(R: LIST);
(*Complex number write. R is a complex number. R is converted
to decimal and written in the output stream. *)
VAR r, i: LIST;
BEGIN
(*1*) IF R = 0 THEN AWRITE(R); RETURN END;
(*2*) FIRST2(R,r,i);
RNWRIT(r);
IF i <> 0 THEN SWRITE(" i "); RNWRIT(i) END;
(*4*) END CNWRITE;
END MASC.
(* -EOF- *)