@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             MFN017
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
~V2 -16
                                                                  ISSUE 8~
~V2 0
~V9 -1
~P
~V9 1
~YMFN017
~S1~M~LMATHEMATICAL LIBRARY IMPLEMENTATION DESCRIPTION
~S1~M~LSection 1 Version 7
~S1~LSection 1.7 Mathematical Functions
~S1~L1. General Description
~BThis section provides machine dependent procedures for single
precision (32 bit)
mathematical functions for MU6G.
The hardware provided functions are invoked where available,
otherwise the functions as described in MFN011 are used.
~BThe algorithms are set up for floating point numbers with a
base of 16.
~BThe Mathematical Library is initially an adaptation of a set of MU5
mathematical functions. Some of the single precision functions are
therefore more precise than necessary. It is hoped to "tune" all
single precision functions to 32 bit at a later date. The complex
functions are also more precise than necessary and will be adjusted later.
~S1~L2. Interfaces~
~
Mathematical Library Procedures:~
~
~LSingle Precision (32 bit)~
   EXP~
   LOG~
   SIN~
   COS~
   TAN~
   ASIN~
   ACOS~
   ATAN~
   SINH~
   COSH~
   TANH~
   SQRT~
   RPOWER~
   IPOWER~
   POWER~
   ATAN2~
   LOG~
~
Other Modules Used:~
   Section  0:   (Configuration)~
~S1~L2.1 Hardware Interface
~S1~L2.2 Software Interface
~S11) EXP(X)RESULT
~BReturns e*.
~S12) LN(X)RESULT
~BReturns the natural logarithm of X.
~S13) SIN(X)RESULT
~BReturns the sin of X.
~S14) COS(X)RESULT
~BReturns cos X.
~S15) TAN(X)RESULT
~BReturns tan X. This is at present implemented by SIN(X)/COS(X).
This is not very efficient and may cause exponent overflow. It
will be rewritten at a future date.
~S16) ASIN(X)RESULT
~BReturns arcsin X in the range -P1/2 to P1/2. Implemented as ATAN[X/SQRT(1-X{2}
)].
~S17) ACOS(X)RESULT
~BReturns arcsin X in the range 0 to PI. Implemented as PI/2 - ASIN(X).
~S18) ATAN(X)RESULT
~BReturns arctan X.
~S19) SINH(X)RESULT
~BReturns sinh X. Implemented as (EXP(X)+EXP(-X))/2.
~S110) COSH(X)RESULT
~BReturns cosh X. Implemented as (EXP(X)-EXP(-X))/2.
~S111) TANH(X)RESULT
~BReturns tanh X.
~S112) SQRT(X)RESULT
~BReturns the square root of X. Implemented using an initial
approximation and four Newton iterations.
~S113) RPOWER(X,Y)RESULT
~BReturns X to the power of Y, where X and Y are floating point
numbers. Implemented as EXP(YLN(X)).
~S114) IPOWER(X,Y)RESULT
~BReturns X to the power of Y, where X is a floating point
number and Y an integer greater or equal to 0.
~S115) POWER(X,Y)RESULT
~BReturns X to the power of Y, where X and Y are integers
and Y is greater or equal to 0.
~S116) ATAN2(X,Y)RESULT
~BReturns arctan (X/Y).~
~S117) LOG(X)RESULT
~BReturns the logarithm to the base 10 of X.
~S1~L3. Implementation
~S1~L3.1 Outline of Operation
~S1~L3.2 Data Structures
~Y
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H                MFN017
~V9 -1
~F
@TITLE MFN01(7,6)
@COL 1S-2F
@FLOW 1-2
@BOX 1.0
SINGLE PRECISION
MATHMATICAL FUNCTIONS
@BOX 2.0
END
@BOX 1.1
PSPEC FORM.R($IN,$RE32)/$RE32;
PSPEC R.EXP($RE32)/$IN;
PSPEC R.MANT($RE32)/$RE32;
LSPEC ENTER.TRAP($IN,$IN);
IMPORT LITERAL MAX.EXP,MIN.EXP;
MODULE(EXP,LN,SIN,COS,TAN,ASIN,ACOS,ATAN,SINH,COSH,TANH,
        SQRT,RPOWER,IPOWER,POWER,ATAN2,LOG);
LSPEC EXP ($RE32  )/$RE32 ;
LSPEC LN ($RE32  )/$RE32 ;
LSPEC SIN ($RE32  )/$RE32 ;
LSPEC COS($RE32)/$RE32;
LSPEC TAN($RE32)/$RE32;
LSPEC ASIN($RE32)/$RE32;
LSPEC ACOS($RE32)/$RE32;
LSPEC ATAN($RE32)/$RE32;
LSPEC SINH($RE32)/$RE32;
LSPEC COSH($RE32)/$RE32;
LSPEC TANH($RE32)/$RE32;
LSPEC SQRT ($RE32  )/$RE32 ;
LSPEC ATAN2 ($RE32  ,$RE32  )/$RE32 ;
LSPEC RPOWER ($RE32  ,$RE32  )/$RE32 ;
LSPEC IPOWER ($RE32  ,$IN  )/$RE32 ;
LSPEC LOG ($RE32  )/$RE32 ;
LSPEC POWER($IN,$IN)/$IN;
LITERAL/$RE32    PIBY2    =    1.570796326794896;
#MFN01.1
#MFN01.2
#MFN01.3
#MFN01.4
#MFN01.5
#MFN01.6
#MFN01.7
#MFN01.8
#MFN01.9
#MFN01.10
#MFN01.11
#MFN01.15
#MFN01.16
#MFN01.17
#MFN01.18
#MFN01.19
#MFN01.20
@BOX 2.1
*END
@END



@TITLE MFN01.1(7,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
EXP(X)
@BOX 2.0
CODE FOR EXP
@BOX 3.0
USES HARDWARE
FN
@BOX 2.1
PROC EXP( AA);
AA;
*#%081C;
*#%0083;
END ;
@END
@TITLE MFN01.2(7,8)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
LN(X)
@BOX 2.0
CODE FOR LN
@BOX 3.0
USES HARDWARE
FN
@BOX 2.1
PROC LN ( AA);
AA;
*#%081B;
*#%0083;
END ;
@END
@TITLE MFN01.3(7,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
SIN(X)
@BOX 2.0
CODE FOR SIN
@BOX 3.0
USES HARDWARE FN
@BOX 2.1
PROC SIN( AA);
AA;
*#%081E;
*#%0083;
END ;
@END
@TITLE MFN01.4(7,6)
@COL 1S-2S-3F
@FLOW 1-2-3
@BOX 1.0
COS(X)
@BOX 2.0
CODE FOR COS
@BOX 3.0
USES HARDWARE FN
@BOX 2.1
PROC COS( AA);
AA;
*#%0816;
*#%0083;
END;
@END
@TITLE MFN01.5(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TAN
@BOX 2.0
TAN = SIN/COS
(NOT VERY EFFICIENT)
@BOX 3.0
END
@BOX 1.1
PROC TAN(X);
@BOX 2.1
SIN(X)/COS(X) => TAN :: MAY CAUSE EXPONENT OVERFLOW

@BOX 3.1
END
@END
@TITLE MFN01.6(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ASIN
@BOX 2.0
ASIN = ATAN(X/SQRT(1-X*X))
@BOX 3.0
END
@BOX 1.1
PROC ASIN(X);
$RE32 Y;
@BOX 2.1
IF X < 0.9999999999 AND X > 0.-0.9999999999 THEN
SQRT(X*X-:1.) => Y; :: NEEDS SENSIBLE ARGUMENT;
ATAN(X/Y) => ASIN;
ELSE;
X * PIBY2=>ASIN;
FI;
@BOX 3.1
END;
@END
@TITLE MFN01.7(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ACOS
@BOX 2.0
ACOS = PI/2 - ASIN
@BOX 3.0
END
@BOX 1.1
PROC ACOS(X);
@BOX 2.1
ASIN(X) -: PIBY2 => ACOS;
@BOX 3.1
END;
@END
@TITLE MFN01.8(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ATAN(X)
@BOX 2.0
CODE FOR ATAN
@BOX 3.0
USES HARDWARE FN
@BOX 2.1
PROC ATAN ( AA);
AA;
*#%0819;
*#%0083;
END ;
@END
@TITLE MFN01.9(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SINH
@BOX 2.0
E^X - E^-X/2
(INACCURATE 1X1<1)
@BOX 3.0
END
@BOX 1.1
PROC SINH(X);
@BOX 2.1
EXP(X) - EXP(0.-X)/2. => SINH;
@BOX 3.1
END;
@END
@TITLE MFN01.10(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
COSH
@BOX 2.0
E^X + E^-X/2
@BOX 3.0
END
@BOX 1.1
PROC COSH(X);
@BOX 2.1
EXP(X) + EXP(0.-X) /2. => COSH;
@BOX 3.1
END;
@END
@TITLE MFN01.11(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
TANH(X)
@BOX 2.0
CODE FOR TANH
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC TANH( AA);
$RE32  XX,XSQ;
LITERAL /$RE32     C1   =            18.368410284838496  ;
LITERAL /$RE32     C2   =             0.162870578986080  ;
LITERAL /$RE32     P7   =             0.003592128036572  ;
LITERAL /$RE32     P6   =            -0.001455834387051  ;
LITERAL /$RE32     P5   =            -0.008863235529902  ;
LITERAL /$RE32     P4   =             0.021869488536155  ;
LITERAL /$RE32     P3   =            -0.053968253968254  ;
LITERAL /$RE32     P2   =             0.133333333333333  ;
LITERAL /$RE32     P1   =            -0.333333333333333  ;
LITERAL /$RE32     P0   =             1.000000000000000  ;
LITERAL /$RE32     ONE   =             1.000000000000000  ;
LITERAL /$RE32     TWO   =             2.000000000000000  ;
IF   AA => XX < 0. THEN
   0. -:> XX;
FI ;
IF   XX >= C1,->UNITY;
IF   XX>= C2,->L2;
 XX*XX=>XSQ*P7+P6*XSQ+P5*XSQ+P4*XSQ
+P3*XSQ+P2*XSQ+P1*XSQ+P0*XX=>XX;
EXITE: IF  AA > 0. THEN
 XX => TANH;
EXIT ;
ELSE ;
 0. - XX => TANH;
EXIT ;
FI ;
UNITY:  ONE => XX;
->EXITE;
L2:  EXP(TWO*XX)+ONE /: TWO -: ONE => XX;
->EXITE;
END ;
@END
@TITLE MFN01.15(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
SQRT(X)
@BOX 2.0
CODE FOR SQRT
@BOX 3.0
USES HARDWARE FN
@BOX 2.1
PROC SQRT( AA);
AA;
*#%081A;
*#%0083;
END ;
@END
@TITLE MFN01.16(7,6)
@COL 1A-2S-3T-4R-5N-6F
@COL 7T-8R-9N
@COL 10R
@ROW 4-7
@ROW 8-10
@ROW 5-9
@FLOW 2-3NO-4-5-6
@FLOW 3YES-7NO-8-9-5
@FLOW 7YES-10-9
@BOX 1.0
RPOWER
@BOX 2.0
RPOWER (P1,P2)
@BOX 3.0
P1 = 0?
@BOX 4.0
RESULT =
EXP (P2*LN(P1))
@BOX 5.0
@BOX 6.0
EXIT
@BOX 7.0
P2 = 0?
@BOX 8.0
RESULT = 0
@BOX 9.0
@BOX 10.0
@BOX 1.1

@BOX 2.1
PROC RPOWER( P1, P2);
@BOX 3.1
IF   P1=0.,
@BOX 4.1
 EXP(LN(P1)*P2)=>RPOWER;
@BOX 6.1
EXIT
END
@BOX 7.1
IF   P2=0.,
@BOX 8.1
0.=>RPOWER;
@BOX 10.1
ENTER.TRAP(8,12);
@END
@TITLE MFN01.17(7,10)
@COL 8A
@COL 1S-2T-3R-5R
@COL 9T-10R-11C-14T-18T-15R-16F
@COL 17R
@ROW 3-9
@ROW 15-17
@FLOW 1-2NO-3-5-14-18NO-15-16
@FLOW 14YES-16
@FLOW 2YES-9NO-10-11
@FLOW 9YES-17-16
@FLOW 18YES-17
@BOX 1.0
IPOWER(R,I)
@BOX 2.0
I=0?
@BOX 3.0
NEGATE I IF NEGATIVE
@BOX 5.0
CALC R**I=>R
@BOX 8.0
IPOWER
@BOX 9.0
R=0?
@BOX 10.0
RESULT=1
@BOX 11.0
EXIT
@BOX 14.0
I INITIALLY > 0
@BOX 18.0
R=0?
@BOX 15.0
1/R
@BOX 16.0
EXIT
@BOX 17.0
ENTER TRAP(8,12)
 0^0 OR -VE I
@BOX 1.1
LIPOWER:
PROC IPOWER( R, I);
$RE32  RKEEP;
$IN32  COUNT,BN;
LITERAL /$RE32  ONE=           1.000000000000000 ;
@BOX 2.1
IF  I=0,
@BOX 3.1
IF  I > 0 THEN
1 => BN -:I<<- 1=>I
ELSE
-1-I<<- 1=>I;
0=>BN;
FI
@BOX 5.1
 R=>RKEEP;
IF  I=0,->B5;
B5.1:
IF  I->> 1=>I&1=0,->B5.2;
 RKEEP*R=>R;
B5.2:
IF  I<2,->B5;
 RKEEP*RKEEP=>RKEEP;
->B5.1;
B5:
@BOX 9.1
   IF   R=0.,
@BOX 10.1
 ONE => IPOWER;
@BOX 11.1
EXIT
@BOX 14.1
   IF  BN=1,
@BOX 18.1
IF   R=0.,
@BOX 15.1
 ONE/R => R;
@BOX 16.1
 R => IPOWER;
EXIT
END
@BOX 17.1
ENTER.TRAP(8,12);
@END
@TITLE MFN01.18(7,6)
@COL 9R-10R
@COL 1S-2T-3T-4T-5T-6T-7R-8F
@COL 11T-12R-13R
@COL 14R-15R
@ROW 3-11
@ROW 9-6
@ROW 7-13-14
@FLOW 1-2NO-3NO-4NO-5NO-6NO-7-8
@FLOW 2YES-11NO-12-14-15
@FLOW 11YES-14
@FLOW 3YES-9-10
@FLOW 4YES-8
@FLOW 5YES-9
@FLOW 6YES-13-14
@BOX 1.0
POWER(I,J)
IS**IS
@BOX 2.0
I=0?
@BOX 3.0
I=1?
@BOX 4.0
J=1?
@BOX 5.0
J=0?
@BOX 6.0
J<0?
@BOX 7.0
FORM I**J
@BOX 8.0
END
@BOX 11.0
J/=0?
@BOX 10.0
RETURN
@BOX 9.0
SET RESULT TO 1
@BOX 13.0
FAULT -VE EXPONENT
ENTERTRAP(8,12)
@BOX 12.0
FAULT 0**0
ENTERTRAP(8,12)
@BOX 14.0
SET RESULT TO 0
@BOX 15.0
RETURN
@BOX 1.1
LPOWER:;
PROC POWER(I,J);
$IN32 [1] CONTROL;
$IN32  IT,JT;
@BOX 2.1
I => IT;
IF  I=0,
@BOX 3.1
IF  I=1,
@BOX 4.1
IF  J=1,
@BOX 5.1
IF  J=0,
@BOX 6.1
IF  J<0,
@BOX 7.1
2 => JT;
1 => CONTROL[ 0];
WHILE [CONTROL[ 0]=1 ]
DO
IT *> IT;
IF JT <<- 1 => JT >= J
THEN 0 => CONTROL[ 0];
FI;
OD;
IF  JT ->> 1 => JT /= J THEN
  1 => CONTROL[ 0];
WHILE [CONTROL[ 0]=1 ]
DO
;
  I *> IT;
  IF 1+>JT=J
THEN 0 => CONTROL[ 0];
FI;
OD;
FI ;
@BOX 8.1
IT => POWER;
END ;
@BOX 11.1
IF  J/=0,
@BOX 10.1
EXIT ;
@BOX 9.1
1. => POWER;
@BOX 13.1
ENTER.TRAP(8,12);
@BOX 12.1
ENTER.TRAP(8,12);
@BOX 14.1
0. => POWER;
@BOX 15.1
EXIT ;
@END


@TITLE MFN01.19(7,6)
@COL 2S-3R-4F
@FLOW 2-3-4
@BOX 2.0
PROC LOG(P1);
@BOX 3.0
EVAL LOG(P1)
@BOX 4.0
END
@BOX 2.1
PROC LOG( A);
LITERAL /$RE32  C=           0.434294481903247
@BOX 3.1
 LN(A)*C => LOG;
@BOX 4.1
EXIT ;
END ;
@END
@TITLE MFN01.20(7,6)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ATAN2(X1,X2)
@BOX 2.0
CODE FOR ATAN2
@BOX 3.0
FOR DESCRIPTION SEE
IMPLEMENTATION MANUAL
@BOX 2.1
PROC ATAN2( X1,  X2);
$IN32  FL;
$RE32  MULT,RES;
LITERAL /$RE32  PI=          3.141592653589793  ;
LITERAL /$RE32  PIBY2=          1.570796326794897  ;
LITERAL /$RE32  ONE=          1.000000000000000  ;
LITERAL /$RE32  M.ONE=         -1.000000000000000  ;
IF   X1 = 0. AND   X2 = 0. THEN
ENTERTRAP(8,13);
FI ;
IF   X1< 0. THEN
 M.ONE=>MULT;
   0. -:> X1;
ELSE ;
 ONE=>MULT;
FI ;
IF   X2 < 0. THEN
   0. -:> X2;
1=>FL;
ELSE ;
0=>FL;
FI ;
IF   X2=<X1 THEN
 ATAN( X2/X1)-:PIBY2=>RES;
ELSE ;
 ATAN( X1/X2)=>RES;
FI ;
IF  FL=1 THEN
 PI-RES*MULT=>ATAN2;
EXIT ;
ELSE ;
 RES *MULT=>ATAN2;
EXIT ;
FI ;
END ;
@END

