-- PiecewiseCubicImpl.mesa -- Michael Plass 15-Dec-81 8:38:56 DIRECTORY PiecewiseCubic; PiecewiseCubicImpl: PROGRAM EXPORTS PiecewiseCubic = BEGIN Handle: TYPE = PiecewiseCubic.Handle; PieceRec: TYPE = PiecewiseCubic.PieceRec; Zero: PUBLIC PROCEDURE RETURNS [Handle] = {RETURN [NIL]}; Piece: PUBLIC PROCEDURE [domainStart, domainEnd: REAL, initValue, initSlope, finalSlope, finalValue: REAL] RETURNS [Handle] = BEGIN IF domainStart=f.first.domainEnd THEN RETURN [f] ELSE BEGIN OPEN f.first; jointValue,jointSlope: REAL; [value:jointValue, deriv:jointSlope] _ EvalAll[f,d]; RETURN [CONS[[domainStart:domainStart, domainEnd:d, initValue:initValue, initSlope:initSlope, finalSlope:jointSlope, finalValue:jointValue], CONS[[domainStart:d, domainEnd:domainEnd, initValue:jointValue, initSlope:jointSlope, finalSlope:finalSlope, finalValue:finalValue],f.rest]]] END END; CombinePieces: PROCEDURE [a: REAL, p: PieceRec, b: REAL, q: PieceRec] RETURNS [PieceRec] = BEGIN -- p and q should have the same domain RETURN [[domainStart:p.domainStart, domainEnd:p.domainEnd, initValue:a*p.initValue+b*q.initValue, initSlope:a*p.initSlope+b*q.initSlope, finalSlope:a*p.finalSlope+b*q.finalSlope, finalValue:a*p.finalValue+b*q.finalValue]] END; Scale: PUBLIC PROCEDURE [f: Handle, a: REAL] RETURNS [Handle] = BEGIN IF a=0 OR f=NIL THEN RETURN [NIL] ELSE IF a=1 THEN RETURN [f] ELSE RETURN [CONS[ScalePiece[f.first,a],Scale[f.rest,a]]] END; EnumerateCommonPieces: PUBLIC PROCEDURE [f: Handle, g: Handle, P: PiecewiseCubic.PieceProc] = BEGIN WHILE f#NIL OR g#NIL DO WHILE f#NIL AND (g=NIL OR f.first.domainStartf.first.domainStart THEN RETURN[Combine[b,g,a,f]] ELSE IF g.first.domainStart=f.first.domainStart THEN BEGIN IF g.first.domainEnd=f.first.domainEnd THEN RETURN[CONS[CombinePieces[a,f.first,b,g.first], Combine[a,f.rest,b,g.rest]]] ELSE IF g.first.domainEndf.first.domainEnd DO f _ f.rest ENDLOOP; IF f=NIL OR tf.first.domainEnd DO f _ f.rest ENDLOOP; IF f=NIL OR t