-- optm2.adb find minimum of an arbitrary function -- no assumption that the function is continuous -- this is reduced version z:=f(x,y) -- given xmin, xmax, ymin, ymax, dxmin, dymin -- and of course f(x,y) with TEXT_IO ; use TEXT_IO ; with GENERIC_DIGITS_TYPES ; procedure OPTM2 is package FLT_IO is new FLOAT_IO(LONG_FLOAT) ; use FLT_IO ; package INT_IO is new INTEGER_IO(INTEGER) ; use INT_IO ; type SIZE_100 is range 0 .. 100 ; package DIGITS_100 is new GENERIC_DIGITS_TYPES(SIZE_100, LONG_FLOAT) ; use DIGITS_100 ; function F(X, Y: D_NUMBER) return D_NUMBER is D10 : D_NUMBER := INTEGER_TO_D_NUMBER(10); D50 : D_NUMBER := INTEGER_TO_D_NUMBER(50); D60 : D_NUMBER := INTEGER_TO_D_NUMBER(60); D70 : D_NUMBER := INTEGER_TO_D_NUMBER(70); D80 : D_NUMBER := INTEGER_TO_D_NUMBER(80); Dfourth : D_NUMBER := INTEGER_TO_D_NUMBER(1) / INTEGER_TO_D_NUMBER(4); begin return Exp(Sin(D50*X))+ Sin(D60*Exp(Y)) +Sin(D70*Sin(X))+ Sin(Sin(D80*Y))-Sin(D10*(X+Y)) +Dfourth*(X*X+Y*Y); end F; function STRING_TO_D_NUMBER(S : string) return D_NUMBER is result : D_NUMBER; last : integer; begin GET(S, result, last); return result; end STRING_TO_D_NUMBER; xmax : D_NUMBER := STRING_TO_D_NUMBER( "-0.244030796943751719036133055699193898194358369381263E-1"); xmin : D_NUMBER := STRING_TO_D_NUMBER( "-0.244030796943751719036133083733373202681760784075469E-1"); ymax : D_NUMBER := STRING_TO_D_NUMBER( "0.210612427155355770591591103322758299678106470385244E0"); ymin : D_NUMBER := STRING_TO_D_NUMBER( "0.210612427155355770591591094208881035390578010456610E0"); dxmin : D_NUMBER := REAL_TO_D_NUMBER( 1.0E-80); dymin : D_NUMBER := REAL_TO_D_NUMBER( 1.0E-80); D2 : D_NUMBER := INTEGER_TO_D_NUMBER(2); dx : D_NUMBER ; dy : D_NUMBER ; x, y, zxy : D_NUMBER ; xm, zxmy, zxmym : D_NUMBER ; xp, zxpy, zxmyp : D_NUMBER ; ym, zxym, zxpym : D_NUMBER ; yp, zxyp, zxpyp : D_NUMBER ; hxm, zhxmym, zhxmy, zhxmyp : D_NUMBER ; hxp, zhxpym, zhxpy, zhxpyp : D_NUMBER ; hym, zxmhym, zxhym, zxphym : D_NUMBER ; hyp, zxmhyp, zxhyp, zxphyp : D_NUMBER ; xbest, ybest, zbest : D_NUMBER ; xhbox, yhbox : D_NUMBER ; improve : integer :=1; iterations : integer := 400; begin PUT("optm2 xmin="); PUT(xmin); NEW_LINE; PUT(" xmax="); PUT(xmax); NEW_LINE; PUT(" ymin="); PUT(ymin); NEW_LINE; PUT(" ymax="); PUT(ymax); NEW_LINE; PUT(" dxmin="); PUT(dxmin); NEW_LINE; PUT(" dymin="); PUT(dymin); NEW_LINE; PUT(" iterations="); PUT(iterations); NEW_LINE; PUT(" digits="); PUT("SIZE_100"); NEW_LINE; dx:=dxmin; dy:=dymin; x:=(xmin+xmax)/D2; y:=(ymin+ymax)/D2; -- initial consistency test if Xmax <= xmin then PUT("xmax<=xmin error"); return; end if; if Ymax <= ymin then PUT("ymax<=ymin error"); return; end if; zxy:=f(x,y); PUT("f(x,y) z="); PUT(zxy); NEW_LINE; PUT(" x="); PUT(x); NEW_LINE; PUT(" y="); PUT(y); NEW_LINE; zbest:=zxy; xbest:=x; ybest:=y; for I in 0..iterations loop -- new zxy,x,y new xmin,ymin from below if improve=0 then PUT("no improvement"); exit; end if; improve:=0; NEW_LINE; xhbox:=(xmax-xmin)/D2; if xhbox