-- 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_250 is range 0 .. 250 ; package DIGITS_250 is new GENERIC_DIGITS_TYPES(SIZE_250, LONG_FLOAT) ; use DIGITS_250 ; 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.244030796943751719036133083296928859043961818589757489609547235429391549376250999868761160466444995901232150575796389461276440307076229632610017256161122248129532246843635556104046709974423163114476698E-1"); xmin : D_NUMBER := STRING_TO_D_NUMBER( "-0.244030796943751719036133083296928859043961818589757489609547235429391549376250999868761160466444995921131644245759342001254814710493477358891924491678464731254922680554419497356191921807048229086600018E-1"); ymax : D_NUMBER := STRING_TO_D_NUMBER( "0.210612427155355770591591100554525535269137074219829175501945407721998784780784006530259049686452987453555827594718481405903456154914223600022996199730301827181509836978266122006605741891145088952891238E0"); ymin : D_NUMBER := STRING_TO_D_NUMBER( "0.210612427155355770591591100554525535269137074219829175501945407721998784780784006530259049686452987452292505638072533958882637600630474025612643425784601093002172627088405341546389515031920188134052516E0"); dxmin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-220"); dymin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-220"); 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 := 800; 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_250"); 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 on iteration "); PUT(I); NEW_LINE; exit; end if; improve:=0; NEW_LINE; xhbox:=(xmax-xmin)/D2; if xhbox