use plotly; fix bitrot

This commit is contained in:
jverzani
2024-06-07 13:07:09 -04:00
parent 0bcc8b5a6c
commit 55f37a6dfb
59 changed files with 423 additions and 176 deletions

View File

@@ -0,0 +1,78 @@
## THIS IS FAILING
## Appendix
There are other packages in the `Julia` ecosystem that can plot implicit equations.
### The ImplicitEquations package
The `ImplicitEquations` packages can plot equations and inequalities. The use is somewhat similar to the examples above, but the object plotted is a predicate, not a function. These predicates are created with functions like `Eq` or `Lt`.
For example, the `ImplicitPlots` manual shows this function $f(x,y) = (x^4 + y^4 - 1) \cdot (x^2 + y^2 - 2) + x^5 \cdot y$ to plot. Using `ImplicitEquations`, this equation would be plotted with:
```{julia}
#| hold: true
using ImplicitEquations
f(x,y) = (x^4 + y^4 - 1) * (x^2 + y^2 - 2) + x^5 * y
r = Eq(f, 0) # the equation f(x,y) = 0
plot(r)
```
Unlike `ImplicitPlots`, inequalities may be displayed:
```{julia}
#| hold: true
f(x,y) = (x^4 + y^4 - 1) * (x^2 + y^2 - 2) + x^5 * y
r = Lt(f, 0) # the inequality f(x,y) < 0
plot(r; M=10, N=10) # less blocky
```
The rendered plots look "blocky" due to the algorithm used to plot the equations. As there is no rule defining $(x,y)$ pairs to plot, a search by regions is done. A region is initially labeled undetermined. If it can be shown that for any value in the region the equation is true (equations can also be inequalities), the region is colored black. If it can be shown it will never be true, the region is dropped. If a black-and-white answer is not clear, the region is subdivided and each subregion is similarly tested. This continues until the remaining undecided regions are smaller than some threshold. Such regions comprise a boundary, and here are also colored black. Only regions are plotted - not $(x,y)$ pairs - so the results are blocky. Pass larger values of $N=M$ (with defaults of $8$) to `plot` to lower the threshold at the cost of longer computation times, as seen in the last example.
### The IntervalConstraintProgramming package
The `IntervalConstraintProgramming` package also can be used to graph implicit equations. For certain problem descriptions it is significantly faster and makes better graphs. The usage is slightly more involved. We show the commands, but don't run them here, as there are minor conflicts with the `CalculusWithJulia`package.
We specify a problem using the `@constraint` macro. Using a macro allows expressions to involve free symbols, so the problem is specified in an equation-like manner:
```{julia}
#| eval: false
S = @constraint x^2 + y^2 <= 2
```
The right hand side must be a number.
The area to plot over must be specified as an `IntervalBox`, basically a pair of intervals. The interval $[a,b]$ is expressed through `a..b`:
```{julia}
#| eval: false
J = -3..3
X = IntervalArithmetic.IntervalBox(J, J)
```
The `pave` command does the heavy lifting:
```{julia}
#| eval: false
region = IntervalConstraintProgramming.pave(S, X)
```
A plot can be made of either the boundary, the interior, or both.
```{julia}
#| eval: false
plot(region.inner) # plot interior; use r.boundary for boundary
```

View File

