-- 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_200 is range 0 .. 200 ; package DIGITS_200 is new GENERIC_DIGITS_TYPES(SIZE_200, LONG_FLOAT) ; use DIGITS_200 ; 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.2440307969437517190361330832969288590439618185897574896095472354293915493762458308157057534373471606370787625457616131057950686579815983834035247981918E-1"); xmin : D_NUMBER := STRING_TO_D_NUMBER( "-0.2440307969437517190361330832969288590439618185897574896095472354293915493764423393205333646106499987430152211496990717007935041470297184693319471669732E-1"); ymax : D_NUMBER := STRING_TO_D_NUMBER( "0.2106124271553557705915911005545255352691370742198291755019454077219987847808472589748507161500434143669280738167008673322492283077752291277306016771177E0"); ymin : D_NUMBER := STRING_TO_D_NUMBER( "0.2106124271553557705915911005545255352691370742198291755019454077219987847807734142493087722605239575399285624608222956901124273488589778494768128971883E0"); dxmin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-180"); dymin : D_NUMBER := STRING_TO_D_NUMBER("1.0E-180"); 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_200"); 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