I’m looking at how to plot Newton’s method. I was going to add x values of each itteration, with y=0 to a DataFrame, then run a scatter plot. Is this what I should do, or is there a better way to go about this?
Probably you just need a vector of data. A DataFrame is a unnecessary complication.
You could also plot the tangents, like eg this:
Plotting \log(\| F(x_n) \|) vs n should tell you what you want to know. Semilog plots are the standard way to do this so you can see what is happening in the terminal phase of the iteration.
If you have a scalar equation and want to plot f(x_n) vs x_n, a semilog plot is still the way to go. If you want to plot x_n vs n, a scatter plot makes sense. You can plot your results with the graph of f(x) as an overlay. This is not as fancy was the moving graph that @Tamas_Papp points to, but is easy to do.
As @leandromartinez98 says, a DataFrame is overkill for this.
That’s what I wanted, I’ll go over how to do this. I always forget the formula for a tangent.
then I can’t remember how to find b.
That’s interesting. I’m not familiar with semilog plots, and I’m learning linear algebra, so I’m not sure how to write that as code.
As for data frames, I don’t think it’s an issue, but in Maple it creates a crazy large file, so I see where it’s not the best option.
Is a vector a csv? I don’t know how to do data in a matrix.
No, a vector is just a list of numbers. You can crate one with (assuming you are storing numbers):
x = Float64
And then add data to it with, for instance,
x is what you need to plot something.
This could be improved, but Makie offers a nice way to explore Newton’s method and its dependence on the initial value. If you install enough packages to get this to run, dragging the initial points shows the method pretty clearly.
using AbstractPlotting using AbstractPlotting.MakieLayout using GLMakie using ForwardDiff D(f) = x -> ForwardDiff.derivative(f, float(x)) function newton(f=x->x^5 - x - 1, x0=1, a=-1, b=1.5, n = 20) function add_move!(scene, points, pplot) idx = Ref(0); dragstart = Ref(false); startpos = Base.RefValue(Point2f0(0)) on(events(scene).mousedrag) do drag if ispressed(scene, Mouse.left) if drag == Mouse.down plot, _idx = mouse_selection(scene) if plot == pplot idx = _idx; dragstart = true startpos = to_world(scene, Point2f0(scene.events.mouseposition)) end elseif drag == Mouse.pressed && dragstart && checkbounds(Bool, points, idx) pos = to_world(scene, Point2f0(scene.events.mouseposition)) # we work with components, not vector x,y = pos ptidx = idx x = clamp(x, a, b) y = zero(y) points[idx] = [x,y] points = points end else dragstart = false end return end end start_point = Node(Point2f0[(x0, 0)]) points = lift(start_point) do x₀ xs = [x₀] for i in 1:n xᵢ₋₁ = xs[end] xᵢ = xᵢ₋₁ - f(xᵢ₋₁) /D(f)(xᵢ₋₁) push!(xs, xᵢ) end xs end plt_points = lift(points) do pts xs = Float64 ys = Float64 for i in 1:length(pts)-1 pᵢ, pᵢ₊₁ = pts[i], pts[i+1] append!(xs, [pᵢ, pᵢ, pᵢ₊₁]) append!(ys, [0, f(pᵢ), 0]) end (xs, ys) end scene = Scene() lines!(scene, a..b, f, linewidth=5, color=:blue) lines!(scene, a..b, zero, color=:red) lines!(scene, plt_points, color=:black, linewidth=2) scatter!(scene, start_point, color=:red) add_move!(scene, start_point, scene[end]) scene end
I ran it. I get warnings from packages but no errors. Is it supposed to output a plot?
scatter! not defined.
It might be missing a package, or that could be a syntax error.
That’s from AbstractPlotting, or should be.
Ok, I’m using Jupyter, does it matter if the using commands are in the same code chunk as other code?
I get the scatter not defined error when I run
I only ran from a terminal. I’m not sure, but WGLMakie might work in place of GLMakie.
For an x, given f(x) and f'(x), if you want the tangent as y = a + bx, then just match values and derivatives, ie f(x) = a + bx and f'(x) = b, obtaining a = f(x) - x f'(x).
fp(x)= ForwardDiff.derivative(f, x)
for i in 1:9
this gives me lines with the correct slope, but they don't move with root or x, to be tangents.
Okay, this should work in Jupyter. The
@manipulate macro from
SimplePlots allows the interaction with the initial point.
using Plots, Interact using ForwardDiff D(f) = x -> ForwardDiff.derivative(f, float(x)) f(x) = x^5 - x - 1 a, b = -1.5, 1.5 nsteps = 20 @manipulate for x0=slider(a:0.1:b, value=1.0, label="x0") ts = range(a, b, length=251) plot(ts, f.(ts), xlim=(a,b), ylim=(-5,5), legend=false) plot!(ts, 0 .* ts) scatter!([x0],) xs = Float64 ys = Float64 for i in 1:nsteps x1 = x0 - f(x0)/D(f)(x0) append!(xs, [x0, x0, x1]) append!(ys, [0,f(x0), 0]) x0 = x1 end plot!(xs, ys) end
[Edited to use Plots+Interact]
I,m getting slider not defined
UndefVarError: slider not defined Stacktrace:  top-level scope at C:\Users\Brett\.julia\packages\SimplePlots\6y94O\src\interact\gui.jl:39  include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091