Merge pull request #14 from jverzani/v0.3

V0.3
This commit is contained in:
john verzani
2022-08-11 13:22:10 -04:00
committed by GitHub
1463 changed files with 1506823 additions and 1821 deletions

View File

@@ -1,9 +0,0 @@
[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
MDBM = "dd61e66b-39ce-57b0-8813-509f78be4b4d"
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
Weave = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"

View File

@@ -1,904 +0,0 @@
# Calculus plots with Makie
XXX https://www.juliapackages.com/p/implicit3dplotting
## XXX This needs a total rewrite for the new Makie
```julia; echo=false; results="hidden"
using CalculusWithJulia
using CalculusWithJulia.WeaveSupport
using AbstractPlotting
Base.showable(m::MIME"image/png", p::AbstractPlotting.Scene) = true # instruct weave to make graphs
nothing
```
The [Makie.jl webpage](https://github.com/JuliaPlots/Makie.jl) says
> From the Japanese word Maki-e, which is a technique to sprinkle lacquer with gold and silver powder. Data is basically the gold and silver of our age, so let's spread it out beautifully on the screen!
`Makie` itself is a metapackage for a rich ecosystem. We show how to
use the interface provided by `AbstractPlotting` and the `GLMakie`
backend to produce the familiar graphics of calculus. We do not
discuss the `MakieLayout` package which provides a means to layout
multiple graphics and add widgets, such as sliders and buttons, to a
layout. We do not discuss `MakieRecipes`. For `Plots`, there are
"recipes" that make some of the plots more straightforward. We do not
discuss the
[`AlgebraOfGraphics`](https://github.com/JuliaPlots/AlgebraOfGraphics.jl)
which presents an interface for the familiar graphics of statistics.
## Scenes
Makie draws graphics onto a canvas termed a "scene" in the Makie documentation. There are `GLMakie`, `WGLMakie`, and `CairoMakie` backends for different types of canvases. In the following, we have used `GLMakie`. `WGLMakie` is useful for incorporating `Makie` plots into web-based technologies.
We begin by loading our two packages:
```julia
using AbstractPlotting
using GLMakie
#using WGLMakie; WGLMakie.activate!()
#AbstractPlotting.set_theme!(scale_figure=false, resolution = (480, 400))
```
The `Makie` developers have workarounds for the delayed time to first plot, but without utilizing these the time to load the package is lengthy.
A scene is produced with `Scene()` or through a plotting primitive:
```julia
scene = Scene()
```
We see next how to move beyond the blank canvas.
## Points (`scatter`)
The task of plotting the points, say $(1,2)$, $(2,3)$, $(3,2)$ can be done different ways. Most plotting packages, and `Makie` is no exception, allow the following: form vectors of the $x$ and $y$ values then plot those with `scatter`:
```julia
xs = [1,2,3]
ys = [2,3,2]
scatter(xs, ys)
```
The `scatter` function creates and returns a `Scene` object, which when displayed shows the plot.
The more generic `plot` function can also be used for this task.
### `Point2`, `Point3`
When learning about points on the Cartesian plane, a "`t`"-chart is often produced:
```
x | y
-----
1 | 2
2 | 3
3 | 2
```
The `scatter` usage above used the columns. The rows are associated with the points, and these too can be used to produce the same graphic.
Rather than make vectors of $x$ and $y$ (and optionally $z$) coordinates, it is more idiomatic to create a vector of "points." `Makie` utilizes a `Point` type to store a 2 or 3 dimensional point. The `Point2` and `Point3` constructors will be utilized.
`Makie` uses a GPU, when present, to accelerate the graphic rendering. GPUs employ 32-bit numbers. Julia uses an `f0` to indicate 32-bit floating points. Hence the alternate types `Point2f0` to store 2D points as 32-bit numbers and `Points3f0` to store 3D points as 32-bit numbers are seen in the documentation for Makie.
We can plot vector of points in as direct manner as vectors of their coordinates:
```julia
pts = [Point2(1,2), Point2(2,3), Point2(3,2)]
scatter(pts)
```
A typical usage is to generate points from some vector-valued
function. Say we have a parameterized function `r` taking $R$ into
$R^2$ defined by:
```julia
r(t) = [sin(t), cos(t)]
```
Then broadcasting values gives a vector of vectors, each identified with a point:
```julia
ts = [1,2,3]
r.(ts)
```
We can broadcast `Point2` over this to create a vector of `Point` objects:
```julia
pts = Point2.(r.(ts))
```
These then can be plotted directly:
```julia
scatter(pts)
```
The ploting of points in three dimesions is essentially the same, save the use of `Point3` instead of `Point2`.
```julia
r(t) = [sin(t), cos(t), t]
ts = range(0, 4pi, length=100)
pts = Point3.(r.(ts))
scatter(pts)
```
----
To plot points generated in terms of vectors of coordinates, the
component vectors must be created. The "`t`"-table shows how, simply
loop over each column and add the corresponding $x$ or $y$ (or $z$)
value. This utility function does exactly that, returning the vectors
in a tuple.
```julia
unzip(vs) = Tuple([vs[j][i] for j in eachindex(vs)] for i in eachindex(vs[1]))
```
(The functionality is essentially a reverse of the `zip` function, hence the name.)
We might have then:
```julia
scatter(unzip(r.(ts))...)
```
where splatting is used to specify the `xs`, `ys`, and `zs` to `scatter`.
(Compare to `scatter(Point3.(r.(ts)))` or `scatter(Point3∘r).(ts))`.)
### Attributes
A point is drawn with a "marker" with a certain size and color. These attributes can be adjusted, as in the following:
```julia
scatter(xs, ys, marker=[:x,:cross, :circle], markersize=25, color=:blue)
```
Marker attributes include
* `marker` a symbol, shape. A single value will be repeated. A vector of values of a matching size will specify a marker for each point.
* `marker_offset` offset coordinates
* `markersize` size (radius pixels) of marker
### Text (`text`)
Text can be placed at a point, as a marker is. To place text the desired text and a position need to be specified.
For example:
```julia
pts = Point2.(1:5, 1:5)
scene = scatter(pts)
[text!(scene, "text", position=pt, textsize=1/i, rotation=2pi/i) for (i,pt) in enumerate(pts)]
scene
```
The graphic shows that `position` positions the text, `textsize` adjusts the displayed size, and `rotation` adjusts the orientation.
Attributes for `text` include:
* `position` to indicate the position. Either a `Point` object, as above, or a tuple
* `align` Specify the text alignment through `(:pos, :pos)`, where `:pos` can be `:left`, `:center`, or `:right`.
* `rotation` to indicate how the text is to be rotated
* `textsize` the font point size for the text
* `font` to indicate the desired font
## Curves
### Plots of univariate functions
The basic plot of univariate calculus is the graph of a function $f$ over an interval $[a,b]$. This is implemented using a familiar strategy: produce a series of representative values between $a$ and $b$; produce the corresponding $f(x)$ values; plot these as points and connect the points with straight lines. The `lines` function of `AbstractPlotting` will do the last step.
By taking a sufficient number of points within $[a,b]$ the connect-the-dot figure will appear curved, when the function is.
To create regular values between `a` and `b` either the `range` function, the related `LinRange` function, or the range operator (`a:h:b`) are employed.
For example:
```julia
f(x) = sin(x)
a, b = 0, 2pi
xs = range(a, b, length=250)
lines(xs, f.(xs))
```
Or
```julia
f(x) = cos(x)
a, b = -pi, pi
xs = a:pi/100:b
lines(xs, f.(xs))
```
As with `scatter`, `lines` returns a `Scene` object that produces a graphic when displayed.
As with `scatter`, `lines` can can also be drawn using a vector of points:
```juila
lines([Point2(x, fx) for (x,fx) in zip(xs, f.(xs))])
```
(Though the advantage isn't clear here, this will be useful when the points are more naturally generated.)
When a `y` value is `NaN` or infinite, the connecting lines are not drawn:
```
xs = 1:5
ys = [1,2,NaN, 4, 5]
lines(xs, ys)
```
As with other plotting packages, this is useful to represent discontinuous functions, such as what occurs at a vertical asymptote.
#### Adding to a scene (`lines!`, `scatter!`, ...)
To *add* or *modify* a scene can be done using a mutating version of a plotting primitive, such as `lines!` or `scatter!`. The names follow `Julia`'s convention of using an `!` to indicate that a function modifies an argument, in this case the scene.
Here is one way to show two plots at once:
```julia
xs = range(0, 2pi, length=100)
scene = lines(xs, sin.(xs))
lines!(scene, xs, cos.(xs))
```
We will see soon how to modify the line attributes so that the curves can be distinguished.
The following shows the construction details in the graphic, and that the initial scene argument is implicitly assumed:
```julia
xs = range(0, 2pi, length=10)
lines(xs, sin.(xs))
scatter!(xs, sin.(xs), markersize=10)
```
----
The current scene will have data limits that can be of interest. The following indicates how they can be manipulated to get the limits of the displayed `x` values.
```julia
xs = range(0, 2pi, length=200)
scene = plot(xs, sin.(xs))
rect = scene.data_limits[] # get limits for g from f
a, b = rect.origin[1], rect.origin[1] + rect.widths[1]
```
In the output it can be discerned that the values are 32-bit floating point numbers *and* yield a slightly larger interval than specified in `xs`.
As an example, this shows how to add the tangent line to a graph. The slope of the tangent line being computed by `ForwardDiff.derivative`.
```julia
using ForwardDiff
f(x) = x^x
a, b= 0, 2
c = 0.5
xs = range(a, b, length=200)
tl(x) = f(c) + ForwardDiff.derivative(f, c) * (x-c)
scene = lines(xs, f.(xs))
lines!(scene, xs, tl.(xs), color=:blue)
```
#### Attributes
In the last example, we added the argument `color=:blue` to the `lines!` call. This set an attribute for the line being drawn. Lines have other attributes that allow different ones to be distinguished, as above where colors indicate the different graphs.
Other attributes can be seen from the help page for `lines`, and include:
* `color` set with a symbol, as above, or a string
* `linestyle` available styles are set by a symbol, one of `:dash`, `:dot`, `:dashdot`, or `:dashdotdot`.
* `linewidth` width of line
* `transparency` the `alpha` value, a number between $0$ and $1$, smaller numbers for more transparent.
A legend can also be used to help identify different curves on the same graphic, though this is not illustrated. There are examples in the Makie gallery.
#### Scene attributes
Attributes of the scene include any titles and labels, the limits that define the coordinates being displayed, the presentation of tick marks, etc.
The `title` function can be used to add a title to a scene. The calling syntax is `title(scene, text)`.
To set the labels of the graph, there are "shorthand" functions `xlabel!`, `ylabel!`, and `zlabel!`. The calling pattern would follow `xlabel!(scene, "x-axis")`.
The plotting ticks and their labels are returned by the unexported functions `tickranges` and `ticklabels`. The unexported `xtickrange`, `ytickrange`, and `ztickrange`; and `xticklabels`, `yticklabels`, and `zticklabels` return these for the indicated axes.
These can be dynamically adjusted using `xticks!`, `yticks!`, or `zticks!`.
```julia
pts = [Point2(1,2), Point2(2,3), Point2(3,2)]
scene = scatter(pts)
title(scene, "3 points")
ylabel!(scene, "y values")
xticks!(scene, xtickrange=[1,2,3], xticklabels=["a", "b", "c"])
```
To set the limits of the graph there are shorthand functions `xlims!`, `ylims!`, and `zlims!`. This might prove useful if vertical asymptotes are encountered, as in this example:
```julia
f(x) = 1/x
a,b = -1, 1
xs = range(-1, 1, length=200)
scene = lines(xs, f.(xs))
ylims!(scene, (-10, 10))
center!(scene)
```
### Plots of parametric functions
A space curve is a plot of a function $f:R^2 \rightarrow R$ or $f:R^3 \rightarrow R$.
To construct a curve from a set of points, we have a similar pattern in both $2$ and $3$ dimensions:
```julia
r(t) = [sin(2t), cos(3t)]
ts = range(0, 2pi, length=200)
pts = Point2.(r.(ts)) # or (Point2∘r).(ts)
lines(pts)
```
Or
```julia
r(t) = [sin(2t), cos(3t), t]
ts = range(0, 2pi, length=200)
pts = Point3.(r.(ts))
lines(pts)
```
Alternatively, vectors of the $x$, $y$, and $z$ components can be produced and then plotted using the pattern `lines(xs, ys)` or `lines(xs, ys, zs)`. For example, using `unzip`, as above, we might have done the prior example with:
```julia
xs, ys, zs = unzip(r.(ts))
lines(xs, ys, zs)
```
#### Tangent vectors (`arrows`)
A tangent vector along a curve can be drawn quite easily using the `arrows` function. There are different interfaces for `arrows`, but we show the one which uses a vector of positions and a vector of "vectors". For the latter, we utilize the `derivative` function from `ForwardDiff`:
```julia
using ForwardDiff
r(t) = [sin(t), cos(t)] # vector, not tuple
ts = range(0, 4pi, length=200)
scene = Scene()
lines!(scene, Point2.(r.(ts)))
nts = 0:pi/4:2pi
us = r.(nts)
dus = ForwardDiff.derivative.(r, nts)
arrows!(scene, Point2.(us), Point2.(dus))
```
In 3 dimensions the differences are minor:
```julia
r(t) = [sin(t), cos(t), t] # vector, not tuple
ts = range(0, 4pi, length=200)
scene = Scene()
lines!(scene, Point3.(r.(ts)))
nts = pi:pi/4:3pi
us = r.(nts)
dus = ForwardDiff.derivative.(r, nts)
arrows!(scene, Point3.(us), Point3.(dus))
```
##### Attributes
Attributes for `arrows` include
* `arrowsize` to adjust the size
* `lengthscale` to scale the size
* `arrowcolor` to set the color
* `arrowhead` to adjust the head
* `arrowtail` to adjust the tail
### Implicit equations (2D)
The graph of an equation is the collection of all $(x,y)$ values satisfying the equation. This is more general than the graph of a function, which can be viewed as the graph of the equation $y=f(x)$. An equation in $x$-$y$ can be graphed if the set of solutions to a related equation $f(x,y)=0$ can be identified, as one can move all terms to one side of an equation and define $f$ as the rule of the side with the terms.
The [MDBM](https://github.com/bachrathyd/MDBM.jl) (Multi-Dimensional Bisection Method) package can be used for the task of characterizing when $f(x,y)=0$. (Also `IntervalConstraintProgramming` can be used.) We first wrap its interface and then define a "`plot`" recipe (through method overloading, not through `MakieRecipes`).
```julia
using MDBM
```
```julia
function implicit_equation(f, axes...; iteration::Int=4, constraint=nothing)
axes = [axes...]
if constraint == nothing
prob = MDBM_Problem(f, axes)
else
prob = MDBM_Problem(f, axes, constraint=constraint)
end
solve!(prob, iteration)
prob
end
```
The `implicit_equation` function is just a simplified wrapper for the `MDBM_Problem` interface. It creates an object to be plotted in a manner akin to:
```julia
f(x,y) = x^3 + x^2 + x + 1 - x*y # solve x^3 + x^2 + x + 1 = x*y
ie = implicit_equation(f, -5:5, -10:10)
```
The function definition is straightforward. The limits for `x` and `y` are specified in the above using ranges. This specifies the initial grid of points for the apdaptive algorithm used by `MDBM` to identify solutions.
To visualize the output, we make a new method for `plot` and `plot!`. There is a distinction between 2 and 3 dimensions. Below in two dimensions curve(s) are drawn. In three dimensions, scaled cubes are used to indicate the surface.
```julia
AbstractPlotting.plot(m::MDBM_Problem; kwargs...) = plot!(Scene(), m; kwargs...)
AbstractPlotting.plot!(m::MDBM_Problem; kwargs...) = plot!(AbstractPlotting.current_scene(), m; kwargs...)
AbstractPlotting.plot!(scene::AbstractPlotting.Scene, m::MDBM_Problem; kwargs...) =
plot!(Val(_dim(m)), scene, m; kwargs...)
_dim(m::MDBM.MDBM_Problem{a,N,b,c,d,e,f,g,h}) where {a,N,b,c,d,e,f,g,h} = N
```
Dispatch is used for the two different dimesions, identified through `_dim`, defined above.
```julia
# 2D plot
function AbstractPlotting.plot!(::Val{2}, scene::AbstractPlotting.Scene,
m::MDBM_Problem; color=:black, kwargs...)
mdt=MDBM.connect(m)
for i in 1:length(mdt)
dt=mdt[i]
P1=getinterpolatedsolution(m.ncubes[dt[1]], m)
P2=getinterpolatedsolution(m.ncubes[dt[2]], m)
lines!(scene, [P1[1],P2[1]],[P1[2],P2[2]], color=color, kwargs...)
end
scene
end
```
```julia
# 3D plot
function AbstractPlotting.plot!(::Val{3}, scene::AbstractPlotting.Scene,
m::MDBM_Problem; color=:black, kwargs...)
positions = Point{3, Float32}[]
scales = Vec3[]
mdt=MDBM.connect(m)
for i in 1:length(mdt)
dt=mdt[i]
P1=getinterpolatedsolution(m.ncubes[dt[1]], m)
P2=getinterpolatedsolution(m.ncubes[dt[2]], m)
a, b = Vec3(P1), Vec3(P2)
push!(positions, Point3(P1))
push!(scales, b-a)
end
cube = Rect{3, Float32}(Vec3(-0.5, -0.5, -0.5), Vec3(1, 1, 1))
meshscatter!(scene, positions, marker=cube, scale = scales, color=color, transparency=true, kwargs...)
scene
end
```
We see that the equation `ie` has two pieces. (This is known as Newton's trident, as Newton was interested in this form of equation.)
```julia
plot(ie)
```
## Surfaces
Plots of surfaces in 3 dimensions are useful to help understand the behavior of multivariate functions.
#### Surfaces defined through $z=f(x,y)$
The "peaks" function generates the logo for MATLAB. Here we see how it can be plotted over the region $[-5,5]\times[-5,5]$.
```julia
peaks(x,y) = 3*(1-x)^2*exp(-x^2 - (y+1)^2) - 10(x/5-x^3-y^5)*exp(-x^2-y^2)- 1/3*exp(-(x+1)^2-y^2)
xs = ys = range(-5, 5, length=25)
surface(xs, ys, peaks)
```
The calling pattern `surface(xs, ys, f)` implies a rectangular grid over the $x$-$y$ plane defined by `xs` and `ys` with $z$ values given by $f(x,y)$.
Alternatively a "matrix" of $z$ values can be specified. For a function `f`, this is conveniently generated by the pattern `f.(xs, ys')`, the `'` being important to get a matrix of all $x$-$y$ pairs through `Julia`'s broadcasting syntax.
```julia
zs = peaks.(xs, ys')
surface(xs, ys, zs)
```
To see how this graph is constructed, the points $(x,y,f(x,y))$ are plotted over the grid and displayed.
Here we downsample to illutrate
```julia
xs = ys = range(-5, 5, length=5)
pts = [Point3(x, y, peaks(x,y)) for x in xs for y in ys]
scatter(pts, markersize=25)
```
These points are connected. The `wireframe` function illustrates just the frame
```julia
wireframe(xs, ys, peaks.(xs, ys'), linewidth=5)
```
The `surface` call triangulates the frame and fills in the shading:
```julia
surface!(xs, ys, peaks.(xs, ys'))
```
#### Implicitly defined surfaces, $F(x,y,z)=0$
The set of points $(x,y,z)$ satisfying $F(x,y,z) = 0$ will form a surface that can be visualized using the `MDBM` package. We illustrate showing two nested surfaces.
```julia
r₂(x,y,z) = x^2 + y^2 + z^2 - 5/4 # a sphere
r₄(x,y,z) = x^4 + y^4 + z^4 - 1
xs = ys = zs = -2:2
m2,m4 = implicit_equation(r₂, xs, ys, zs), implicit_equation(r₄, xs, ys, zs)
plot(m4, color=:yellow)
plot!(m2, color=:red)
```
#### Parametrically defined surfaces
A surface may be parametrically defined through a function $r(u,v) = (x(u,v), y(u,v), z(u,v))$. For example, the surface generated by $z=f(x,y)$ is of the form with $r(u,v) = (u,v,f(u,v))$.
The `surface` function and the `wireframe` function can be used to display such surfaces. In previous usages, the `x` and `y` values were vectors from which a 2-dimensional grid is formed. For parametric surfaces, a grid for the `x` and `y` values must be generated. This function will do so:
```julia
function parametric_grid(us, vs, r)
n,m = length(us), length(vs)
xs, ys, zs = zeros(n,m), zeros(n,m), zeros(n,m)
for (i, uᵢ) in enumerate(us)
for (j, vⱼ) in enumerate(vs)
x,y,z = r(uᵢ, vⱼ)
xs[i,j] = x
ys[i,j] = y
zs[i,j] = z
end
end
(xs, ys, zs)
end
```
With the data suitably massaged, we can directly plot either a `surface` or `wireframe` plot.
----
As an aside, The above can be done more campactly with nested list comprehensions:
```
xs, ys, zs = [[pt[i] for pt in r.(us, vs')] for i in 1:3]
```
Or using the `unzip` function directly after broadcasting:
```
xs, ys, zs = unzip(r.(us, vs'))
```
----
For example, a sphere can be parameterized by $r(u,v) = (\sin(u)\cos(v), \sin(u)\sin(v), \cos(u))$ and visualized through:
```julia
r(u,v) = [sin(u)*cos(v), sin(u)*sin(v), cos(u)]
us = range(0, pi, length=25)
vs = range(0, pi/2, length=25)
xs, ys, zs = parametric_grid(us, vs, r)
scene = Scene()
surface!(scene, xs, ys, zs)
wireframe!(scene, xs, ys, zs)
```
A surface of revolution for $g(u)$ revolved about the $z$ axis can be visualized through:
```julia
g(u) = u^2 * exp(-u)
r(u,v) = (g(u)*sin(v), g(u)*cos(v), u)
us = range(0, 3, length=10)
vs = range(0, 2pi, length=10)
xs, ys, zs = parametric_grid(us, vs, r)
scene = Scene()
surface!(scene, xs, ys, zs)
wireframe!(scene, xs, ys, zs)
```
A torus with big radius $2$ and inner radius $1/2$ can be visualized as follows
```julia
r1, r2 = 2, 1/2
r(u,v) = ((r1 + r2*cos(v))*cos(u), (r1 + r2*cos(v))*sin(u), r2*sin(v))
us = vs = range(0, 2pi, length=25)
xs, ys, zs = parametric_grid(us, vs, r)
scene = Scene()
surface!(scene, xs, ys, zs)
wireframe!(scene, xs, ys, zs)
```
A Möbius strip can be produced with:
```julia
ws = range(-1/4, 1/4, length=8)
thetas = range(0, 2pi, length=30)
r(w, θ) = ((1+w*cos(θ/2))*cos(θ), (1+w*cos(θ/2))*sin(θ), w*sin(θ/2))
xs, ys, zs = parametric_grid(ws, thetas, r)
scene = Scene()
surface!(scene, xs, ys, zs)
wireframe!(scene, xs, ys, zs)
```
## Contour plots (`contour`, `heatmap`)
For a function $z = f(x,y)$ an alternative to a surface plot, is a contour plot. That is, for different values of $c$ the level curves $f(x,y)=c$ are drawn.
For a function $f(x,y)$, the syntax for generating a contour plot follows that for `surface`.
For example, using the `peaks` function, previously defined, we have a contour plot over the region $[-5,5]\times[-5,5]$ is generated through:
```julia
xs = ys = range(-5, 5, length=100)
contour(xs, ys, peaks)
```
The default of $5$ levels can be adjusted using the `levels` keyword:
```julia
contour(xs, ys, peaks.(xs, ys'), levels = 20)
```
(As a reminder, the above also shows how to generate values "`zs`" to pass to `contour` instead of a function.)
The contour graph makes identification of peaks and valleys easy as the limits of patterns of nested contour lines.
An alternative visualzation using color to replace contour lines is a heatmap. The `heatmap` function produces these. The calling syntax is similar to `contour` and `surface`:
```julia
heatmap(xs, ys, peaks)
```
This graph shows peaks and valleys through "hotspots" on the graph.
The `MakieGallery` package includes an example of a surface plot with both a wireframe and 2D contour graph added. It is replicated here using the `peaks` function scaled by $5$.
The function and domain to plot are described by:
```julia
xs = ys = range(-5, 5, length=51)
zs = peaks.(xs, ys') / 5;
```
The `zs` were generated, as `wireframe` does not provide the interface for passing a function.
The `surface` and `wireframe` are produced as follows:
```julia
scene = surface(xs, ys, zs)
wireframe!(scene, xs, ys, zs, overdraw = true, transparency = true, color = (:black, 0.1))
```
To add the contour, a simple call via `contour!(scene, xs, ys, zs)` will place the contour at the $z=0$ level which will make it hard to read. Rather, placing at the "bottom" of the scene is desirable. To identify that the "scene limits" are queried and the argument `transformation = (:xy, zmin)` is passed to `contour!`:
```julia
xmin, ymin, zmin = minimum(scene_limits(scene))
contour!(scene, xs, ys, zs, levels = 15, linewidth = 2, transformation = (:xy, zmin))
center!(scene)
```
The `transformation` plot attribute sets the "plane" (one of `:xy`, `:yz`, or `:xz`) at a location, in this example `zmin`.
### Three dimensional contour plots
The `contour` function can also plot $3$-dimensional contour plots. Concentric spheres, contours of $x^2 + y^2 + z^2 = c$ for $c > 0$ are presented by the following:
```julia
f(x,y,z) = x^2 + y^2 + z^2
xs = ys = zs = range(-3, 3, length=100)
contour(xs, ys, zs, f)
```
## Vector fields. Visualizations of $f:R^2 \rightarrow R^2$
The vector field $f(x,y) = (y, -x)$ can be visualized as a set of vectors, $f(x,y)$, positioned at a grid. These can be produced with the `arrows` function. Below we pass a vector of points for the anchors and a vector of points representing the vectors.
We can generate these on a regular grid through:
```julia
f(x, y) = [y, -x]
xs = ys = -5:5
pts = vec(Point2.(xs, ys'))
dus = vec(Point2.(f.(xs, ys')))
```
Broadcasting over `(xs, ys')` ensures each pair of possible values is encountered. The `vec` call reshapes an array into a vector.
Calling `arrows` on the prepared data produces the graphic:
```julia
arrows(pts, dus)
```
The grid seems rotated at first glance. This is due to the length of the vectors as the $(x,y)$ values get farther from the origin. Plotting the *normalized* values (each will have length $1$) can be done easily using `norm` (which requires `LinearAlgebra` to be loaded):
```julia
using LinearAlgebra
dvs = dus ./ norm.(dus)
arrows(pts, dvs)
```
The rotational pattern becomes quite clear now.
The `streamplot` function also illustrates this phenomenon. This implements an "algorithm [that] puts an arrow somewhere and extends the streamline in both directions from there. Then, it chooses a new position (from the remaining ones), repeating the the exercise until the streamline gets blocked, from which on a new starting point, the process repeats."
The `streamplot` function expects a `point` not a pair of values, so we adjust `f` slightly and call the function using the pattern `streamplot(f, xs, ys)`:
```julia
g(x,y) = Point2(f(x,y))
streamplot(g, xs, ys)
```
(The viewing range could also be adjusted with the `-5..5` notation from the `IntervalSets` package which is brought in when `AbstractPlotting` is loaded.)
## Interacting with a scene
[Interaction](http://makie.juliaplots.org/stable/interaction.html) with a scene is very much integrated into `Makie`, as the design has a "sophisticated referencing system" which allows sharing of attributes. Adjusting one attribute, can then propogate to others.
In Makie, a `Node` is a structure that allows its value to be updated, similar to an array.
Nodes are `Observables`, which when changed can trigger an event. Nodes can rely on other nodes, so events can be cascaded.
A simple example is a means to dynamically adjust a label for a scene.
```
xs, = 1:5, rand(5)
scene = scatter(xs, ys)
```
We can create a "Node" through:
```
x = Node("x values")
```
The value of the node is retrieved by `x[]`, though the function call `to_value(x)` is recommened, as it will be defined even when `x` is not a node. This stored value could be used to set the $x$-label in our scene:
```
xlabel!(scene, x[])
```
We now set up an observer to update the label whenever the value of `x` is updated:
```
on(x) do val
xlabel!(scen, val)
end
```
Now setting the value of `x` will also update the label:
```
x[] = "The x axis"
```
A node can be more complicated. This shows how a node of $x$ value can be used to define dependent $y$ values. A scatter plot will update when the $x$ values are updated:
```
xs = Node(1:10)
ys = lift(a -> f.(a), xs)
```
The `lift` function lifts the values of `xs` to the values of `ys`.
These can be plotted directly:
```
scene = lines(xs, ys)
```
Changes to the `xs` values will be reflected in the `scene`.
```
xs[] = 2:9
```
We can incoporporate the two:
```
lab = lift(val -> "Showing from $(val.start) to $(val.stop)", xs)
on(lab) do val
xlabel!(scene, val)
udpate!(scene)
end
```
The `update!` call redraws the scene to adjust to increased or decreased range of $x$ values.
The mouse position can be recorded. An example in the gallery of examples shows how.
Here is a hint:
```
scene = lines(1:5, rand(5))
pos = lift(scene.events.mouseposition) do mpos
@show AbstractPlotting.to_world(scene, Point2f0(mpos))
end
```
This will display the coordinates of the mouse in the terminal, as the mouse is moved around.

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
name = "CalculusWithJuliaNotes"
uuid = "8cd3c377-0a30-4ec5-b85a-75291d749efe"
authors = ["jverzani <jverzani@gmail.com> and contributors"]
version = "0.1.1"
version = "0.1.2"
[compat]
julia = "1"

View File

@@ -0,0 +1 @@
ff40b40b

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 53 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 78 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,980 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.0.32">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Calculus with Julia - 50&nbsp; The problem-algorithm-solve interface</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
<script src="../site_libs/quarto-nav/headroom.min.js"></script>
<script src="../site_libs/clipboard/clipboard.min.js"></script>
<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
<script src="../site_libs/quarto-search/fuse.min.js"></script>
<script src="../site_libs/quarto-search/quarto-search.js"></script>
<meta name="quarto:offset" content="../">
<link href="../ODEs/differential_equations.html" rel="next">
<link href="../ODEs/euler.html" rel="prev">
<script src="../site_libs/quarto-html/quarto.js"></script>
<script src="../site_libs/quarto-html/popper.min.js"></script>
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../site_libs/quarto-html/anchor.min.js"></script>
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
"location": "navbar",
"copy-button": false,
"collapse-after": 3,
"panel-placement": "end",
"type": "overlay",
"limit": 20,
"language": {
"search-no-results-text": "No results",
"search-matching-documents-text": "matching documents",
"search-copy-link-title": "Copy link to search",
"search-hide-matches-text": "Hide additional matches",
"search-more-match-text": "more match in this document",
"search-more-matches-text": "more matches in this document",
"search-clear-button-title": "Clear",
"search-detached-cancel-button-title": "Cancel",
"search-submit-button-title": "Submit"
}
}</script>
<script async="" src="https://hypothes.is/embed.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
</head>
<body class="nav-sidebar floating nav-fixed">
<div id="quarto-search-results"></div>
<header id="quarto-header" class="headroom fixed-top">
<nav class="navbar navbar-expand-lg navbar-dark ">
<div class="navbar-container container-fluid">
<a class="navbar-brand" href="../index.html">
<img src="../logo.png" alt="">
<span class="navbar-title">Calculus with Julia</span>
</a>
<div id="quarto-search" class="" title="Search"></div>
</div> <!-- /container-fluid -->
</nav>
<nav class="quarto-secondary-nav" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
<div class="container-fluid d-flex justify-content-between">
<h1 class="quarto-secondary-nav-title"><span class="chapter-number">50</span>&nbsp; <span class="chapter-title">The problem-algorithm-solve interface</span></h1>
<button type="button" class="quarto-btn-toggle btn" aria-label="Show secondary navigation">
<i class="bi bi-chevron-right"></i>
</button>
</div>
</nav>
</header>
<!-- content -->
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
<!-- sidebar -->
<nav id="quarto-sidebar" class="sidebar collapse sidebar-navigation floating overflow-auto">
<div class="mt-2 flex-shrink-0 align-items-center">
<div class="sidebar-search">
<div id="quarto-search" class="" title="Search"></div>
</div>
</div>
<div class="sidebar-menu-container">
<ul class="list-unstyled mt-1">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../index.html" class="sidebar-item-text sidebar-link">Preface</a>
</div>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" aria-expanded="false">Precalculus Concepts</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-1" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-1" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/calculator.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">1</span>&nbsp; <span class="chapter-title">From calculator to computer</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/variables.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">2</span>&nbsp; <span class="chapter-title">Variables</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/numbers_types.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">3</span>&nbsp; <span class="chapter-title">Number systems</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/logical_expressions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">4</span>&nbsp; <span class="chapter-title">Inequalities, Logical expressions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/vectors.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">5</span>&nbsp; <span class="chapter-title">Vectors</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/ranges.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">6</span>&nbsp; <span class="chapter-title">Ranges and Sets</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">7</span>&nbsp; <span class="chapter-title">Functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/plotting.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">8</span>&nbsp; <span class="chapter-title">The Graph of a Function</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/transformations.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">9</span>&nbsp; <span class="chapter-title">Function manipulations</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/inversefunctions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">10</span>&nbsp; <span class="chapter-title">The Inverse of a Function</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/polynomial.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">11</span>&nbsp; <span class="chapter-title">Polynomials</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/polynomial_roots.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">12</span>&nbsp; <span class="chapter-title">Roots of a polynomial</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/polynomials_package.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">13</span>&nbsp; <span class="chapter-title">The Polynomials package</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/rational_functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">14</span>&nbsp; <span class="chapter-title">Rational functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/exp_log_functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">15</span>&nbsp; <span class="chapter-title">Exponential and logarithmic functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/trig_functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">16</span>&nbsp; <span class="chapter-title">Trigonometric functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../precalc/julia_overview.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">17</span>&nbsp; <span class="chapter-title">Overview of Julia commands</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" aria-expanded="false">Limits</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-2" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-2" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../limits/limits.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">18</span>&nbsp; <span class="chapter-title">Limits</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../limits/limits_extensions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">19</span>&nbsp; <span class="chapter-title">Limits, issues, extensions of the concept</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../limits/continuity.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">20</span>&nbsp; <span class="chapter-title">Continuity</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../limits/intermediate_value_theorem.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">21</span>&nbsp; <span class="chapter-title">Implications of continuity</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" aria-expanded="false">Derivatives</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-3" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-3" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/derivatives.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">22</span>&nbsp; <span class="chapter-title">Derivatives</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/numeric_derivatives.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">23</span>&nbsp; <span class="chapter-title">Numeric derivatives</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/symbolic_derivatives.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">24</span>&nbsp; <span class="chapter-title">Symbolic derivatives</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/mean_value_theorem.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">25</span>&nbsp; <span class="chapter-title">The mean value theorem for differentiable functions.</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/optimization.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">26</span>&nbsp; <span class="chapter-title">Optimization</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/first_second_derivatives.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">27</span>&nbsp; <span class="chapter-title">The first and second derivatives</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/curve_sketching.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">28</span>&nbsp; <span class="chapter-title">Curve Sketching</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/linearization.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">29</span>&nbsp; <span class="chapter-title">Linearization</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/newtons_method.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">30</span>&nbsp; <span class="chapter-title">Newtons method</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/more_zeros.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">31</span>&nbsp; <span class="chapter-title">Derivative-free alternatives to Newtons method</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/lhospitals_rule.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">32</span>&nbsp; <span class="chapter-title">LHospitals Rule</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/implicit_differentiation.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">33</span>&nbsp; <span class="chapter-title">Implicit Differentiation</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/related_rates.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">34</span>&nbsp; <span class="chapter-title">Related rates</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../derivatives/taylor_series_polynomials.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">35</span>&nbsp; <span class="chapter-title">Taylor Polynomials and other Approximating Polynomials</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-4" aria-expanded="false">Integrals</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-4" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-4" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/area.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">36</span>&nbsp; <span class="chapter-title">Area under a curve</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/ftc.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">37</span>&nbsp; <span class="chapter-title">Fundamental Theorem or Calculus</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/substitution.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">38</span>&nbsp; <span class="chapter-title">Substitution</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/integration_by_parts.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">39</span>&nbsp; <span class="chapter-title">Integration By Parts</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/partial_fractions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">40</span>&nbsp; <span class="chapter-title">Partial Fractions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/improper_integrals.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">41</span>&nbsp; <span class="chapter-title">Improper Integrals</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/mean_value_theorem.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">42</span>&nbsp; <span class="chapter-title">Mean value theorem for integrals</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/area_between_curves.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">43</span>&nbsp; <span class="chapter-title">Area between two curves</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/center_of_mass.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">44</span>&nbsp; <span class="chapter-title">Center of Mass</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/volumes_slice.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">45</span>&nbsp; <span class="chapter-title">Volumes by slicing</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/arc_length.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">46</span>&nbsp; <span class="chapter-title">Arc length</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integrals/surface_area.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">47</span>&nbsp; <span class="chapter-title">Surface Area</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-5" aria-expanded="true">ODEs</a>
<a class="sidebar-item-toggle text-start" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-5" aria-expanded="true">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-5" class="collapse list-unstyled sidebar-section depth1 show">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../ODEs/odes.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">48</span>&nbsp; <span class="chapter-title">ODEs</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../ODEs/euler.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">49</span>&nbsp; <span class="chapter-title">Eulers method</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../ODEs/solve.html" class="sidebar-item-text sidebar-link active"><span class="chapter-number">50</span>&nbsp; <span class="chapter-title">The problem-algorithm-solve interface</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../ODEs/differential_equations.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">51</span>&nbsp; <span class="chapter-title">The <code>DifferentialEquations</code> suite</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-6" aria-expanded="false">Differential vector calculus</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-6" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-6" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/polar_coordinates.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">52</span>&nbsp; <span class="chapter-title">Polar Coordinates and Curves</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/vectors.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">53</span>&nbsp; <span class="chapter-title">Vectors and matrices</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/vector_valued_functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">54</span>&nbsp; <span class="chapter-title">Vector-valued functions, <span class="math inline">\(f:R \rightarrow R^n\)</span></span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/scalar_functions.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">55</span>&nbsp; <span class="chapter-title">Scalar functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/scalar_functions_applications.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">56</span>&nbsp; <span class="chapter-title">Applications with scalar functions</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/vector_fields.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">57</span>&nbsp; <span class="chapter-title">Functions <span class="math inline">\(R^n \rightarrow R^m\)</span></span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../differentiable_vector_calculus/plots_plotting.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">58</span>&nbsp; <span class="chapter-title">2D and 3D plots in Julia with Plots</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-7" aria-expanded="false">Integral vector calculus</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-7" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-7" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integral_vector_calculus/double_triple_integrals.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">59</span>&nbsp; <span class="chapter-title">Multi-dimensional integrals</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integral_vector_calculus/line_integrals.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">60</span>&nbsp; <span class="chapter-title">Line and Surface Integrals</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integral_vector_calculus/div_grad_curl.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">61</span>&nbsp; <span class="chapter-title">The Gradient, Divergence, and Curl</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integral_vector_calculus/stokes_theorem.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">62</span>&nbsp; <span class="chapter-title">Greens Theorem, Stokes Theorem, and the Divergence Theorem</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../integral_vector_calculus/review.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">63</span>&nbsp; <span class="chapter-title">Quick Review of Vector Calculus</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-8" aria-expanded="false">Alternatives</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-8" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-8" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../alternatives/plotly_plotting.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">64</span>&nbsp; <span class="chapter-title">JavaScript based plotting libraries</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../alternatives/makie_plotting.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">65</span>&nbsp; <span class="chapter-title">Calculus plots with Makie</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item sidebar-item-section">
<div class="sidebar-item-container">
<a class="sidebar-item-text sidebar-link text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-9" aria-expanded="false">Appendices</a>
<a class="sidebar-item-toggle text-start collapsed" data-bs-toggle="collapse" data-bs-target="#quarto-sidebar-section-9" aria-expanded="false">
<i class="bi bi-chevron-right ms-2"></i>
</a>
</div>
<ul id="quarto-sidebar-section-9" class="collapse list-unstyled sidebar-section depth1 ">
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../misc/getting_started_with_julia.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">66</span>&nbsp; <span class="chapter-title">Getting started with Julia</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../misc/julia_interfaces.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">67</span>&nbsp; <span class="chapter-title">Julia interfaces</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../misc/calculus_with_julia.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">68</span>&nbsp; <span class="chapter-title">The <code>CalculusWithJulia</code> package</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../misc/unicode.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">69</span>&nbsp; <span class="chapter-title">Usages of Unicode symbols</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../misc/quick_notes.html" class="sidebar-item-text sidebar-link"><span class="chapter-number">70</span>&nbsp; <span class="chapter-title">Quick introduction to Calculus with Julia</span></a>
</div>
</li>
</ul>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../references.html" class="sidebar-item-text sidebar-link">References</a>
</div>
</li>
</ul>
</div>
</nav>
<!-- margin-sidebar -->
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
</div>
<!-- main -->
<main class="content" id="quarto-document-content">
<header id="title-block-header" class="quarto-title-block default">
<div class="quarto-title">
<h1 class="title d-none d-lg-block"><span class="chapter-number">50</span>&nbsp; <span class="chapter-title">The problem-algorithm-solve interface</span></h1>
</div>
<div class="quarto-title-meta">
</div>
</header>
<p>This section uses these add-on packages:</p>
<div class="sourceCode cell-code" id="cb1"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="im">using</span> <span class="bu">Plots</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="im">using</span> <span class="bu">MonteCarloMeasurements</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<hr>
<p>The <a href="https://github.com/SciML">DifferentialEquations.jl</a> package is an entry point to a suite of <code>Julia</code> packages for numerically solving differential equations in <code>Julia</code> and other languages. A common interface is implemented that flexibly adjusts to the many different problems and algorithms covered by this suite of packages. In this section, we review a very informative <a href="https://discourse.julialang.org/t/function-depending-on-the-global-variable-inside-module/64322/10">post</a> by discourse user <code>@genkuroki</code> which very nicely demonstrates the usefulness of the problem-algorithm-solve approach used with <code>DifferentialEquations.jl</code>. We slightly modify the presentation below for our needs, but suggest a perusal of the original post.</p>
<section id="example-freefall" class="level5">
<h5 class="anchored" data-anchor-id="example-freefall">Example: FreeFall</h5>
<p>The motion of an object under a uniform gravitational field is of interest.</p>
<p>The parameters that govern the equation of motions are the gravitational constant, <code>g</code>; the initial height, <code>y0</code>; and the initial velocity, <code>v0</code>. The time span for which a solution is sought is <code>tspan</code>.</p>
<p>A problem consists of these parameters. Typical <code>Julia</code> usage would be to create a structure to hold the parameters, which may be done as follows:</p>
<div class="cell" data-execution_count="4">
<div class="sourceCode cell-code" id="cb2"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Problem{G, Y0, V0, TS}</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> g<span class="op">::</span><span class="dt">G</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> y0<span class="op">::</span><span class="dt">Y0</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> v0<span class="op">::</span><span class="dt">V0</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> tspan<span class="op">::</span><span class="dt">TS</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="fu">Problem</span>(;g<span class="op">=</span><span class="fl">9.80665</span>, y0<span class="op">=</span><span class="fl">0.0</span>, v0<span class="op">=</span><span class="fl">30.0</span>, tspan<span class="op">=</span>(<span class="fl">0.0</span>,<span class="fl">8.0</span>)) <span class="op">=</span> <span class="fu">Problem</span>(g, y0, v0, tspan)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="5">
<pre><code>Problem</code></pre>
</div>
</div>
<p>The above creates a type, <code>Problem</code>, <em>and</em> a default constructor with default values. (The original uses a more sophisticated setup that allows the two things above to be combined.)</p>
<p>Just calling <code>Problem()</code> will create a problem suitable for the earth, passing different values for <code>g</code> would be possible for other planets.</p>
<p>To solve differential equations there are many different possible algorithms. Here is the construction of two types to indicate two algorithms:</p>
<div class="cell" data-execution_count="5">
<div class="sourceCode cell-code" id="cb4"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> EulerMethod{T}</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> dt<span class="op">::</span><span class="dt">T</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="fu">EulerMethod</span>(; dt<span class="op">=</span><span class="fl">0.1</span>) <span class="op">=</span> <span class="fu">EulerMethod</span>(dt)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ExactFormula{T}</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a> dt<span class="op">::</span><span class="dt">T</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="fu">ExactFormula</span>(; dt<span class="op">=</span><span class="fl">0.1</span>) <span class="op">=</span> <span class="fu">ExactFormula</span>(dt)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="6">
<pre><code>ExactFormula</code></pre>
</div>
</div>
<p>The above just specifies a type for dispatch - the directions indicating what code to use to solve the problem. As seen, each specifies a size for a time step with default of <code>0.1</code>.</p>
<p>A type for solutions is useful for different <code>show</code> methods or other methods. One can be created through:</p>
<div class="sourceCode cell-code" id="cb6"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Solution{Y, V, T, P<span class="op">&lt;:</span><span class="dt">Problem</span>, A}</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> y<span class="op">::</span><span class="dt">Y</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> v<span class="op">::</span><span class="dt">V</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> t<span class="op">::</span><span class="dt">T</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a> prob<span class="op">::</span><span class="dt">P</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a> alg<span class="op">::</span><span class="dt">A</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<p>The different algorithms then can be implemented as part of a generic <code>solve</code> function. Following the post we have:</p>
<div class="cell" data-execution_count="7">
<div class="sourceCode cell-code" id="cb7"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">solve</span>(prob<span class="op">::</span><span class="dt">Problem</span>) <span class="op">=</span> <span class="fu">solve</span>(prob, <span class="fu">default_algorithm</span>(prob))</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="fu">default_algorithm</span>(prob<span class="op">::</span><span class="dt">Problem</span>) <span class="op">=</span> <span class="fu">EulerMethod</span>()</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">solve</span>(prob<span class="op">::</span><span class="dt">Problem</span>, alg<span class="op">::</span><span class="dt">ExactFormula</span>)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a> g, y0, v0, tspan <span class="op">=</span> prob.g, prob.y0, prob.v0, prob.tspan</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a> dt <span class="op">=</span> alg.dt</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a> t0, t1 <span class="op">=</span> tspan</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a> t <span class="op">=</span> <span class="fu">range</span>(t0, t1 <span class="op">+</span> dt<span class="op">/</span><span class="fl">2</span>; step <span class="op">=</span> dt)</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">y</span>(t) <span class="op">=</span> y0 <span class="op">+</span> <span class="fu">v0*</span>(t <span class="op">-</span> t0) <span class="op">-</span> <span class="fu">g*</span>(t <span class="op">-</span> t0)<span class="op">^</span><span class="fl">2</span><span class="op">/</span><span class="fl">2</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a> <span class="fu">v</span>(t) <span class="op">=</span> v0 <span class="op">-</span> <span class="fu">g*</span>(t <span class="op">-</span> t0)</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a> <span class="fu">Solution</span>(<span class="fu">y</span>.(t), <span class="fu">v</span>.(t), t, prob, alg)</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">solve</span>(prob<span class="op">::</span><span class="dt">Problem</span>, alg<span class="op">::</span><span class="dt">EulerMethod</span>)</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a> g, y0, v0, tspan <span class="op">=</span> prob.g, prob.y0, prob.v0, prob.tspan</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a> dt <span class="op">=</span> alg.dt</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a> t0, t1 <span class="op">=</span> tspan</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a> t <span class="op">=</span> <span class="fu">range</span>(t0, t1 <span class="op">+</span> dt<span class="op">/</span><span class="fl">2</span>; step <span class="op">=</span> dt)</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a> n <span class="op">=</span> <span class="fu">length</span>(t)</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a> y <span class="op">=</span> <span class="fu">Vector</span><span class="dt">{typeof(y0)}</span>(<span class="cn">undef</span>, n)</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a> v <span class="op">=</span> <span class="fu">Vector</span><span class="dt">{typeof(v0)}</span>(<span class="cn">undef</span>, n)</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a> y[<span class="fl">1</span>] <span class="op">=</span> y0</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a> v[<span class="fl">1</span>] <span class="op">=</span> v0</span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> i <span class="kw">in</span> <span class="fl">1</span><span class="op">:</span>n<span class="op">-</span><span class="fl">1</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a> v[i<span class="op">+</span><span class="fl">1</span>] <span class="op">=</span> v[i] <span class="op">-</span> g<span class="op">*</span>dt <span class="co"># F*h step of Euler</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a> y[i<span class="op">+</span><span class="fl">1</span>] <span class="op">=</span> y[i] <span class="op">+</span> v[i]<span class="op">*</span>dt <span class="co"># F*h step of Euler</span></span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a> <span class="cf">end</span></span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-33"><a href="#cb7-33" aria-hidden="true" tabindex="-1"></a> <span class="fu">Solution</span>(y, v, t, prob, alg)</span>
<span id="cb7-34"><a href="#cb7-34" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="8">
<pre><code>solve (generic function with 3 methods)</code></pre>
</div>
</div>
<p>The post has a more elegant means to unpack the parameters from the structures, but for each of the above, the parameters are unpacked, and then the corresponding algorithm employed. As of version <code>v1.7</code> of <code>Julia</code>, the syntax <code>(;g,y0,v0,tspan) = prob</code> could also be employed.</p>
<p>The exact formulas, <code>y(t) = y0 + v0*(t - t0) - g*(t - t0)^2/2</code> and <code>v(t) = v0 - g*(t - t0)</code>, follow from well-known physics formulas. Each answer is wrapped in a <code>Solution</code> type so that the answers found can be easily extracted in a uniform manner.</p>
<p>For example, plots of each can be obtained through:</p>
<div class="cell" data-execution_count="8">
<div class="sourceCode cell-code" id="cb9"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>earth <span class="op">=</span> <span class="fu">Problem</span>()</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>sol_euler <span class="op">=</span> <span class="fu">solve</span>(earth)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>sol_exact <span class="op">=</span> <span class="fu">solve</span>(earth, <span class="fu">ExactFormula</span>())</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="fu">plot</span>(sol_euler.t, sol_euler.y;</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a> label<span class="op">=</span><span class="st">"Euler's method (dt = </span><span class="sc">$</span>(sol_euler.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="fu">plot!</span>(sol_exact.t, sol_exact.y; label<span class="op">=</span><span class="st">"exact solution"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="9">
<p><img src="solve_files/figure-html/cell-9-output-1.svg" class="img-fluid"></p>
</div>
</div>
<p>Following the post, since the time step <code>dt = 0.1</code> is not small enough, the error of the Euler method is rather large. Next we change the algorithm parameter, <code>dt</code>, to be smaller:</p>
<div class="cell" data-execution_count="9">
<div class="sourceCode cell-code" id="cb10"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>earth₂ <span class="op">=</span> <span class="fu">Problem</span>()</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>sol_euler₂ <span class="op">=</span> <span class="fu">solve</span>(earth₂, <span class="fu">EulerMethod</span>(dt <span class="op">=</span> <span class="fl">0.01</span>))</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>sol_exact₂ <span class="op">=</span> <span class="fu">solve</span>(earth₂, <span class="fu">ExactFormula</span>())</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="fu">plot</span>(sol_euler₂.t, sol_euler₂.y;</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a> label<span class="op">=</span><span class="st">"Euler's method (dt = </span><span class="sc">$</span>(sol_euler₂.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="fu">plot!</span>(sol_exact₂.t, sol_exact₂.y; label<span class="op">=</span><span class="st">"exact solution"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="10">
<p><img src="solve_files/figure-html/cell-10-output-1.svg" class="img-fluid"></p>
</div>
</div>
<p>It is worth noting that only the first line is modified, and only the method requires modification.</p>
<p>Were the moon to be considered, the gravitational constant would need adjustment. This parameter is part of the problem, not the solution algorithm.</p>
<p>Such adjustments are made by passing different values to the <code>Problem</code> constructor:</p>
<div class="cell" data-execution_count="10">
<div class="sourceCode cell-code" id="cb11"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>moon <span class="op">=</span> <span class="fu">Problem</span>(g <span class="op">=</span> <span class="fl">1.62</span>, tspan <span class="op">=</span> (<span class="fl">0.0</span>, <span class="fl">40.0</span>))</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>sol_eulerₘ <span class="op">=</span> <span class="fu">solve</span>(moon)</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>sol_exactₘ <span class="op">=</span> <span class="fu">solve</span>(moon, <span class="fu">ExactFormula</span>(dt <span class="op">=</span> sol_euler.alg.dt))</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="fu">plot</span>(sol_eulerₘ.t, sol_eulerₘ.y;</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> label<span class="op">=</span><span class="st">"Euler's method (dt = </span><span class="sc">$</span>(sol_eulerₘ.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="fu">plot!</span>(sol_exactₘ.t, sol_exactₘ.y; label<span class="op">=</span><span class="st">"exact solution"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Moon"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="11">
<p><img src="solve_files/figure-html/cell-11-output-1.svg" class="img-fluid"></p>
</div>
</div>
<p>The code above also adjusts the time span in addition to the graviational constant. The algorithm for exact formula is set to use the <code>dt</code> value used in the <code>euler</code> formula, for easier comparison. Otherwise, outside of the labels, the patterns are the same. Only those things that need changing are changed, the rest comes from defaults.</p>
<p>The above shows the benefits of using a common interface. Next, the post illustrates how <em>other</em> authors could extend this code, simply by adding a <em>new</em> <code>solve</code> method. For example,</p>
<div class="cell" data-execution_count="11">
<div class="sourceCode cell-code" id="cb12"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Symplectic2ndOrder{T}</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a> dt<span class="op">::</span><span class="dt">T</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="fu">Symplectic2ndOrder</span>(;dt<span class="op">=</span><span class="fl">0.1</span>) <span class="op">=</span> <span class="fu">Symplectic2ndOrder</span>(dt)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">solve</span>(prob<span class="op">::</span><span class="dt">Problem</span>, alg<span class="op">::</span><span class="dt">Symplectic2ndOrder</span>)</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> g, y0, v0, tspan <span class="op">=</span> prob.g, prob.y0, prob.v0, prob.tspan</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> dt <span class="op">=</span> alg.dt</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a> t0, t1 <span class="op">=</span> tspan</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a> t <span class="op">=</span> <span class="fu">range</span>(t0, t1 <span class="op">+</span> dt<span class="op">/</span><span class="fl">2</span>; step <span class="op">=</span> dt)</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a> n <span class="op">=</span> <span class="fu">length</span>(t)</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a> y <span class="op">=</span> <span class="fu">Vector</span><span class="dt">{typeof(y0)}</span>(<span class="cn">undef</span>, n)</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a> v <span class="op">=</span> <span class="fu">Vector</span><span class="dt">{typeof(v0)}</span>(<span class="cn">undef</span>, n)</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a> y[<span class="fl">1</span>] <span class="op">=</span> y0</span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a> v[<span class="fl">1</span>] <span class="op">=</span> v0</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> i <span class="kw">in</span> <span class="fl">1</span><span class="op">:</span>n<span class="op">-</span><span class="fl">1</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a> ytmp <span class="op">=</span> y[i] <span class="op">+</span> v[i]<span class="op">*</span>dt<span class="op">/</span><span class="fl">2</span></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a> v[i<span class="op">+</span><span class="fl">1</span>] <span class="op">=</span> v[i] <span class="op">-</span> g<span class="op">*</span>dt</span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a> y[i<span class="op">+</span><span class="fl">1</span>] <span class="op">=</span> ytmp <span class="op">+</span> v[i<span class="op">+</span><span class="fl">1</span>]<span class="op">*</span>dt<span class="op">/</span><span class="fl">2</span></span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a> <span class="cf">end</span></span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a> <span class="fu">Solution</span>(y, v, t, prob, alg)</span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a><span class="kw">end</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="12">
<pre><code>solve (generic function with 4 methods)</code></pre>
</div>
</div>
<p>Had the two prior methods been in a package, the other user could still extend the interface, as above, with just a slight standard modification.</p>
<p>The same approach works for this new type:</p>
<div class="cell" data-execution_count="12">
<div class="sourceCode cell-code" id="cb14"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>earth₃ <span class="op">=</span> <span class="fu">Problem</span>()</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>sol_sympl₃ <span class="op">=</span> <span class="fu">solve</span>(earth₃, <span class="fu">Symplectic2ndOrder</span>(dt <span class="op">=</span> <span class="fl">2.0</span>))</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>sol_exact₃ <span class="op">=</span> <span class="fu">solve</span>(earth₃, <span class="fu">ExactFormula</span>())</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="fu">plot</span>(sol_sympl₃.t, sol_sympl₃.y; label<span class="op">=</span><span class="st">"2nd order symplectic (dt = </span><span class="sc">$</span>(sol_sympl₃.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="fu">plot!</span>(sol_exact₃.t, sol_exact₃.y; label<span class="op">=</span><span class="st">"exact solution"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="13">
<p><img src="solve_files/figure-html/cell-13-output-1.svg" class="img-fluid"></p>
</div>
</div>
<p>Finally, the author of the post shows how the interface can compose with other packages in the <code>Julia</code> package ecosystem. This example uses the external package <code>MonteCarloMeasurements</code> which plots the behavior of the system for perturbations of the initial value:</p>
<div class="cell" data-execution_count="13">
<div class="sourceCode cell-code" id="cb15"><pre class="sourceCode julia code-with-copy"><code class="sourceCode julia"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>earth₄ <span class="op">=</span> <span class="fu">Problem</span>(y0 <span class="op">=</span> <span class="fl">0.0</span> <span class="op">±</span> <span class="fl">0.0</span>, v0 <span class="op">=</span> <span class="fl">30.0</span> <span class="op">±</span> <span class="fl">1.0</span>)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>sol_euler₄ <span class="op">=</span> <span class="fu">solve</span>(earth₄)</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>sol_sympl₄ <span class="op">=</span> <span class="fu">solve</span>(earth₄, <span class="fu">Symplectic2ndOrder</span>(dt <span class="op">=</span> <span class="fl">2.0</span>))</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>sol_exact₄ <span class="op">=</span> <span class="fu">solve</span>(earth₄, <span class="fu">ExactFormula</span>())</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>ylim <span class="op">=</span> (<span class="op">-</span><span class="fl">100</span>, <span class="fl">60</span>)</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>P <span class="op">=</span> <span class="fu">plot</span>(sol_euler₄.t, sol_euler₄.y;</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a> label<span class="op">=</span><span class="st">"Euler's method (dt = </span><span class="sc">$</span>(sol_euler₄.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft, ylim)</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>Q <span class="op">=</span> <span class="fu">plot</span>(sol_sympl₄.t, sol_sympl₄.y;</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a> label<span class="op">=</span><span class="st">"2nd order symplectic (dt = </span><span class="sc">$</span>(sol_sympl₄.alg.dt)<span class="st">)"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft, ylim)</span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>R <span class="op">=</span> <span class="fu">plot</span>(sol_exact₄.t, sol_exact₄.y; label<span class="op">=</span><span class="st">"exact solution"</span>, ls<span class="op">=:</span>auto)</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a><span class="fu">title!</span>(<span class="st">"On the Earth"</span>; xlabel<span class="op">=</span><span class="st">"t"</span>, legend<span class="op">=:</span>bottomleft, ylim)</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a><span class="fu">plot</span>(P, Q, R; size<span class="op">=</span>(<span class="fl">720</span>, <span class="fl">600</span>))</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="14">
<p><img src="solve_files/figure-html/cell-14-output-1.svg" class="img-fluid"></p>
</div>
</div>
<p>The only change was in the problem, <code>Problem(y0 = 0.0 ± 0.0, v0 = 30.0 ± 1.0)</code>, where a different number type is used which accounts for uncertainty. The rest follows the same pattern.</p>
<p>This example, shows the flexibility of the problem-algorithm-solver pattern while maintaining a consistent pattern for execution.</p>
</section>
</main> <!-- /main -->
<script id="quarto-html-after-body" type="application/javascript">
window.document.addEventListener("DOMContentLoaded", function (event) {
const toggleBodyColorMode = (bsSheetEl) => {
const mode = bsSheetEl.getAttribute("data-mode");
const bodyEl = window.document.querySelector("body");
if (mode === "dark") {
bodyEl.classList.add("quarto-dark");
bodyEl.classList.remove("quarto-light");
} else {
bodyEl.classList.add("quarto-light");
bodyEl.classList.remove("quarto-dark");
}
}
const toggleBodyColorPrimary = () => {
const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
if (bsSheetEl) {
toggleBodyColorMode(bsSheetEl);
}
}
toggleBodyColorPrimary();
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {
placement: 'right',
icon: icon
};
anchorJS.add('.anchored');
const clipboard = new window.ClipboardJS('.code-copy-button', {
target: function(trigger) {
return trigger.previousElementSibling;
}
});
clipboard.on('success', function(e) {
// button target
const button = e.trigger;
// don't keep focus
button.blur();
// flash "checked"
button.classList.add('code-copy-button-checked');
var currentTitle = button.getAttribute("title");
button.setAttribute("title", "Copied!");
setTimeout(function() {
button.setAttribute("title", currentTitle);
button.classList.remove('code-copy-button-checked');
}, 1000);
// clear code selection
e.clearSelection();
});
function tippyHover(el, contentFn) {
const config = {
allowHTML: true,
content: contentFn,
maxWidth: 500,
delay: 100,
arrow: false,
appendTo: function(el) {
return el.parentElement;
},
interactive: true,
interactiveBorder: 10,
theme: 'quarto',
placement: 'bottom-start'
};
window.tippy(el, config);
}
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
for (var i=0; i<noterefs.length; i++) {
const ref = noterefs[i];
tippyHover(ref, function() {
let href = ref.getAttribute('href');
try { href = new URL(href).hash; } catch {}
const id = href.replace(/^#\/?/, "");
const note = window.document.getElementById(id);
return note.innerHTML;
});
}
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
for (var i=0; i<bibliorefs.length; i++) {
const ref = bibliorefs[i];
const cites = ref.parentNode.getAttribute('data-cites').split(' ');
tippyHover(ref, function() {
var popup = window.document.createElement('div');
cites.forEach(function(cite) {
var citeDiv = window.document.createElement('div');
citeDiv.classList.add('hanging-indent');
citeDiv.classList.add('csl-entry');
var biblioDiv = window.document.getElementById('ref-' + cite);
if (biblioDiv) {
citeDiv.innerHTML = biblioDiv.innerHTML;
}
popup.appendChild(citeDiv);
});
return popup.innerHTML;
});
}
var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
var filterRegex = new RegExp('/' + window.location.host + '/');
var isInternal = (href) => {
return filterRegex.test(href) || localhostRegex.test(href);
}
// Inspect non-navigation links and adorn them if external
var links = window.document.querySelectorAll('a:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external)');
for (var i=0; i<links.length; i++) {
const link = links[i];
if (!isInternal(link.href)) {
// target, if specified
link.setAttribute("target", "_blank");
}
}
});
</script>
<nav class="page-navigation">
<div class="nav-page nav-page-previous">
<a href="../ODEs/euler.html" class="pagination-link">
<i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">49</span>&nbsp; <span class="chapter-title">Eulers method</span></span>
</a>
</div>
<div class="nav-page nav-page-next">
<a href="../ODEs/differential_equations.html" class="pagination-link">
<span class="nav-page-text"><span class="chapter-number">51</span>&nbsp; <span class="chapter-title">The <code>DifferentialEquations</code> suite</span></span> <i class="bi bi-arrow-right-short"></i>
</a>
</div>
</nav>
</div> <!-- /content -->
<footer class="footer">
<div class="nav-footer">
<div class="nav-footer-center">Copyright 2022, John Verzani</div>
</div>
</footer>
</body></html>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 54 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 260 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More