DIRECTORY Basics, FloatingPointCommon, Real, RealSupport USING [Fix], RealFns; RealFnsImpl: CEDAR PROGRAM IMPORTS Basics, FloatingPointCommon, Real, RealSupport EXPORTS RealFns = BEGIN SingleReal: TYPE = MACHINE DEPENDENT RECORD [ sign (0: 0..0): BOOL, exp (0: 1..8): Exponent, m (0: 9..31): Mantissa]; Exponent: TYPE = CARDINAL [0..256); Mantissa: TYPE = CARDINAL [0..HiddenBit); HiddenBit: CARDINAL = 800000h; ExponentBias: INTEGER = 127; DenormExponent: INTEGER = Exponent.FIRST; NaNExponent: INTEGER = Exponent.LAST; SquareReal: TYPE = MACHINE DEPENDENT RECORD [ sign (0: 0..0): BOOL, expD2 (0: 1..7): CARDINAL [0..128), index (0: 8..12): CARDINAL [0..32), m (0: 13..31): CARDINAL [0..2000000B)]; Bomb: PROC [x: REAL, exCode: FloatingPointCommon.Exception ¬ invalidOperation] = { ERROR FloatingPointCommon.Error[exCode]; }; Ln2: REAL = 0.693147181; LogBase2ofE: REAL ¬ 1/Ln2; smallnumber: REAL = 0.00000000005; PI: REAL = 3.1415926535; twoPI: REAL ¬ PI*2; piHalves: REAL ¬ PI/2; pi3ovr2: REAL ¬ 3*piHalves; pi3Eighths: REAL = pi3ovr2/4; piFourths: REAL = PI/4; piEighths: REAL ¬ PI/8; radiansPerDegree: REAL ¬ PI/180; degreesPerRadian: REAL ¬ 180/PI; rec2pi: REAL ¬ 1.0/twoPI; rec360: REAL ¬ 1.0/360.0; fourOverPI: REAL ¬ 4.0/PI; twoOverPI: REAL ¬ 2.0/PI; invRoot2: REAL ¬ 0.70710678119; lnRoot2pi: REAL ¬ 0.9189385332; sqrtEps: REAL ¬ Real.FScale[1.0, -12]; -- 2­-12 = square root of machine epsilon Exp: PUBLIC PROC [x: REAL] RETURNS [REAL] = { r, f: REAL; k: INTEGER; fl: SingleReal ¬ LOOPHOLE[1.0, SingleReal]; SELECT ABS[x] FROM < 3e-4 => RETURN [1+x]; < 3e-3 => RETURN [1+x+x*x*0.5]; ENDCASE; x ¬ x*LogBase2ofE; --exponent of 2 (instead of e) IF x < -ExponentBias THEN RETURN [0.0]; IF x > ExponentBias THEN Bomb[x]; k ¬ RealSupport.Fix[x]; --integer part (was InlineFixI) x ¬ x - k; --fractional part x ¬ x*Ln2; --now result = 2­k * exp(x) and 0<=x 3e-3 => {}; > 3e-4 => RETURN [xm1 - 0.5*xm1*xm1]; ENDCASE => RETURN [xm1]; fl ¬ LOOPHOLE[x, SingleReal]; m ¬ fl.exp - (ExponentBias - 1); fl.exp ¬ ExponentBias - 1; --now 1/2 <= z < 1 x ¬ LOOPHOLE[fl, REAL]; IF x = 0.5 THEN RETURN[Ln2*(m-1)]; OneMinusX ¬ 1 - x; x ¬ m*Ln2; OneMinusXPowerRep ¬ 1; FOR i: CARDINAL ¬ 1, i+1 DO PreviousVal: REAL ¬ x; OneMinusXPowerRep ¬ OneMinusXPowerRep*OneMinusX; x ¬ x - OneMinusXPowerRep/i; IF x = PreviousVal THEN EXIT; ENDLOOP; RETURN[x]; }; SqRt: PUBLIC PROC [a: REAL] RETURNS [b: REAL ¬ 0.0] = { SELECT TRUE FROM a <= 0.0 => { IF a < 0.0 THEN Bomb[a]; b ¬ 0.0; }; LOOPHOLE[a, SingleReal].exp = 0 => b ¬ SqRt[a * (LONG[20000B] * LONG[20000B])] / 20000B; ENDCASE => { aFmt: SquareReal ¬ LOOPHOLE[a, SquareReal]; bFmt: SingleReal ¬ LOOPHOLE[sqGuesses[aFmt.index], SingleReal]; aExp: CARDINAL ¬ aFmt.expD2; bFmt.exp ¬ bFmt.exp + aExp - 63; b ¬ LOOPHOLE[bFmt, REAL]; b ¬ LOOPHOLE[LOOPHOLE[b + a/b, LONG CARDINAL] - 40000000B, REAL]; b ¬ LOOPHOLE[LOOPHOLE[b + a/b, LONG CARDINAL] - 40000000B, REAL]; }; }; sqGuesses: ARRAY[0..32) OF CARD = [ 7715741440B, 7717240700B, 7720514140B, 7721745140B, -- 0.71782 .. 0.78043 7723155200B, 7724346000B, 7725517500B, 7726654000B, -- 0.80021 .. 0.85681 7727773400B, 7731077100B, 7732167300B, 7733245000B, -- 0.87486 .. 0.92691 7734310400B, 7735342500B, 7736363400B, 7737373700B, -- 0.94362 .. 0.99206 7740370240B, 7741351440B, 7742314540B, 7743243000B, -- 1.01516 .. 1.10370 7744155200B, 7745054400B, 7745741300B, 7746614600B, -- 1.13167 .. 1.21172 7747457040B, 7750310640B, 7751132500B, 7751745000B, -- 1.23725 .. 1.31085 7752550100B, 7753344400B, 7754132600B, 7754712500B -- 1.33448 .. 1.40299 ]; Root: PUBLIC PROC [index, arg: REAL] RETURNS [REAL] = { RETURN[Exp[Ln[arg]/index]]; }; Power: PUBLIC PROC [base, exponent: REAL] RETURNS [REAL] = { IF base = 0 THEN IF exponent = 0 THEN RETURN[1] ELSE RETURN[0]; RETURN[Exp[exponent*Ln[base]]]; }; Sin: PUBLIC PROC [radians: REAL] RETURNS [sin: REAL] = { rem: REAL ¬ ABS[radians]; IF rem > twoPI THEN rem ¬ GetWithinTwoPI[rem]; { SELECT RealSupport.Fix[rem * fourOverPI] FROM -- was InlineFixC 0 => {GO TO posSin}; 1 => {rem ¬ piHalves - rem; GO TO posCos}; 2 => {rem ¬ rem - piHalves; GO TO posCos}; 3 => {rem ¬ PI - rem; GO TO posSin}; 4 => {rem ¬ rem - PI; GO TO negSin}; 5 => {rem ¬ pi3ovr2 - rem; GO TO negCos}; 6 => {rem ¬ rem - pi3ovr2; GO TO negCos}; 7 => {rem ¬ twoPI - rem; GO TO negSin}; ENDCASE => RETURN [0.0]; EXITS posSin => {sin ¬ SinFirstOctant[rem]; IF radians < 0.0 THEN GO TO neg}; negSin => {sin ¬ SinFirstOctant[rem]; IF radians > 0.0 THEN GO TO neg}; posCos => {sin ¬ CosFirstOctant[rem]; IF radians < 0.0 THEN GO TO neg}; negCos => {sin ¬ CosFirstOctant[rem]; IF radians > 0.0 THEN GO TO neg}; }; EXITS neg => sin ¬ - sin; }; Cos: PUBLIC PROC [radians: REAL] RETURNS [cos: REAL] = { rem: REAL ¬ ABS[radians]; IF rem > twoPI THEN rem ¬ GetWithinTwoPI[rem]; { SELECT RealSupport.Fix[rem * fourOverPI] FROM -- was InlineFixC 0 => {GO TO posCos}; 1 => {rem ¬ piHalves - rem; GO TO posSin}; 2 => {rem ¬ rem - piHalves; GO TO negSin}; 3 => {rem ¬ PI - rem; GO TO negCos}; 4 => {rem ¬ rem - PI; GO TO negCos}; 5 => {rem ¬ pi3ovr2 - rem; GO TO negSin}; 6 => {rem ¬ rem - pi3ovr2; GO TO posSin}; 7 => {rem ¬ twoPI - rem; GO TO posCos}; ENDCASE => cos ¬ 1.0; EXITS posSin => {cos ¬ SinFirstOctant[rem]}; negSin => {cos ¬ SinFirstOctant[rem]; cos ¬ -cos}; posCos => {cos ¬ CosFirstOctant[rem]}; negCos => {cos ¬ CosFirstOctant[rem]; cos ¬ -cos}; }; }; SinDeg: PUBLIC PROC [degrees: REAL] RETURNS [sin: REAL] = { IF ABS[degrees] > 360 THEN degrees ¬ GetWithin360[degrees]; sin ¬ Sin[degrees*radiansPerDegree]; }; CosDeg: PUBLIC PROC [degrees: REAL] RETURNS [cos: REAL] = { degrees ¬ ABS[degrees]; IF degrees > 360 THEN degrees ¬ GetWithin360[degrees]; cos ¬ Cos[degrees*radiansPerDegree]; }; Tan: PUBLIC PROC [radians: REAL] RETURNS [tan: REAL] = { RETURN[TanCot[radians, FALSE]]; }; CoTan: PUBLIC PROC [radians: REAL] RETURNS [cotan: REAL] = { RETURN[TanCot[radians, TRUE]]; }; TanCot: PUBLIC PROC [x: REAL, cot: BOOLEAN] RETURNS [tan: REAL] = { c1: REAL = 201.0/128.0; -- exactly representable c2: REAL = .000483826794897; -- c1 + c2 = pi/2 xn, f, g: REAL; num, den: REAL; n: INT; p1: REAL = -.0958017723; q1: REAL = -0.429135777; q2: REAL = .00971685835; n ¬ Real.Round[twoOverPI*x]; xn ¬ REAL[n]; f ¬ (x - xn*c1) - xn*c2; IF ABS[f] < sqrtEps THEN { num ¬ f; den ¬ 1.0; } ELSE { g ¬ f*f; num ¬ f + f*g*p1; den ¬ (q2*g + q1)*g + 1; }; IF cot THEN {IF Basics.OddInt[n] THEN RETURN[-num/den] ELSE RETURN[den/num]} ELSE {IF Basics.OddInt[n] THEN RETURN[-den/num] ELSE RETURN[num/den]}; }; TanDeg: PUBLIC PROC [degrees: REAL] RETURNS [tan: REAL] = { IF ABS[degrees] > 360 THEN degrees ¬ GetWithin360[degrees]; tan ¬ SinDeg[degrees] / CosDeg[degrees]; }; CoTanDeg: PUBLIC PROC [degrees: REAL] RETURNS [cotan: REAL] = { IF ABS[degrees] > 360 THEN degrees ¬ GetWithin360[degrees]; cotan ¬ CoTan[degrees*radiansPerDegree]; }; ArcSin: PUBLIC PROC [x: REAL] RETURNS [ REAL] = { z: REAL; SELECT (z ¬ ABS[x]) FROM < sqrtEps => RETURN[x]; -- so small that arcsin(x) = x + x­3/6 + x­5/40 + ... S x < 0.5 => { RETURN[ArcTan[x, SqRt[1 - z*z]]]; }; ENDCASE => { RETURN[ArcTan[x, SqRt[2*(1-z) - (1-z)*(1-z)]]]; }; }; ArcCos: PUBLIC PROC [x: REAL] RETURNS [REAL] = { RETURN[IF x = -1.0 THEN PI ELSE 2.0*ArcTan[SqRt[(1.0-x)/(1.0+x)], 1.0]]; }; ArcSinDeg: PUBLIC PROC [x: REAL] RETURNS [degrees: REAL] = { degrees ¬ ArcSin[x]*degreesPerRadian; }; ArcCosDeg: PUBLIC PROC [x: REAL] RETURNS [degrees: REAL] = { degrees ¬ ArcCos[x]*degreesPerRadian; }; tanPI16: REAL = .1989123673; x2: REAL ¬ 1/(.414213562); x22: REAL ¬ x2*x2 + 1; tan3PI16: REAL = .668178638; x4: REAL = 1.0; x44: REAL ¬ x4*x4 + 1; tan5PI16: REAL = 1.496605763; x6: REAL ¬ 1/(2.41421356); x66: REAL ¬ x6*x6 + 1; tan7PI16: REAL = 5.02733949; p0: REAL = .999999998; p1: REAL = -.333331726; p2: REAL = .1997952738; p3: REAL = -.134450639; ArcTan: PUBLIC PROC [y, x: REAL] RETURNS [radians: REAL] = { s, v, t, t2, c, q: REAL; IF ABS[x] <= ABS[smallnumber] THEN IF ABS[y] <= ABS[smallnumber] THEN RETURN[0] ELSE IF y < 0 THEN RETURN[-piHalves] ELSE RETURN[piHalves]; IF x < 0 THEN IF y < 0 THEN {q ¬ -PI; s ¬ 1} ELSE {q ¬ PI; s ¬ -1} ELSE IF y < 0 THEN {q ¬ 0; s ¬ -1} ELSE {q ¬ 0; s ¬ 1}; v ¬ ABS[y/x]; SELECT v FROM < tanPI16 => {t ¬ v; c ¬ 0}; < tan3PI16 => {t ¬ x2 - x22/(x2 + v); c ¬ piEighths}; < tan5PI16 => {t ¬ x4 - x44/(x4 + v); c ¬ piFourths}; < tan7PI16 => {t ¬ x6 - x66/(x6 + v); c ¬ pi3Eighths}; ENDCASE => {t ¬ -1/v; c ¬ piHalves}; t2 ¬ t*t; radians ¬ s*(t*(p0 + t2*(p1 + t2*(p2 + t2*p3))) + c) + q; }; ArcTanDeg: PUBLIC PROC [y, x: REAL] RETURNS [degrees: REAL] = { degrees ¬ ArcTan[y, x]*degreesPerRadian; }; SinH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { ex: REAL = Exp[x]; emx: REAL = 1/ex; f ¬ (ex-emx)/2.0 }; CosH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { ex: REAL = Exp[x]; emx: REAL = 1/ex; f ¬ (ex+emx)/2.0 }; TanH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF ABS[x] > 20. THEN f ¬ (IF x<0. THEN -1. ELSE 1.) ELSE { ex: REAL = Exp[x]; emx: REAL = 1/ex; f ¬ (ex-emx)/(ex+emx); }; }; CotH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF ABS[x] > 20. THEN f ¬ (IF x<0. THEN -1. ELSE 1.) ELSE { ex: REAL = Exp[x]; emx: REAL = 1/ex; f ¬ (ex+emx)/(ex-emx); }; }; InvSinH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { f ¬ Ln[x+SqRt[x*x+1.0]]; }; InvCosH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF x < 1.0 THEN Bomb[x]; f ¬ Ln[x+SqRt[x*x-1.0]]; }; InvTanH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF ABS[x] >= 1.0 THEN Bomb[x]; f ¬ 0.5*Ln[(1.0+x)/(1.0-x)]; }; InvCotH: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF ABS[x] <= 1.0 THEN Bomb[x]; f ¬ 0.5*Ln[(x+1.0)/(x-1.0)]; }; LnGamma: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { phi: REAL; lnAdjFact: REAL ¬ 0; IF x <= 0.0 THEN Bomb[x]; IF x < 8 THEN { -- Gamma[x+1] = x! = x*(x-1)! = x*Gamma[x] adjFact: REAL ¬ 1.0; WHILE x < 8 DO adjFact ¬ adjFact*x; x ¬ x+1.0; ENDLOOP; lnAdjFact ¬ Ln[adjFact]; }; phi ¬ (-0.2762472E-2/(x*x)+0.8333327385E-1)/x; -- LGAM 5400 - 8.82 digits f ¬ (x-0.5)*Ln[x]-x+lnRoot2pi+phi-lnAdjFact; -- Stirling's approx. }; Gamma: PUBLIC PROC [x: REAL] RETURNS [REAL] = { RETURN[Exp[LnGamma[x]]]; }; J0: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { IF x < 0.0 THEN x ¬ -x; IF x < 8.0 THEN { x2: REAL = x*x; P: REAL = (((( (-0.1849052456E3)*x2+ (0.7739233017E5))*x2+ (-0.1121442418E8))*x2+ (0.6516196407E9))*x2+ (-0.1336259035E11))*x2+ (0.5756849057E11); Q: REAL = (((( x2+ (0.2678532712E3))*x2+ (0.5927264853E5))*x2+ (0.9494680718E7))*x2+ (0.1029532985E10))*x2+ (0.5756849041E11); f ¬ P/Q; } ELSE { X0: REAL = x-piFourths; p0, q0: REAL; [p0, q0] ¬ PQ0[x]; f ¬ SqRt[2.0/(PI*x)]*(p0*Cos[radians: X0]-q0*Sin[radians: X0]); }; }; PQ0: PROC [x: REAL] RETURNS [P0, Q0: REAL] = { z: REAL = 8.0/x; z2: REAL = z*z; P0 ¬ (( -- PZERO 6502 - 8.78 digits (-0.165711693E-5)*z2+ (0.270871648E-4))*z2+ (-0.1098577711E-2))*z2+ (0.9999999983); Q0 ¬ ((( -- QZERO 6901 - 9.13 digits (0.576476505E-6)*z2+ (-0.6796319617E-5))*z2+ (0.1430262718E-3))*z2+ (-0.1562499927E-1))*z; }; pi34: REAL ¬ 3*piFourths; J1: PUBLIC PROC [x: REAL] RETURNS [f: REAL] = { sign: REAL ¬ 1.0; IF x < 0.0 THEN {sign ¬ -1.0; x ¬ -x}; IF x < 8.0 THEN { x2: REAL = x*x; P: REAL = ((( (0.6543001487E1)*x2+ (-0.1988185996E4))*x2+ (0.1978615055E6))*x2+ (-0.7064812917E7))*x2+ (0.6706259146E8); Q: REAL = ((( x2+ (0.1766217266E3))*x2+ (0.2668508067E5))*x2+ (0.2635953855E7))*x2+ (0.1341252501E9); f ¬ sign*x*P/Q; } ELSE { X1: REAL = x-pi34; p1, q1: REAL; [p1, q1] ¬ PQ1[x]; f ¬ sign*SqRt[2.0/(PI*x)]*(p1*Cos[radians: X1]-q1*Sin[radians: X1]); }; }; PQ1: PROC [x: REAL] RETURNS [P1, Q1: REAL] = { z: REAL = 8.0/x; z2: REAL = z*z; P1 ¬ (( -- PONE 6702 - 8.72 digits (0.19796752E-5)*z2+ (-0.348677998E-4))*z2+ (0.1830991520E-2))*z2+ (0.1000000001E1); Q1 ¬ ((( -- QONE 7102 - 9.08 digits (-0.67222066E-6)*z2+ (0.831923005E-5))*z2+ (-0.2002434943E-3))*z2+ (0.4687499917E-1))*z; }; OldJn: PUBLIC PROC [n: INT, x: REAL] RETURNS [f: REAL] = { sign: REAL ¬ 1.0; IF n<0 THEN {n ¬ -n; sign ¬ IF n MOD 2 # 0 THEN -1.0 ELSE 1.0}; SELECT n FROM 0 => f ¬ J0[x]; 1 => f ¬ sign*J1[x]; ENDCASE => { v0: REAL ¬ J0[x]; v1: REAL ¬ J1[x]; FOR m: INT IN [2..n] DO v2: REAL ¬ 2*(m-1)*v1/x-v0; v0 ¬ v1; v1 ¬ v2; ENDLOOP; f ¬ sign*v1; }; }; lagestNumber: REAL ¬ Real.LargestNumber; factLimit: NAT ¬ 8; Jn: PUBLIC PROC [n: INT, x: REAL] RETURNS [f: REAL] = { sign: REAL ¬ 1.0; IF n<0 THEN {n ¬ -n; sign ¬ IF n MOD 2 # 0 THEN -1.0 ELSE 1.0}; SELECT TRUE FROM n=0 => RETURN [J0[x]]; n=1 => f ¬ sign*J1[x]; x=0.0 => RETURN [0.0]; ENDCASE => { halfX: REAL ~ x*0.5; halfX2: REAL ~ halfX * halfX; term, sum: REAL; IF n <= factLimit THEN { term ¬ halfX; FOR j: NAT IN [2..n] DO term ¬ term * (halfX / j) ENDLOOP; } ELSE term ¬ Exp[n*Ln[halfX] - LnGamma[n+1] ]; sum ¬ term; FOR k: REAL ¬ 1, k+1 DO newSum: REAL; term ¬ -term * (halfX2 / (k*(n+k))); newSum ¬ sum + term; IF newSum=sum THEN EXIT ELSE sum ¬ newSum; ENDLOOP; f ¬ sum*sign; }; }; RationalFromReal: PUBLIC PROC [x: REAL, limit: INT ¬ LAST[INT]] RETURNS [RealFns.Rational] ~ { tooLargeToFix: REAL ~ Real.FScale[1.0, BITS[INT] - 1]; -- 2147483648.0 tooSmallToFix: REAL ~ Real.FScale[1.0, 1 - BITS[INT]]; -- 4.65661280e-10 halfTooSmallToFix: REAL ~ Real.FScale[tooSmallToFix, -1]; -- 4.65661280e-10 / 2 expForInt: INT ~ 150; -- This exponent in SingleReal makes the significand an INT ratZero: RealFns.Rational ~ [0, 1]; sign: INT ¬ 1; flip: BOOL ¬ FALSE; -- If TRUE, nk and dk are swapped scale: INT; -- Power of 2 to get x into integer domain ak2, ak1, ak: CARD; -- GCD arguments, initially 1 and x ck, climit: CARD; -- ck is GCD quotient and c.f. term k nk, dk: INT; -- Result num. and den., recursively found nk1, dk2: INT ¬ 0; -- History terms for recursion nk2, dk1: INT ¬ 1; IF limit <= 0 THEN RETURN[ratZero]; -- Insist limit > 0 IF x < 0.0 THEN { x ¬ -x; sign ¬ -1; }; IF x >= 1.0 THEN { -- First continued fraction term is non-zero rest: REAL; IF x >= tooLargeToFix OR (ck ¬ Real.Fix[x]) >= CARD[limit] THEN RETURN [[sign*limit, 1]]; flip ¬ TRUE; -- Keep denominator larger, for fast loop test nk ¬ 1; dk ¬ ck; -- Make new numerator and denominator rest ¬ x - ck; scale ¬ expForInt - LOOPHOLE[1.0, SingleReal].exp; ak ¬ Real.Fix[Real.FScale[rest, scale]]; ak1 ¬ Real.Fix[Real.FScale[1.0, scale]]; } ELSE { -- First continued fraction term is zero n, num: CARD; IF x <= tooSmallToFix -- Is x too tiny to be 1/INT ? THEN { IF x <= halfTooSmallToFix THEN RETURN[ratZero]; IF CARD[limit] > CARD[Real.Fix[0.5/x]] THEN RETURN [[sign, limit]] ELSE RETURN[ratZero]; }; scale ¬ expForInt - LOOPHOLE[x, SingleReal].exp; ak1 ¬ Real.Fix[Real.FScale[x, scale]]; n ¬ MIN[BITS[CARD]-1, scale]; -- Stay within CARD arithmetic num ¬ Basics.BITLSHIFT[1, n]; ck ¬ num/ak1; -- First attempt at 1/x ak ¬ num MOD ak1; -- First attempt at remainder WHILE (scale ¬ scale-n) > 0 DO -- Shift quotient and remainder until done n ¬ MIN[8, scale]; -- That 8 is from 24 bits of x in a 32 bit CARD num ¬ Basics.BITLSHIFT[ak, n]; ck ¬ Basics.BITLSHIFT[ck, n] + num/ak1; ak ¬ num MOD ak1; -- Reduce remainder ENDLOOP; IF ck >= CARD[limit] -- Is x too tiny to be 1/limit ? THEN { IF CARD[2*limit] > ck THEN RETURN [[sign, limit]] ELSE RETURN[ratZero]; }; nk ¬ 1; dk ¬ ck; -- Make new numerator and denominator }; WHILE ak # 0 DO -- If possible, quit when have exact result ak2 ¬ ak1; ak1 ¬ ak; -- Prepare for next term nk2 ¬ nk1; nk1 ¬ nk; -- (This loop does essentially all the work) dk2 ¬ dk1; dk1 ¬ dk; ck ¬ ak2/ak1; -- Get next term of continued fraction ak ¬ ak2 - ck*ak1; -- Get remainder (GCD step) climit ¬ (limit - dk2)/dk1; -- Anticipate result of recursion on denominator IF climit <= ck THEN GOTO Interpolate; -- Do not let denominator exceed limit nk ¬ ck*nk1 + nk2; -- Make new result numerator and denominator dk ¬ ck*dk1 + dk2; REPEAT Interpolate => { twoClimit: CARD ¬ 2*climit; IF twoClimit >= ck THEN { -- If climit < ck/2 no improvement possible nk ¬ climit*nk1 + nk2; -- Make limited numerator and denominator dk ¬ climit*dk1 + dk2; IF twoClimit = ck THEN TRUSTED {-- If climit = ck improvement not sure -- Using climit is better only when dk2/dk1 > ak/ak1 dk2ak1Hi, dk2ak1Lo, dk1akHi, dk1akLo: CARD32; [dk2ak1Hi, dk2ak1Lo] ¬ Mul32[IF flip THEN nk2 ELSE dk2, ak1]; [dk1akHi, dk1akLo] ¬ Mul32[IF flip THEN nk1 ELSE dk1, ak]; IF dk2ak1Hi < dk1akHi OR (dk2ak1Hi = dk1akHi AND dk2ak1Lo <= dk1akLo) THEN { nk ¬ nk1; dk ¬ dk1; }; -- Not an improvement, so undo step } }; }; ENDLOOP; IF flip THEN RETURN [[sign*dk, nk]] ELSE RETURN [[sign*nk, dk]]; }; OldRationalFromReal: PROC [x: REAL, limit: INT] RETURNS [RealFns.Rational] = { oneOverX: REAL; sign: INT ¬ 1; inverse: BOOL ¬ FALSE; p0, q0, lambda: INT; q1, p2: INT ¬ 0; p1, q2: INT ¬ 1; IF x < 0.0 THEN { x ¬ -x; sign ¬ -1 }; IF x = 1.0 THEN RETURN [[numerator: sign, denominator: 1]]; IF x > 1.0 THEN { x ¬ 1.0/x; inverse ¬ TRUE }; lambda ¬ 0; -- = FLOOR[x] WHILE (oneOverX ¬ (x-lambda))*REAL[limit-q1] > REAL[q2] DO x ¬ 1.0/oneOverX; lambda ¬ RealSupport.Fix[x]; -- was InlineFix q0 ¬ q1; q1 ¬ q2; q2 ¬ lambda*q1+q0; p0 ¬ p1; p1 ¬ p2; p2 ¬ lambda*p1+p0; ENDLOOP; IF NOT inverse THEN RETURN [[numerator: sign*p2, denominator: q2]] ELSE RETURN [[numerator: sign*q2, denominator: p2]]; }; AlmostZero: PUBLIC PROC [x: REAL, distance: INTEGER [-126..127]] RETURNS [BOOL] = { RETURN[LOOPHOLE[x, SingleReal].exp < (distance + ExponentBias)]; }; AlmostEqual: PUBLIC PROC [y, x: REAL, distance: INTEGER [-126..0]] RETURNS [BOOL] = { xe: SingleReal ¬ LOOPHOLE[x]; ye: SingleReal ¬ LOOPHOLE[y]; SELECT TRUE FROM xe.exp = NaNExponent => RETURN [FALSE]; ye.exp = NaNExponent => RETURN [FALSE]; x = y => RETURN [TRUE]; xe.sign # ye.sign => RETURN [FALSE]; distance = 0 => RETURN [TRUE]; xe.exp > ye.exp+1, ye.exp > xe.exp+1 => RETURN [FALSE]; ENDCASE => { IF xe.exp = 0 OR ye.exp = 0 THEN { reNorm: REAL ¬ 1.0; LOOPHOLE[reNorm, SingleReal].exp ¬ LOOPHOLE[reNorm, SingleReal].exp + 24; xe ¬ LOOPHOLE[x ¬ x * reNorm]; ye ¬ LOOPHOLE[y ¬ y * reNorm]; }; { delta: SingleReal ¬ LOOPHOLE[(x - y)]; keyExp: INTEGER ¬ MAX[xe.exp, ye.exp] + distance; SELECT INTEGER[delta.exp] FROM < keyExp => RETURN [TRUE]; > keyExp => RETURN [FALSE]; ENDCASE => RETURN [delta.m = 0]; }; }; }; fact9recip: REAL ¬ 1.0/(INT[1]*2*3*4*5*6*7*8*9); fact8recip: REAL ¬ 1.0/(INT[1]*2*3*4*5*6*7*8); fact7recip: REAL ¬ 1.0/(INT[1]*2*3*4*5*6*7); fact6recip: REAL ¬ 1.0/(INT[1]*2*3*4*5*6); fact5recip: REAL ¬ 1.0/(INT[1]*2*3*4*5); fact4recip: REAL ¬ 1.0/(INT[1]*2*3*4); fact3recip: REAL ¬ 1.0/(INT[1]*2*3); fact2recip: REAL ¬ 1.0/(INT[1]*2); minEps: REAL ¬ 1.0 - LOOPHOLE[LOOPHOLE[1.0, LONG CARDINAL]-1, REAL]; sinCosEps: REAL ¬ SqRt[minEps]; SinFirstOctant: PROC [radians: REAL] RETURNS [REAL] = { IF radians <= sinCosEps THEN RETURN [radians] ELSE { r2: REAL ~ radians*radians; RETURN [(((fact9recip*r2-fact7recip)*r2+fact5recip)*r2-fact3recip)*r2*radians+radians]; }; }; CosFirstOctant: PROC [radians: REAL] RETURNS [REAL] = { IF radians <= sinCosEps THEN RETURN [1.0] ELSE { r2: REAL ~ radians*radians; RETURN [((((fact8recip*r2-fact6recip)*r2+fact4recip)*r2-fact2recip)*r2+1)]; }; }; PIc1: REAL ¬ 6.28125; -- 402.0/64 (exact representation near twoPI) PIc2: REAL ¬ twoPI-PIc1; -- 2*PI - c1 GetWithinTwoPI: PROC [radians: REAL] RETURNS [REAL] = { xn: REAL ¬ RealSupport.Fix[radians * rec2pi]; -- was InlineFix RETURN [(radians - xn*PIc1) - xn*PIc2]; }; GetWithin360: PROC [degrees: REAL] RETURNS [REAL] = { xn: REAL ¬ RealSupport.Fix[degrees * rec360]; -- was InlineFix RETURN [degrees - xn*360]; }; Mul32: PROC [x, y: CARD32] RETURNS [CARD32, CARD32] ~ { a: Basics.LongNumber ¬ [card[x]]; b: Basics.LongNumber ¬ [card[y]]; hi, lo, t1, t2: Basics.LongNumber; cy: CARDINAL; lo.card ¬ CARD32[a.lo]*CARD32[b.lo]; hi.card ¬ CARD32[a.hi]*CARD32[b.hi]; t1.card ¬ CARD32[a.hi]*CARD32[b.lo]; t2.card ¬ CARD32[a.lo]*CARD32[b.hi]; [cy, lo.hi] ¬ ADC3[lo.hi, t1.lo, t2.lo]; hi.card ¬ hi.card + t1.hi + t2.hi + cy; RETURN[hi.card, lo.card]; }; ADC3: PROC [a, b, c: CARD16] RETURNS [CARD16, CARD16] = INLINE { s: Basics.LongNumber; s.card ¬ CARD32[a] + CARD32[b] + CARD32[c]; RETURN[s.hi, s.lo]; }; END. September 16, 1980 3:13 PM, Stewart; Bug in Exp September 28, 1980 8:28 PM, Stewart; Add AlmostEqual and AlmostZero, format November 7, 1980 3:33 PM, Stewart; fix AlmostZero August 27, 1982 1:07 pm, Stewart; CEDAR October 24, 1984 4:37:17 pm PDT, Plass; New impls for Sin, Cos, SinDeg, CosDeg November 2, 1984, Atkinson; Faster & more accurate SqRt, Sin, Cos, SinDeg, CosDeg !ê RealFnsImpl.mesa Copyright Ó 1984, 1985, 1986, 1987, 1988, 1989, 1991 by Xerox Corporation. All rights reserved. Stewart on August 27, 1982 1:07 pm Paul Rovner on May 4, 1983 10:13 am Levin, August 8, 1983 4:39 pm Plass, August 5, 1991 11:28 am PDT E. McCreight, November 16, 1984 11:48:22 am PST (RealFnsExtrasImpl) Russ Atkinson (RRA), July 5, 1989 11:36:56 pm PDT Doug Wyatt, January 15, 1987 1:59:52 pm PST Chauser, March 16, 1990 4:06 pm PST Loner, February 26, 1991 8:33 am PST Willie-s, August 6, 1991 1:06 pm PDT the bias, amount to subtract to make the exponent "correct" biased, just as it appears in SingleReal biased, just as it appears in SingleReal This declaration obviously depends on IEEE format 32-bit numbers (SingleReal). The idea is that the index field has the low bit of the exponent and the high 4 bits of the mantissa, which is used to index a table of initial guesses at the square root, each guess is roughly halfway between the lowest and highest root with the given index, which allows convergence with only two iterations. I don't know where the table originated. Some useful constants (must be variables) compute e^x using continued fractions ACM Algorithm 229, Morelock, James C., "Elementary functions by continued fractions" To keep the error small near 0.0, use this Taylor's series Expand the continued fraction loop a few times Note, if LoopCount > 3, then use the following comments f _ (4*(LoopCount-3) - 2) + r/f; f _ (4*(LoopCount-4) - 2) + r/f; unscaled result is (f+x)/(f-x) scale: multipy by 2^k by adding k to the exponent logxy = Ln(y)/Ln(x) To keep the error small near 1.0, use this Taylor's series if x = z * 2^m then Ln(x) = m * Ln2 + Ln(z). Here, 1/2 <= z < 1 special case for limit condition (x a power of 2) RRA: The idea is to lookup a square root guess from the table, adjusting for the exponent, then perform a few iterations to get within a reasonable error. HIGHLY IEEE DEPENDENT! Denormalized exponent. The guess is only valid when we have a normalized number, so we force it to be normalized, then correct for the shift. Get the initial guess based on the top 4 bits of the mantissa and the bottom bit of the exponent. Adjust the guess exponent based on adding half of the initial exponent (adjusted for the offset inherent in IEEE format). The result is initially the guess This is really b _ (b + a/b)/2, but much faster This is really b _ (b + a/b)/2, but much faster yth root of x = e^(Ln(x)/y) x^y = e^(y*Ln(x)) We need to have rem IN [0..twoPI] Now select the appropriate formula given the octant. We need to have rem IN [0..twoPI] Now select the appropriate formula given the octant. We get better results if we compute in the degrees domain for a while. We get better results if we compute in the degrees domain for a while. if f is small, then tan(f) S f, otherwise use ratl approximation from Cody & Waite RETURN[2*ArcTan[SqRt[(1-x)/(1+x)], 1]]; David Goldberg notes regarding the accuracy of two methods for computing ArcCos, where Method 1 is ArcTan[SqRt[1.0-x*x], x], and Method 2 is the one above: When x ~ y, then x-y is dangerous if x and/or y have suffered roundoff error, because all the significant digits may be cancelled, leaving only roundoff error. That's the trouble with 1-x*x; there will be roundoff error in x*x, and if x ~ 1, then 1-x*x can have a large relative error. However, if x ~ 1, (in fact, if 1/2 < x < 2), then 1-x is exact because there is no roundoff error. Thus 1/(1-x) is very accurate. That's the theory according to floating point experts. Method 1 is worse when x = 1-n*2^(-24), n = sqrt(2^(23)), i.e., x = 0.9998274. The correct value is 1.857983e-02; Method 1 gives 1.858144e-2 (error .000161e-2) while Method 2 gives 1.858064e-2 (error .000081e-2). So, in this case, Method 2 has half the error of Method 1. [Artwork node; type 'Artwork on' to command tool] The ArcCos Geometry for Method 2 Constants for ArcTan This function is good to 8.7 decimal places and is taken from: Computer Approximations, John F. Hart et.al. pp129(top 2nd col). The following approximations are taken from the book "Computer Approximations", by Hart, Cheney, Lawson, Maehly, Mesztenyi, Rice, Thacher, and Witzgall, published by Wiley. Function names and indexes refer to that book. Bessel function of first kind of order 0 JZERO 5838 - 8.54 digits Bessel function of first kind of order 1 JONE 6036 - 7.08 digits ..actually, JONE 6038 - 8.19 digits would be better, but that page is missing from my copy. Bessel function of first kind of order n Bessel function of first kind of order n Jn(x) = Sum[k>=0] (-1)k(x/2)n+2k / k! (n+k)! -- All best rational approximations of a real x may be obtained from x's continued fraction representation, x = c0 + 1/(c1 + 1/(c2 + 1/(...))) = [c0, c1, c2, ... ], by truncation to k terms and possibly "interpolation" of the last term. The continued fraction expansion itself is obtained by a variant of the standard GCD algorithm, which is folded into the recursions generating successive numerators and denominators. These recursions both have the same form: fk _ ck*fk-1 + fk-2. For further information, see CSL-Notebook entry 88CSLN-0045, Nov. 28, 1988; cited there is Fundamentals of Mathematics, Volume I, MIT Press, 1983. On return, |numer| <= limit, 0 < denom <= limit. -- Handle first non-zero term of continued fraction, rest setup for integer GCD, sure to fit. -- Treating 1.0 and x as integers, divide 1/x in a peculiar way to get accurate remainder num _ Basics.BITLSHIFT[[lc[1]], n].lc; num _ Basics.BITLSHIFT[[li[ak]], n].lc; ck _ Basics.BITLSHIFT[[lc[ck]], n].lc + num/ak1; All done with divide [dk2ak1Hi, dk2ak1Lo] _ Mul32[[lc[IF flip THEN nk2 ELSE dk2]],[lc[ak1]]]; [dk1akHi, dk1akLo] _ Mul32[[lc[IF flip THEN nk1 ELSE dk1]],[lc[ak]]]; The best rational approximation to a real x is obtained using continued fractions. The following algorithm is adapted from Wm. J. LeVeque's book, Fundamentals of Number Theory, Addison Wesley, 1977, page 229. |num| <= limit, 0 < denom <= limit. Here x lies in [0..1) This test ensures that q2 never exceeds limit. Because the initial x was <1, p2<=q2. The best approximation so far is p2/q2, and q2 > p2. The range of distance has been carefully chosen to 1. make zero and all denormalized values of x return TRUE 2. make all NaN values of x return FALSE AlmostEqual[y, x, distance] == NotNaN[x] AND NotNaN[y] AND ABS[x-y] <= MAX[ABS[x], ABS[y]]*2^distance for valid x & y: x = y => TRUE Sign[x] # Sign[y] => FALSE Sign[x] = Sign[y] AND distance = 0 => TRUE Rewritten by RRA on November 11, 1986, previous implementation returned FALSE when x = y = 0.0, which was counterintuitive, to say the least. NotNaN[x] => FALSE NotNaN[y] => FALSE exactly equal valid numbers are always AlmostEqual (use REAL equality to check with -0.0) xe.sign # ye.sign => ABS[x-y] > MAX[ABS[x],ABS[y]] xe.sign = ye.sign AND x # y => ABS[x-y] < MAX[ABS[x],ABS[y]] ABS[x-y] > MAX[ABS[x],ABS[y]]*0.5 Sigh, one of them is denormalized! Helpful internal functions Coefficients for the taylor series for sin and cos. roughly 5.96e-8, the minimum relative error between two different reals RRA: IF radians <= sinEps THEN SinFirstOctant[radians] = radians AND CosFirstOctant[radians] = 1.0 to the precision of our number system. The contribution of the smaller term of two consecutive terms in the Sin or Cos polynomials is down by the square from the larger (and a factor of at least two). So sinCosEps roughly equals 1.726e-4. Testing for this case improves accuracy at small values. This version of Sin is only guaranteed to be accurate within the first octant: [0.0..PI/4], which is approximately [0.0..0.785+]. When radians = PI/4 we have the maximum contribution of the term after the fact9recip term, for a truncation error of roughly 1.76e-9, which is within minEps*Sin[radians] (= 4.2e-8). This version of Cos is only guaranteed to be accurate within the first octant: [0.0..PI/4]. When radians = PI/4 we have the maximum contribution of the terms after the fact8recip term, for a truncation error of roughly 2.46e-8, which is within minEps*Cos[PI/4] (= 4.2e-8). Two constants used to add N*PI with more than normal precision. Let the returned value be R. Then radians <= 0 J radians S xn*twoPI + R & -twoPI < R < 0 radians >= 0 J radians S xn*twoPI + R & 0 < R < twoPI Let the returned value be R. Then degrees <= 0 J degrees S xn*360 + R & -360 < R < 0 degrees >= 0 J degrees S xn*360 + R & 0 < R < 360 Add with Carry Carl Hauser, January 21, 1988 2:08:18 pm PST For PortableCedar Removed instances of Real.InlineFix* , replacing with RealSupport.Fix and labelling what was replaced. ÊY/–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ÏeœU™`KšÏy"™"Kšž#™#Kšž™Kšœ"™"JšžC™CKšœ1™1K™+K™#K™$K™$—K˜šÏk ˜ K˜K˜K˜Kšœ Ÿœ˜K˜—headšÏb œŸœŸ˜KšŸœ/˜6KšŸœ˜KšœŸ˜K˜š œ ŸœŸœŸ œŸœ˜-KšœŸœ˜Kšœ˜Kšœ˜K˜Kšœ ŸœŸœ ˜#šœ ŸœŸœ˜)Kšœ Ÿœ ˜—K˜šÏn œŸœ˜K™;—š¡œŸœ Ÿœ˜)Kšœ(™(—š¡ œŸœ Ÿœ˜%Kšœ(™(—K˜—š œ ŸœŸœŸ œŸœ˜-KšœŸœ˜KšœŸœ ˜#KšœŸœ ˜#KšœŸœ˜'K˜Kšœ°™°K˜——K˜š¡œŸœŸœ?˜RKšŸœ#˜(K˜K˜—šœ)™)KšœŸœ˜Kšœ Ÿœ ˜Kšœ Ÿœ˜"KšŸœŸœ˜KšœŸœŸœ˜Kšœ ŸœŸœ˜Kšœ Ÿœ˜Kšœ Ÿœ ˜Kšœ ŸœŸœ˜Kšœ ŸœŸœ˜KšœŸœŸœ˜ KšœŸœŸœ˜ KšœŸœ ˜KšœŸœ ˜Kšœ ŸœŸœ˜Kšœ ŸœŸœ˜Kšœ Ÿœ˜Kšœ Ÿœ˜Kšœ ŸœÏc)˜P—K˜š ¡œŸœŸœŸœŸœŸœ˜-šœ%™%KšœT™T—KšœŸœ˜ KšœŸœ˜ KšœŸœ˜+K˜Kšœ:™:šŸœŸœŸ˜Kšœ Ÿœ˜Kšœ Ÿœ˜KšŸœ˜—K˜Kšœ¢˜1KšŸœŸœŸœ˜'KšŸœŸœ ˜!K˜Kšœ¢˜7Kšœ ¢˜K˜Kšœ ¢(˜3K˜K˜˜Kšœ.™.Kšœ Ÿœ˜K˜Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜šœ7™7Kšœ ™ Kšœ ™ —K˜—K˜Kšœ™Kšœ˜Kšœ1™1Kšœ˜KšŸœŸœŸœ˜K˜K˜—š ¡œŸœŸœ ŸœŸœŸœ˜5Kšœ™KšŸœ˜K˜K˜—š ¡œŸœŸœŸœŸœŸœ˜,Kšœ˜KšœŸœ˜ KšœŸœ˜KšœŸœ˜#KšŸœŸœ ˜K˜Kšœ:™:šŸœŸœŸ˜Kšœ ˜ Kšœ Ÿœ˜%KšŸœŸœ˜K˜—Kšœ@™@KšœŸœ˜Kšœ ˜ Kšœ¢˜-KšœŸœŸœ˜K˜Kšœ1™1KšŸœ ŸœŸœ ˜"K˜K˜K˜ K˜šŸœŸœ Ÿ˜Kšœ Ÿœ˜K˜0K˜KšŸœŸœŸœ˜KšŸœ˜K˜—KšŸœ˜ K˜K˜—š ¡œŸ œŸœŸœŸœ ˜7KšŸœ™ œ™²šŸœŸœŸ˜šœ ˜ KšŸœ Ÿœ ˜Kšœ˜K˜—šŸœ˜"KšœŽ™ŽKšœŸœ Ÿœ˜5—šŸœ˜ KšœŸœ˜+šœŸœ$˜?Kšœa™a—KšœŸœ˜šœ ˜ Kšœy™y—šœŸœŸœ˜Kšœ!™!—š œŸœŸœ ŸœŸœŸœ˜AKšœ/™/—š œŸœŸœ ŸœŸœŸœ˜AKšœ/™/—K˜——K˜K˜šœ ŸœŸœŸœ˜#KšœJ˜JKšœJ˜JKšœJ˜JKšœJ˜JKšœJ˜JKšœJ˜JKšœJ˜JKšœJ˜JK˜K˜——š ¡œŸœŸœŸœŸœŸœ˜7Kšœ™KšŸœ˜K˜K˜—š ¡œŸœŸœŸœŸœŸœ˜ÄÁ¼ÄTb7¡’ÄDjeÄ%Ë¿Äy³Äês˜Ä<!Ħÿl¡’Äw±Ä!`ħùÄUH7Ä4ÙOIJŠs¡’Ä ØÄCNÄc•ÄtÀKÄ-©EÄ>K(¡’Ä°ñ‘Ä~2QÄdR™Ä hgÄRñÄôF¡’Ä0JÄꯗÄ‘)Äu¸Ä_»”Ä5£È¡’Äg[ Ä%²Äy)Ä’˜_Ä‚wÊÄ‚ñU¡’ĆiÐÄ“ÄÄ…=WÄV«…ÄŽ1]¡’Ä5QÄ"¾Ä&Ü;ÄŠß[Ä[cŠÄü©¡’Ä'ý<Ä”!aÄJ`oÄ@=*Ä¥/ÄI0¡’Ä¢•ðÄ/ÄæÞSÄa ?ÄÓQ5ÄrQJ¡’Ä´rÄ#Ä27IÄfqBÄ#,3Ä,IÁ¡’˜ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä Âý ¤Ä*=Äñ ¢ ¥ ¨  Š¡²“Á/2– k¡¡¨ ¡ ¡™ x jį“¢°“¢·“¡¡¨Ä,ýPÄ‹[™Ä4½^ÄôUÄN]ŒÄ,WÄ“,ÄÙ'Ž¡’ĆéÄGç/Ä ÄB?ÈÄ-ÌSĹy¡’ÄtÓÄ8È%Ä$ÈCÄ›/eÄÀR_Ä#b¡’Ä-LSÄBR+ÄYI¤ÄfBÄ@„wÄ ¡’Ä8?hÄyNÄ2¯^ÄÃå~ÄËzÄ4S¡’Ä2Q^Ä‚ñTÄ9kÄZ‡:Äl%ÌÄ|ëP¡’ÄuñÄO«3Ä?Ä0hÄ+HSÄþI£¡’Är”ÝÄb-?ÄO™ÄMÇ2ĺ[ÄyN¡’Ä0Ý_ÄYå:Ä,¹Wă„UÄDe…ĉyY¡’ÄRÙ¡Ä)Ä eÄÚŽÄ¢Ä9Ä…aW¡’Ä=µvćñÄ7Ýjă™VÄàñÄ S¡’Ä=‚sÄ Ì1fÄ7ÿhÄZ|;Ä Äœ¡’Ä!×>Ä~IRÄô|½ÄqïÄ7ÇeÄ𛡒ÄtqÒÄ–™aÄ èÄqœIÄœÎÄþI£¡’˜ kÄ¡¨ ¡ ¡™ x j¢°“¢¯“¡¡¨ÄW ¡¹¢°“¡¯“¡¡¨ ` ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ Ä+¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä+Ä¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äõ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨õÄ ë: %¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨óÄWó ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ó óÄ+¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨óÄ+óÄ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨óÄóõ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨óõóÄ ë: %¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄOBÄWÄOB ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄOB ÄOBÄ+¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä6×B ÄOB ¡¹ kÄ¡¨ ¡ ¡™ x j¢°“¢¯“¡¡¨Äõ¡¹¢°“¡¯“¡¡¨õ`õ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä6×Bõóõ¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä Âý ¤Ät3•Ä‘ ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä Âý ¤ÄNÄ0 ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄÑ ¤Äc-}ÄÕ– ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä³Äêèm ¢ ¥ ¨  Š¡²“ÁP = (– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä…OOÄÏ5` ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä¦ÈaÄ…‰= ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄG)Ä\‡+ ¢ ¥ ¨  Š¡²“Á,– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄPQ-Ä@© ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä\3/Äêèm ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä –‡ÄE™  ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄWÜ=Äêèm ¢ ¥ ¨  Š¡²“Á1-– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä€ ÄBë ¢ ¥ ¨  Š¡²“Á)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä™)QÄA! ¢ ¥ ¨  Š¡²“Á,– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äªc]Ät}6™Ä«¿]ÄÆe[—Äþ¸‰Äêèm—Äj“8ÄI«!—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äj“8ÄI«!Ä‘aGÄI«!¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä/CÄS) ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤ÄìÀÄZƒ, ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä(´Ä) ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä#õÄ> ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä®.QÄ¡!O ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä1Ä‹N ¢ ¥ ¨  Š¡²“Á1-– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äà^qÄeß±™Ä^/Ä‘/G—Ä Ä‹N—Ĩ£RÄ’ËF—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä¨£RÄ’ËFÄ̲]Ä’ËF¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Äí/ŠÄS) ¢ ¥ ¨  Š¡²“Áx+– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄYƒ5Ĺÿ]Ä–µPĹÿ]¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä«|YĹÿ]Ä—͹Ĺÿ]¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä¢Ï\ÄIC ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄÌIdĈšG ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄI9 ¤ÄZä7ć-D ¢ ¥ ¨  Š¡²“Á(– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄÓ0 ¤Ä¹›ÇÄ+ ¢ ¥ ¨  Š¡²“Á)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄgDÄM]' ¢ ¥ ¨  Š¡²“ÁM=– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄÄ–Ä2¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄŒ ÄvÄ ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄÔÄ\ľÄ|¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä2ðÄÖ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨î´ÄÔÄ\¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä@öeÄ^7Ä.¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÊÄÄSóoÄZ¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä,ÄÆOmÄøÄС¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄÄÄpÄROgĺ4c¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä Âý ¤ÄQõwÄ$m ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä Âý ¤^v ¢ ¥ ¨  Š¡²“Á1– k¡¡¨ ¡ ¡™ x jį“¢°“¢·“¡¡¨Ä˜šgÄÑÙw™Ä±%ÄVj1ÄA ,ÄÁ½ÿÄŒI_Äh;¡’ÄH21Äk§=ćI\ÄHn)Ä.û Ä’ÒS¡’ÄkIÄ0—¬Är=NÄ\ªUÄ.Ó ÄdçÉ¡’ÄZ>Ä•“TÄ3#ÄW„1Ä.— Ä9O ¡’ÄdXEÄyùDÄe§FÄ£x[ÄÌmÄ™¡’Ä>;+Ä WYăn[ÄÖ°wÄõÄá¡’Ä@¬-ÄV­0Ä¡ ÄOk,Ä? ªÄ9³ ¡’Ä>½,ÄMq+ĘHkÄ[«3ÄY’?Ä9c ¡’ÄdÞGÄi ;Ä-s ÄûóÄV§=ÄÛa{¡’Ä‹AbÄÇ Ä Ä K*ÏÄ¡YqÄ’ÒS¡’Ä’fÄ=Ò#Äm1LÄ„eKĈì_Ä ‘¡’Ä_{BÄyåEÄOÑ7ÄZ@3ÄS:™Ä6O¯¡’Ä.½ ÄAÇ%Ä:›(ÄAû%j¡’Ä:Ý(ĘuUĽ Ä4'Ä_IÄ9³ ¡’˜ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄBÄƲq ¢ ¥ ¨  Š¡²“Á/2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄQÄH8) ¢ ¥ ¨  Š¡²“Á= arcTan– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄI9 ¤ÄŠÊIÄK¦+ ¢ ¥ ¨  Š¡²“Á(– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄÓ0 ¤Ä´&IĘÿW ¢ ¥ ¨  Š¡²“Á)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄÁWQÄ–PS ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä¿}¹ÄBM$ ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä€8Ä–PS ¢ ¥ ¨  Š¡²“Áx+– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä$!ÄR.ĺ;ÄR.¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Äû ÄÒ ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä‚¥CÄ~GF ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄN±%Än= ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä5,ÄÊjo ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄCå!Äu>A ¢ ¥ ¨  Š¡²“Á1-– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄKå&Ä]ç4™Ä@a Ä—ÊS—ć¢CÄu>A—Ä9éÄtŸ>—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä9éÄtŸ>ÄpÙ3ÄtŸ>¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä¤ÅUÄÂrmÄɨ[ÄÂrm¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä[7©Ä˜Y ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Äuí5ÄD(· ¢ ¥ ¨  Š¡²“Á,– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä‹CÄ ¿F ¢ ¥ ¨  Š¡²“Áx– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨Ä%£ ¤Ä¦´OĘOü ¢ ¥ ¨  Š¡²“Á2– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä Ä ¿F ¢ ¥ ¨  Š¡²“Á1-– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄÒlÄõ˜9™ÄȬéÄŠ+U—Ä/WÄ ¿F—ÄLŸ&ÄzyI—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨ÄLŸ&ÄzyIÄX˜)ÄzyI¡¹ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä¡êIÄ ¿F ¢ ¥ ¨  Š¡²“Á1+x– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä…öUÄam= ¢ ¥ ¨  Š¡²“Á = arcTan (– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄµçMÄ ¿F ¢ ¥ ¨  Š¡²“Á)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä}W:Ä ¿F ¢ ¥ ¨  Š¡²“Á,– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä¯À[ÄTíD™Ä†EEÄ­åR—Ä…¼ÇÄ5+—Äpm¸Ä%—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äpm¸Ä%™Ä‚ Ä1 #—ÄIv!Ž˜ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Äq+7į ƒ ¢ ¥ ¨  Š¡²“Á1-x– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä´†YÄ} ¢ ¥ ¨  Š¡²“Á1+x– kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Äyy<ÄLW:Ä‚ý<ÄLW:¡¹ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä_)1Äna™ÄËJÄ*ó—Ä‹ÐGÄDn/—Ä‚ÙAÄÇ])—˜ kÄ¡¨ ¡ ¡™ x j¡¯“¢°“¢·“¡¡¨Ä‚ÙAÄÇ])™ÄVM(ŽÄé ªŽ˜ k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä ÄT£: ¢ ¥ ¨  Š¡²“Á (1-x)(1+x)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Ä~­6Ä}/V ¢ ¥ ¨  Š¡²“Á, 1+x)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤Úî ¢ ¥ ¨  Š¡²“Á, 1)– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄSe5Ä'Õã ¢ ¥ ¨  Š¡²“Á = arcTan (– k x jÅxeroxÅ pressfontsÅ helvetica-mrr£¡ “¡•¡ —¡¡¨ÄRo ¤ÄPJ3ÄY;= ¢ ¥ ¨  Š¡²“Á = arcTan (– k k é k é k gš¡3™3Icenterš  ™ —K™—šœ™Kšœ Ÿœ˜KšœŸœ˜KšœŸœ ˜Kšœ Ÿœ˜KšœŸœ˜KšœŸœ ˜Kšœ Ÿœ˜KšœŸœ˜KšœŸœ ˜šœ Ÿœ˜K˜—KšœŸœ˜KšœŸœ˜KšœŸœ˜KšœŸœ˜K˜—š ¡œŸœŸœŸœŸœ Ÿœ˜<šœ>™>Kšœ@™@—KšœŸœ˜šŸœŸœŸœŸ˜"šŸœŸœŸœ ˜KšŸœŸœ˜Kš ŸœŸœŸœŸœ ŸœŸœ ˜;——šŸœ˜Kš ŸœŸœŸœŸœ ŸœŸœ ˜9KšŸœŸœŸœŸœ˜7—KšœŸœ˜ šŸœŸ˜ Kšœ˜Kšœ5˜5Kšœ5˜5Kšœ6˜6KšŸœ˜&—K˜ K˜9K˜K˜—š ¡ œŸœŸœŸœŸœ Ÿœ˜?Kšœ(˜(Kšœ˜K˜—K˜š ¡œŸœŸœŸœŸœŸœ˜1KšœŸœ ˜KšœŸœ˜Kšœ˜Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜1KšœŸœ ˜KšœŸœ˜Kšœ˜Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜1Kš ŸœŸœ ŸœŸœŸœŸœ˜3šŸœ˜KšœŸœ ˜KšœŸœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜1Kš ŸœŸœ ŸœŸœŸœŸœ˜3šŸœ˜KšœŸœ ˜KšœŸœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜4Kšœ˜Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜4KšŸœ Ÿœ ˜Kšœ˜Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜4KšŸœŸœ Ÿœ ˜Kšœ˜Kšœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜4KšŸœŸœ Ÿœ ˜Kšœ˜Kšœ˜K˜—šœÜ™ÜJ™—š ¡œŸœŸœŸœŸœŸœ˜4KšœŸœ˜ Kšœ Ÿœ˜KšŸœ Ÿœ ˜šŸœŸœ¢*˜:Kšœ Ÿœ˜šŸœŸ˜Kšœ˜Kšœ ˜ KšŸœ˜—Kšœ˜Kšœ˜—Kšœ/¢˜IKšœ-¢˜BKšœ˜K˜—š ÐbnœŸœŸœŸœŸœŸœ˜/KšŸœ˜Kšœ˜—K˜š ¡œŸœŸœŸœŸœŸœ˜/Jšœ(™(KšŸœ Ÿœ˜šŸœ Ÿœ˜Jšœ™KšœŸœ˜šŸœŸœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœŸœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—KšœŸœŸœ˜Kšœ˜—šŸœ˜KšœŸœ˜KšœŸœ˜ Kšœ˜KšœŸœ/˜?Kšœ˜—Kšœ˜J™—š ¡œŸœŸœŸœ Ÿœ˜.KšœŸœ ˜KšœŸœ˜šœ¢˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ ¢˜$Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—šœŸœ˜K˜—š ¡œŸœŸœŸœŸœŸœ˜/Jšœ(™(KšœŸœ˜KšŸœ Ÿœ˜&šŸœ Ÿœ˜šœ™J™[—KšœŸœ˜šŸœŸœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœŸœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ ŸœŸœ˜Kšœ˜—šŸœ˜KšœŸœ ˜KšœŸœ˜ Kšœ˜KšœŸœ/˜DKšœ˜—Kšœ˜J™—š ¡œŸœŸœŸœ Ÿœ˜.KšœŸœ ˜KšœŸœ˜šœ¢˜"Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœ ¢˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ˜J™—š¡œŸœŸœŸœŸœŸœŸœ˜:Jšœ(™(KšœŸœ˜Kš ŸœŸœŸœŸœŸœŸœ˜?šŸœŸ˜ K˜K˜šŸœ˜ KšœŸœ ˜KšœŸœ ˜šŸœŸœŸœŸ˜KšœŸœ˜Kšœ˜Kšœ˜KšŸœ˜—K˜ Kšœ˜——Kšœ˜K˜—KšœŸœ˜(Kšœ Ÿœ˜K˜š¡œŸœŸœŸœŸœŸœŸœ˜7Jšœ(™(KšœŸœ˜Kš ŸœŸœŸœŸœŸœŸœ˜?šŸœŸœŸ˜KšœŸœŸœ˜KšœŸœ˜Kšœ Ÿœ˜šŸœ˜ JšœÏdœÏuœ¦œ ™,KšœŸœ ˜Kšœ¦œŸœ˜Kšœ Ÿœ˜šŸœŸœ˜Kšœ ˜ Kš ŸœŸœŸœŸœŸœ˜:K˜—KšŸœ)˜-K˜ šŸœŸœ Ÿ˜KšœŸœ˜ Kšœ¦œ˜$Kšœ˜KšŸœ ŸœŸœŸœ˜*KšŸœ˜—K˜ Kšœ˜——Kšœ˜K˜—š¡œŸœŸœŸœ ŸœŸœŸœ˜?KšŸœ˜Kšœ˜JšHœqÐdrœÏrœ¨œ§œ¨œ¨œ§œ¨œ¨œ¨œ¨œ¨œ§¨œ§¨œ§¨œ¨œ®Ðdoœ¨œ©¨œ©¥§œ¨œ©¥§œ^Ðbi%œÐprœ«Ïp«¬œ¬«¬«¬œ¬«¬œ™ªK˜KšœŸœŸœŸœ¢˜HKšœŸœŸœŸœ¢˜JKšœŸœ#¢˜OKšœ Ÿœ ¢8Ðck˜RKšœ#˜#K˜KšœŸœ˜Kš œŸœŸœ¢ ­¢©¢©¢ ˜=KšœŸœ ¢ Ðcr¢˜@Kš œ©œ©œ©œŸœ ¢®¢˜?Kš œ©œ©¥œŸœ ¢œ©¢ ˜@Kšœ©œ©œŸœ ¢*˜AKšœ©œ©œŸœ¢˜:Kšœ©œ©œŸœ˜K˜Kš Ÿœ ŸœŸœ ¢®¢®˜:KšŸœ Ÿœ˜'Jšœ]™]šŸœ ˜ šŸœ ¢,˜=KšœŸœ˜ šŸœŸœ©œŸœ˜:KšŸœŸœ˜—KšœŸœ ¢.˜CKšœ©œ©œ©œ¢'˜=Kšœ ©œ˜KšœŸœ˜2Kšœ©œ&˜(Kšœ©œ%˜(Kšœ˜—šŸœ ¢(˜9KšœŸœ˜ šŸœ¢­œ˜9šŸœŸ˜KšŸœŸœŸœ ˜/šŸœŸœ Ÿœ˜&KšŸœŸœ˜KšŸœŸœ ˜—K˜——Jšœ ¨œ¨œ-™YKšœŸœ˜0Kšœ©œ#˜&Kš œŸœŸœŸœ¢­¢ ˜>Jšœ Ÿ œ™&Kšœ Ÿ œ˜Kšœ©œ©œ ¢®¢˜,Kšœ©œŸœ©œ¢˜5šŸœŸœ¢*˜KKšœŸœ¢+­˜GJšœ Ÿ œ©œ ™'Jš œ©œ Ÿ œ©œ©œ™0Kšœ Ÿ œ©œ˜Kš œ©œ Ÿ œ©œ ©œ˜'Kšœ©œŸœ©œ¢˜*KšŸœ˜—J™šŸœ©œŸœ¢$˜9šŸœ˜šŸœŸœ ©˜KšŸœŸœ˜KšŸœŸœ ˜—K˜——Kšœ©œ©œ©œ¢)˜KšŸœ!˜'K˜K˜—š ¡ œŸœ ŸœŸœŸœ˜5šœ"™"Kš œ £œ £œ £œ£œ£œ™2Kš œ £œ £œ £œ£œ£œ™1—KšœŸœ&¢˜>KšŸœ˜K˜—K˜š ¡œŸœŸœŸœŸœŸœ˜3Kšœ˜Kšœ!˜!Kšœ!˜!Kšœ"˜"KšœŸœ˜ Kšœ ŸœŸœ˜$Kšœ ŸœŸœ˜$Kšœ ŸœŸœ˜$Kšœ ŸœŸœ˜$Kšœ(˜(Kšœ'˜'KšŸœ˜K˜—K˜šœ™K˜—š¡œŸœ ŸœŸœŸœŸœŸœ˜@Kšœ˜Kšœ ŸœŸœŸœ˜+KšŸœ ˜K˜—K˜—K˜šŸœ˜K˜—KšœŸœ˜0KšœŸœ1˜LKšœŸœ˜2Kšœ"Ÿ˜'K˜NK˜Q™,K™Kšœf™f—K™—…—RJÍc