MODULE LR2 EXPORTS LR2, LR2Extras; (* Hand-optimized implementation of the interfaces "LR2" and "LR2Extras". Created by J. Stolfi, with contributions by M. C. Carrard and R. L. W. Liesenfeld. *) IMPORT LR2Rep, LRN, Math, Wr, Thread, Random, GaussRandom; PROCEDURE Zero(): T = BEGIN RETURN T{0.0d0, 0.0d0} END Zero; PROCEDURE All(x: LONGREAL): T = BEGIN RETURN T{x, x} END All; PROCEDURE Axis(i: [0..N-1]): T = VAR r: T := T{0.0d0, 0.0d0}; BEGIN r[i] := 1.0d0; RETURN r END Axis; PROCEDURE Get(READONLY a: T; i: [0..N-1]): LONGREAL = BEGIN RETURN a[i] END Get; PROCEDURE Set(VAR a: T; i: [0..N-1]; x: LONGREAL) = BEGIN a[i] := x END Set; PROCEDURE Add(READONLY a, b: T): T = BEGIN RETURN T{a[0] + b[0], a[1] + b[1]} END Add; PROCEDURE Sub(READONLY a, b: T): T = BEGIN RETURN T{a[0] - b[0], a[1] - b[1]} END Sub; PROCEDURE Neg(READONLY a: T): T = BEGIN RETURN T{- a[0], - a[1]} END Neg; PROCEDURE Scale(s: LONGREAL; READONLY a: T): T = BEGIN RETURN T{s*a[0], s*a[1]} END Scale; PROCEDURE Weigh(READONLY w: LongRealT; READONLY a: T): T = BEGIN RETURN T{a[0]*w[0], a[1]*w[1]} END Weigh; PROCEDURE Mix(s: LONGREAL; READONLY a: T; t: LONGREAL; READONLY b: T): T = BEGIN RETURN T{s*a[0] + t*b[0], s*a[1] + t*b[1]} END Mix; PROCEDURE Norm(READONLY a: T): LONGREAL = BEGIN RETURN Math.hypot(a[0], a[1]) END Norm; PROCEDURE NormSqr(READONLY a: T): LONGREAL = BEGIN WITH a0 = a[0], a1 = a[1], normSqr = a0*a0 + a1*a1 DO RETURN normSqr END END NormSqr; PROCEDURE Dist(READONLY a, b: T): LONGREAL = BEGIN WITH t0 = a[0] - b[0], t1 = a[1] - b[1], dist = Math.hypot(t0, t1) DO RETURN dist END END Dist; PROCEDURE DistSqr(READONLY a, b: T): LONGREAL = BEGIN WITH t0 = a[0] - b[0], t1 = a[1] - b[1], distSqr = t0*t0 + t1*t1 DO RETURN distSqr END END DistSqr; PROCEDURE Dir(READONLY a: T): T = BEGIN WITH a0 = a[0], a1 = a[1], norm = Math.hypot(a0, a1) DO RETURN T{a0/norm, a1/norm} END END Dir; PROCEDURE LInfNorm(READONLY a: T): LONGREAL = BEGIN WITH norm = MAX(ABS(a[0]), ABS(a[1])) DO RETURN norm END END LInfNorm; PROCEDURE LInfDist(READONLY a, b: T): LONGREAL = BEGIN WITH dist = MAX(ABS(a[0] - b[0]), ABS(a[1] - b[1])) DO RETURN dist END END LInfDist; PROCEDURE LInfDir(READONLY a: T): T = BEGIN WITH norm = MAX(ABS(a[0]), ABS(a[1])) DO RETURN T{a[0]/norm, a[1]/norm} END END LInfDir; PROCEDURE Dot(READONLY a, b: T): LONGREAL = BEGIN WITH a0 = a[0], a1 = a[1], b0 = b[0], b1 = b[1], dot = a0*b0 + a1*b1 DO RETURN dot END END Dot; PROCEDURE Cos(READONLY a, b: T): LONGREAL = BEGIN WITH a0 = a[0], a1 = a[1], b0 = b[0], b1 = b[1], aa = a0*a0 + a1*a1, bb = b0*b0 + b1*b1, ab = a0*b0 + a1*b1, cos = ab/(Math.sqrt(aa)*Math.sqrt(bb)) DO RETURN cos END END Cos; PROCEDURE Sin(READONLY a, b: T): LONGREAL = BEGIN WITH a0 = a[0], a1 = a[1], b0 = b[0], b1 = b[1], aa = a0*a0 + a1*a1, bb = b0*b0 + b1*b1, c = a0*b1 - a1*b0, sin = Math.sqrt((c/aa)*(c/bb)) DO RETURN sin END END Sin; PROCEDURE Det(READONLY a, b: T): LONGREAL = BEGIN WITH a0 = a[0], a1 = a[1], b0 = b[0], b1 = b[1], t = a0*b1 - a1*b0 DO RETURN t END END Det; PROCEDURE Cross(READONLY a: T): T = BEGIN RETURN T{-a[1], +a[0]} END Cross; PROCEDURE Project(READONLY a, u: T): T = BEGIN WITH a0 = a[0], a1 = a[1], u0 = u[0], u1 = u[1], sau = a0*u0 + a1*u1 DO IF sau = 0.0d0 THEN RETURN T{0.0d0, 0.0d0} ELSE WITH suu = u0*u0 + u1*u1, c = sau/suu DO RETURN T{c*u0, c*u1} END END END; END Project; PROCEDURE Orthize(READONLY a, u: T): T = BEGIN WITH u0 = u[0], u1 = u[1], suu = u0*u0 + u1*u1 DO IF suu = 0.0d0 THEN RETURN a ELSE WITH a0 = a[0], a1 = a[1], sau = a0*u0 + a1*u1 DO IF sau = 0.0d0 THEN RETURN a ELSE WITH c = sau/suu DO RETURN T{a0-c*u0, a1-c*u1} END END END END END; END Orthize; PROCEDURE ToReal(READONLY a: T): RealT = BEGIN RETURN RealT{ FLOAT(a[0], REAL), FLOAT(a[1], REAL) } END ToReal; PROCEDURE FromReal(READONLY a: RealT): T = BEGIN RETURN T{ FLOAT(a[0], LONGREAL), FLOAT(a[1], LONGREAL) } END FromReal; PROCEDURE ToLongReal(READONLY a: T): LongRealT = BEGIN RETURN a END ToLongReal; PROCEDURE FromLongReal(READONLY a: LongRealT): T = BEGIN RETURN a END FromLongReal; PROCEDURE URandom(rnd: Random.T; min, max: LONGREAL): T = VAR r: T; BEGIN FOR i := 0 TO N-1 DO r[i] := rnd.longreal(min, max) END; RETURN r END URandom; PROCEDURE NRandom(rnd: Random.T; avg, dev: LONGREAL): T = VAR r: T; BEGIN FOR i := 0 TO N-1 DO r[i] := avg + dev * GaussRandom.LongReal(rnd) END; RETURN r END NRandom; PROCEDURE Print( wr: Wr.T; READONLY a: T; lp := "("; sep := " "; rp := ")"; fmt: PROCEDURE (x: ElemT): TEXT := LR2Rep.DefaultElemFmt; ) RAISES {Wr.Failure, Thread.Alerted} = BEGIN LRN.Print(wr, a, lp, sep, rp, fmt) END Print; PROCEDURE ToText(READONLY a: T): TEXT = BEGIN RETURN LRN.ToText(a) END ToText; BEGIN END LR2.