-- 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_150 is range 0 .. 150 ; package DIGITS_150 is new GENERIC_DIGITS_TYPES(SIZE_150, LONG_FLOAT) ; use DIGITS_150 ; 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.24403079694375171903613308329692885904396181858975692838229330481944670677953599653515904788738368880E-1"); xmin : D_NUMBER := STRING_TO_D_NUMBER( "-0.24403079694375171903613308329692885904396181858975925964936504493186818001627673339198307814709455916E-1"); ymax : D_NUMBER := STRING_TO_D_NUMBER( "0.21061242715535577059159110055452553526913707421982988806251272633819131278260506960638227821022321260E0"); ymin : D_NUMBER := STRING_TO_D_NUMBER( "0.21061242715535577059159110055452553526913707421982902380130554425950953300496744249973133080419411640E0"); dxmin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-120"); dymin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-120"); 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 := 600; 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_150"); 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