@@ -9,6 +9,7 @@ This section uses the following add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
using Roots
using Polynomials # some name clash with SymPy
@@ -38,7 +39,7 @@ With these, a sketch fills in between the points/lines associated with these val
#| echo: false
#| cache: true
### {{{ sketch_sin_plot }}}
gr()
function sketch_sin_plot_graph(i)
f(x) = 10*sin(pi/2*x) # [0,4]
@@ -84,7 +85,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
```
@@ -218,6 +219,7 @@ The slope of the secant line represents the average rate of change over a given
#| hold: true
#| echo: false
#| cache: true
gr()
function secant_line_tangent_line_graph(n)
f(x) = sin(x)
c = pi/3
@@ -251,6 +253,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```
@@ -268,6 +271,7 @@ We will define the tangent line at $(c, f(c))$ to be the line through the point
#| hold: true
#| echo: false
#| cache: true
gr()
function line_approx_fn_graph(n)
f(x) = sin(x)
c = pi/3
@@ -296,6 +300,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
using Roots
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using Roots
using SymPy
```
@@ -993,81 +994,3 @@ choices = ["concave up", "concave down", "both concave up and down"]
answ = 3
radioq(choices, answ, keep_order=true)
```
## Appendix
There are other packages in the `Julia` ecosystem that can plot implicit equations.
### The ImplicitEquations package
The `ImplicitEquations` packages can plot equations and inequalities. The use is somewhat similar to the examples above, but the object plotted is a predicate, not a function. These predicates are created with functions like `Eq` or `Lt`.
For example, the `ImplicitPlots` manual shows this function $f(x,y) = (x^4 + y^4 - 1) \cdot (x^2 + y^2 - 2) + x^5 \cdot y$ to plot. Using `ImplicitEquations`, this equation would be plotted with:
```{julia}
#| hold: true
using ImplicitEquations
f(x,y) = (x^4 + y^4 - 1) * (x^2 + y^2 - 2) + x^5 * y
r = Eq(f, 0) # the equation f(x,y) = 0
plot(r)
```
Unlike `ImplicitPlots`, inequalities may be displayed:
```{julia}
#| hold: true
f(x,y) = (x^4 + y^4 - 1) * (x^2 + y^2 - 2) + x^5 * y
r = Lt(f, 0) # the inequality f(x,y) < 0
plot(r; M=10, N=10) # less blocky
```
The rendered plots look "blocky" due to the algorithm used to plot the equations. As there is no rule defining $(x,y)$ pairs to plot, a search by regions is done. A region is initially labeled undetermined. If it can be shown that for any value in the region the equation is true (equations can also be inequalities), the region is colored black. If it can be shown it will never be true, the region is dropped. If a black-and-white answer is not clear, the region is subdivided and each subregion is similarly tested. This continues until the remaining undecided regions are smaller than some threshold. Such regions comprise a boundary, and here are also colored black. Only regions are plotted - not $(x,y)$ pairs - so the results are blocky. Pass larger values of $N=M$ (with defaults of $8$) to `plot` to lower the threshold at the cost of longer computation times, as seen in the last example.
### The IntervalConstraintProgramming package
The `IntervalConstraintProgramming` package also can be used to graph implicit equations. For certain problem descriptions it is significantly faster and makes better graphs. The usage is slightly more involved. We show the commands, but don't run them here, as there are minor conflicts with the `CalculusWithJulia`package.
We specify a problem using the `@constraint` macro. Using a macro allows expressions to involve free symbols, so the problem is specified in an equation-like manner:
```{julia}
#| eval: false
S = @constraint x^2 + y^2 <= 2
```
The right hand side must be a number.
The area to plot over must be specified as an `IntervalBox`, basically a pair of intervals. The interval $[a,b]$ is expressed through `a..b`:
```{julia}
#| eval: false
J = -3..3
X = IntervalArithmetic.IntervalBox(J, J)
```
The `pave` command does the heavy lifting:
```{julia}
#| eval: false
region = IntervalConstraintProgramming.pave(S, X)
```
A plot can be made of either the boundary, the interior, or both.
```{julia}
#| eval: false
plot(region.inner) # plot interior; use r.boundary for boundary
```

View File

