Last active
December 2, 2019 01:57
-
-
Save oxinabox/33f862cd5a89c6107432a0179e22ee6f to your computer and use it in GitHub Desktop.
A Particle Swarm Opotimizer in DexLang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:p optimize 42 rosenbrock2 ([-3.0, -3.0],[3.0, 3.0]) (0.4,0.3,0.3) | |
Compiler bug!Not an int: newPbests_2.v_15 | |
context: | |
v_3::Real[2]{ | |
v_3[0] := %copy -3.0 | |
v_3[1] := %copy -3.0 | |
v_4::Real[2]{ | |
v_4[0] := %copy 3.0 | |
v_4[1] := %copy 3.0 | |
v_1::Int[]{ | |
v_1[] := %%threefry2x32 42 0 | |
v_5::Int[]{ | |
v_5[] := %%threefry2x32 42 1 | |
v_6::Int[]{ | |
v_6[] := %%threefry2x32 v_5 0 | |
v_7::Int[]{ | |
v_7[] := %%threefry2x32 v_5 1 | |
initPositions::Real[10, 2]{ | |
for p < 10 | |
v_2::Int[]{ | |
v_2[] := %copy p | |
v_8::Int[]{ | |
v_8[] := %%threefry2x32 v_1 v_2 | |
for i < 2 | |
v_9::Int[]{ | |
v_9[] := %copy i | |
v_10::Int[]{ | |
v_10[] := %%threefry2x32 v_8 v_9 | |
v_11::Real[]{ | |
v_11[] := %%randunif v_10 | |
v_12::Real[]{ | |
v_12[] := %fsub v_4.i v_3.i | |
v_13::Real[]{ | |
v_13[] := %fmul v_11 v_12 | |
initPositions[p, i] := %fadd v_3.i v_13}}}}}}} | |
initVelocities::Real[10, 2]{ | |
for p < 10 | |
v_2::Int[]{ | |
v_2[] := %copy p | |
v_8::Int[]{ | |
v_8[] := %%threefry2x32 v_6 v_2 | |
for i < 2 | |
v_9::Int[]{ | |
v_9[] := %copy i | |
v_10::Int[]{ | |
v_10[] := %%threefry2x32 v_8 v_9 | |
v_11::Real[]{ | |
v_11[] := %%randunif v_10 | |
v_12::Real[]{ | |
v_12[] := %fsub v_4.i v_3.i | |
v_13::Real[]{ | |
v_13[] := %fmul v_11 v_12 | |
initVelocities[p, i] := %fadd v_3.i v_13}}}}}}} | |
initPs::Real[10]{ | |
for p < 10 | |
v_8::Int[]{ | |
v_8[] := %copy 0 | |
v_2::Int[]{ | |
v_2[] := %copy 1 | |
v::Real[]{ | |
v[] := %fsub 1.0 initPositions.p.v_8 | |
v_9::Real[]{ | |
v_9[] := %fmul v v | |
v_10::Real[]{ | |
v_10[] := %fmul initPositions.p.v_8 initPositions.p.v_8 | |
v_11::Real[]{ | |
v_11[] := %fsub initPositions.p.v_2 v_10 | |
v_12::Real[]{ | |
v_12[] := %fmul v_11 v_11 | |
v_13::Real[]{ | |
v_13[] := %fmul 100.0 v_12 | |
v_14::Real[]{ | |
v_14[] := %fadd v_9 v_13 | |
initPs[p] := %copy v_14}}}}}}}}} | |
v_2::Int[]{ | |
v_2[] := %copy 0 | |
v_8::Real[]{ | |
v_9::Real[2]{ | |
v_8[] := %copy initPs.v_2 | |
v_9[] := %copy initPositions.v_2 | |
for i < 10 | |
v_10::Real[2]{ | |
v_11::Real[2, 2]{ | |
v_10[0] := %copy initPs.i | |
v_11[0] := %copy initPositions.i | |
v_10[1] := %copy v_8 | |
v_11[1] := %copy v_9 | |
v_12::Bool[]{ | |
v_12[] := %flt initPs.i v_8 | |
v_13::Int[]{ | |
v_13[] := %booltoint v_12 | |
v_14::Int[]{ | |
v_14[] := %copy v_13 | |
v_8[] := %copy v_10.v_14 | |
v_9[] := %copy v_11.v_14}}}}} | |
v_10::Int[]{ | |
v_10[] := %%threefry2x32 v_7 0 | |
v_11::Int[]{ | |
v_11[] := %%threefry2x32 v_7 1 | |
v_12::Int[]{ | |
v_12[] := %%threefry2x32 v_11 0 | |
v_13::Int[]{ | |
v_13[] := %%threefry2x32 v_11 1 | |
v::Real[]{ | |
v[] := %%randunif v_10 | |
gWeight::Real[]{ | |
gWeight[] := %fmul 0.3 v | |
v_14::Real[]{ | |
v_14[] := %%randunif v_12 | |
pWeight::Real[]{ | |
pWeight[] := %fmul 0.3 v_14 | |
gDirs::Real[10, 2]{ | |
for p < 10 | |
for i < 2 | |
gDirs[p, i] := %fsub v_9.i initPositions.p.i | |
pDirs::Real[10, 2]{ | |
for p < 10 | |
for i < 2 | |
pDirs[p, i] := %fsub initPositions.p.i initPositions.p.i | |
newVelocities::Real[10, 2]{ | |
for p < 10 | |
for i < 2 | |
v_15::Real[]{ | |
v_15[] := %fmul 0.4 initVelocities.p.i | |
v_16::Real[]{ | |
v_16[] := %fmul gWeight gDirs.p.i | |
v_17::Real[]{ | |
v_17[] := %fadd v_15 v_16 | |
v_18::Real[]{ | |
v_18[] := %fmul pWeight gDirs.p.i | |
newVelocities[p, i] := %fadd v_17 v_18}}}} | |
newPositions::Real[10, 2]{ | |
for p < 10 | |
for i < 2 | |
newPositions[p, i] := %fadd initPositions.p.i initVelocities.p.i | |
newPbests::Real[10, 2]{ | |
newPbests_1::Real[10, 2, 2]{ | |
newPbests_2::Int[10]{ | |
for p < 10 | |
v_15::Int[]{ | |
v_15[] := %copy 0 | |
v_16::Int[]{ | |
v_16[] := %copy 1 | |
v_17::Real[]{ | |
v_17[] := %fsub 1.0 newPositions.p.v_15 | |
v_18::Real[]{ | |
v_18[] := %fmul v_17 v_17 | |
v_19::Real[]{ | |
v_19[] := %fmul newPositions.p.v_15 newPositions.p.v_15 | |
v_20::Real[]{ | |
v_20[] := %fsub newPositions.p.v_16 v_19 | |
v_21::Real[]{ | |
v_21[] := %fmul v_20 v_20 | |
v_22::Real[]{ | |
v_22[] := %fmul 100.0 v_21 | |
v_23::Real[]{ | |
v_23[] := %fadd v_18 v_22 | |
v_24::Real[2]{ | |
v_25::Real[2, 2]{ | |
v_24[0] := %copy initPs.p | |
v_25[0] := %copy initPositions.p | |
v_24[1] := %copy v_23 | |
v_25[1] := %copy newPositions.p | |
v_26::Bool[]{ | |
v_26[] := %flt initPs.p v_23 | |
v_27::Int[]{ | |
v_27[] := %booltoint v_26 | |
v_28::Int[]{ | |
v_28[] := %copy v_27 | |
newPbests[p] := %copy v_24 | |
newPbests_1[p] := %copy v_25 | |
newPbests_2[p] := %copy v_28}}}}}}}}}}}}}} | |
v_15::Int[]{ | |
v_15[] := %copy 0 | |
v_16::Real[]{ | |
v_17::Real[2]{ | |
v_16[] := %copy newPbests.v_15.newPbests_2.v_15 | |
v_17[] := %copy newPbests_1.v_15.newPbests_2.v_15 | |
for i < 10 | |
v_18::Real[2]{ | |
v_19::Real[2, 2]{ | |
v_18[0] := %copy newPbests.i.newPbests_2.i | |
v_19[0] := %copy newPbests_1.i.newPbests_2.i | |
v_18[1] := %copy v_16 | |
v_19[1] := %copy v_17 | |
v_20::Bool[]{ | |
v_20[] := %flt newPbests.i.newPbests_2.i v_16 | |
v_21::Int[]{ | |
v_21[] := %booltoint v_20 | |
v_22::Int[]{ | |
v_22[] := %copy v_21 | |
v_16[] := %copy v_18.v_22 | |
v_17[] := %copy v_19.v_22}}}}} | |
v_18::Real[2]{ | |
v_19::Real[2, 2]{ | |
v_18[0] := %copy v_8 | |
v_19[0] := %copy v_9 | |
v_18[1] := %copy v_16 | |
v_19[1] := %copy v_17 | |
v_20::Bool[]{ | |
v_20[] := %flt v_8 v_16 | |
v_21::Int[]{ | |
v_21[] := %booltoint v_20 | |
v_22::Int[]{ | |
v_22[] := %copy v_21 | |
%imptmp[] := %copy v_19.v_22}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' # Particle Swarm Optimizer | |
' ## Fitness function | |
rosenbrock:: Real -> Real -> Real | |
rosenbrock x y = sq (1.0 - x) + 100.0*sq (y - x*x) | |
' We write one that uses vector for input | |
rosenbrock2:: (2=>Real) -> Real | |
rosenbrock2 xs = | |
x = xs.(asidx 0) | |
y = xs.(asidx 1) | |
rosenbrock x y | |
' Min should be at 1.0, 1.0 | |
:p rosenbrock 1.0 1.000 | |
:p rosenbrock2 [1.0, 1.000] | |
:p rosenbrock 1.0 1.02 | |
:p rosenbrock2 [1.0, 1.02] | |
:plotmat for i. for j. rosenbrock xs.i ys.j | |
' ## Helper functions | |
' make a random vector unifornly distrubuted between lb and ub | |
randBounded:: Key -> (d=>Real)->(d=>Real)->(d=>Real) | |
randBounded key lb ub = | |
for i. lb.i + ((rand $ ixkey key i) * (ub.i - lb.i)) | |
randBounded 1 x y | |
' minby and minimumby | |
' to find the smallest values | |
minby:: (a->Real)->a->a->a | |
minby f x y = [x,y].(asidx $ b2i $ (f x) > (f y)) | |
minby sq -1.0 0.5 | |
minby fst (0.7, 10.0) (3.0, 12.0) | |
minimumby:: (q->Real)->(p=>q)->q | |
minimumby f xs = fold xs.(asidx 0) (for i. minby f xs.i) | |
minimumby sq [-1.0, -0.1, 2.0, 3.0] | |
' ## The Optimizer itself. | |
### TODO: | |
- Replace `res = optStep inits` with `res = fold inits (for iter::20. optStep)` | |
- workout how to pass nparticles and niters in as a variable | |
- Currrently hardcoded as 10 and 20 respectively | |
- workout more compact wa to define type sig | |
optimize:: Key->((d=>Real)->Real) -> (d=>Real,d=>Real) -> (Real,Real,Real) -> (d=>Real) | |
optimize key f (lb,ub) (momentum,gRate,pRate) = | |
optStep (keyL, gbest, pbests,positions,velocities) = | |
(keyG, keyP, keyNext) = splitKey3 keyL | |
gWeight::Real = gRate * rand keyG | |
pWeight::Real = pRate * rand keyP | |
(gscore, gloc) = gbest | |
plocs = map snd pbests | |
gDirs::(10=>d=>Real) = for p i. gloc.i - positions.p.i | |
pDirs::(10=>d=>Real) = for p i. plocs.p.i - positions.p.i | |
newVelocities::(10=>d=>Real) = for p i. momentum*velocities.p.i + gWeight*gDirs.p.i + pWeight*gDirs.p.i | |
newPositions::(10=>d=>Real) = for p i. positions.p.i + velocities.p.i | |
newPbests::(10=>(Real, d=>Real)) = for p. minby fst pbests.p (f newPositions.p, newPositions.p) | |
newGbest::(Real, d=>Real) = minby fst gbest (minimumby fst newPbests) | |
(keyNext,newGbest,newPbests,newPositions,newVelocities) | |
randInit1 keyI1 = randBounded keyI1 lb ub | |
randInit keyI = for p::10. randInit1 $ ixkey keyI p | |
(keyPos, keyVel, keyLoop) = splitKey3 key | |
initPositions::(10=>d=>Real) = randInit keyPos | |
initVelocities::(10=>d=>Real) = randInit keyVel | |
initPs::(10=>(Real, d=>Real)) = for p. (f initPositions.p, initPositions.p) | |
initG::(Real, d=>Real) = minimumby fst initPs | |
inits = (keyLoop,initG,initPs,initPositions,initVelocities) | |
res = optStep inits | |
(dc0,(finalGscore, finalGloc),dc1,dc2,dc3) = res | |
finalGloc | |
:p optimize 42 rosenbrock2 ([-3.0, -3.0],[3.0, 3.0]) (0.4,0.3,0.3) | |
' --- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment