Particle swarm optimization: Difference between revisions

m
→‎{{header|REXX}}: shortened some statements, optimized a function, added/changed comments and whitespace.
m (→‎{{header|REXX}}: shortened some statements, optimized a function, added/changed comments and whitespace.)
Line 977:
=={{header|REXX}}==
{{trans|ooRexx}}
This REXX version uses a large   ''numeric digits''   (the number of decimal digits in pi),   but only displays '''25''' digits).
 
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; '''118110''').
 
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 calculation of the function value stabilizes.
 
Note that REXX useduses decimal floating point, not binary.
<lang rexx>/*REXX program calculates Particle Swarm Optimization as it migrates through a solution.*/
numeric digits length( pi() ) - 1 - 1 /*sDigs: is the # of displayed digits.*/
parse arg x y d #part sDigs . . /*obtain optional arguments from the CL*/
if x=='' | | x=="," then x= -0.5 /*Not specified? Then use the default.*/
if y=='' | | y=="," then y= -1.5 /* " " " " " " */
if d=='' | | d=="," then d= 1 /* " " " " " " */
if #part=='' | #part=="," then #part=1e12 1e12 /* " " " " " " */
if sDigs=='' | sDigs=="," then sDigs= 25 25 /* " " " " " " */
minF=#part; old= old= /*number of particles is one billion. */
say center('X', sDigs+3, "═") center('Y', sDigs+3, "═") center('D', sDigs+3, "═")
call refine x,y /* [↓] same as ÷ by five.*/
call refine x,y
do until refine(minX, minY); d=d * .2 /*increasedecrease 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 /*compute ½ distance.*/
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(?arg(1), , sDigs); L=length(?); if pos(., ?)\==0 then ?=strip( strip(?, 'T', 0), "T", .); return left(?, L)
pi: pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865; return pi
pi: pi=3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282307; return pi
r2r: return arg(1) // ( pi() * 2) /*normalize radians ───► a unit circle.*/
sin: procedure; parse arg x; x=r2r(x arg(1); numeric fuzz 5); z=x; _=x; q=x*x; do k=2 by 2 until p=z; p=z; _ x= -_x*q/ (k*(k+1)); z= z+_x; end; return z</lang>
'''{{out|output''' |text=&nbsp; when using the default inputsinput:}}
<pre>
═════════════X══════════════ ═════════════Y══════════════ ═════════════D══════════════