@@ -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"
|
||||
@@ -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.
|
||||
1046
CwJ/alternatives/makie_plotting.jmd
Normal 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"
|
||||
|
||||
1
quarto/0e7f54ed/.nojekyll
Normal file
@@ -0,0 +1 @@
|
||||
ff40b40b
|
||||
1124
quarto/0e7f54ed/ODEs/differential_equations.html
Normal file
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 76 KiB |
1575
quarto/0e7f54ed/ODEs/euler.html
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 32 KiB |
687
quarto/0e7f54ed/ODEs/euler_files/figure-html/cell-7-output-1.svg
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
quarto/0e7f54ed/ODEs/figures/bead-game.jpg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
quarto/0e7f54ed/ODEs/figures/euler.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
quarto/0e7f54ed/ODEs/figures/galileo.gif
Normal file
|
After Width: | Height: | Size: 885 B |
|
After Width: | Height: | Size: 98 KiB |
1874
quarto/0e7f54ed/ODEs/odes.html
Normal file
109
quarto/0e7f54ed/ODEs/odes_files/figure-html/cell-27-output-1.svg
Normal file
|
After Width: | Height: | Size: 23 KiB |
679
quarto/0e7f54ed/ODEs/odes_files/figure-html/cell-29-output-1.svg
Normal file
|
After Width: | Height: | Size: 57 KiB |
734
quarto/0e7f54ed/ODEs/odes_files/figure-html/cell-30-output-1.svg
Normal file
|
After Width: | Height: | Size: 64 KiB |
134
quarto/0e7f54ed/ODEs/odes_files/figure-html/cell-5-output-1.svg
Normal file
|
After Width: | Height: | Size: 22 KiB |
980
quarto/0e7f54ed/ODEs/solve.html
Normal 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 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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <span class="chapter-title">Newton’s 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> <span class="chapter-title">Derivative-free alternatives to Newton’s 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> <span class="chapter-title">L’Hospital’s 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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <span class="chapter-title">Euler’s 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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <span class="chapter-title">Green’s 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> <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> <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> <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> <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> <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> <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> <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> <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> <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"><:</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> <span class="chapter-title">Euler’s 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> <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>
|
||||
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 45 KiB |
1564
quarto/0e7f54ed/ODEs/solve_files/figure-html/cell-14-output-1.svg
Normal file
|
After Width: | Height: | Size: 260 KiB |
130
quarto/0e7f54ed/ODEs/solve_files/figure-html/cell-9-output-1.svg
Normal file
|
After Width: | Height: | Size: 44 KiB |
1806
quarto/0e7f54ed/alternatives/makie_plotting.html
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 200 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 10 KiB |