Minimize: Commander.CommandProc ~ {
t0A, t1A, v0A, v1A, vrefA, maxslopeA, alphaA, slopefacA, accelfacA, certainfacA, epsilonA: Args.Arg;
[t0A, t1A, v0A, v1A, vrefA, maxslopeA, alphaA, slopefacA, accelfacA, certainfacA, epsilonA] ¬ Args.ArgsGet[cmd, "-t%rr-v%rr-vref%r-maxslope%r-alpha%r-slopefac%r-accelfac%r-certainfac%r-epsilon%r" ! Args.Error => {msg ¬ reason; GOTO ArgsErr}];
{
NewControl:
PROC [name:
ROPE, min, max:
REAL, arg: Args.Arg, default:
REAL]
RETURNS [Control]
~ {
RETURN[Controls.NewControl[
name: name,
type: hSlider,
clientData: m, -- backpointer from each control to top level
min: min,
max: max,
init: IF arg.ok THEN arg.real ELSE default,
proc: UpdateControl]];
};
Package all the parameters needed to control minimization algorithm.
m: MinimizeInfo ¬ NEW[MinimizeInfoRec];
m ¬ [
t0: NewControl["t0", -1500., 1500., t0A, 0.],
t1: NewControl["t1", -1500., 1500., t1A, 360.],
v0: NewControl["v0", -5., -1., v0A, -2.],
v1: NewControl["v1", 1., 5., v1A, 1.],
vref: NewControl["vref", -1., 1., vrefA, 0.],
func: TestFunc,
logslope: NewControl["maxslope", -10., 10., maxslopeA, RealFns.Log[10., 3.1416/180.]],
alpha: NewControl["alpha", 0., 1., alphaA, .35],
slopefac: NewControl["slopefac", 0., 2., slopefacA, .5],
certainfac: NewControl["certainfac", 0., 2., certainfacA, 1.],
logeps: NewControl["epsilon", -10., 0., epsilonA, -4.]
];
Create a viewer drawn by RedrawGraph[] when viewer is created or a control is tweaked.
[] ¬ Controls.OuterViewer[
name: "Minimize",
graphicsHeight: 400,
drawProc: RedrawGraph,
typescriptHeight: 18,
clientData: m,
controls:
LIST[m.t0, m.t1, m.v0, m.v1, m.logslope, m.alpha, m.slopefac, m.certainfac, m.logeps]
];
};
EXITS ArgsErr => RETURN[$Failure, msg];
};
RedrawGraph: Controls.DrawProc ~ {
Redraw the graph viewer, called by Viewer.
UserToScreenX: PROC [x: REAL] RETURNS [i: INT16] ~ {i ¬ Real.Round[sx0+mx*(x-ux0)]};
UserToScreenY: PROC [y: REAL] RETURNS [i: INT16] ~ {i ¬ Real.Round[sy0+my*(y-uy0)]};
ScreenToUserX: PROC [sx: INTEGER] RETURNS [REAL] ~ {RETURN[ux0+(sx-sx0)/mx]};
ScreenToUserY: PROC [sy: INTEGER] RETURNS [REAL] ~ {RETURN[uy0+(sy-sy0)/my]};
Line: G3dFunction.LineProc ~ {
sx0: INTEGER ¬ UserToScreenX[x0];
sy0: INTEGER ¬ UserToScreenY[y0];
sx1: INTEGER ¬ UserToScreenX[x1];
sy1: INTEGER ¬ UserToScreenY[y1];
Imager.MaskRectangle[context, [sx0, sy0, sx1-sx0+1, sy1-sy0+1]];
Imager.MaskRectangle[context, [sx0-1, sy0-1, 3, 3]];
Imager.MaskRectangle[context, [sx1-1, sy1-1, 3, 3]];
};
m: MinimizeInfo ~ NARROW[clientData];
ux0: REAL ¬ m.t0.value;
ux1: REAL ¬ m.t1.value;
uy0: REAL ¬ m.v0.value;
uy1: REAL ¬ m.v1.value;
uyref: REAL ¬ m.vref.value;
sx0: INTEGER ¬ 32; -- screen left margin
sy0: INTEGER ¬ 17; -- screen bottom margin
sx1: INTEGER ¬ viewer.cw-sx0;
sy1: INTEGER ¬ viewer.ch-sy0;
mx: REAL ¬ (sx1-sx0)/(ux1-ux0);
my: REAL ¬ (sy1-sy0)/(uy1-uy0);
dx: REAL ¬ (ux1-ux0)/RealFns.Power[2.0, Real.Floor[RealFns.Log[2.0, (sx1-sx0)/40.0]]];
dy: REAL ¬ (uy1-uy0)/Real.Floor[(sy1-sy0)/30.];
tick: INTEGER ~ 5;
Imager.MaskRectangle[context, [sx0, UserToScreenY[uyref], sx1-sx0+1, 1]]; -- ref. line
Imager.MaskRectangle[context, [sx0, sy0, sx1-sx0+1, 1]]; -- line along bottom
Imager.MaskRectangle[context, [sx0, sy1, sx1-sx0+1, 1]]; -- line along top
Imager.MaskRectangle[context, [sx0, sy0, 1, sy1-sy0+1]]; -- line along left
Imager.MaskRectangle[context, [sx1, sy0, 1, sy1-sy0+1]]; -- line along right
FOR y:
REAL ¬ uy0, y+dy
WHILE y < uy1+.5*dy
DO
-- left edge ticks
sy: INTEGER ~ UserToScreenY[y];
Imager.MaskRectangle[context, [sx0-tick, sy, tick, 1]];
Draw2d.Label[context, [3, sy], IO.PutFR1["%3.2f", IO.real[y]]];
ENDLOOP;
FOR x:
REAL ¬ ux0, x+dx
WHILE x < ux1+.5*dx
DO
-- bottom edge ticks
sx: INTEGER ~ UserToScreenX[x];
Imager.MaskRectangle[context, [sx, sy0-tick, 1, tick]];
Draw2d.Label[context, [sx-sx0/2, 3], IO.PutFR1["%5.1f", IO.real[x]]];
ENDLOOP;
FOR sx:
INTEGER
IN [sx0..sx1]
DO
y: REAL ~ m.func[ScreenToUserX[sx]];
Imager.MaskRectangle[context, [sx, UserToScreenY[y], 1, 1]];
ENDLOOP;
[] ¬ G3dFunction.MinimizeFunction[
function: m.func,
t0: m.t0.value,
t1: m.t1.value,
logSlope: m.logslope.value,
alpha: m.alpha.value,
slopeFac: m.slopefac.value,
certainFac: m.certainfac.value,
logEps: m.logeps.value,
lineProc: Line,
report: NARROW[viewer.parent.data, Controls.OuterData].typescript.out];
};