Last active
February 4, 2019 16:44
-
-
Save asinghvi17/2d192f7379c6abb1f5536be4f8f457b5 to your computer and use it in GitHub Desktop.
Julia interactive gradient ascent on a contour map (2D or 3D), can be changed to a heatmap (which is nice) or a surface (which has some bugs).
This file contains 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
##setup | |
# using Pkg | |
# pkg"add Makie ForwardDiff" | |
## begin program | |
using Makie, | |
ForwardDiff | |
# using MakieThemes | |
using AbstractPlotting: textslider | |
# AbstractPlotting.set_theme!(ggthemr(:flat_dark)) | |
f(x::Real, y::Real) = 2/(x^2 - 4*x + y^2 + 5) + 3/(x^2 - 4*y + y^2 + 6) | |
f(x::Array{T, 1} where T <: Real) = f(x[1], x[2]) | |
∇f(x::Real, y::Real) = ForwardDiff.gradient(f, [x, y]) | |
∇f(x::Array{Float64, 1}) = ForwardDiff.gradient(f, x) | |
xa = LinRange(-5, 5, 500) | |
ya = LinRange(-5, 5, 500) | |
za = [f(x, y) for x ∈ xa, y ∈ ya] | |
# ∇za = [∇f(x, y) for x ∈ xa, y ∈ ya] | |
# different plots you can see of f and grad f | |
# remove semicolon to display | |
fsurf = surface(xa, ya, za, shading = false); | |
# ∇fsurf = surface(xa, ya, ∇za, shading = false); | |
fcont = contour(xa, ya, za, levels = 20, linewidth = 3); | |
# ∇fcont = contour(xa, ya, ∇za, levels = 20, linewidth = 3); | |
fheat = heatmap(xa, ya, za); | |
# ∇fheat = heatmap(xa, ya, ∇za); | |
fcont3 = contour3d(xa, ya, za, levels = 20, linewidth = 3); | |
# ∇fcont3 = contour3d(xa, ya, ∇za, levels = 20, linewidth = 3); | |
p = fcont3; | |
function ascend( | |
Δ::Real, | |
x0::Real, | |
y0::Real; | |
numsteps = 10 | |
)::Array{Float64, 2} | |
coords = zeros(numsteps, 2) | |
coords[1, 1] = x0 | |
coords[1, 2] = y0 | |
for i ∈ 2:numsteps | |
coords[i, :] = coords[i-1, :] + Δ*∇f(coords[i-1, :]) | |
end | |
coords | |
end | |
p # show the plot | |
# setup slider | |
sd, delta = textslider(0.01:0.01:4, "Δ", start = 0.1) | |
x0 = Node(0f0) | |
y0 = Node(0f0) | |
coords = Makie.lift(ascend, delta, x0, y0) | |
xs = lift(x -> x[:, 1], coords) | |
ys = lift(x -> x[:, 2], coords) | |
# lines!(p, xs, ys, color = :black, linewidth = 10) # for two dimensional plots | |
zs = lift((x, y) -> f.(x, y), xs, ys) # for three dimensional plots | |
lines!(p, xs, ys, zs, color = :black, linewidth = 10) | |
parenta = hbox(vbox(sd), p) | |
# setup mouse interactiomn, kind of works but it's buggy. | |
# on(parenta.events.mousebuttons) do buttons | |
# if ispressed(parenta, Mouse.left) | |
# pos = to_world(parenta, Point2f0(parenta.events.mouseposition[])) | |
# push!(x0, pos[1]) | |
# push!(y0, pos[2]) | |
# end | |
# return | |
# end | |
parenta |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment