Particle swarm optimization: Difference between revisions

m
→‎{{header|REXX}}: added/changed whitespace and comments, added a comment to the REXX section header.
m (→‎{{header|REXX}}: added/changed whitespace and comments, added a comment to the REXX section header.)
Line 416:
Classic REXX doesn't have a   '''sine'''   function, so a RYO version is included here.
 
The numeric precision is only limited to the number of decimal digits defined in the &nbsp; <big> '''pi''' </big> &nbsp; variable &nbsp; (in this case, &nbsp; '''100''').
 
This REXX version supports the specifying of &nbsp; '''X''', &nbsp; '''Y''', &nbsp; and &nbsp; '''D''', &nbsp; as well as the number of particles, &nbsp; and the number of decimal digits to be displayed.
 
The refinement loop is stopped when the function value stabilizes.
 
<lang rexx>/*REXX pgm calc. Particle Swarm Optimization as it migrates through a solution*/
Note that REXX used decimal floating point, not binary.
numeric digits length(pi()) /*sDigs: is the # of displayed digits.*/
<lang rexx>/*REXX pgmprogram calc.calculates Particle Swarm Optimization as it migrates through a solution.*/
parse arg x y d #part sDigs . /*obtain optional arguments from the CL*/
ifnumeric x==''digits length(pi()) | x==',' then x= -0.5 /*is /*sDigs: is the X# of displayed not defined?digits.*/
if y=='' parse arg |x y==',' d #part sDigs then y= -1.5 /* " Y " /*obtain "optional arguments from the CL*/
if dx=='' | dx==',' then dx= -0.5 1 /*Not " D " specified? " Then use the default.*/
if #party=='' | #party==',' then #part y=1e12 -1.5 /* " the # particles " " " " " */
if sDigsd=='' | sDigsd==',' then sDigs d= 251 /* " the # of digits " " " " " */
minF=if #part;=='' | #part==',' oldthen #part=1e12 /* " " /*number of particles is" " " " one billion. */
if sDigs=='' | sDigs==',' then sDigs= 25 /* " " " " " " */
say center('X',sDigs+3,'═') center('Y',sDigs+3,'═') center('D',sDigs+3,'═')
minF=#part; old= /*number of particles is one billion. */
say center('X', sDigs+3, '═') center('Y', sDigs+3, '═') center('D', sDigs+3, '═')
call refine x,y
do until refine(minX,minY); d=d*.2 /*increase the difference.*/
end /*until ···*/ /* [↑] stop refining if no difference.*/
say
indent=1 + (sDigs+3) * 2 /*compute the indentation for alignment*/
say right('The global minimum for f(-.54719, -1.54719) ───► ', indent) fmt(f(-.54719, -1.54719))
say right('The published global minimum is:' , indent) fmt( -1.9133 )
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*────────────────────────────────────────────────────────────────────────────*/
refine: parse arg xx,yy; h=d * .5
do x=xx-d to xx+d by h
do y=yy-d to yy+d by h; f=f(x,y); if f>=minF then iterate
new=fmt(x) fmt(y) fmt(f); if new=old then return 1
say new; minF=f; minX=x; minY=y; old=new
end /*y*/
end /*x*/
return 0
/*──────────────────────────────────────────────────────────────────────────────────one─liner subroutines───────────────────────────────*/
f: procedure: parse arg a,b; return sin(a+b) + (a-b)**2 - 1.5*a + 2.5*b + 1
fmt: parse arg ?; ?=format(?,,sDigs); L=length(?); if pos(.,?)\==0 then ?=strip(strip(?,'T',0),'T',.); return left(?,L)
pi: pi=3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068; return pi
r2r: return arg(1) // (pi()*2) /*normalize radians ───► a unit circle.*/
sin: procedure; parse arg x; x=r2r(x); numeric fuzz 5; z=x; _=x; q=x*x; do k=2 by 2 until p=z; p=z; _=-_*q/(k*(k+1)); z=z+_; end; return z</lang>
'''output''' &nbsp; when using the default inputs: