pdf files; edits
This commit is contained in:
28
quarto/alternatives/Project.toml
Normal file
28
quarto/alternatives/Project.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[deps]
|
||||
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||
CalculusWithJulia = "a2e0e22d-7d4c-5312-9169-8b992201a882"
|
||||
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
|
||||
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
|
||||
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
|
||||
Implicit3DPlotting = "d997a800-832a-4a4c-b340-7dddf3c1ad50"
|
||||
Integrals = "de52edbc-65ea-441a-8357-d3a637375a31"
|
||||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||
Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73"
|
||||
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
|
||||
NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
|
||||
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
|
||||
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
|
||||
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
|
||||
PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5"
|
||||
PlotlyKaleido = "f2990250-8cf9-495f-b13a-cce12b45703c"
|
||||
PlotlyLight = "ca7969ec-10b3-423e-8d99-40f33abb42bf"
|
||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
|
||||
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"
|
||||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
|
||||
SymbolicLimits = "19f23fe9-fdab-4a78-91af-e7b7767979c3"
|
||||
SymbolicNumericIntegration = "78aadeae-fbc0-11eb-17b6-c7ec0477ba9e"
|
||||
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
|
||||
@@ -304,11 +304,11 @@ x0 = [4.0]
|
||||
prob = OptimizationProblem(F, x0)
|
||||
```
|
||||
|
||||
The problem is solved through the common interface with a specified method, in this case `Newton`:
|
||||
The problem is solved through the common interface with a specified method, in this case `NelderMead`:
|
||||
|
||||
|
||||
```{julia}
|
||||
soln = solve(prob, Newton())
|
||||
soln = solve(prob, NelderMead())
|
||||
```
|
||||
|
||||
:::{.callout-note}
|
||||
|
||||
1
quarto/alternatives/_pdf_index.qmd
Symbolic link
1
quarto/alternatives/_pdf_index.qmd
Symbolic link
@@ -0,0 +1 @@
|
||||
../alternatives.qmd
|
||||
18
quarto/alternatives/make_pdf.jl
Normal file
18
quarto/alternatives/make_pdf.jl
Normal file
@@ -0,0 +1,18 @@
|
||||
module Make
|
||||
|
||||
# makefile for generating typst pdfs
|
||||
# per directory usage
|
||||
|
||||
dir = "alternatives"
|
||||
files = (
|
||||
"symbolics",
|
||||
"SciML",
|
||||
"plotly_plotting",
|
||||
"makie_plotting",
|
||||
|
||||
)
|
||||
|
||||
include("../_make_pdf.jl")
|
||||
|
||||
main()
|
||||
end
|
||||
@@ -867,52 +867,31 @@ end
|
||||
|
||||
To plot the equation $F(x,y,z)=0$, for $F$ a scalar-valued function, again the implicit function theorem says that, under conditions, near any solution $(x,y,z)$, $z$ can be represented as a function of $x$ and $y$, so the graph will look likes surfaces stitched together. The `Implicit3DPlotting` package takes an approach like `ImplicitPlots` to represent these surfaces. It replaces the `Contour` package computation with a $3$-dimensional alternative provided through the `Meshing` and `GeometryBasics` packages.
|
||||
|
||||
|
||||
The `Implicit3DPlotting` package needs some maintenance, so we borrow the main functionality and wrap it into a function:
|
||||
|
||||
|
||||
```{julia}
|
||||
import Meshing
|
||||
import GeometryBasics
|
||||
|
||||
function make_mesh(xlims, ylims, zlims, f,
|
||||
M = Meshing.MarchingCubes(); # or Meshing.MarchingTetrahedra()
|
||||
samples=(35, 35, 35),
|
||||
)
|
||||
|
||||
lims = extrema.((xlims, ylims, zlims))
|
||||
Δ = xs -> last(xs) - first(xs)
|
||||
xs = Vec(first.(lims))
|
||||
Δxs = Vec(Δ.(lims))
|
||||
|
||||
GeometryBasics.Mesh(f, Rect(xs, Δxs), M; samples = samples)
|
||||
end
|
||||
using Implicit3DPlotting
|
||||
```
|
||||
|
||||
The `make_mesh` function creates a mesh that can be visualized with the `wireframe` or `mesh` plotting functions.
|
||||
|
||||
|
||||
This example, plotting an implicitly defined sphere, comes from the documentation of `Implicit3DPlotting`. The `f` in `make_mesh` is a scalar-valued function of a vector:
|
||||
This example, plotting an implicitly defined sphere, comes from the documentation of `Implicit3DPlotting`. The `f` to be plotted is a scalar-valued function of a vector:
|
||||
|
||||
|
||||
```{julia}
|
||||
f(x) = sum(x.^2) - 1
|
||||
xs = ys = zs = (-5, 5)
|
||||
m = make_mesh(xs, ys, zs, f)
|
||||
wireframe(m)
|
||||
xlims = ylims = zlims = (-5, 5)
|
||||
plot_implicit_surface(f; xlims, ylims, zlims)
|
||||
```
|
||||
|
||||
|
||||
|
||||
Here we visualize an intersection of a sphere with another figure:
|
||||
|
||||
|
||||
```{julia}
|
||||
r₂(x) = sum(x.^2) - 5/4 # a sphere
|
||||
r₄(x) = sum(x.^4) - 1
|
||||
xs = ys = zs = -2:2
|
||||
m2,m4 = make_mesh(xs, ys, zs, r₂), make_mesh(xs, ys, zs, r₄)
|
||||
|
||||
wireframe(m4, color=:yellow)
|
||||
wireframe!(m2, color=:red)
|
||||
xlims = ylims = zlims = (-2, 2)
|
||||
p = plot_implicit_surface(r₂; xlims, ylims, zlims, color=:yellow)
|
||||
plot_implicit_surface!(p, r₄; xlims, ylims, zlims, color=:red)
|
||||
current_figure()
|
||||
```
|
||||
|
||||
@@ -921,9 +900,8 @@ This example comes from [Wikipedia](https://en.wikipedia.org/wiki/Implicit_surfa
|
||||
|
||||
```{julia}
|
||||
f(x,y,z) = 2y*(y^2 -3x^2)*(1-z^2) + (x^2 +y^2)^2 - (9z^2-1)*(1-z^2)
|
||||
zs = ys = xs = range(-5/2, 5/2, length=100)
|
||||
m = make_mesh(xs, ys, zs, x -> f(x...))
|
||||
wireframe(m)
|
||||
xlims = ylims = zlims = (-5/2, 5/2)
|
||||
plot_implicit_surface(x -> f(x...); xlims, ylims, zlims)
|
||||
```
|
||||
|
||||
(This figure does not render well through `contour(xs, ys, zs, f, levels=[0])`, as the hole is not shown.)
|
||||
@@ -937,9 +915,8 @@ function cassini(λ, ps = ((1,0,0), (-1, 0, 0)))
|
||||
n = length(ps)
|
||||
x -> prod(norm(x .- p) for p ∈ ps) - λ^n
|
||||
end
|
||||
xs = ys = zs = range(-2, 2, length=100)
|
||||
m = make_mesh(xs, ys, zs, cassini(1.05))
|
||||
wireframe(m)
|
||||
xlims = ylims = zlims = (-2, 2)
|
||||
plot_implicit_surface(cassini(1.05); xlims, ylims, zlims)
|
||||
```
|
||||
|
||||
## Vector fields. Visualizations of $f:R^2 \rightarrow R^2$
|
||||
|
||||
@@ -140,8 +140,8 @@ typeof(sin(x)), typeof(Symbolics.value(sin(x)))
|
||||
The `TermInterface` package is used by `SymbolicUtils` to explore the tree structure of an expression. The main methods are (cf. [SymbolicUtils.jl](https://symbolicutils.juliasymbolics.org/#expression_interface)):
|
||||
|
||||
|
||||
* `istree(ex)`: `true` if `ex` is not a *leaf* node (like a symbol or numeric literal)
|
||||
* `operation(ex)`: the function being called (if `istree` returns `true`)
|
||||
* `iscall(ex)`: `true` if `ex` is not a *leaf* node (like a symbol or numeric literal). The old name was `istree`.
|
||||
* `operation(ex)`: the function being called (if `iscall` returns `true`)
|
||||
* `arguments(ex)`: the arguments to the function being called
|
||||
* `symtype(ex)`: the inferred type of the expression
|
||||
|
||||
@@ -163,7 +163,7 @@ arguments(ex) # `+` is n-ary, in this case with 3 arguments
|
||||
```
|
||||
|
||||
```{julia}
|
||||
ex1 = arguments(ex)[3] # terms have been reordered
|
||||
ex1 = arguments(ex)[2] # terms have been reordered
|
||||
operation(ex1) # operation for `x^2` is `^`
|
||||
```
|
||||
|
||||
@@ -172,10 +172,10 @@ a, b = arguments(ex1)
|
||||
```
|
||||
|
||||
```{julia}
|
||||
istree(ex1), istree(a)
|
||||
iscall(ex1), iscall(a)
|
||||
```
|
||||
|
||||
Here `a` is not a "tree", as it has no operation or arguments, it is just a variable (the `x` variable).
|
||||
Here `a` is not a call, as it has no operation or arguments, it is just a variable (the `x` variable).
|
||||
|
||||
|
||||
The value of `symtype` is the *inferred* type of an expression, which may not match the actual type. For example,
|
||||
@@ -199,7 +199,7 @@ As an example, we write a function to find the free symbols in a symbolic expres
|
||||
import Symbolics.SymbolicUtils: issym
|
||||
free_symbols(ex) = (s=Set(); free_symbols!(s, ex); s)
|
||||
function free_symbols!(s, ex)
|
||||
if istree(ex)
|
||||
if iscall(ex)
|
||||
for a ∈ arguments(ex)
|
||||
free_symbols!(s, a)
|
||||
end
|
||||
@@ -660,11 +660,11 @@ or
|
||||
eqs = [5x + 2y, 6x + 3y] .~ [1, 2]
|
||||
```
|
||||
|
||||
The `Symbolics.solve_for` function can solve *linear* equations. For example,
|
||||
The `Symbolics.symbolic_linear_solve` function can solve *linear* equations. For example,
|
||||
|
||||
|
||||
```{julia}
|
||||
Symbolics.solve_for(eqs, [x, y])
|
||||
Symbolics.symbolic_linear_solve(eqs, [x, y])
|
||||
```
|
||||
|
||||
The coefficients can be symbolic. Two examples could be:
|
||||
@@ -673,7 +673,7 @@ The coefficients can be symbolic. Two examples could be:
|
||||
```{julia}
|
||||
@variables m b x y
|
||||
eq = y ~ m*x + b
|
||||
Symbolics.solve_for(eq, x)
|
||||
Symbolics.symbolic_linear_solve(eq, x)
|
||||
```
|
||||
|
||||
```{julia}
|
||||
@@ -683,13 +683,30 @@ eqs = R*X .~ b
|
||||
```
|
||||
|
||||
```{julia}
|
||||
Symbolics.solve_for(eqs, [x,y])
|
||||
Symbolics.symbolic_linear_solve(eqs, [x,y])
|
||||
```
|
||||
|
||||
### Limits
|
||||
|
||||
Many symbolic limits involving exponentials and logarithms can be
|
||||
computed in Symbolics, as of recent versions. The underlying package
|
||||
is `SymbolicLimits`. This package is in development. Below we use the
|
||||
unwrapped version of the variable. We express limits as $x$ goes to
|
||||
infinity, which can be achieved by rewriting:
|
||||
|
||||
As of writing, there is no extra functionality provided by `Symbolics` for computing limits.
|
||||
```{julia}
|
||||
@variables x
|
||||
𝑥 = x.val # unwrapped
|
||||
F(x) = exp(x+exp(-x))-exp(x)
|
||||
limit(F(𝑥), 𝑥, Inf)
|
||||
```
|
||||
|
||||
Or
|
||||
|
||||
```{julia}
|
||||
F(x) = log(log(x*exp(x*exp(x))+1))-exp(exp(log(log(x))+1/x))
|
||||
limit(F(𝑥), 𝑥, Inf)
|
||||
```
|
||||
|
||||
|
||||
### Derivatives
|
||||
@@ -708,7 +725,7 @@ Or to find a critical point:
|
||||
|
||||
|
||||
```{julia}
|
||||
Symbolics.solve_for(yp ~ 0, x) # linear equation to solve
|
||||
Symbolics.symbolic_linear_solve(yp ~ 0, x) # linear equation to solve
|
||||
```
|
||||
|
||||
The derivative computation can also be broken up into an expression indicating the derivative and then a function to apply the derivative rules:
|
||||
@@ -726,7 +743,8 @@ and then
|
||||
expand_derivatives(D(y))
|
||||
```
|
||||
|
||||
Using `Differential`, differential equations can be specified. An example was given in [ODEs](../ODEs/differential_equations.html), using `ModelingToolkit`.
|
||||
Using `Differential`, differential equations can be specified. An example was given in [ODEs](../ODEs/differential_equations.html),
|
||||
using `ModelingToolkit`.
|
||||
|
||||
|
||||
Higher order derivatives can be done through composition:
|
||||
@@ -774,12 +792,6 @@ Symbolics.jacobian(eqs, [x,y])
|
||||
|
||||
### Integration
|
||||
|
||||
::: {.callout-note}
|
||||
#### This area is very much WIP
|
||||
|
||||
The use of `SymbolicNumericIntegration` below is currently broken.
|
||||
:::
|
||||
|
||||
The `SymbolicNumericIntegration` package provides a means to integrate *univariate* expressions through its `integrate` function.
|
||||
|
||||
|
||||
@@ -838,18 +850,10 @@ substitute(ΣqᵢΘᵢ, d)
|
||||
The package provides an algorithm for the creation of candidates and the means to solve when possible. The `integrate` function is the main entry point. It returns three values: `solved`, `unsolved`, and `err`. The `unsolved` is the part of the integrand which can not be solved through this package. It is `0` for a given problem when `integrate` is successful in identifying an antiderivative, in which case `solved` is the answer. The value of `err` is a bound on the numerical error introduced by the algorithm.
|
||||
|
||||
|
||||
::: {.callout-note}
|
||||
### This is currently broken
|
||||
|
||||
The following isn't working with `SymbolicNumericIntegration` version `v"1.4.0"`. For now, the cells are not evaluated.
|
||||
|
||||
:::
|
||||
|
||||
To see, we have:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| eval: false
|
||||
using SymbolicNumericIntegration
|
||||
@variables x
|
||||
|
||||
@@ -871,7 +875,6 @@ Powers of trig functions have antiderivatives, as can be deduced using integrati
|
||||
|
||||
|
||||
```{julia}
|
||||
#| eval: false
|
||||
u,v,w = integrate(sin(x)^5)
|
||||
```
|
||||
|
||||
@@ -879,7 +882,6 @@ The derivative of `u` matches up to some numeric tolerance:
|
||||
|
||||
|
||||
```{julia}
|
||||
#| eval: false
|
||||
Symbolics.derivative(u, x) - sin(x)^5
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user