@@ -9,8 +9,8 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
```
@@ -245,6 +245,7 @@ A first proof of L'Hospital's rule takes advantage of Cauchy's [generalization](
#| echo: false
#| cache: true
using Roots
gr()
let
## {{{lhopitals_picture}}}
@@ -293,7 +294,7 @@ imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
plotly()
ImageFile(imgfile, caption)
end
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
using TaylorSeries
using DualNumbers

View File

@@ -9,8 +9,8 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using Roots
```
```{julia}
@@ -288,13 +288,19 @@ j(x) = exp(x) * x * (x-1)
find_zeros(j', 0, 1)
```
This graph illustrates the lone value for $c$ for this problem
The following graph illustrates the lone value for $c$ in $[a,b]$ for
this problem:
```{julia}
#| echo: false
x0 = find_zero(j', (0, 1))
plot([j, x->j(x0) + 0*(x-x0)], 0, 1)
j₀ = j(x0)
plot([j, x->j₀ + 0*(x-x0)], 0, 1; legend=false)
scatter!([0,x0,1], [j₀, j₀, j₀])
annotate!([(0,j₀,text("a", :bottom)),
(x0, j₀, text("c", :bottom)),
(1, j₀, text("b", :bottom))])
```
## The mean value theorem
@@ -327,10 +333,15 @@ cps = find_zeros(x -> f'(x) - m, a, b)
p = plot(f, a-1, b+1, linewidth=3, legend=false)
plot!(x -> f(a) + m*(x-a), a-1, b+1, linewidth=3, color=:orange)
scatter!([a,b], [f(a), f(b)])
annotate!([(a, f(a), text("a", :bottom)),
(b, f(b), text("b", :bottom))])
for cp in cps
plot!(x -> f(cp) + f'(cp)*(x-cp), a-1, b+1, color=:red)
plot!(x -> f(cp) + f'(cp)*(x-cp), a-1, b+1, color=:red)
end
scatter!(cps, f.(cps))
subsscripts = collect("₀₁₂₃₄₅₆₇₈₉")
annotate!([(cp, f(cp), text("c"*subsscripts[i], :bottom)) for (i,cp) ∈ enumerate(cps)])
p
```
@@ -454,7 +465,7 @@ The Cauchy mean value theorem can be visualized in terms of a tangent line and a
#| echo: false
#| cache: true
### {{{parametric_fns}}}
gr()
function parametric_fns_graph(n)
@@ -488,7 +499,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,7 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
using ImplicitEquations
plotly()
using Roots
using SymPy
```
@@ -23,7 +23,7 @@ Newton's method is not the only algorithm of its kind for identifying zeros of a
## The `find_zero(f, x0)` function
The function `find_zero` from the `Roots` packages provides several different algorithms for finding a zero of a function, including some a derivative-free algorithms for finding zeros when started with an initial guess. The default method is similar to Newton's method in that only a good initial guess is needed. However, the algorithm, while possibly slower in terms of function evaluations and steps, is engineered to be a bit more robust to the choice of initial estimate than Newton's method. (If it finds a bracket, it will use a bisection algorithm which is guaranteed to converge, but can be slower to do so.) Here we see how to call the function:
The function `find_zero` from the `Roots` packages provides several different algorithms for finding a zero of a function, including some derivative-free algorithms for finding zeros when started with a nearby initial guess. The default method is similar to Newton's method in that only a good, initial guess is needed. However, the algorithm, while possibly slower in terms of function evaluations and steps, is engineered to be a bit more robust to the choice of initial estimate than Newton's method. (If it finds a bracket, it will use a bisection algorithm which is guaranteed to converge, but can be slower to do so.) Here we see how to call the function:
```{julia}
@@ -279,10 +279,14 @@ We can see it in action on the sine function. Here we pass in $\lambda$, but i
chandrapatla(sin, 3, 4, λ3, verbose=true)
```
```{julia}
#| output: false
#=
The condition `Φ^2 < ξ < 1 - (1-Φ)^2` can be visualized. Assume `a,b=0,1`, `fa,fb=-1/2,1`, Then `c < a < b`, and `fc` has the same sign as `fa`, but what values of `fc` will satisfy the inequality?
```{julia}
XX```{julia}
ξ(c,fc) = (a-b)/(c-b)
Φ(c,fc) = (fa-fb)/(fc-fb)
Φl(c,fc) = Φ(c,fc)^2
@@ -291,7 +295,7 @@ a,b = 0, 1
fa,fb = -1/2, 1
region = Lt(Φl, ξ) & Lt(ξ,Φr)
plot(region, xlims=(-2,a), ylims=(-3,0))
```
XX```
When `(c,fc)` is in the shaded area, the inverse quadratic step is chosen. We can see that `fc < fa` is needed.
@@ -299,14 +303,16 @@ When `(c,fc)` is in the shaded area, the inverse quadratic step is chosen. We ca
For these values, this area is within the area where a implicit quadratic step will result in a value between `a` and `b`:
```{julia}
XX```{julia}
l(c,fc) = λ3(fa,fb,fc,a,b,c)
region₃ = ImplicitEquations.Lt(l,b) & ImplicitEquations.Gt(l,a)
plot(region₃, xlims=(-2,0), ylims=(-3,0))
```
XX```
There are values in the parameter space where this does not occur.
=#
nothing
```
## Tolerances

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
using Roots
```
@@ -20,7 +21,7 @@ using Roots
The Babylonian method is an algorithm to find an approximate value for $\sqrt{k}$. It was described by the first-century Greek mathematician Hero of [Alexandria](http://en.wikipedia.org/wiki/Babylonian_method).
The method starts with some initial guess, called $x_0$. It then applies a formula to produce an improved guess. This is repeated until the improved guess is accurate enough or it is clear the algorithm fails to work.
The method starts with some initial guess, called $x_0$. This is usually some nearby value to the answer. The method then applies a formula to produce an improved guess. This is repeated until the improved guess is accurate enough or it is clear the algorithm fails to work.
For the Babylonian method, the next guess, $x_{i+1}$, is derived from the current guess, $x_i$. In mathematical notation, this is the updating step:
@@ -250,7 +251,7 @@ nothing
#| echo: false
#| cache: true
### {{{newtons_method_example}}}
gr()
caption = """
Illustration of Newton's Method converging to a zero of a function.
@@ -266,7 +267,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```
@@ -730,6 +731,7 @@ What can go wrong when one of these isn't the case is illustrated next:
#| echo: false
#| cache: true
### {{{newtons_method_poor_x0}}}
gr()
caption = """
Illustration of Newton's Method converging to a zero of a function,
@@ -748,7 +750,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 2)
plotly()
ImageFile(imgfile, caption)
```
@@ -757,6 +759,7 @@ ImageFile(imgfile, caption)
#| echo: false
#| cache: true
# {{{newtons_method_flat}}}
gr()
caption = L"""
Illustration of Newton's method failing to converge as for some $x_i$,
@@ -777,7 +780,7 @@ anim = @animate for i=1:n
end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```
@@ -789,7 +792,7 @@ ImageFile(imgfile, caption)
#| echo: false
#| cache: true
# {{{newtons_method_cycle}}}
gr()
fn, a, b, c, = x -> abs(x)^(0.49), -2, 2, 1.0
caption = L"""
@@ -808,6 +811,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 2)
plotly()
ImageFile(imgfile, caption)
```
@@ -819,7 +823,7 @@ ImageFile(imgfile, caption)
#| echo: false
#| cache: true
# {{{newtons_method_wilkinson}}}
gr()
caption = L"""
The function $f(x) = x^{20} - 1$ has two bad behaviours for Newton's
@@ -845,7 +849,7 @@ anim = @animate for i=1:n
end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using ForwardDiff
using SymPy
using Roots

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using Roots
using SymPy
```
@@ -60,7 +61,7 @@ We began with the question of which rectangles of perimeter $20$ have the larges
#| cache: true
### {{{perimeter_area_graphic}}}
gr()
function perimeter_area_graphic_graph(n)
h = 1 + 2n
w = 10-h
@@ -83,7 +84,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using Roots
using SymPy
```
@@ -36,6 +37,7 @@ The following is a typical "book" problem:
#| cache: true
### {{{growing_rects}}}
## Secant line approaches tangent line...
gr()
function growing_rects_graph(n)
w = (t) -> 2 + 4t
h = (t) -> 3/2 * w(t)
@@ -67,7 +69,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```
@@ -400,6 +402,7 @@ $$
#| cache: true
###{{{baseball_been_berry_good}}}
## Secant line approaches tangent line...
gr()
function baseball_been_berry_good_graph(n)
v0 = 15
@@ -438,7 +441,7 @@ end
imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)
plotly()
ImageFile(imgfile, caption)
```

View File

@@ -9,6 +9,7 @@ This section uses these add-on packages:
```{julia}
using CalculusWithJulia
using Plots
plotly()
using SymPy
using Unitful
```
@@ -37,6 +38,7 @@ We will see in this section how the Taylor polynomial answers these questions, a
#| echo: false
#| cache: true
###{{{taylor_animation}}}
gr()
taylor(f, x, c, n) = series(f, x, c, n+1).removeO()
function make_taylor_plot(u, a, b, k)
k = 2k
@@ -67,7 +69,7 @@ caption = L"""
Illustration of the Taylor polynomial of degree $k$, $T_k(x)$, at $c=0$ and its graph overlaid on that of the function $1 - \cos(x)$.
"""
plotly()
ImageFile(imgfile, caption)
```