CalculusWithJuliaSquared API
CalculusWithJuliaSquared is a separate, pure-Julia package — a fork of CalculusWithJulia — that these study materials are built on. It has its own repository, versioning, and documentation; it is not maintained as part of Calculus.
Calculus does, however, @reexport it, so its exported helpers (lim, tangent, secant, D, riemann, ∇, …) are available directly once you using Calculus — no separate install or using CalculusWithJuliaSquared needed. That is why its API is documented here: the reference below is generated from the package's own docstrings, so it always tracks the installed version.
The companion notes that exercise this package are a work-in-progress port of the Calculus with Julia notes onto Symbolics / pure Julia:
- The original notes (Python-backed
SymPy): Calculus with Julia, by John Verzani. - Our fork, where the port progresses chapter by chapter: CalculusWithJuliaSquaredNotes.jl on GitHub.
- The rendered ported book — forthcoming at
fourm.info/cwjsn.
CalculusWithJuliaSquared.CalculusWithJuliaSquared — Module
CalculusWithJuliaSquaredA personal, pure-Julia fork of CalculusWithJulia.jl to accompany notes at https://calculuswithjulia.github.io on using Julia for topics from the calculus sequence.
This package does two things:
It loads a few other packages making it easier to use (and install) the functionality provided by them and
It defines a handful of functions for convenience. The exported ones
are unzip, rangeclamp tangent, secant, D (and the prime notation), divergence, gradient, curl, and ∇, along with some plotting functions. The constant e is assigned to exp(1).
Packages loaded by CalculusWithJuliaSquared
The
SpecialFunctionsis loaded giving access to a few special functions used in these notes, e.g.,airyai,gammaThe
ForwardDiffpackage is loaded giving access to itsderivative,gradient,jacobian, andhessianfunctions for finding automatic derivatives of functions. In addition, this package defines'(for functions) to return a derivative (which commits type piracy),∇to find the gradient (∇(f)), the divergence (∇⋅F). and the curl (∇×F), along withdivergenceandcurl.
The
LinearAlgebrapackage is loaded for access to several of its functions for working with vectorsnorm,cdot(⋅),cross(×),det.The
PlotUtilspackage is loaded so that itsadapted_gridfunction is available.The
Symbolicspackage is loaded (and reexported) giving access to symbolic math (@variables, etc.) along with symbolicgradient,divergence, andcurlmethods – pure Julia, no Python dependency.The
Plotspackage is loaded (and reexported) providing the plotting interface directly – no separateusing Plotsneeded.
Several plot recipes are provided to ease the creation of plots in the notes. plotif, trimplot, and signchart are used for plotting univariate functions; plot_polar and plot_parametric are used to plot curves in 2 or 3 dimensions; plot_parametric also makes the plotting og parameterically defined surfaces easier; vectorfieldplot and vectorfieldplot3d can be used to plot vector fields; and arrow is a simplified interface to quiver that also indicates 3D vectors.
The plot_implicit function can plot 2D implicit plots. (It is borrowed from ImplicitPlots.jl, which is avoided, as it has dependencies that hold other packages back.)
Other packages with a recurring role in the accompanying notes:
Rootsis used to find zeros of univariate functionsQuadGKandHCubatureare used for numeric integration
CalculusWithJuliaSquared.SignChart — Type
SignChart(f, a, b)Numerically identifies values of x in [a,b] where f is 0, oo, or undefined.
Displays the output as a sideways interval displaying the sign of f in between these values.
Example
julia> SignChart((x -> sqrt(1 - x^2))', -1, 1)
↑
⋮
1.0 is infinite
⋮
+
⋮
0.0 a zero
⋮
-
⋮
-1.0 is infinite
⋮
↓
CalculusWithJuliaSquared.D — Function
D(f)Function interface to ForwardDiff.derivative.
A method for adjoint for functions dispatches to D, so that the notation f' can be used to take the derivative of a function. (This is type piracy.)
CalculusWithJuliaSquared.arrow! — Method
arrow(p, v)
Add vector, v, to plot anchored at point p.
Example
Fn = parametric(t -> [2cos(t), 3sin(t)])
Fnp = t -> ForwardDiff.derivative(Fn, t)
p = plot(Fn, 0, 2pi, legend=false)
for t in 0:pi/4:pi
arrow!(Fn(t), Fnp(t))
end
pCalculusWithJuliaSquared.arrow! — Method
arrow(p, v)
Add vector, v, to plot anchored at point p.
Example
Fn = parametric(t -> [2cos(t), 3sin(t)])
Fnp = t -> ForwardDiff.derivative(Fn, t)
p = plot(Fn, 0, 2pi, legend=false)
for t in 0:pi/4:pi
arrow!(Fn(t), Fnp(t))
end
pCalculusWithJuliaSquared.arrow! — Method
arrow!(p, v)
Add the vector v to the plot anchored at p.
This would just be a call to quiver, but there is no 3-D version of that. As well, the syntax for quiver is a bit awkward for plotting just a single arrow. (Though efficient if plotting many).
using Plots
r(t) = [sin(t), cos(t), t]
rp(t) = [cos(t), -sin(t), 1]
plot(unzip(r, 0, 2pi)...)
t0 = 1
arrow!(r(t0), rp(t0))CalculusWithJuliaSquared.arrow — Method
arrow(p, v)
Add vector, v, to plot anchored at point p.
Example
Fn = parametric(t -> [2cos(t), 3sin(t)])
Fnp = t -> ForwardDiff.derivative(Fn, t)
p = plot(Fn, 0, 2pi, legend=false)
for t in 0:pi/4:pi
arrow!(Fn(t), Fnp(t))
end
pCalculusWithJuliaSquared.curl — Method
curl(F)Find curl of a 2 or 3-D vector field.
CalculusWithJuliaSquared.divergence — Method
divergence(F)Find divergence of a 3-D vector vield.
CalculusWithJuliaSquared.fisheye — Method
fisheye(f)Transform f defined on (-∞, ∞) to a new function whose domain is in (-π/2, π/2) and range is within (-π/2, π/2). Useful for finding all zeros over the real line. For example
f(x) = 1 + 100x^2 - x^3
fzeros(f, -100, 100) # empty just misses the zero found with:
fzeros(fisheye(f), -pi/2, pi/2) .|> tan # finds 100.19469143521222, not perfect but easy to getBy Gunter Fuchs.
CalculusWithJuliaSquared.fubini — Method
fubini(f, [zs], [ys], xs; rtol=missing, kws...)Integrate f of 1, 2, or 3 input variables.
The zs may depend (x,y), the ys may depend on x
Examples
# integrate over the unit square
fubini((x,y) -> sin(x-y), (0,1), (0,1))
# integrate over a triangle
fubini((x,y) -> 1, (0,identity), (0,1 ))
#
f(x,y,z) = x*y^2*z^3
fubini(f, (0,(x,y) -> x+ y), (0, x -> x), (0,1))!!! Note This uses nested calls to quadgk. The use of hcubature is recommended, typically after a change of variables to make a rectangular domain. The relative tolerance increases at each nested level.
CalculusWithJuliaSquared.lim — Method
lim(f, c; n=6, m=1, dir="+-")
lim(f, c, dir; n-5)Means to generate numeric table of values of f as h gets close to c.
n,m: powers of10to add (subtract) to (from)c.dir: Either"+-"(show left and right),"+"(right limit), or"-"(left limit). Can also use functions+,-,±.
Example:
julia> f(x) = sin(x) / x
f (generic function with 1 method)
julia> lim(f, 0)
0.1 0.9983341664682815
0.01 0.9999833334166665
0.001 0.9999998333333416
0.0001 0.9999999983333334
1.0e-5 0.9999999999833332
1.0e-6 0.9999999999998334
⋮ ⋮
c L?
⋮ ⋮
-1.0e-6 0.9999999999998334
-1.0e-5 0.9999999999833332
-0.0001 0.9999999983333334
-0.001 0.9999998333333416
-0.01 0.9999833334166665
-0.1 0.9983341664682815CalculusWithJuliaSquared.newton_plot! — Method
newton_plot!(f, x0; steps=5, annotate_steps::Int=0, kwargs...)Add trace of Newton's method to plot.
steps: how many steps fromx0to illustrateannotate_steps::Int: how may steps to annotate
CalculusWithJuliaSquared.plot_implicit_surface — Function
Visualize `F(x,y,z) = c` by plotting assorted contour linesThis graphic makes slices in the x, y, and/or z direction of the 3-D level surface and plots them accordingly. Which slices (and their colors) are specified through a dictionary.
Examples:
F(x,y,z) = x^2 + y^2 + x^2
plot_implicit_surface(F, 20) # 20 slices in z direction
plot_implicit_surface(F, 20, slices=Dict(:x=>:blue, :y=>:red, :z=>:green), nlevels=6) # all 3 shown
# A heart
a,b = 1,3
F(x,y,z) = (x^2+((1+b)*y)^2+z^2-1)^3-x^2*z^3-a*y^2*z^3
plot_implicit_surface(F, xlims=-2..2,ylims=-1..1,zlims=-1..2)Note: Idea from.
Not exported.
CalculusWithJuliaSquared.plot_parametric — Method
plot_parametric(ab, r; kwargs...)
plot_parametric!(ab, r; kwargs...)
plot_parametric(u, v, F; kwargs...)
plot_parametric!(u, v, F; kwargs...)Make a parametric plot of a space curve or parametrized surface
The intervals to plot over are specifed using a..b notation, from IntervalSets
CalculusWithJuliaSquared.plotif — Method
plotif(f, g, a, b)Plot of f over [a,b] with the intervals where g ≥ 0 highlighted in many ways.
CalculusWithJuliaSquared.rangeclamp — Function
rangeclamp(f, hi=20, lo=-hi; replacement=NaN)Modify f so that values of f(x) outside of [lo,hi] are replaced by replacement.
Examples
f(x) = 1/x
plot(rangeclamp(f), -1, 1)
plot(rangeclamp(f, 10), -1, 1) # no `abs(y)` values exceeding 10CalculusWithJuliaSquared.riemann — Method
riemann(f, a, b, n; method="right"Compute an approximations to the definite integral of f over [a,b] using an equal-sized partition of size n+1.
method: "right" (default), "left", "trapezoid", "simpsons", "ct", "m̃" (minimum over interval), "M̃" (maximum over interval)
Example:
f(x) = exp(x^2)
riemann(f, 0, 1, 1000) # default right-Riemann sums
riemann(f, 0, 1, 1000; method="left") # left sums
riemann(f, 0, 1, 1000; method="trapezoid") # use trapezoid rule
riemann(f, 0, 1, 1000; method="simpsons") # use Simpson's ruleCalculusWithJuliaSquared.riemann_plot — Method
riemann_plot!(f, a, b, n; method="method", fill, kwargs...)
riemann_plot(f, a, b, n; method="method", fill, kwargs...)Add visualization of riemann sum in a layer.
method: one ofright,left,trapezoid,simpsonsfill: to specify fill color, something like("green", 0.25, 0)will fill in green with an alpha transparency.
CalculusWithJuliaSquared.secant — Method
secant(f::Function, a, b)Returns a function describing the secant line to the graph of f at x=a and x=b.
Example. Where does the secant line intersect the y axis?
f(x) = sin(x)
a, b = pi/4, pi/3
sl = secant(f, a, b) # or sl(x) = secant(f, a, b)(x) to use a generic function
sl(0)CalculusWithJuliaSquared.sign_chart — Method
sign_chart(f, a, b; atol=1e-4)
Create a sign chart for f over (a,b). Returns a collection of named tuples, each with an identified zero or vertical asymptote and the corresponding sign change. The tolerance is used to disambiguate numerically found values.
Example
julia> sign_chart(x -> (x-1/2)/(x*(1-x)), 0, 1)
3-element Vector{NamedTuple{(:zero_oo_NaN, :sign_change)}}:
(zero_oo_NaN = 0.0, sign_change = an endpoint)
(zero_oo_NaN = 0.5, sign_change = - to +)
(zero_oo_NaN = 1.0, sign_change = an endpoint)CalculusWithJuliaSquared.signchart — Method
signchart(f, a, b)
Plot f over a,b with different color when negative.
CalculusWithJuliaSquared.tangent — Method
tangent(f::Function, c)Returns a function describing the tangent line to the graph of f at x=c.
Example. Where does the tangent line intersect the y axis?
f(x) = sin(x)
tl = tangent(f, pi/4) # or tl(x) = tangent(f, pi/3)(x) to use a generic function
tl(0)Uses the automatic derivative of f to find the slope of the tangent line at x=c.
CalculusWithJuliaSquared.trimplot — Function
trimplot(f, a, b, c=20; kwargs...)
Plot f over [a,b] but break graph if it exceeds c in absolute value.
CalculusWithJuliaSquared.unzip — Method
unzip(vs)
unzip(v1, v2, ...)
unzip(r::Function, a, b)Take a vector of points described by vectors (as returned by, say r(t)=[sin(t),cos(t)], r.([1,2,3]), and return a tuple of collected x values, y values, and optionally z values.
Wrapper around the invert function of SplitApplyCombine.
If the argument is specified as a comma separated collection of vectors, then these are combined and passed along.
If the argument is a function and two end points, then the function is evaluated at points between a and b; for the univaraite case, the points are chosen adaptively.
This is useful for plotting when the data is more conveniently represented in terms of vectors, but the plotting interface requires the x and y values collected.
Examples:
using Plots
r(t) = [sin(t), cos(t)]
rp(t) = [cos(t), -sin(t)]
plot(unzip(r, 0, 2pi)...) # calls plot(xs, ys)
t0, t1 = pi/6, pi/4
p, v = r(t0), rp(t0)
plot!(unzip(p, p+v)...) # connect p to p+v with line
p, v = r(t1), rp(t1)
quiver!(unzip([p])..., quiver=unzip([v]))Based on unzip from the Plots package. Implemented through invert of SplitApplyCombine
Note: for a vector of points, xs, each of length 2, a similar functionality would be (first.(xs), last.(xs)). If each point had length 3, then with second(x)=x[2], a similar functionality would be (first.(xs), second.(xs), last.(xs)).
```
CalculusWithJuliaSquared.uvec — Method
uvec(x)
Helper to find a unit vector.
CalculusWithJuliaSquared.vectorfieldplot! — Method
vectorfieldplot(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=8], [ny=8])Create a vector field plot using a grid described by xlim, ylim with nx and ny grid points in each direction.
F(x,y) = [-y, x]
vectorfieldplot(F, xlim=(-4,4), ylim=(-4,4))CalculusWithJuliaSquared.vectorfieldplot! — Method
vectorfieldplot(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=8], [ny=8])Create a vector field plot using a grid described by xlim, ylim with nx and ny grid points in each direction.
F(x,y) = [-y, x]
vectorfieldplot(F, xlim=(-4,4), ylim=(-4,4))CalculusWithJuliaSquared.vectorfieldplot! — Method
vectorfieldplot(V; xlim=(-5,5), ylim=(-5,5), n=10; kwargs...)V is a function that takes a point and returns a vector (2D dimensions), such as V(x) = x[1]^2 + x[2]^2.
The grid xlim × ylim is paritioned into (n+1) × (n+1) points. At each point, pt, a vector proportional to V(pt) is drawn.
This is written to add to an existing plot.
plot() # make a plot
V(x,y) = [x, y-x]
vectorfield_plot!(p, V)
pCalculusWithJuliaSquared.vectorfieldplot — Method
vectorfieldplot(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=8], [ny=8])Create a vector field plot using a grid described by xlim, ylim with nx and ny grid points in each direction.
F(x,y) = [-y, x]
vectorfieldplot(F, xlim=(-4,4), ylim=(-4,4))CalculusWithJuliaSquared.vectorfieldplot3d! — Method
vectorfieldplot3d(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=5], [ny=5])Create a 3 dimensional vector field plot using a grid described by xlim, ylim, zlim with nx, ny, and nz grid points in each direction.
Note: the vectors are represented with line, not arrow due to no implementation of :quiver3d.
F(x,y,z) = [-y, x,z]
vectorfieldplot3d(F, xlims=(-4,4), ylims=(-4,4), zlims=(0,3))CalculusWithJuliaSquared.vectorfieldplot3d! — Method
vectorfieldplot3d(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=5], [ny=5])Create a 3 dimensional vector field plot using a grid described by xlim, ylim, zlim with nx, ny, and nz grid points in each direction.
Note: the vectors are represented with line, not arrow due to no implementation of :quiver3d.
F(x,y,z) = [-y, x,z]
vectorfieldplot3d(F, xlims=(-4,4), ylims=(-4,4), zlims=(0,3))CalculusWithJuliaSquared.vectorfieldplot3d — Method
vectorfieldplot3d(F; [xlim=(-5,5)], [ylim=(-5,5)], [nx=5], [ny=5])Create a 3 dimensional vector field plot using a grid described by xlim, ylim, zlim with nx, ny, and nz grid points in each direction.
Note: the vectors are represented with line, not arrow due to no implementation of :quiver3d.
F(x,y,z) = [-y, x,z]
vectorfieldplot3d(F, xlims=(-4,4), ylims=(-4,4), zlims=(0,3))