diff --git a/CwJ/alternatives/plotly_plotting.jmd b/CwJ/alternatives/plotly_plotting.jmd index e887b5d..84eaae5 100644 --- a/CwJ/alternatives/plotly_plotting.jmd +++ b/CwJ/alternatives/plotly_plotting.jmd @@ -1,5 +1,10 @@ # JavaScript based plotting libraries +!!! alert "Not working with quarto" + Currently, the plots generated here are not rendering within quarto. + + + This section uses this add-on package: ```julia diff --git a/CwJ/derivatives/mean_value_theorem.jmd b/CwJ/derivatives/mean_value_theorem.jmd index ddb846e..af71977 100644 --- a/CwJ/derivatives/mean_value_theorem.jmd +++ b/CwJ/derivatives/mean_value_theorem.jmd @@ -396,7 +396,39 @@ That is the function $f(x)$, minus the secant line between $(a,f(a))$ and $(b, f nothing ``` -An interactive example can be found at [jsxgraph](http://jsxgraph.uni-bayreuth.de/wiki/index.php?title=Mean_Value_Theorem). +```=html +
+``` + +```ojs +//| echo: false +//| output: false + +JXG = require("jsxgraph"); + +board = JXG.JSXGraph.initBoard('jsxgraph', {boundingbox: [-5, 10, 7, -6], axis:true}); +p = [ + board.create('point', [-1,-2], {size:2}), + board.create('point', [6,5], {size:2}), + board.create('point', [-0.5,1], {size:2}), + board.create('point', [3,3], {size:2}) +]; +f = JXG.Math.Numerics.lagrangePolynomial(p); +graph = board.create('functiongraph', [f,-10, 10]); + +g = function(x) { + return JXG.Math.Numerics.D(f)(x)-(p[1].Y()-p[0].Y())/(p[1].X()-p[0].X()); +}; + +r = board.create('glider', [ + function() { return JXG.Math.Numerics.root(g,(p[0].X()+p[1].X())*0.5); }, + function() { return f(JXG.Math.Numerics.root(g,(p[0].X()+p[1].X())*0.5)); }, + graph], {name:' ',size:4,fixed:true}); +board.create('tangent', [r], {strokeColor:'#ff0000'}); +line = board.create('line',[p[0],p[1]],{strokeColor:'#ff0000',dash:1}); +``` + +This interactive example can also be found at [jsxgraph](http://jsxgraph.uni-bayreuth.de/wiki/index.php?title=Mean_Value_Theorem). It shows a cubic polynomial fit to the ``4`` adjustable points labeled A through D. The secant line is drawn between points A and B with a dashed line. A tangent line -- with the same slope as the secant line -- is identified at a point ``(\alpha, f(\alpha))`` where ``\alpha`` is between the points A and B. That this can always be done is a conseuqence of the mean value theorem. ##### Example diff --git a/CwJ/derivatives/newtons_method.jmd b/CwJ/derivatives/newtons_method.jmd index 8c0390a..f4ddcc2 100644 --- a/CwJ/derivatives/newtons_method.jmd +++ b/CwJ/derivatives/newtons_method.jmd @@ -285,6 +285,96 @@ gif(anim, imgfile, fps = 1) ImageFile(imgfile, caption) ``` +---- + +This interactive graphic (built using [JSXGraph](https://jsxgraph.uni-bayreuth.de/wp/index.html)) allows the adjustment of the point `x0`, initially at ``0.85``. Five iterations of Newton's method are illustrated. Different positions of `x0` clearly converge, others will not. + +```=html +
+``` + +```ojs +//| echo: false +//| output: false + +JXG = require("jsxgraph"); + +// newton's method + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-3,5,3,-5], axis:true +}); + + +f = function(x) {return x*x*x*x*x - x - 1}; +fp = function(x) { return 4*x*x*x*x - 1}; +x0 = 0.85; + +nm = function(x) { return x - f(x)/fp(x);}; + +l = b.create('point', [-1.5,0], {name:'', size:0}); +r = b.create('point', [1.5,0], {name:'', size:0}); +xaxis = b.create('line', [l,r]) + + +P0 = b.create('glider', [x0,0,xaxis], {name:'x0'}); +P0a = b.create('point', [function() {return P0.X();}, + function() {return f(P0.X());}], {name:''}); + +P1 = b.create('point', [function() {return nm(P0.X());}, + 0], {name:''}); +P1a = b.create('point', [function() {return P1.X();}, + function() {return f(P1.X());}], {name:''}); + +P2 = b.create('point', [function() {return nm(P1.X());}, + 0], {name:''}); +P2a = b.create('point', [function() {return P2.X();}, + function() {return f(P2.X());}], {name:''}); + +P3 = b.create('point', [function() {return nm(P2.X());}, + 0], {name:''}); +P3a = b.create('point', [function() {return P3.X();}, + function() {return f(P3.X());}], {name:''}); + +P4 = b.create('point', [function() {return nm(P3.X());}, + 0], {name:''}); +P4a = b.create('point', [function() {return P4.X();}, + function() {return f(P4.X());}], {name:''}); +P5 = b.create('point', [function() {return nm(P4.X());}, + 0], {name:'x5', strokeColor:'black'}); + + + + + +P0a.setAttribute({fixed:true}); +P1.setAttribute({fixed:true}); +P1a.setAttribute({fixed:true}); +P2.setAttribute({fixed:true}); +P2a.setAttribute({fixed:true}); +P3.setAttribute({fixed:true}); +P3a.setAttribute({fixed:true}); +P4.setAttribute({fixed:true}); +P4a.setAttribute({fixed:true}); +P5.setAttribute({fixed:true}); + +sc = '#000000'; +b.create('segment', [P0,P0a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P0a, P1], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P1,P1a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P1a, P2], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P2,P2a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P2a, P3], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P3,P3a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P3a, P4], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P4,P4a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P4a, P5], {strokeColor:sc, strokeWidth:1}); + +b.create('functiongraph', [f, -1.5, 1.5]) + +``` + + ##### Example: numeric not algebraic diff --git a/CwJ/integrals/area.jmd b/CwJ/integrals/area.jmd index 34fd530..6bf78f3 100644 --- a/CwJ/integrals/area.jmd +++ b/CwJ/integrals/area.jmd @@ -1430,11 +1430,49 @@ The area under a curve approximated by a Riemann sum. # url = "riemann.js" #CalculusWithJulia.WeaveSupport.JSXGraph(:integrals, url, caption) # This is just wrong... -url = "https://raw.githubusercontent.com/jverzani/CalculusWithJulia.jl/master/CwJ/integrals/riemann.js" -url = "./riemann.js" -CalculusWithJulia.WeaveSupport.JSXGraph(url, caption) +#CalculusWithJulia.WeaveSupport.JSXGraph(url, caption) +nothing ``` +```=html +
+``` + +```ojs +//| echo: false +//| output: false +JXG = require("jsxgraph"); + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-0.5,0.3,1.5,-1/4], axis:true +}); + +g = function(x) { return x*x*x*x + 10*x*x - 60* x + 100} +f = function(x) {return 1/Math.sqrt(g(x))}; + +type = "right"; +l = 0; +r = 1; +rsum = function() { + return JXG.Math.Numerics.riemannsum(f,n.Value(), type, l, r); +}; +n = b.create('slider', [[0.1, -0.05],[0.75,-0.05], [2,1,50]],{name:'n',snapWidth:1}); + +graph = b.create('functiongraph', [f, l, r]); +os = b.create('riemannsum', + [f, + function(){ return n.Value();}, + type, l, r + ], + {fillColor:'#ffff00', fillOpacity:0.3}); + +b.create('text', [0.1,0.25, function(){ + return 'Riemann sum='+(rsum().toFixed(4)); +}]); +``` + + + The interactive graphic shows the area of a right-Riemann sum for different partitions. The function is @@ -1451,7 +1489,7 @@ numericq(0.1224) When ``n=50`` what is the area of the Riemann sum? ```julia; hold=true; echo=false -numericq(0.1887) +numericq(0.1187) ``` Using `quadgk` what is the area under the curve? diff --git a/CwJ/limits/limits.jmd b/CwJ/limits/limits.jmd index 43a9058..2a2d5e7 100644 --- a/CwJ/limits/limits.jmd +++ b/CwJ/limits/limits.jmd @@ -384,6 +384,43 @@ get close to $c$ - allows us to gather quickly if a function seems to have a limit at $c$, though the precise value of $L$ may be hard to identify. +##### Example + +This example illustrates the same limit a different way. Sliding the ``x`` value towards ``0`` shows ``f(x) = \sin(x)/x`` approaches a value of ``1``. + + +```=html +
+``` + +```ojs +//| echo: false +//| output: false + +JXG = require("jsxgraph") + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-6, 1.2, 6,-1.2], axis:true +}); + +f = function(x) {return Math.sin(x) / x;}; +graph = b.create("functiongraph", [f, -6, 6]) +seg = b.create("line", [[-6,0], [6,0]], {fixed:true}); + +X = b.create("glider", [2, 0, seg], {name:"x", size:4}); +P = b.create("point", [function() {return X.X()}, function() {return f(X.X())}], {name:""}); +Q = b.create("point", [0, function() {return P.Y();}], {name:"f(x)"}); + +segup = b.create("segment", [P,X], {dash:2}); +segover = b.create("segment", [P, [0, function() {return P.Y()}]], {dash:2}); + + +txt = b.create('text', [2, 1, function() { + return "x = " + X.X().toFixed(4) + ", f(x) = " + P.Y().toFixed(4); +}]); +``` + + ##### Example @@ -436,8 +473,6 @@ $g(x) = (x-3)/(x+3)$ when $x \neq 2$. The function $g(x)$ is $g(2) = (2 - 3)/(2 + 3) = -0.2$ it would be made continuous, hence the term removable singularity. - - ## Numerical approaches to limits The investigation of $\lim_{x \rightarrow 0}(1 + x)^{1/x}$ by diff --git a/Project.toml b/Project.toml index 0429915..217b330 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CalculusWithJuliaNotes" uuid = "8cd3c377-0a30-4ec5-b85a-75291d749efe" authors = ["jverzani and contributors"] -version = "0.1.0" +version = "0.1.1" [compat] julia = "1" diff --git a/quarto/.gitignore b/quarto/.gitignore index f038895..332e5e0 100644 --- a/quarto/.gitignore +++ b/quarto/.gitignore @@ -1,5 +1,5 @@ /.quarto/ -/_site/ /_book/ /_freeze/ /*/*_files/ +/*/*.ipynb/ \ No newline at end of file diff --git a/quarto/ODEs/Project.toml b/quarto/ODEs/Project.toml deleted file mode 100644 index d455e5c..0000000 --- a/quarto/ODEs/Project.toml +++ /dev/null @@ -1,10 +0,0 @@ -[deps] -DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" -DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" -NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/quarto/ODEs/differential_equations.qmd b/quarto/ODEs/differential_equations.qmd index 054e4c9..0097bb5 100644 --- a/quarto/ODEs/differential_equations.qmd +++ b/quarto/ODEs/differential_equations.qmd @@ -1,33 +1,7 @@ # The `DifferentialEquations` suite -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/ODEs/euler.qmd b/quarto/ODEs/euler.qmd index 86391b4..535b62e 100644 --- a/quarto/ODEs/euler.qmd +++ b/quarto/ODEs/euler.qmd @@ -1,33 +1,7 @@ # Euler's method -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/ODEs/odes.qmd b/quarto/ODEs/odes.qmd index 5df743b..8aaed8e 100644 --- a/quarto/ODEs/odes.qmd +++ b/quarto/ODEs/odes.qmd @@ -1,33 +1,7 @@ # ODEs -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/ODEs/process.jl b/quarto/ODEs/process.jl deleted file mode 100644 index 067dff1..0000000 --- a/quarto/ODEs/process.jl +++ /dev/null @@ -1,27 +0,0 @@ -using WeavePynb -using Mustache - -mmd(fname) = mmd_to_html(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") -## uncomment to generate just .md files -mmd(fname) = mmd_to_md(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") - -fnames = [ - "odes", - "euler" - ] - - - -function process_file(nm, twice=false) - include("$nm.jl") - mmd_to_md("$nm.mmd") - markdownToHTML("$nm.md") - twice && markdownToHTML("$nm.md") -end - -process_files(twice=false) = [process_file(nm, twice) for nm in fnames] - -""" -## TODO ODEs - -""" diff --git a/quarto/ODEs/solve.qmd b/quarto/ODEs/solve.qmd index cee804a..79e67f7 100644 --- a/quarto/ODEs/solve.qmd +++ b/quarto/ODEs/solve.qmd @@ -1,33 +1,7 @@ # The problem-algorithm-solve interface -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/README.md b/quarto/README-quarto.md similarity index 77% rename from quarto/README.md rename to quarto/README-quarto.md index ef36dea..1325e56 100644 --- a/quarto/README.md +++ b/quarto/README-quarto.md @@ -1,3 +1,14 @@ +## TODO + +* download links to Pluto .jl files (if we have .jmd, but we might deprecate...) +* PlotlyLight +* mermaid, ojs? + +DONE * clean up edit link +DONE * remove pinned header +DONE * clean up directory +DONE (?) * JSXGraph files + # CalculusWithJulia via quarto To compile the pages through quarto @@ -15,6 +26,7 @@ To compile the pages through quarto * bump the version number in `_quarto.yml`, `Project.toml` * run `quarto publish gh-pages` to publish +* or `quarto publish gh-pages --no-render` to avoid re-rendering, when just done * should also push project to github * no need to push `_freeze` the repo, as files are locally rendered for now. diff --git a/quarto/_common_code.qmd b/quarto/_common_code.qmd new file mode 100644 index 0000000..824af09 --- /dev/null +++ b/quarto/_common_code.qmd @@ -0,0 +1,27 @@ +```{julia} +#| echo: false + +import Logging +Logging.disable_logging(Logging.Info) # or e.g. Logging.Info +Logging.disable_logging(Logging.Warn) + +import SymPy +function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} + println(io, " ") + println(io, "\\[") + println(io, sympy.latex(x)) + println(io, "\\]") + println(io, "") +end + +# hack to work around issue +import Markdown +import CalculusWithJulia +function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) + nm = joinpath("..", string(d), f) + u = "![$caption]($nm)" + Markdown.parse(u) +end + +nothing +``` diff --git a/quarto/_quarto.yml b/quarto/_quarto.yml index 7299c55..aec86c9 100644 --- a/quarto/_quarto.yml +++ b/quarto/_quarto.yml @@ -8,22 +8,20 @@ comments: book: title: "Calculus with Julia" - date: now author: "John Verzani" + date: now search: true repo-url: https://github.com/jverzani/CalculusWithJuliaNotes.jl - repo-actions: [edit] - downloads: [pdf, epub] + repo-subdir: quarto/ + repo-actions: [edit, issue] navbar: background: light search: true logo: logo.png - pinned: true - page-footer: - left: "Copyright 2022, John Verzani" - right: - - icon: github - href: https://github.com/ + pinned: false + sidebar: + collapse-level: 1 + page-footer: "Copyright 2022, John Verzani" chapters: - index.qmd - part: "Precalculus Concepts" @@ -125,10 +123,11 @@ bibliography: references.bib website: favicon: logo.png + reader-mode: true format: html: - theme: lux # spacelab # lux # sketchy # cosmo # https://quarto.org/docs/output-formats/html-themes.html + theme: lux #lux # spacelab # lux # sketchy # cosmo # https://quarto.org/docs/output-formats/html-themes.html number-depth: 3 toc-depth: 3 link-external-newwindow: true diff --git a/quarto/alternatives/Project.toml b/quarto/alternatives/Project.toml deleted file mode 100644 index 5e0192b..0000000 --- a/quarto/alternatives/Project.toml +++ /dev/null @@ -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" diff --git a/quarto/alternatives/plotly_plotting.qmd b/quarto/alternatives/plotly_plotting.qmd index 19749f2..a35a9d7 100644 --- a/quarto/alternatives/plotly_plotting.qmd +++ b/quarto/alternatives/plotly_plotting.qmd @@ -1,33 +1,13 @@ # JavaScript based plotting libraries -```{julia} -#| echo: false +{{< include ../_common_code.qmd >}} -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) +:::{.callout-note} +## Not working with quarto +Currently, the plots generated here are not rendering within quarto. -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +::: This section uses this add-on package: diff --git a/quarto/cover.png b/quarto/cover.png deleted file mode 100644 index e1f5bc6..0000000 Binary files a/quarto/cover.png and /dev/null differ diff --git a/quarto/derivatives/Project.toml b/quarto/derivatives/Project.toml deleted file mode 100644 index f6a9189..0000000 --- a/quarto/derivatives/Project.toml +++ /dev/null @@ -1,17 +0,0 @@ -[deps] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -EllipsisNotation = "da5c29d0-fa7d-589e-88eb-ea29b0a81949" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -ImplicitPlots = "55ecb840-b828-11e9-1645-43f4a9f9ace7" -IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -IntervalConstraintProgramming = "138f1668-1576-5ad7-91b9-7425abbf3153" -LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -MDBM = "dd61e66b-39ce-57b0-8813-509f78be4b4d" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" -TaylorSeries = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c" -Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" diff --git a/quarto/derivatives/curve_sketching.qmd b/quarto/derivatives/curve_sketching.qmd index 3a05bef..729f29a 100644 --- a/quarto/derivatives/curve_sketching.qmd +++ b/quarto/derivatives/curve_sketching.qmd @@ -1,33 +1,7 @@ # Curve Sketching -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: diff --git a/quarto/derivatives/derivatives.qmd b/quarto/derivatives/derivatives.qmd index 9ea180c..1ed4c5a 100644 --- a/quarto/derivatives/derivatives.qmd +++ b/quarto/derivatives/derivatives.qmd @@ -1,33 +1,7 @@ # Derivatives -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/first_second_derivatives.qmd b/quarto/derivatives/first_second_derivatives.qmd index 0e68c22..c312726 100644 --- a/quarto/derivatives/first_second_derivatives.qmd +++ b/quarto/derivatives/first_second_derivatives.qmd @@ -1,33 +1,7 @@ # The first and second derivatives -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/implicit_differentiation.qmd b/quarto/derivatives/implicit_differentiation.qmd index 1232992..9401b88 100644 --- a/quarto/derivatives/implicit_differentiation.qmd +++ b/quarto/derivatives/implicit_differentiation.qmd @@ -1,33 +1,7 @@ # Implicit Differentiation -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/lhospitals_rule.qmd b/quarto/derivatives/lhospitals_rule.qmd index fe0e82a..29c0f9e 100644 --- a/quarto/derivatives/lhospitals_rule.qmd +++ b/quarto/derivatives/lhospitals_rule.qmd @@ -1,33 +1,7 @@ # L'Hospital's Rule -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/linearization.qmd b/quarto/derivatives/linearization.qmd index 6c0c3b4..677270a 100644 --- a/quarto/derivatives/linearization.qmd +++ b/quarto/derivatives/linearization.qmd @@ -1,33 +1,7 @@ # Linearization -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/mean_value_theorem.qmd b/quarto/derivatives/mean_value_theorem.qmd index a28f9ad..6f36a58 100644 --- a/quarto/derivatives/mean_value_theorem.qmd +++ b/quarto/derivatives/mean_value_theorem.qmd @@ -1,33 +1,7 @@ # The mean value theorem for differentiable functions. -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: @@ -390,7 +364,39 @@ That is the function $f(x)$, minus the secant line between $(a,f(a))$ and $(b, f nothing ``` -An interactive example can be found at [jsxgraph](http://jsxgraph.uni-bayreuth.de/wiki/index.php?title=Mean_Value_Theorem). +```{=html} +
+``` + +```{ojs} +//| echo: false +//| output: false + +JXG = require("jsxgraph"); + +board = JXG.JSXGraph.initBoard('jsxgraph', {boundingbox: [-5, 10, 7, -6], axis:true}); +p = [ + board.create('point', [-1,-2], {size:2}), + board.create('point', [6,5], {size:2}), + board.create('point', [-0.5,1], {size:2}), + board.create('point', [3,3], {size:2}) +]; +f = JXG.Math.Numerics.lagrangePolynomial(p); +graph = board.create('functiongraph', [f,-10, 10]); + +g = function(x) { + return JXG.Math.Numerics.D(f)(x)-(p[1].Y()-p[0].Y())/(p[1].X()-p[0].X()); +}; + +r = board.create('glider', [ + function() { return JXG.Math.Numerics.root(g,(p[0].X()+p[1].X())*0.5); }, + function() { return f(JXG.Math.Numerics.root(g,(p[0].X()+p[1].X())*0.5)); }, + graph], {name:' ',size:4,fixed:true}); +board.create('tangent', [r], {strokeColor:'#ff0000'}); +line = board.create('line',[p[0],p[1]],{strokeColor:'#ff0000',dash:1}); +``` + +This interactive example can also be found at [jsxgraph](http://jsxgraph.uni-bayreuth.de/wiki/index.php?title=Mean_Value_Theorem). It shows a cubic polynomial fit to the $4$ adjustable points labeled A through D. The secant line is drawn between points A and B with a dashed line. A tangent line – with the same slope as the secant line – is identified at a point $(\alpha, f(\alpha))$ where $\alpha$ is between the points A and B. That this can always be done is a conseuqence of the mean value theorem. ##### Example diff --git a/quarto/derivatives/more_zeros.qmd b/quarto/derivatives/more_zeros.qmd index 189d89c..2544101 100644 --- a/quarto/derivatives/more_zeros.qmd +++ b/quarto/derivatives/more_zeros.qmd @@ -1,33 +1,7 @@ # Derivative-free alternatives to Newton's method -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/newtons_method.qmd b/quarto/derivatives/newtons_method.qmd index bc567f0..803f49b 100644 --- a/quarto/derivatives/newtons_method.qmd +++ b/quarto/derivatives/newtons_method.qmd @@ -1,33 +1,7 @@ # Newton's method -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: @@ -311,6 +285,97 @@ gif(anim, imgfile, fps = 1) ImageFile(imgfile, caption) ``` +--- + + +This interactive graphic (built using [JSXGraph](https://jsxgraph.uni-bayreuth.de/wp/index.html)) allows the adjustment of the point `x0`, initially at $0.85$. Five iterations of Newton's method are illustrated. Different positions of `x0` clearly converge, others will not. + + +```{=html} +
+``` + +```{ojs} +//| echo: false +//| output: false + +JXG = require("jsxgraph"); + +// newton's method + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-3,5,3,-5], axis:true +}); + + +f = function(x) {return x*x*x*x*x - x - 1}; +fp = function(x) { return 4*x*x*x*x - 1}; +x0 = 0.85; + +nm = function(x) { return x - f(x)/fp(x);}; + +l = b.create('point', [-1.5,0], {name:'', size:0}); +r = b.create('point', [1.5,0], {name:'', size:0}); +xaxis = b.create('line', [l,r]) + + +P0 = b.create('glider', [x0,0,xaxis], {name:'x0'}); +P0a = b.create('point', [function() {return P0.X();}, + function() {return f(P0.X());}], {name:''}); + +P1 = b.create('point', [function() {return nm(P0.X());}, + 0], {name:''}); +P1a = b.create('point', [function() {return P1.X();}, + function() {return f(P1.X());}], {name:''}); + +P2 = b.create('point', [function() {return nm(P1.X());}, + 0], {name:''}); +P2a = b.create('point', [function() {return P2.X();}, + function() {return f(P2.X());}], {name:''}); + +P3 = b.create('point', [function() {return nm(P2.X());}, + 0], {name:''}); +P3a = b.create('point', [function() {return P3.X();}, + function() {return f(P3.X());}], {name:''}); + +P4 = b.create('point', [function() {return nm(P3.X());}, + 0], {name:''}); +P4a = b.create('point', [function() {return P4.X();}, + function() {return f(P4.X());}], {name:''}); +P5 = b.create('point', [function() {return nm(P4.X());}, + 0], {name:'x5', strokeColor:'black'}); + + + + + +P0a.setAttribute({fixed:true}); +P1.setAttribute({fixed:true}); +P1a.setAttribute({fixed:true}); +P2.setAttribute({fixed:true}); +P2a.setAttribute({fixed:true}); +P3.setAttribute({fixed:true}); +P3a.setAttribute({fixed:true}); +P4.setAttribute({fixed:true}); +P4a.setAttribute({fixed:true}); +P5.setAttribute({fixed:true}); + +sc = '#000000'; +b.create('segment', [P0,P0a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P0a, P1], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P1,P1a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P1a, P2], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P2,P2a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P2a, P3], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P3,P3a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P3a, P4], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P4,P4a], {strokeColor:sc, strokeWidth:1}); +b.create('segment', [P4a, P5], {strokeColor:sc, strokeWidth:1}); + +b.create('functiongraph', [f, -1.5, 1.5]) + +``` + ##### Example: numeric not algebraic diff --git a/quarto/derivatives/numeric_derivatives.qmd b/quarto/derivatives/numeric_derivatives.qmd index 32243af..afbcc90 100644 --- a/quarto/derivatives/numeric_derivatives.qmd +++ b/quarto/derivatives/numeric_derivatives.qmd @@ -1,33 +1,7 @@ # Numeric derivatives -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/optimization.qmd b/quarto/derivatives/optimization.qmd index 5171032..1c0d17b 100644 --- a/quarto/derivatives/optimization.qmd +++ b/quarto/derivatives/optimization.qmd @@ -1,33 +1,7 @@ # Optimization -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/derivatives/process.jl b/quarto/derivatives/process.jl deleted file mode 100644 index 3ef5ee5..0000000 --- a/quarto/derivatives/process.jl +++ /dev/null @@ -1,44 +0,0 @@ -using WeavePynb - -using CwJWeaveTpl - - - -fnames = [ - "derivatives", ## more questions - "numeric_derivatives", - - "mean_value_theorem", - "optimization", - "curve_sketching", - - "linearization", - "newtons_method", - "lhopitals_rule", ## Okay - -but could beef up questions.. - - - "implicit_differentiation", ## add more questions? - "related_rates", - "taylor_series_polynomials" -] - - -process_file(nm; cache=:off) = CwJWeaveTpl.mmd(nm * ".jmd", cache=cache) - -function process_files(;cache=:user) - for f in fnames - @show f - process_file(f, cache=cache) - end -end - - - - -""" -## TODO derivatives - -tangent lines intersect at avearge for a parabola - -Should we have derivative results: inverse functions, logarithmic differentiation... -""" diff --git a/quarto/derivatives/related_rates.qmd b/quarto/derivatives/related_rates.qmd index 03e982b..e61753e 100644 --- a/quarto/derivatives/related_rates.qmd +++ b/quarto/derivatives/related_rates.qmd @@ -1,33 +1,7 @@ # Related rates -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packaages: diff --git a/quarto/derivatives/symbolic_derivatives.qmd b/quarto/derivatives/symbolic_derivatives.qmd index 7d30bfa..c3b1149 100644 --- a/quarto/derivatives/symbolic_derivatives.qmd +++ b/quarto/derivatives/symbolic_derivatives.qmd @@ -1,33 +1,7 @@ # Symbolic derivatives -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses this add-on package: diff --git a/quarto/derivatives/taylor_series_polynomials.qmd b/quarto/derivatives/taylor_series_polynomials.qmd index 328327b..cb6f8ec 100644 --- a/quarto/derivatives/taylor_series_polynomials.qmd +++ b/quarto/derivatives/taylor_series_polynomials.qmd @@ -1,33 +1,7 @@ # Taylor Polynomials and other Approximating Polynomials -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/Project.toml b/quarto/differentiable_vector_calculus/Project.toml deleted file mode 100644 index c6d07d2..0000000 --- a/quarto/differentiable_vector_calculus/Project.toml +++ /dev/null @@ -1,15 +0,0 @@ -[deps] -CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MDBM = "dd61e66b-39ce-57b0-8813-509f78be4b4d" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/quarto/differentiable_vector_calculus/plots_plotting.qmd b/quarto/differentiable_vector_calculus/plots_plotting.qmd index f1b74c0..fe9a3a3 100644 --- a/quarto/differentiable_vector_calculus/plots_plotting.qmd +++ b/quarto/differentiable_vector_calculus/plots_plotting.qmd @@ -1,33 +1,7 @@ # 2D and 3D plots in Julia with Plots -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/polar_coordinates.qmd b/quarto/differentiable_vector_calculus/polar_coordinates.qmd index 0532ccf..bb4d4fb 100644 --- a/quarto/differentiable_vector_calculus/polar_coordinates.qmd +++ b/quarto/differentiable_vector_calculus/polar_coordinates.qmd @@ -1,33 +1,7 @@ # Polar Coordinates and Curves -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/process.jl b/quarto/differentiable_vector_calculus/process.jl deleted file mode 100644 index aeee5ed..0000000 --- a/quarto/differentiable_vector_calculus/process.jl +++ /dev/null @@ -1,36 +0,0 @@ -using WeavePynb -using Mustache - -mmd(fname) = mmd_to_html(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") -## uncomment to generate just .md files -#mmd(fname) = mmd_to_md(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") - - - - -fnames = ["polar_coordinates", - "vectors", - "vector_valued_functions", - "scalar_functions", - "scalar_functions_applications", - "vector_fields" -] - -function process_file(nm, twice=false) - include("$nm.jl") - mmd_to_md("$nm.mmd") - markdownToHTML("$nm.md") - twice && markdownToHTML("$nm.md") -end - -process_files(twice=false) = [process_file(nm, twice) for nm in fnames] - - -""" -## TODO differential_vector_calcululs - -### Add questions for scalar_function_applications -* Newton's method?? -* optimization. Find least squares for perpendicular distance using the same 3 points...?? - -""" diff --git a/quarto/differentiable_vector_calculus/scalar_functions.qmd b/quarto/differentiable_vector_calculus/scalar_functions.qmd index 5d151b4..7f4cb13 100644 --- a/quarto/differentiable_vector_calculus/scalar_functions.qmd +++ b/quarto/differentiable_vector_calculus/scalar_functions.qmd @@ -1,33 +1,7 @@ # Scalar functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/scalar_functions_applications.qmd b/quarto/differentiable_vector_calculus/scalar_functions_applications.qmd index f71c36a..58a646f 100644 --- a/quarto/differentiable_vector_calculus/scalar_functions_applications.qmd +++ b/quarto/differentiable_vector_calculus/scalar_functions_applications.qmd @@ -1,33 +1,7 @@ # Applications with scalar functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/vector_fields.qmd b/quarto/differentiable_vector_calculus/vector_fields.qmd index 6c207ea..ea8da2e 100644 --- a/quarto/differentiable_vector_calculus/vector_fields.qmd +++ b/quarto/differentiable_vector_calculus/vector_fields.qmd @@ -1,33 +1,7 @@ # Functions $R^n \rightarrow R^m$ -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/differentiable_vector_calculus/vector_valued_functions.qmd b/quarto/differentiable_vector_calculus/vector_valued_functions.qmd index 19545b4..4d7ec1d 100644 --- a/quarto/differentiable_vector_calculus/vector_valued_functions.qmd +++ b/quarto/differentiable_vector_calculus/vector_valued_functions.qmd @@ -1,35 +1,7 @@ # Vector-valued functions, $f:R \rightarrow R^n$ -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` - +{{< include ../_common_code.qmd >}} This section uses these add-on packages: @@ -2823,3 +2795,4 @@ choices = [ answ = 1 radioq(choices, answ) ``` + diff --git a/quarto/differentiable_vector_calculus/vectors.qmd b/quarto/differentiable_vector_calculus/vectors.qmd index 7d0b3c8..e35ab11 100644 --- a/quarto/differentiable_vector_calculus/vectors.qmd +++ b/quarto/differentiable_vector_calculus/vectors.qmd @@ -1,33 +1,7 @@ # Vectors and matrices -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on package: diff --git a/quarto/integral_vector_calculus/#line_integrals.jmd# b/quarto/integral_vector_calculus/#line_integrals.jmd# deleted file mode 100644 index 3984468..0000000 --- a/quarto/integral_vector_calculus/#line_integrals.jmd# +++ /dev/null @@ -1,1315 +0,0 @@ -# Line and Surface Integrals - -This section uses these add-on packages: - - -```julia -using CalculusWithJulia -using Plots -using QuadGK -using SymPy -using HCubature -``` - -```julia; echo=false; results="hidden" -using CalculusWithJulia.WeaveSupport - -const frontmatter = ( - title = "Line and Surface Integrals", - description = "Calculus with Julia: Line and Surface Integrals", - tags = ["CalculusWithJulia", "integral_vector_calculus", "line and surface integrals"], -); -nothing -``` - ----- - -This section discusses generalizations to the one- and two-dimensional definite integral. These two integrals integrate a function over a one or two dimensional region (e.g., $[a,b]$ or $[a,b]\times[c,d]$). The generalization is to change this region to a one-dimensional piece of path in $R^n$ or a two-dimensional surface in $R^3$. - -To fix notation, consider $\int_a^b f(x)dx$ and $\int_a^b\int_c^d g(x,y) dy dx$. In defining both, a Riemann sum is involved, these involve a partition of $[a,b]$ or $[a,b]\times[c,d]$ and terms like $f(c_i) \Delta{x_i}$ and $g(c_i, d_j) \Delta{x_i}\Delta{y_j}$. The $\Delta$s the diameter of an intervals $I_i$ or $J_j$. Consider now two parameterizations: $\vec{r}(t)$ for $t$ in $[a,b]$ and $\Phi(u,v)$ for $(u,v)$ in $[a,b]\times[c,d]$. One is a parameterization of a space curve, $\vec{r}:R\rightarrow R^n$; the other a parameterization of a surface, $\Phi:R^2 \rightarrow R^3$. The *image* of $I_i$ or $I_i\times{J_j}$ under $\vec{r}$ and $\Phi$, respectively, will look *almost* linear if the intervals are small enough, so, at least on the microscopic level. A Riemann term can be based around this fact, provided it is understood how much the two parameterizations change the interval $I_i$ or region $I_i\times{J_j}$. - -This chapter will quantify this change, describing it in terms of associated vectors to $\vec{r}$ and $\Phi$, yielding formulas for an integral of a *scalar* function along a path or over a surface. Furthermore, these integrals will be generalized to give meaning to physically useful interactions between the path or surface and a vector field. - - - - - -## Line integrals - -In [arc length](../integrals/arc-length.html) a formula to give the -arc-length of the graph of a univariate function or parameterized -curve in $2$ dimensions is given in terms of an integral. The -intuitive approximation involved segments of the curve. To review, let -$\vec{r}(t)$, $a \leq t \leq b$, describe a curve, $C$, in $R^n$, $n -\geq 2$. Partition $[a,b]$ into $a=t_0 < t_1 < \cdots < t_{n-1} < t_n = -b$. - -Consider the path segment connecting $\vec{r}(t_{i-1})$ to $\vec{r}(t_i)$. If the partition of $[a,b]$ is microscopically small, this path will be *approximated* by $\vec{r}(t_i) - \vec{r}(t_{i-1})$. This difference in turn is approximately $\vec{r}'(t_i) (t_i - t_{i-1}) = \vec{r}'(t_i) \Delta{t}_i$, provided $\vec{r}$ is differentiable. - - -If $f:R^n \rightarrow R$ is a scalar function. Taking right-hand end points, we can consider the Riemann sum $\sum (f\circ\vec{r})(t_i) \|\vec{r}'(t_i)\| \Delta{t}_i$. For integrable functions, this sum converges to the *line integral* defined as a one-dimensional integral for a given parameterization: - -```math -\int_a^b f(\vec{r}(t)) \| \vec{r}'(t) \| dt. -``` - -The weight $\| \vec{r}'(t) \|$ can be interpreted by how much the parameterization stretches (or contracts) an interval $[t_{i-1},t_i]$ when mapped to its corresponding path segment. - ----- - - -The curve $C$ can be parameterized many different ways by introducing a function $s(t)$ to change the time. If we use the arc-length parameterization with $\gamma(0) = a$ and $\gamma(l) = b$, where $l$ is the arc-length of $C$, then we have by change of variables $t = \gamma(s)$ that - -```math -\int_a^b f(\vec{r}(t)) \| \vec{r}'(t) \| dt = -\int_0^l (f \circ \vec{r} \circ \gamma)(s) \| \frac{d\vec{r}}{dt}\mid_{t = \gamma(s)}\| \gamma'(s) ds. -``` - -But, by the chain rule: - -```math -\frac{d(\vec{r} \circ\gamma)}{du}(s) = \frac{d\vec{r}}{dt}\mid_{t=\gamma(s)} \frac{d\gamma}{du}. -``` - -Since $\gamma$ is increasing, $\gamma' \geq 0$, so we get: - -```math -\int_a^b f(\vec{r}(t)) \| \vec{r}'(t) \| dt = -\int_0^l (f \circ \vec{r} \circ \gamma)(s) \|\frac{d(\vec{r}\circ\gamma)}{ds}\| ds = -\int_0^l (f \circ \vec{r} \circ \gamma)(s) ds. -``` - -The last line, as the derivative is the unit tangent vector, $T$, with norm $1$. - -This shows that the line integral is *not* dependent on the parameterization. The notation $\int_C f ds$ is used to represent the line integral of a scalar function, the $ds$ emphasizing an implicit parameterization of $C$ by arc-length. When $C$ is a closed curve, the $\oint_C fds$ is used to indicate that. - -### Example - - -When $f$ is identically $1$, the line integral returns the arc length. When $f$ varies, then the line integral can be interpreted a few ways. First, if $f \geq 0$ and we consider a sheet hung from the curve $f\circ \vec{r}$ and cut to just touch the ground, the line integral gives the area of this sheet, in the same way an integral gives the area under a positive curve. - -If the composition $f \circ \vec{r}$ is viewed as a density of the arc (as though it were constructed out of some non-uniform material), then the line integral can be seen to return the mass of the arc. - -Suppose $\rho(x,y,z) = 5 - z$ gives the density of an arc where the arc is parameterized by $\vec{r}(t) = \langle \cos(t), 0, \sin(t) \rangle$, $0 \leq t \leq \pi$. (A half-circular arc.) Find the mass of the arc. - -```julia; -rho(x,y,z) = 5 - z -rho(v) = rho(v...) -r(t) = [cos(t), 0, sin(t)] - -@syms t -rp = diff.(r(t),t) # r' -area = integrate((rho ∘ r)(t) * norm(rp), (t, 0, PI)) -``` - -Continuing, we could find the center of mass by integrating $\int_C z (f\circ \vec{r}) \|r'\| dt$: - -```julia; -Mz = integrate(r(t)[3] * (rho ∘ r)(t) * norm(rp), (t, 0, PI)) -Mz -``` - -Finally, we get the center of mass by - -```julia; -Mz / area -``` - -##### Example - -Let $f(x,y,z) = x\sin(y)\cos(z)$ and $C$ the path described by $\vec{r}(t) = \langle t, t^2, t^3\rangle$ for $0 \leq t \leq \pi$. Find the line integral $\int_C fds$. - -We find the numeric value with: - -```julia; hold=true -f(x,y,z) = x*sin(y)*cos(z) -f(v) = f(v...) -r(t) = [t, t^2, t^3] -integrand(t) = (f ∘ r)(t) * norm(r'(t)) -quadgk(integrand, 0, pi) -``` - - -##### Example - -Imagine the $z$ axis is a wire and in the $x$-$y$ plane the unit circle is a path. If there is a magnetic field, $B$, then the field will induce a current to flow along the wire. [Ampere's]https://tinyurl.com/y4gl9pgu) circuital law states $\oint_C B\cdot\hat{T} ds = \mu_0 I$, where $\mu_0$ is a constant and $I$ the current. If the magnetic field is given by $B=(x^2+y^2)^{1/2}\langle -y,x,0\rangle$ compute $I$ in terms of $\mu_0$. - -We have the path is parameterized by $\vec{r}(t) = \langle \cos(t), \sin(t), 0\rangle$, and so $\hat{T} = \langle -\sin(t), \cos(t), 0\rangle$ and the integrand, $B\cdot\hat{T}$ is - -```math -(x^2 + y^2)^{-1/2}\langle -\sin(t), \cos(t), 0\rangle\cdot -\langle -\sin(t), \cos(t), 0\rangle = (x^2 + y^2)(-1/2), -``` - -which is $1$ on the path $C$. So $\int_C B\cdot\hat{T} ds = \int_C ds = 2\pi$. So the current satisfies $2\pi = \mu_0 I$, so $I = (2\pi)/\mu_0$. - -(Ampere's law is more typically used to find $B$ from an current, then $I$ from $B$, for special circumstances. The Biot-Savart does this more generally.) - -### Line integrals and vector fields; work and flow - -As defined above, the line integral is defined for a scalar function, but this can be generalized. If $F:R^n \rightarrow R^n$ is a vector field, then each component is a scalar function, so the integral $\int (F\circ\vec{r}) \|\vec{r}'\| dt$ can be defined component by component to yield a vector. - -However, it proves more interesting to define an integral -incorporating how properties of the path interact with the vector -field. The key is $\vec{r}'(t) dt = \hat{T} \| \vec{r}'(t)\|dt$ describes both the magnitude of how the parameterization stretches an interval but also a direction the path is taking. This direction allows interaction with the vector field. - -The canonical example is [work](https://en.wikipedia.org/wiki/Work_(physics)), which is a measure of a -force times a distance. For an object following a path, the work done is still a force times a distance, but only that force in the direction of the motion is considered. (The *constraint force* keeping the object on the path does no work.) Mathematically, $\hat{T}$ describes the direction of motion along a path, so the work done in moving an object over a small segment of the path is $(F\cdot\hat{T}) \Delta{s}$. Adding up incremental amounts of work leads to a Riemann sum for a line integral involving a vector field. - -> The *work* done in moving an object along a path $C$ by a force field, $F$, is given by the integral -> ```math -> \int_C (F \cdot \hat{T}) ds = \int_C F\cdot d\vec{r} = \int_a^b ((F\circ\vec{r}) \cdot \frac{d\vec{r}}{dt})(t) dt. -> ``` - - ----- - - -In the $n=2$ case, there is another useful interpretation of the line integral. -In this dimension the normal vector, $\hat{N}$, is well defined in terms of the tangent vector, $\hat{T}$, through a rotation: -$\langle a,b\rangle^t = \langle b,-a\rangle^t$. (The negative, $\langle -b,a\rangle$ is also a candidate, the difference in this choice would lead to a sign difference in in the answer.) -This allows the definition of a different line integral, called a flow integral, as detailed later: - -> The *flow* across a curve $C$ is given by -> ```math -> \int_C (F\cdot\hat{N}) ds = \int_a^b (F \circ \vec{r})(t) \cdot (\vec{r}'(t))^t dt. -> ``` - - -### Examples - -##### Example - -Let $F(x,y,z) = \langle x - y, x^2 - y^2, x^2 - z^2 \rangle$ and -$\vec{r}(t) = \langle t, t^2, t^3 \rangle$. Find the work required to move an object along the curve described by $\vec{r}$ between $0$ and $1$. - -```julia; hold=true -F(x,y,z) = [x-y, x^2 - y^2, x^2 - z^2] -F(v) = F(v...) -r(t) = [t, t^2, t^3] - -@syms t::real -integrate((F ∘ r)(t) ⋅ diff.(r(t), t), (t, 0, 1)) -``` - - -##### Example - -Let $C$ be a closed curve. For a closed curve, the work integral is also termed the *circulation*. For the vector field $F(x,y) = \langle -y, x\rangle$ compute the circulation around the triangle with vertices $(-1,0)$, $(1,0)$, and $(0,1)$. - -We have three integrals using $\vec{r}_1(t) = \langle -1+2t, 0\rangle$, -$\vec{r}_2(t) = \langle 1-t, t\rangle$ and -$\vec{r}_3(t) = \langle -t, 1-t \rangle$, all from $0$ to $1$. (Check that the parameterization is counter clockwise.) - -The circulation then is: - -```julia; hold=true -r1(t) = [-1 + 2t, 0] -r2(t) = [1-t, t] -r3(t) = [-t, 1-t] -F(x,y) = [-y, x] -F(v) = F(v...) -integrand(r) = t -> (F ∘ r)(t) ⋅ r'(t) -C1 = quadgk(integrand(r1), 0, 1)[1] -C2 = quadgk(integrand(r2), 0, 1)[1] -C3 = quadgk(integrand(r3), 0, 1)[1] -C1 + C2 + C3 -``` - -That this is non-zero reflects a feature of the vector field. In this case, the vector field spirals around the origin, and the circulation is non zero. - -##### Example - -Let $F$ be the force of gravity exerted by a mass $M$ on a mass $m$ a distance $\vec{r}$ away, that is $F(\vec{r}) = -(GMm/\|\vec{r}\|^2)\hat{r}$. - -Let $\vec{r}(t) = \langle 1-t, 0, t\rangle$, $0 \leq t \leq 1$. For concreteness, we take $G M m$ to be $10$. Then the work to move the mass is given by: - -```julia; -uvec(v) = v/norm(v) # unit vector -GMm = 10 -Fₘ(r) = - GMm /norm(r)^2 * uvec(r) -rₘ(t) = [1-t, 0, t] -quadgk(t -> (Fₘ ∘ rₘ)(t) ⋅ rₘ'(t), 0, 1) -``` - -Hmm, a value of $0$. That's a bit surprising at first glance. Maybe it had something to do with the specific path chosen. To investigate, we connect the start and endpoints with a circular arc, instead of a straight line: - - -```julia; -rₒ(t) = [cos(t), 0, sin(t)] -quadgk(t -> (Fₘ ∘ rₒ)(t) ⋅ rₒ'(t), 0, 1) -``` - -Still $0$. We will see next that this is not surprising if something about $F$ is known. - -!!! note - The [Washington Post](https://www.washingtonpost.com/outlook/everything-you-thought-you-knew-about-gravity-is-wrong/2019/08/01/627f3696-a723-11e9-a3a6-ab670962db05_story.html") had an article by Richard Panek with the quote "Well, yes — depending on what we mean by 'attraction.' Two bodies of mass don’t actually exert some mysterious tugging on each other. Newton himself tried to avoid the word 'attraction' for this very reason. All (!) he was trying to do was find the math to describe the motions both down here on Earth and up there among the planets (of which Earth, thanks to Copernicus and Kepler and Galileo, was one)." The point being the formula above is a mathematical description of the force, but not an explanation of how the force actually is transferred. - - -#### Work in a *conservative* vector field - -Let $f: R^n \rightarrow R$ be a scalar function. Its gradient, $\nabla f$ is a *vector field*. For a *scalar* function, we have by the chain rule: - -```math -\frac{d(f \circ \vec{r})}{dt} = \nabla{f}(\vec{r}(t)) \cdot \frac{d\vec{r}}{dt}. -``` - -If we integrate, we see: - -```math -W = \int_a^b \nabla{f}(\vec{r}(t)) \cdot \frac{d\vec{r}}{dt} dt = -\int_a^b \frac{d(f \circ \vec{r})}{dt} dt = -(f\circ\vec{r})\mid_{t = a}^b = -(f\circ\vec{r})(b) - (f\circ\vec{r})(a), -``` -using the Fundamental Theorem of Calculus. - -The main point above is that *if* the vector field is the gradient of a scalar field, then the work done depends *only* on the endpoints of the path and not the path itself. - -> **Conservative vector field**: -> If $F$ is a vector field defined in an *open* region $R$; $A$ and $B$ are points in $R$ and *if* for *any* curve $C$ in $R$ connecting $A$ to $B$, the line integral of $F \cdot \vec{T}$ over $C$ depends *only* on the endpoint $A$ and $B$ and not the path, then the line integral is called *path indenpendent* and the field is called a *conservative field*. - -The force of gravity is the gradient of a scalar field. As such, the two integrals above which yield $0$ could have been computed more directly. The particular scalar field is $f = -GMm/\|\vec{r}\|$, which goes by the name the gravitational *potential* function. As seen, $f$ depends only on magnitude, and as the endpoints of the path in the example have the same distance to the origin, the work integral, $(f\circ\vec{r})(b) - (f\circ\vec{r})(a)$ will be $0$. - - -##### Example - -Coulomb's law states that the electrostatic force between two charged particles is proportional to the product of their charges and *inversely* proportional to square of the distance between the two particles. That is, - -```math -F = k\frac{ q q_0}{\|\vec{r}\|^2}\frac{\vec{r}}{\|\vec{r}\|}. -``` - -This is similar to gravitational force and is a *conservative force*. We saw that a line integral for work in a conservative force depends only on the endpoints. Verify, that for a closed loop the work integral will yield $0$. - -Take as a closed loop the unit circle, parameterized by arc-length by $\vec{r}(t) = \langle \cos(t), \sin(t)\rangle$. The unit tangent will be $\hat{T} = \vec{r}'(t) = \langle -\sin(t), \cos(t) \rangle$. The work to move a particle of charge $q_0$ about a partical of charge $q$ at the origin around the unit circle would be computed through: - -```julia; hold=true -@syms k q q0 t -F(r) = k*q*q0 * r / norm(r)^3 -r(t) = [cos(t), sin(t)] -T(r) = [-r[2], r[1]] -W = integrate(F(r(t)) ⋅ T(r(t)), (t, 0, 2PI)) -``` - -### Closed curves and regions; - -There are technical assumptions about curves and regions that are necessary for some statements to be made: - -* Let $C$ be a [Jordan](https://en.wikipedia.org/wiki/Jordan_curve_theorem) curve - a non-self-intersecting continuous loop in the plane. Such a curve divides the plane into two regions, one bounded and one unbounded. The normal to a Jordan curve is assumed to be in the direction of the unbounded part. - -* Further, we will assume that our curves are *piecewise smooth*. That is comprised of finitely many smooth pieces, continuously connected. - -* The region enclosed by a closed curve has an *interior*, $D$, which we assume is an *open* set (one for which every point in $D$ has some "ball" about it entirely within $D$ as well.) - -* The region $D$ is *connected* meaning between any two points there is a continuous path in $D$ between the two points. - -* The region $D$ is *simply connected*. This means it has no "holes." Technically, any path in $D$ can be contracted to a point. Connected means one piece, simply connected means no holes. - - -### The fundamental theorem of line integrals - -The fact that work in a potential field is path independent is a consequence of the Fundamental Theorem of Line [Integrals](https://en.wikipedia.org/wiki/Gradient_theorem): - -> Let $U$ be an open subset of $R^n$, $f: U \rightarrow R$ a *differentiable* function and $\vec{r}: R \rightarrow R^n$ a differentiable function such that the the path $C = \vec{r}(t)$, $a\leq t\leq b$ is contained in $U$. Then -> ```math -> \int_C \nabla{f} \cdot d\vec{r} = -> \int_a^b \nabla{f}(\vec{r}(t)) \cdot \vec{r}'(t) dt = -> f(\vec{r}(b)) - f(\vec{r}(a)). -> ``` - - - -That is, a line integral through a gradient field can be evaluated by -evaluating the original scalar field at the endpoints of the -curve. In other words, line integrals through gradient fields are conservative. - -Are conservative fields gradient fields? The answer is yes. - -Assume $U$ is an open region in $R^n$ and $F$ is a continuous and conservative vector field in $U$. - -Let $a$ in $U$ be some fixed point. For $\vec{x}$ in $U$, define: - -```math -\phi(\vec{x}) = \int_{\vec\gamma[a,\vec{x}]} F \cdot \frac{d\vec\gamma}{dt}dt, -``` - -where $\vec\gamma$ is *any* differentiable path in $U$ connecting $a$ to -$\vec{x}$ (as a point in $U$). The function $\phi$ is uniquely -defined, as the integral only depends on the endpoints, not the choice -of path. - -It is [shown](https://en.wikipedia.org/wiki/Gradient_theorem#Converse_of_the_gradient_theorem) that the directional derivative $\nabla{\phi} \cdot \vec{v}$ is equal to $F \cdot \vec{v}$ by showing - -```math -\lim_{t \rightarrow 0}\frac{\phi(\vec{x} + t\vec{v}) - \phi(\vec{x})}{t} -= \lim_{t \rightarrow 0} \frac{1}{t} \int_{\vec\gamma[\vec{x},\vec{x}+t\vec{v}]} F \cdot \frac{d\vec\gamma}{dt}dt -= F(\vec{x}) \cdot \vec{v}. -``` - -This is so for all $\vec{v}$, so in particular for the coordinate vectors. So $\nabla\phi = F$. - - -##### Example - -Let $Radial(x,y) = \langle x, y\rangle$. This is a conservative field. Show the work integral over the half circle in the upper half plane is the same as the work integral over the $x$ axis connecting $-1$ to $1$. - -We have: - -```julia; -Radial(x,y) = [x,y] -Radial(v) = Radial(v...) - -r₁(t) = [-1 + t, 0] -quadgk(t -> Radial(r₁(t)) ⋅ r₁'(t), 0, 2) -``` - -Compared to - -```julia; -r₂(t) = [-cos(t), sin(t)] -quadgk(t -> Radial(r₂(t)) ⋅ r₂'(t), 0, pi) -``` - -##### Example - - - - - ----- - -Not all vector fields are conservative. How can a vector field in $U$ -be identified as conservative? For now, this would require either -finding a scalar potential *or* showing all line integrals are path -independent. - -In dimension $2$ there is an easy to check method assuming $U$ is *simply connected*: If $F=\langle F_x, F_y\rangle$ is continuously differentiable in an simply connected region *and* $\partial{F_y}/\partial{x} - \partial{F_x}/\partial{y} = 0$ then $F$ is conservative. A similarly statement is available in dimension $3$. The reasoning behind this will come from the upcoming Green's theorem. - - - - -### Flow across a curve - - -The flow integral in the $n=2$ case was - -```math -\int_C (F\cdot\hat{N}) ds = \int_a^b (F \circ \vec{r})(t) \cdot (\vec{r}'(t))^{t} dt, -``` - -where $\langle a,b\rangle^t = \langle b, -a\rangle$. - - -For a given section of $C$, the vector field breaks down into a -tangential and normal component. The tangential component moves along -the curve and so doesn't contribute to any flow *across* the curve, only -the normal component will contribute. Hence the -$F\cdot\hat{N}$ integrand. The following figure indicates the flow of a vector -field by horizontal lines, the closeness of the lines representing -strength, though these are all evenly space. The two line segments -have equal length, but the one captures more flow than the other, as -its normal vector is more parallel to the flow lines: - -```julia; hold=true; echo=false -p = plot(legend=false, aspect_ratio=:equal) -for y in range(0, 1, length=15) - arrow!( [0,y], [3,0]) -end -plot!(p, [2,2],[.6, .9], linewidth=3) -arrow!( [2,.75],1/2*[1,0], linewidth=3) -theta = pi/3 -l = .3/2 -plot!(p, [2-l*cos(theta), 2+l*cos(theta)], [.25-l*sin(theta), .25+l*sin(theta)], linewidth=3) -arrow!( [2, 0.25], 1/2*[sin(theta), -cos(theta)], linewidth=3) - -p -``` - - -The flow integral is typically computed for a closed (Jordan) curve, measuring the total flow out of a region. In this case, the integral is written $\oint_C (F\cdot\hat{N})ds$. - - -!!! note - For a Jordan curve, the positive orientation of the curve is such that the normal direction (proportional to $\hat{T}'$) points away from the bounded interior. For a non-closed path, the choice of parameterization will determine the normal and the integral for flow across a curve is dependent - up to its sign - on this choice. - - -##### Example - -The [New York Times](https://www.nytimes.com/interactive/2019/06/20/world/asia/hong-kong-protest-size.html) showed aerial photos to estimate the number of protest marchers in Hong Kong. This is a more precise way to estimate crowd size, but requires a drone or some such to take photos. If one is on the ground, the number of marchers could be *estimated* by finding the flow of marchers across a given width. In the Times article, we see "Protestors packed the width of Hennessy Road for more than 5 hours. If this road is 50 meters wide and the rate of the marchers is 3 kilometers per hour, estimate the number of marchers. - -The basic idea is to compute the rate of flow *across* a part of the street and then multiply by time. For computational sake, say the marchers are on a grid of 1 meters (that is in a 40m wide street, there is room for 40 marchers at a time. In one minute, the marchers move 50 meters: - -```julia; -3000/60 -``` - -This means the rate of marchers per minute is `40 * 50`. If this is steady over 5 hours, this *simple* count gives: - -```julia; -40 * 50 * 5 * 60 -``` - -This is short of the estimate 2M marchers, but useful for a rough estimate. The point is from rates of flow, which can be calculated locally, amounts over bigger scales can be computed. The word "*across*" is used, as only the direction across the part of the street counts in the computation. Were the marchers in total unison and then told to take a step to the left and a step to the right, they would have motion, but since it wasn't across the line in the road (rather along the line) there would be no contribution to the count. The dot product with the normal vector formalizes this. - -##### Example - -Let a path $C$ be parameterized by $\vec{r}(t) = \langle \cos(t), 2\sin(t)\rangle$, $0 \leq t \leq \pi/2$ and $F(x,y) = \langle \cos(x), \sin(xy)\rangle$. Compute the flow across $C$. - -We have - -```julia; hold=true -r(t) = [cos(t), 2sin(t)] -F(x,y) = [cos(x), sin(x*y)] -F(v) = F(v...) -normal(a,b) = [b, -a] -G(t) = (F ∘ r)(t) ⋅ normal(r(t)...) -a, b = 0, pi/2 -quadgk(G, a, b)[1] -``` - -##### Example - -Example, let $F(x,y) = \langle -y, x\rangle$ be a vector field. (It represents an rotational flow.) What is the flow across the unit circle? - -```julia; hold=true -@syms t::real -F(x,y) = [-y,x] -F(v) = F(v...) -r(t) = [cos(t),sin(t)] -T(t) = diff.(r(t), t) -normal(a,b) = [b,-a] -integrate((F ∘ r)(t) ⋅ normal(T(t)...) , (t, 0, 2PI)) -``` - - - -##### Example - -Let $F(x,y) = \langle x,y\rangle$ be a vector field. (It represents a *source*.) What is the flow across the unit circle? - -```julia; hold=true -@syms t::real -F(x,y) = [x, y] -F(v) = F(v...) -r(t) = [cos(t),sin(t)] -T(t) = diff.(r(t), t) -normal(a,b) = [b,-a] -integrate((F ∘ r)(t) ⋅ normal(T(t)...) , (t, 0, 2PI)) -``` - -##### Example - - -Let $F(x,y) = \langle x, y\rangle / \| \langle x, y\rangle\|^3$: - -```julia; -F₁(x,y) = [x,y] / norm([x,y])^2 -F₁(v) = F₁(v...) -``` - -Consider $C$ to be the square with vertices at $(-1,-1)$, $(1,-1)$, $(1,1)$, and $(-1, 1)$. What is the flow across $C$ for this vector field? The region has simple outward pointing *unit* normals, these being $\pm\hat{i}$ and $\pm\hat{j}$, the unit vectors in the $x$ and $y$ direction. The integral can be computed in 4 parts. The first (along the bottom): - -```julia; hold=true -@syms s::real - -r(s) = [-1 + s, -1] -n = [0,-1] -A1 = integrate(F₁(r(s)) ⋅ n, (s, 0, 2)) - -#The other three sides are related as each parameterization and normal is similar: - -r(s) = [1, -1 + s] -n = [1, 0] -A2 = integrate(F₁(r(s)) ⋅ n, (s, 0, 2)) - - -r(s) = [1 - s, 1] -n = [0, 1] -A3 = integrate(F₁(r(s)) ⋅ n, (s, 0, 2)) - - -r(s) = [-1, 1-s] -n = [-1, 0] -A4 = integrate(F₁(r(s)) ⋅ n, (s, 0, 2)) - -A1 + A2 + A3 + A4 -``` - -As could have been anticipated by symmetry, the answer is simply `4A1` or $2\pi$. What likely is not anticipated, is that this integral will be the same as that found by integrating over the unit circle (an easier integral): - -```julia; hold=true -@syms t::real -r(t) = [cos(t), sin(t)] -N(t) = r(t) -integrate(F₁(r(t)) ⋅ N(t), (t, 0, 2PI)) -``` - -This equivalence is a consequence of the upcoming Green's theorem, as the vector field satisfies a particular equation. - - - - -## Surface integrals - -```julia; hold=true; echo=false -#out = download("https://upload.wikimedia.org/wikipedia/en/c/c1/Cloud_Gate_%28The_Bean%29_from_east%27.jpg") -#cp(out, "figures/kapoor-cloud-gate.jpg") -imgfile = "figures/kapoor-cloud-gate.jpg" -caption = """ -The Anish Kapoor sculpture Cloud Gate maps the Cartesian grid formed by its concrete resting pad onto a curved surface showing the local distortions. Knowing the areas of the reflected grid after distortion would allow the computation of the surface area of the sculpture through addition. (Wikipedia) -""" -ImageFile(:integral_vector_calculus, imgfile, caption) -``` - - -We next turn attention to a generalization of line integrals to surface integrals. Surfaces were described in one of three ways: directly through a function as $z=f(x,y)$, as a level curve through $f(x,y,z) = c$, and parameterized through a function $\Phi: R^2 \rightarrow R^3$. The level curve description is locally a function description, and the function description leads to a parameterization ($\Phi(u,v) = \langle u,v,f(u,v)\rangle$) so we restrict to the parameterized case. - - - - -Consider the figure of the surface described by $\Phi(u,v) = \langle u,v,f(u,v)\rangle$: - - -```julia; hold=true; echo=false -f(x,y) = 2 - (x+1/2)^2 - y^2 -xs = ys = range(0, 1/2, length=10) -p = surface(xs, ys, f, legend=false, camera=(45,45)) -for x in xs - plot!(p, unzip(y -> [x, y, f(x,y)], 0, 1/2)..., linewidth=3) - plot!(p, unzip(y -> [x, y, 0], 0, 1/2)..., linewidth=3) -end -for y in ys - plot!(p, unzip(x -> [x, y, f(x,y)], 0, 1/2)..., linewidth=3) - plot!(p, unzip(x -> [x, y, 0], 0, 1/2)..., linewidth=3) -end -p -``` - -The partitioning of the $u-v$ plane into a grid, lends itself to a partitioning of the surface. To compute the total *surface area* of the surface, it would be natural to begin by *approximating* the area of each cell of this partition and add. As with other sums, we would expect that as the cells got smaller in diameter, the sum would approach an integral, in this case an integral yielding the surface area. - -Consider a single cell: - -```julia; hold=true; echo=false; -# from https://commons.wikimedia.org/wiki/File:Surface_integral1.svg -#cp(download("https://upload.wikimedia.org/wikipedia/commons/thumb/8/87/Surface_integral1.svg/500px-Surface_integral1.svg.png"), "figures/surface-integral-cell.png", force=true) -#imgfile = "figures/surface-integral-cell.png" -#caption = "The rectangular region maps to a piece of the surface approximated by #a parallelogram whose area can be computed. (Wikipedia)" -#ImageFile(:integral_vector_calculus, imgfile, caption) -nothing -``` - -```julia; hold=true; echo=false -f(x,y)= .5 - ((x-2)/4)^2 - ((y-1)/3)^2 -Phi(uv) = [uv[1],uv[2],f(uv...)] - -xs = range(0, 3.5, length=50) -ys = range(0, 2.5, length=50) -surface(xs,ys, f, legend=false) -Δx = 0.5; Δy = 0.5 -x0 = 2.5; y0 = 0.25 - -ps = [[x0,y0,0], [x0+Δx,y0,0],[x0+Δx,y0+Δy,0],[x0, y0+Δy, 0],[x0,y0,0]] -plot!(unzip(ps)..., seriestype=:shape, color =:blue) - -fx = t -> [x0+t, y0, f(x0+t, y0)] -fy = t -> [x0, y0+t, f(x0, y0+t)] -plot!(unzip(fx.(xs.-x0))..., color=:green) -plot!(unzip(fy.(ys.-y0))..., color=:green) -fx = t -> [x0+t, y0+Δy, f(x0+t, y0+Δy)] -fy = t -> [x0+Δx, y0+t, f(x0+Δx, y0+t)] -ts = range(0, 1, length=20) -plot!(unzip(fx.(ts*Δx))..., color=:green) -plot!(unzip(fy.(ts*Δy))..., color=:green) - -Pt = [x0,y0,f(x0,y0)] -Jac = ForwardDiff.jacobian(Phi, Pt[1:2]) -v1 = Jac[:,1]; v2 = Jac[:,2] -arrow!(Pt, v1/2, linewidth=5, color=:red) -arrow!(Pt, v2/2, linewidth=5, color=:red) -arrow!(Pt + v1/2, v2/2, linewidth=1, linetype=:dashed, color=:red) -arrow!(Pt + v2/2, v1/2, linewidth=1, linetype=:dashed, color=:red) -arrow!(Pt, (1/4)*(v1 × v2), linewidth=3, color=:blue) -``` - -The figure shows that a cell on the grid in the $u-v$ plane of area $\Delta{u}\Delta{v}$ maps to a cell of the partition with surface area $\Delta{S}$ which can be *approximated* by a part of the tangent plane described by two vectors $\vec{v}_1 = \partial{\Phi}/\partial{u}$ and $\vec{v}_2 = \partial{\Phi}/\partial{v}$. These two vectors have cross product which a) points in the direction of the normal vector, and b) has magnitude yielding the approximation $\Delta{S} \approx \|\vec{v}_1 \times \vec{v}_2\|\Delta{u}\Delta{v}$. - -If we were to integrate the function $G(x,y, z)$ over the *surface* $S$, then an approximating Riemann sum could be produced by $G(c) \| \vec{v}_1 \times \vec{v}_2\| \Delta u \Delta v$, for some point $c$ on the surface. - -In the limit a definition of an *integral* over a surface $S$ in $R^3$ is found by a two-dimensional integral over $R$ in $R^2$: - -```math -\int_S G(x,y,z) dS = \int_R G(\Phi(u,v)) -\| \frac{\partial{\Phi}}{\partial{u}} \times \frac{\partial{\Phi}}{\partial{v}} \| du dv. -``` - -In the case that the surface is described by $z = f(x,y)$, then the formula's become $\vec{v}_1 = \langle 1,0,\partial{f}/\partial{x}\rangle$ and $\vec{v}_2 = \langle 0, 1, \partial{f}/\partial{y}\rangle$ with cross product $\vec{v}_1\times\vec{v}_2 =\langle -\partial{f}/\partial{x}, -\partial{f}/\partial{y},1\rangle$. - -The value $\| \frac{\partial{\Phi}}{\partial{u}} \times -\frac{\partial{\Phi}}{\partial{y}} \|$ is called the *surface -element*. As seen, it is the scaling between a unit area in the $u-v$ -plane and the approximating area on the surface after the -parameterization. - -### Examples - -Let us see that the formula holds for some cases where the answer is known by other means. - -##### A cone - -The surface area of cone is a known quantity. In cylindrical coordinates, the cone may be described by $z = a - br$, so the parameterization $(r, \theta) \rightarrow \langle r\cos(\theta), r\sin(\theta), a - br \rangle$ maps $T = [0, a/b] \times [0, 2\pi]$ onto the surface (less the bottom). - -The surface element is the cross product $\langle \cos(\theta), \sin(\theta), -b\rangle$ and $\langle -r\sin(\theta), r\cos(\theta), 0\rangle$, which is: - -```julia; -@syms 𝑹::postive θ::positive 𝒂::positive 𝒃::positive -𝒏 = [cos(θ), sin(θ), -𝒃] × [-𝑹*sin(θ), 𝑹*cos(θ), 0] -𝒔𝒆 = simplify(norm(𝒏)) -``` - -(To do this computationally, one might compute: -```julia; hold=true -Phi(r, theta) = [r*cos(theta), r*sin(theta), 𝒂 - 𝒃*r] -Phi(𝑹, θ).jacobian([𝑹, θ]) -``` - -and from here pull out the two vectors to take a cross product.) - - -The surface area is then found by integrating $G(\vec{x}) = 1$: - -```julia; -integrate(1 * 𝒔𝒆, (𝑹, 0, 𝒂/𝒃), (θ, 0, 2PI)) -``` - -A formula from a *quick* Google search is $A = \pi r(r^2 + \sqrt{h^2 + r^2}$. Does this match up? - -```julia; hold=true -𝑹 = 𝒂/𝒃; 𝒉 = 𝒂 -pi * 𝑹 * (𝑹 + sqrt(𝑹^2 + 𝒉^2)) |> simplify -``` - -Nope, off by a summand of $\pi(a/b)^2 = \pi r^2$, which may be recognized as the area of the base, which we did not compute, but which the Google search did. So yes, the formulas do agree. - -##### Example - -The sphere has known surface area $4\pi r^2$. Let's see if we can compute this. With the parameterization from spherical coordinates $(\theta, \phi) \rightarrow \langle r\sin\phi\cos\theta, r\sin\phi\sin\theta,r\cos\phi\rangle$, we have approaching this *numerically*: - -```julia; hold=true -Rad = 1 -Phi(theta, phi) = Rad * [sin(phi)*cos(theta), sin(phi)*sin(theta), cos(phi)] -Phi(v) = Phi(v...) - -function surface_element(pt) - Jac = ForwardDiff.jacobian(Phi, pt) - v1, v2 = Jac[:,1], Jac[:,2] - norm(v1 × v2) -end -out = hcubature(surface_element, (0, 0), (2pi, 1pi)) -out[1] - 4pi*Rad^2 # *basically* zero -``` - - -##### Example - -In [Surface area](../integrals/surface_area.mmd) the following formula for the surface area of a surface of *revolution* about the $x$ axis is described by $r=f(x)$ is given: - -```math -\int_a^b 2\pi f(x) \cdot \sqrt{1 + f'(x)^2} dx. -``` - -Consider the transformation $(x, \theta) \rightarrow \langle x, f(x)\cos(\theta), f(x)\sin(\theta)$. This maps the region $[a,b] \times [0, 2\pi]$ *onto* the surface of revolution. As such, the surface element would be: - -```julia -@syms 𝒇()::positive x::real theta::real - -Phi(x, theta) = [x, 𝒇(x)*cos(theta), 𝒇(x)*sin(theta)] -Jac = Phi(x, theta).jacobian([x, theta]) -v1, v2 = Jac[:,1], Jac[:,2] -se = norm(v1 × v2) -se .|> simplify -``` - -This in agreement with the previous formula. - - -##### Example - -Consider the *upper* half sphere, $S$. Compute $\int_S z dS$. - -Were the half sphere made of a thin uniform material, this would be computed to find the $z$ direction of the centroid. - -We use the spherical coordinates to parameterize: - -```math -\Phi(\theta, \phi) = \langle \cos(\phi)\cos(\theta), \cos(\phi)\sin(\theta), \sin(\phi) \rangle -``` - -The Jacobian and surface element are computed and then the integral is performed: - -```julia; hold=true -@syms theta::real phi::real -Phi(theta, phi) = [cos(phi)*cos(theta), cos(phi)*sin(theta), sin(phi)] -Jac = Phi(theta,phi).jacobian([theta, phi]) - -v1, v2 = Jac[:,1], Jac[:,2] -SurfElement = norm(v1 × v2) |> simplify - -z = sin(phi) -integrate(z * SurfElement, (theta, 0, 2PI), (phi, 0, PI/2)) -``` - -### Orientation - -A smooth surface $S$ is *orientable* if it possible to define a unit normal vector, $\vec{N}$ that varies continuously with position. For example, a sphere has a normal vector that does this. On the other hand, a Mobius strip does not, as a normal when moved around the surface may necessarily be reversed as it returns to its starting point. For a closed, orientable smooth surface there are two possible choices for a normal, and convention chooses the one that points away from the contained region, such as the outward pointing normal for the sphere or torus. - - -### Surface integrals in vector fields - -Beyond finding surface area, surface integrals can also compute interesting physical phenomena. These are often associated to a vector field (in this case a function $\vec{F}: R^3 \rightarrow R^3$), and the typical case is the *flux* through a surface defined locally by $\vec{F} \cdot \hat{N}$, that is the *magnitude* of the *projection* of the field onto the *unit* normal vector. - - -Consider the flow of water through an opening in a time period $\Delta t$. The amount of water mass to flow through would be the area of the opening times the velocity of the flow perpendicular to the surface times the density times the time period; symbolically: $dS \cdot ((\rho \vec{v}) \cdot \vec{N}) \cdot \Delta t$. Dividing by $\Delta t$ gives a rate of flow as $((\rho \vec{v}) \cdot \vec{N}) dS$. With $F = \rho \vec{v}$, the flux integral can be seen as the rate of flow through a surface. - -To find the normal for a surface element arising from a parameterization $\Phi$, we have the two *partial* derivatives $\vec{v}_1=\partial{\Phi}/\partial{u}$ and $\vec{v}_2 = \partial{\Phi}/\partial{v}$, the two column vectors of the Jacobian matrix of $\Phi(u,v)$. These describe the tangent plane, and even more their cross product will be a) *normal* to the tangent plane and b) have magnitude yielding the surface element of the transformation. - - -From this, for a given parameterization, $\Phi(u,v):T \rightarrow S$, the following formula is suggested for orientable surfaces: - -```math -\int_S \vec{F} \cdot \hat{N} dS = -\int_T \vec{F}(\Phi(u,v)) \cdot -(\frac{\partial{\Phi}}{\partial{u}} \times \frac{\partial{\Phi}}{\partial{v}}) -du dv. -``` - - -When the surface is described by a function, $z=f(x,y)$, the parameterization is $(u,v) \rightarrow \langle u, v, f(u,v)\rangle$, and the two vectors are $\vec{v}_1 = \langle 1, 0, \partial{f}/\partial{u}\rangle$ and $\vec{v}_2 = \langle 0, 1, \partial{f}/\partial{v}\rangle$ and their cross product is $\vec{v}_1\times\vec{v}_1=\langle -\partial{f}/\partial{u}, -\partial{f}/\partial{v}, 1\rangle$. - - -##### Example - -Suppose a vector field $F(x,y,z) = \langle 0, y, -z \rangle$ is given. Let $S$ be the surface of the paraboloid $y = x^2 + z^2$ between $y=0$ and $y=4$. Compute the surface integral $\int_S F\cdot \hat{N} dS$. - -This is a surface of revolution about the $y$ axis, so a parameterization is -$\Phi(y,\theta) = \langle \sqrt{y} \cos(\theta), y, \sqrt{y}\sin(\theta) \rangle$. The surface normal is given by: - -```julia; hold=true -@syms y::positive theta::positive -Phi(y,theta) = [sqrt(y)*cos(theta), y, sqrt(y)*sin(theta)] -Jac = Phi(y, theta).jacobian([y, theta]) -v1, v2 = Jac[:,1], Jac[:,2] -Normal = v1 × v2 - -# With this, the surface integral becomes: - -F(x,y,z) = [0, y, -z] -F(v) = F(v...) -integrate(F(Phi(y,theta)) ⋅ Normal, (theta, 0, 2PI), (y, 0, 4)) -``` - -##### Example - -Let $S$ be the closed surface bounded by the cylinder $x^2 + y^2 = 1$, the plane $z=0$, and the plane $z = 1+x$. Let $F(x,y,z) = \langle 1, y, -z \rangle$. Compute $\oint_S F\cdot\vec{N} dS$. - - -```julia; -𝐅(x,y,z) = [1, y, z] -𝐅(v) = 𝐅(v...) -``` - -The surface has three faces, with different outward pointing normals for each. Let $S_1$ be the unit disk in the $x-y$ plane with normal $-\hat{k}$; $S_2$ be the top part, with normal $\langle \langle-1, 0, 1\rangle$ (as the plane is $-1x + 0y + 1z = 1$); and $S_3$ be the cylindrical part with outward pointing normal $\vec{r}$. - - -Integrating over $S_1$, we have the parameterization $\Phi(r,\theta) = \langle r\cos(\theta), r\sin(\theta), 0\rangle$: - -```julia; -@syms 𝐑::positive 𝐭heta::positive -𝐏hi₁(r,theta) = [r*cos(theta), r*sin(theta), 0] -𝐉ac₁ = 𝐏hi₁(𝐑, 𝐭heta).jacobian([𝐑, 𝐭heta]) -𝐯₁, 𝐰₁ = 𝐉ac₁[:,1], 𝐉ac₁[:,2] -𝐍ormal₁ = 𝐯₁ × 𝐰₁ .|> simplify -``` - -```julia; -A₁ = integrate(𝐅(𝐏hi₁(𝐑, 𝐭heta)) ⋅ (-𝐍ormal₁), (𝐭heta, 0, 2PI), (𝐑, 0, 1)) # use -Normal for outward pointing -``` - -Integrating over $S_2$ we use the parameterization $\Phi(r, \theta) = \langle r\cos(\theta), r\sin(\theta), 1 + r\cos(\theta)\rangle$. - -```julia; -𝐏hi₂(r, theta) = [r*cos(theta), r*sin(theta), 1 + r*cos(theta)] -𝐉ac₂ = 𝐏hi₂(𝐑, 𝐭heta).jacobian([𝐑, 𝐭heta]) -𝐯₂, 𝐰₂ = 𝐉ac₂[:,1], 𝐉ac₂[:,2] -𝐍ormal₂ = 𝐯₂ × 𝐰₂ .|> simplify # has correct orientation -``` - -With this, the contribution for $S_2$ is: - -```julia; -A₂ = integrate(𝐅(𝐏hi₂(𝐑, 𝐭heta)) ⋅ (𝐍ormal₂), (𝐭heta, 0, 2PI), (𝐑, 0, 1)) -``` - -Finally for $S_3$, the parameterization used is $\Phi(z, \theta) = \langle \cos(\theta), \sin(\theta), z\rangle$, but this is over a non-rectangular region, as $z$ is between $0$ and $1 + x$. - -This parameterization gives a normal computed through: - -```julia; -@syms 𝐳::positive -𝐏hi₃(z, theta) = [cos(theta), sin(theta), 𝐳] -𝐉ac₃ = 𝐏hi₃(𝐳, 𝐭heta).jacobian([𝐳, 𝐭heta]) -𝐯₃, 𝐰₃ = 𝐉ac₃[:,1], 𝐉ac₃[:,2] -𝐍ormal₃ = 𝐯₃ × 𝐰₃ .|> simplify # wrong orientation, so we change sign below -``` - -The contribution is - -```julia; -A₃ = integrate(𝐅(𝐏hi₃(𝐑, 𝐭heta)) ⋅ (-𝐍ormal₃), (𝐳, 0, 1 + cos(𝐭heta)), (𝐭heta, 0, 2PI)) -``` - -In total, the surface integral is - -```julia; -A₁ + A₂ + A₃ -``` - -##### Example - -Two point charges with charges $q$ and $q_0$ will exert an electrostatic force of attraction or repulsion according to [Coulomb](https://en.wikipedia.org/wiki/Coulomb%27s_law)'s law. The Coulomb force is $kqq_0\vec{r}/\|\vec{r}\|^3$. -This force is proportional to the product of the charges, $qq_0$, and inversely proportional to the square of the distance between them. - -The electric field is a vector field is the field generated by the force on a test charge, and is given by $E = kq\vec{r}/\|\vec{r}\|^3$. - - -Let $S$ be the unit sphere $\|\vec{r}\|^2 = 1$. Compute the surface integral of the electric field over the closed surface, $S$. - -We have (using $\oint$ for a surface integral over a closed surface): - -```math -\oint_S S \cdot \vec{N} dS = -\oint_S \frac{kq}{\|\vec{r}\|^2} \hat{r} \cdot \hat{r} dS = -\oint_S \frac{kq}{\|\vec{r}\|^2} dS = -kqq_0 \cdot SA(S) = -4\pi k q -``` - - -Now consider the electric field generated by a point charge within the unit sphere, but not at the origin. The integral now will not fall in place by symmetry considerations, so we will approach the problem numerically. - - -```julia; -E(r) = (1/norm(r)^2) * uvec(r) # kq = 1 - -Phiₑ(theta, phi) = 1*[sin(phi)*cos(theta), sin(phi) * sin(theta), cos(phi)] -Phiₑ(r) = Phiₑ(r...) - -normal(r) = Phiₑ(r)/norm(Phiₑ(r)) - -function SE(r) - Jac = ForwardDiff.jacobian(Phiₑ, r) - v1, v2 = Jac[:,1], Jac[:,2] - v1 × v2 -end - -a = rand() * Phiₑ(2pi*rand(), pi*rand()) -A1 = hcubature(r -> E(Phiₑ(r)-a) ⋅ normal(r) * norm(SE(r)), (0.0,0.0), (2pi, 1pi)) -A1[1] -``` - -The answer is $4\pi$, regardless of the choice of `a`, as long as it is *inside* the surface. (We see above, some fussiness in the limits of integration. `HCubature` does some conversion of the limits, but does not *currently* do well with mixed types, so in the above only floating point values are used.) - -When `a` is *outside* the surface, the answer is *always* a constant: - -```julia; hold=true -a = 2 * Phiₑ(2pi*rand(), pi*rand()) # random point with radius 2 -A1 = hcubature(r -> E(Phiₑ(r)-a) ⋅ normal(r) * norm(SE(r)), (0.0,0.0), (2pi, pi/2)) -A2 = hcubature(r -> E(Phiₑ(r)-a) ⋅ normal(r) * norm(SE(r)), (0.0,pi/2), (2pi, 1pi)) -A1[1] + A2[1] -``` - -That constant being $0$. - -This is a consequence of [Gauss's law](https://en.wikipedia.org/wiki/Gauss%27s_law), which states that for an electric field $E$, the electric flux through a closed surface is proportional to the total charge contained. (Gauss's law is related to the upcoming divergence theorem.) When `a` is inside the surface, the total charge is the same regardless of exactly where, so the integral's value is always the same. When `a` is outside the surface, the total charge inside the sphere is $0$, so the flux integral is as well. - -Gauss's law is typically used to identify the electric field by choosing a judicious surface where the surface integral can be computed. For example, suppose a ball of radius $R_0$ has a *uniform* charge. What is the electric field generated? *Assuming* it is dependent only on the distance from the center of the charged ball, we can, first, take a sphere of radius $R > R_0$ and note that $E(\vec{r})\cdot\hat{N}(r) = \|E(R)\|$, the magnitude a distance $R$ away. So the surface integral is simply $\|E(R)\|4\pi R^2$ and by Gauss's law a constant depending on the total charge. So $\|E(R)\| ~ 1/R^2$. When $R < R_0$, the same applies, but the total charge within the surface will be like $(R/R_0 )^3$, so the result will be *linear* in $R$, as: - -```math -4 \pi \|E(R)\| R^2 = k 4\pi \left(\frac{R}{R_0}\right)^3. -``` - - - - -## Questions - -###### Question - -Let $\vec{r}(t) = \langle e^t\cos(t), e^{-t}\sin(t) \rangle$. - -What is $\|\vec{r}'(1/2)\|$? - -```julia; hold=true; echo=false -r(t) = [exp(t)*cos(t), exp(-t)*sin(t)] -val = norm(r'(1/2)) -numericq(val) -``` - -What is the $x$ (first) component of $\hat{N}(t) = \hat{T}'(t)/\|\hat{T}'(t)\|$ at $t=1/2$? - -```julia; hold=true; echo=false -r(t) = [exp(t)*cos(t), exp(-t)*sin(t)] -T(t) = r'(t)/norm(r'(t)) -N(t) = T'(t)/norm(T'(t)) -val = N(1/2)[1] -numericq(val) -``` - - -###### Question - -Let $\Phi(u,v) = \langle u,v,u^2+v^2\rangle$ parameterize a surface. Find the magnitude of -$\| \partial{\Phi}/\partial{u} \times \partial{\Phi}/\partial{v} \|$ at $u=1$ and $v=2$. - -```julia; hold=true; echo=false -Phi(u,v) = [u, v, u^2 + v^2] -Jac = ForwardDiff.jacobian(uv -> Phi(uv...), [1,2]) -val = norm(Jac[:,1] × Jac[:,2]) -numericq(val) -``` - - -###### Question - -For a plane $ax+by+cz=d$ find the unit normal. - -```julia; hold=true; echo=false -choices = [ -raw" ``\langle a, b, c\rangle / \| \langle a, b, c\rangle\|``", -raw" ``\langle a, b, c\rangle``", -raw" ``\langle d-a, d-b, d-c\rangle / \| \langle d-a, d-b, d-c\rangle\|``", -] -answ = 1 -radioq(choices, answ) -``` - -Does it depend on $d$? - -```julia; hold=true; echo=false -choices = [ -L"No. Moving $d$ just shifts the plane up or down the $z$ axis, but won't change the normal vector", -L"Yes. Of course. Different values for $d$ mean different values for $x$, $y$, and $z$ are needed.", -L"Yes. The gradient of $F(x,y,z) = ax + by + cz$ will be normal to the level curve $F(x,y,z)=d$, and so this will depend on $d$." -] -answ = 1 -radioq(choices, answ) -``` - - - - -###### Question - -Let $\vec{r}(t) = \langle \cos(t), \sin(t), t\rangle$ and let $F(x,y,z) = \langle -y, x, z\rangle$ - -Numerically compute $\int_0^{2\pi} F(\vec{r}(t)) \cdot \vec{r}'(t) dt$. - -```julia; hold=true; echo=false -F(x,y,z) = [-y, x, z] -r(t) = [cos(t), sin(t), t] -val = quadgk(t -> F(r(t)...) ⋅ r'(t), 0, 2pi)[1] -numericq(val) -``` - - -Compute the value symbolically: - -```julia; hold=true; echo=false -choices = [ -raw" ``2\pi + 2\pi^2``", -raw" ``2\pi^2``", -raw" ``4\pi``" -] -answ = 1 -radioq(choices, answ) -``` - -###### Question - - -Let $F(x,y) = \langle 2x^3y^2, xy^4 + 1\rangle$. What is the work done in integrating $F$ along the parabola $y=x^2$ between $(-1,1)$ and $(1,1)$? Give a numeric answer: - -```julia; hold=true; echo=false -F(x,y) = [2x^3*y^2, x*y^4 + 1] -r(t) = [t, t^2] -val = quadgk(t -> F(r(t)...) ⋅ r'(t), -1, 1)[1] -numericq(val) -``` - - - -###### Question - -Let $F = \nabla{f}$ where $f:R^2 \rightarrow R$. The level curves of $f$ are curves in the $x-y$ plane where $f(x,y)=c$, for some constant $c$. Suppose $\vec{r}(t)$ describes a path on the level curve of $f$. What is the value of $\int_C F \cdot d\vec{r}$? - -```julia; hold=true; echo=false -choices =[ -L"It will be $0$, as $\nabla{f}$ is orthogonal to the level curve and $\vec{r}'$ is tangent to the level curve", -L"It will $f(b)-f(a)$ for any $b$ or $a$" -] -answ = 1 -radioq(choices, answ) -``` - - -###### Question - -Let $F(x,y) = (x^2+y^2)^{-k/2} \langle x, y \rangle$ be a radial field. The work integral around the unit circle simplifies: - -```math -\int_C F\cdot \frac{dr}{dt} dt = \int_0^{2pi} \langle (1)^{-k/2} \cos(t), \sin(t) \rangle \cdot \langle-\sin(t), \cos(t)\rangle dt. -``` - -For any $k$, this integral will be: - -```julia; hold=true; echo=false -numericq(0) -``` - -###### Question - -Let $f(x,y) = \tan^{-1}(y/x)$. We will integrate $\nabla{f}$ over the unit circle. The integrand wil be: - -```julia; hold=true -@syms t::real x::real y::real -f(x,y) = atan(y/x) -r(t) = [cos(t), sin(t)] -∇f = subs.(∇(f(x,y)), x .=> r(t)[1], y .=> r(t)[2]) .|> simplify -drdt = diff.(r(t), t) -∇f ⋅ drdt |> simplify -``` - -So $\int_C \nabla{f}\cdot d\vec{r} = \int_0^{2\pi} \nabla{f}\cdot d\vec{r}/dt dt = 2\pi$. - -Why is this surprising? - -```julia; hold=true; echo=false -choices = [ -L"The field is a potential field, but the path integral around $0$ is not path dependent.", -L"The value of $d/dt(f\circ\vec{r})=0$, so the integral should be $0$." -] -answ =1 -radioq(choices, answ) -``` - -The function $F = \nabla{f}$ is - -```julia; hold=true; echo=false -choices = [ -"Not continuous everywhere", -"Continuous everywhere" -] -answ = 1 -radioq(choices, answ) -``` - -###### Question - -Let $F(x,y) = \langle F_x, F_y\rangle = \langle 2x^3y^2, xy^4 + 1\rangle$. Compute - -```math -\frac{\partial{F_y}}{\partial{x}}- \frac{\partial{F_x}}{\partial{y}}. -``` - -Is this $0$? - -```julia; hold=true; echo=false -@syms x y -F(x,y) = [2x^3*y^2, x*y^4 + 1] -val = iszero(diff(F(x,y)[2],x) - diff(F(x,y)[1],y)) -yesnoq(val) -``` - - -###### Question - -Let $F(x,y) = \langle F_x, F_y\rangle = \langle 2x^3, y^4 + 1\rangle$. Compute - -```math -\frac{\partial{F_y}}{\partial{x}} - \frac{\partial{F_x}}{\partial{y}}. -``` - -Is this $0$? - -```julia; hold=true; echo=false -@syms x y -F(x,y) = [2x^3, y^4 + 1] -val = iszero(diff(F(x,y)[2],x) - diff(F(x,y)[1],y)) -yesnoq(val) -``` - - - -###### Question - -It is not unusual to see a line integral, $\int F\cdot d\vec{r}$, where $F=\langle M, N \rangle$ expressed as $\int Mdx + Ndy$. This uses the notation for a differential form, so is familiar in some theoretical usages, but does not readily lend itself to computation. It does yield pleasing formulas, such as $\oint_C x dy$ to give the area of a two-dimensional region, $D$, in terms of a line integral around its perimeter. To see that this is so, let $\vec{r}(t) = \langle a\cos(t), b\sin(t)\rangle$, $0 \leq t \leq 2\pi$. This parameterizes an ellipse. Let $F(x,y) = \langle 0,x\rangle$. What does $\oint_C xdy$ become when translated into $\int_a^b (F\circ\vec{r})\cdot\vec{r}' dt$? - -```julia; hold=true; echo=false -choices = [ -raw" ``\int_0^{2\pi} (a\cos(t)) \cdot (b\cos(t)) dt``", -raw" ``\int_0^{2\pi} (-b\sin(t)) \cdot (b\cos(t)) dt``", -raw" ``\int_0^{2\pi} (a\cos(t)) \cdot (a\cos(t)) dt``" -] -answ=1 -radioq(choices, answ) -``` - - -###### Question - -Let a surface be parameterized by $\Phi(u,v) = \langle u\cos(v), u\sin(v), u\rangle$. - -Compute $\vec{v}_1 = \partial{\Phi}/\partial{u}$ - -```julia; hold=true; echo=false -choices = [ -raw" ``\langle \cos(v), \sin(v), 1\rangle``", -raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``", -raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``" -] -answ = 1 -radioq(choices, answ, keep_order=true) -``` - -Compute $\vec{v}_2 = \partial{\Phi}/\partial{u}$ - -```julia; hold=true; echo=false -choices = [ -raw" ``\langle \cos(v), \sin(v), 1\rangle``", -raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``", -raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``" -] -answ = 2 -radioq(choices, answ, keep_order=true) -``` - -Compute $\vec{v}_1 \times \vec{v}_2$ - - -```julia; hold=true; echo=false -choices = [ -raw" ``\langle \cos(v), \sin(v), 1\rangle``", -raw" ``\langle -u\sin(v), u\cos(v), 0\rangle``", -raw" ``u\langle -\cos(v), -\sin(v), 1\rangle``" -] -answ = 3 -radioq(choices, answ, keep_order=true) -``` - - -###### Question - -For the surface parameterized by $\Phi(u,v) = \langle uv, u^2v, uv^2\rangle$ for $(u,v)$ in $[0,1]\times[0,1]$, numerically find the surface area. - -```julia; hold=true; echo=false -Phi(u,v) = [u*v, u^2*v, u*v^2] -Phi(v) = Phi(v...) -function SurfaceElement(u,v) - pt = [u,v] - Jac = ForwardDiff.jacobian(Phi, pt) - v1, v2 = Jac[:,1], Jac[:,2] - cross(v1, v2) -end -a,err = hcubature(uv -> norm(SurfaceElement(uv...)), (0,0), (1,1)) -numericq(a) -``` - -###### Question - -For the surface parameterized by $\Phi(u,v) = \langle uv, u^2v, uv^2\rangle$ for $(u,v)$ in $[0,1]\times[0,1]$ and vector field $F(x,y,z) =\langle y^2, x, z\langle$, numerically find $\iint_S (F\cdot\hat{N}) dS$. - -```julia; hold=true; echo=false -Phi(u,v) = [u*v, u^2*v, u*v^2] -Phi(v) = Phi(v...) -function SurfaceElement(u,v) - pt = [u,v] - Jac = ForwardDiff.jacobian(Phi, pt) - v1, v2 = Jac[:,1], Jac[:,2] - cross(v1, v2) -end -F(x,y,z) = [y^2,x,z] -F(v) = F(v...) -integrand(uv) = dot(F(Phi(uv)...), SurfaceElement(uv...)) -a, err = hcubature(integrand, (0,0), (1,1)) -numericq(a) -``` - -###### Question - -Let $F=\langle 0,0,1\rangle$ and $S$ be the upper-half unit sphere, parameterized by $\Phi(\theta, \phi) = \langle \sin(\phi)\cos(\theta), \sin(\phi)\sin(\theta), \cos(\phi)\rangle$. Compute $\iint_S (F\cdot\hat{N}) dS$ numerically. Choose the normal direction so that the answer is postive. - -```julia; hold=true; echo=false -F(v) = [0,0,1] -Phi(theta, phi) = [sin(phi)*cos(theta), sin(phi)*sin(theta), cos(phi)] -Phi(v) = Phi(v...) -function SurfaceElement(u,v) - pt = [u,v] - Jac = ForwardDiff.jacobian(Phi, pt) - v1, v2 = Jac[:,1], Jac[:,2] - cross(v1, v2) -end -integrand(uv) = dot(F(Phi(uv)), SurfaceElement(uv...)) -a, err = hcubature(integrand, (0, 0), (2pi, pi/2)) -numericq(abs(a)) -``` - -###### Question - -Let $\phi(x,y,z) = xy$ and $S$ be the triangle $x+y+z=1$, $x,y,z \geq 0$. The surface may be described by $z=f(x,y) = 1 - (x + y)$, $0\leq y \leq 1-x, 0 \leq x \leq 1$ is useful in describing the surface. With this, the following integral will compute $\int_S \phi dS$: - -```math -\int_0^1 \int_0^{1-x} xy \sqrt{1 + \left(\frac{\partial{f}}{\partial{x}}\right)^2 + \left(\frac{\partial{f}}{\partial{y}}\right)^2} dy dx. -``` - -Compute this. - -```julia; hold=true; echo=false -#@syms x y real=true -#phi = 1 - (x+y) -#SE = sqrt(1 + diff(phi,x)^2, diff(phi,y)^2) -#integrate(x*y*S_, (y, 0, 1-x), (x,0,1)) # \sqrt{2}/24 -choices = [ -raw" ``\sqrt{2}/24``", -raw" ``2/\sqrt{24}``", -raw" ``1/12``" -] -answ = 1 -radioq(choices, answ) -``` - - -###### Question - -Let $\Phi(u,v) = \langle u^2, uv, v^2\rangle$, $(u,v)$ in $[0,1]\times[0,1]$ and $F(x,y,z) = \langle x,y^2,z^3\rangle$. Find $\int_S (F\cdot\hat{N})dS$ - -```julia; hold=true; echo=false -#Phi(u,v) = [u^2, u*v, v^2] -#F(x,y,z) = [x,y^2,z^3] -#Phi(v) = Phi(v...); F(v) = F(v...) -#@syms u::real v::real -#function SurfaceElement(u,v) -# pt = [u,v] -# Jac = Phi(u,v).jacobian([u,v]) -# v1, v2 = Jac[:,1], Jac[:,2] -# cross(v1, v2) -#end -#integrate(F(Phi(u,v)) ⋅ SurfaceElement(u,v), (u,0,1), (v,0,1)) # 17/252 -choices = [ -raw" ``17/252``", -raw" ``0``", -raw" ``7/36``", -raw" ``1/60``" -] -answ = 1 -radioq(choices, answ) -``` diff --git a/quarto/integral_vector_calculus/Project.toml b/quarto/integral_vector_calculus/Project.toml deleted file mode 100644 index 98e581a..0000000 --- a/quarto/integral_vector_calculus/Project.toml +++ /dev/null @@ -1,8 +0,0 @@ -[deps] -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49" -LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/quarto/integral_vector_calculus/div_grad_curl.qmd b/quarto/integral_vector_calculus/div_grad_curl.qmd index 1e51fe5..659c9a3 100644 --- a/quarto/integral_vector_calculus/div_grad_curl.qmd +++ b/quarto/integral_vector_calculus/div_grad_curl.qmd @@ -1,33 +1,7 @@ # The Gradient, Divergence, and Curl -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integral_vector_calculus/double_triple_integrals.qmd b/quarto/integral_vector_calculus/double_triple_integrals.qmd index 41ccc94..74746b4 100644 --- a/quarto/integral_vector_calculus/double_triple_integrals.qmd +++ b/quarto/integral_vector_calculus/double_triple_integrals.qmd @@ -1,33 +1,7 @@ # Multi-dimensional integrals -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integral_vector_calculus/line_integrals.qmd b/quarto/integral_vector_calculus/line_integrals.qmd index 8e63d45..2aa1936 100644 --- a/quarto/integral_vector_calculus/line_integrals.qmd +++ b/quarto/integral_vector_calculus/line_integrals.qmd @@ -1,33 +1,7 @@ # Line and Surface Integrals -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integral_vector_calculus/process.jl b/quarto/integral_vector_calculus/process.jl deleted file mode 100644 index f61af14..0000000 --- a/quarto/integral_vector_calculus/process.jl +++ /dev/null @@ -1,35 +0,0 @@ -using WeavePynb -using Mustache - -mmd(fname) = mmd_to_html(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") -## uncomment to generate just .md files -#mmd(fname) = mmd_to_md(fname, BRAND_HREF="../toc.html", BRAND_NAME="Calculus with Julia") - - - - -fnames = [ - "double_triple_integrals", - "line_integrals", - "div_grad_curl", - "stokes_theorem", - "review" -] - -function process_file(nm, twice=false) - include("$nm.jl") - mmd_to_md("$nm.mmd") - markdownToHTML("$nm.md") - twice && markdownToHTML("$nm.md") -end - -process_files(twice=false) = [process_file(nm, twice) for nm in fnames] - - - - -""" -## TODO integral_vector_calculus -* line integrals needs an image (lasso?) -* more questions -""" diff --git a/quarto/integral_vector_calculus/review.qmd b/quarto/integral_vector_calculus/review.qmd index 03fdea2..558b535 100644 --- a/quarto/integral_vector_calculus/review.qmd +++ b/quarto/integral_vector_calculus/review.qmd @@ -1,33 +1,7 @@ # Quick Review of Vector Calculus -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/integral_vector_calculus/stokes_theorem.qmd b/quarto/integral_vector_calculus/stokes_theorem.qmd index 6d347bc..c90f708 100644 --- a/quarto/integral_vector_calculus/stokes_theorem.qmd +++ b/quarto/integral_vector_calculus/stokes_theorem.qmd @@ -1,33 +1,7 @@ # Green's Theorem, Stokes' Theorem, and the Divergence Theorem -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/Project.toml b/quarto/integrals/Project.toml deleted file mode 100644 index a9f6bb7..0000000 --- a/quarto/integrals/Project.toml +++ /dev/null @@ -1,8 +0,0 @@ -[deps] -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" -Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" -UnitfulUS = "7dc9378f-8956-57ef-a780-aa31cc70ff3d" diff --git a/quarto/integrals/arc_length.qmd b/quarto/integrals/arc_length.qmd index 68c9e9a..6633e41 100644 --- a/quarto/integrals/arc_length.qmd +++ b/quarto/integrals/arc_length.qmd @@ -1,33 +1,7 @@ # Arc length -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/area.qmd b/quarto/integrals/area.qmd index 00d4346..35777ae 100644 --- a/quarto/integrals/area.qmd +++ b/quarto/integrals/area.qmd @@ -1,33 +1,7 @@ # Area under a curve -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: @@ -1442,9 +1416,45 @@ The area under a curve approximated by a Riemann sum. # url = "riemann.js" #CalculusWithJulia.WeaveSupport.JSXGraph(:integrals, url, caption) # This is just wrong... -url = "https://raw.githubusercontent.com/jverzani/CalculusWithJulia.jl/master/CwJ/integrals/riemann.js" -url = "./riemann.js" -CalculusWithJulia.WeaveSupport.JSXGraph(url, caption) +#CalculusWithJulia.WeaveSupport.JSXGraph(url, caption) +nothing +``` + +```{=html} +
+``` + +```{ojs} +//| echo: false +//| output: false +JXG = require("jsxgraph"); + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-0.5,0.3,1.5,-1/4], axis:true +}); + +g = function(x) { return x*x*x*x + 10*x*x - 60* x + 100} +f = function(x) {return 1/Math.sqrt(g(x))}; + +type = "right"; +l = 0; +r = 1; +rsum = function() { + return JXG.Math.Numerics.riemannsum(f,n.Value(), type, l, r); +}; +n = b.create('slider', [[0.1, -0.05],[0.75,-0.05], [2,1,50]],{name:'n',snapWidth:1}); + +graph = b.create('functiongraph', [f, l, r]); +os = b.create('riemannsum', + [f, + function(){ return n.Value();}, + type, l, r + ], + {fillColor:'#ffff00', fillOpacity:0.3}); + +b.create('text', [0.1,0.25, function(){ + return 'Riemann sum='+(rsum().toFixed(4)); +}]); ``` The interactive graphic shows the area of a right-Riemann sum for different partitions. The function is @@ -1469,7 +1479,7 @@ When $n=50$ what is the area of the Riemann sum? ```{julia} #| hold: true #| echo: false -numericq(0.1887) +numericq(0.1187) ``` Using `quadgk` what is the area under the curve? diff --git a/quarto/integrals/area_between_curves.qmd b/quarto/integrals/area_between_curves.qmd index cf0491e..6c5781b 100644 --- a/quarto/integrals/area_between_curves.qmd +++ b/quarto/integrals/area_between_curves.qmd @@ -1,33 +1,7 @@ # Area between two curves -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/center_of_mass.qmd b/quarto/integrals/center_of_mass.qmd index 85b27e8..3e64c05 100644 --- a/quarto/integrals/center_of_mass.qmd +++ b/quarto/integrals/center_of_mass.qmd @@ -1,33 +1,7 @@ # Center of Mass -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/ftc.qmd b/quarto/integrals/ftc.qmd index dc10b00..0c7b6da 100644 --- a/quarto/integrals/ftc.qmd +++ b/quarto/integrals/ftc.qmd @@ -1,33 +1,7 @@ # Fundamental Theorem or Calculus -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/improper_integrals.qmd b/quarto/integrals/improper_integrals.qmd index af49409..1db8842 100644 --- a/quarto/integrals/improper_integrals.qmd +++ b/quarto/integrals/improper_integrals.qmd @@ -1,33 +1,7 @@ # Improper Integrals -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/integration_by_parts.qmd b/quarto/integrals/integration_by_parts.qmd index 23b4e9a..baa40e2 100644 --- a/quarto/integrals/integration_by_parts.qmd +++ b/quarto/integrals/integration_by_parts.qmd @@ -1,33 +1,7 @@ # Integration By Parts -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/mean_value_theorem.qmd b/quarto/integrals/mean_value_theorem.qmd index 645fe9b..5699f0a 100644 --- a/quarto/integrals/mean_value_theorem.qmd +++ b/quarto/integrals/mean_value_theorem.qmd @@ -1,33 +1,7 @@ # Mean value theorem for integrals -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/partial_fractions.qmd b/quarto/integrals/partial_fractions.qmd index 34e9bd7..c975e9d 100644 --- a/quarto/integrals/partial_fractions.qmd +++ b/quarto/integrals/partial_fractions.qmd @@ -1,33 +1,7 @@ # Partial Fractions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} using CalculusWithJulia diff --git a/quarto/integrals/process.jl b/quarto/integrals/process.jl deleted file mode 100644 index a9e21b8..0000000 --- a/quarto/integrals/process.jl +++ /dev/null @@ -1,41 +0,0 @@ - -fnames = [ - "area", - "ftc", - - "substitution", - "integration_by_parts", - "partial_fractions", # XX add in trig integrals (cos()sin() stuff? mx or ^m... XXX - "improper_integrals", ## - - "mean_value_theorem", - "area_between_curves", - "center_of_mass", - "volumes_slice", - #"volumes_shell", ## XXX add this in if needed, but not really that excited to now XXX - "arc_length", - "surface_area" -] - - - -function process_file(nm, twice=false) - include("$nm.jl") - mmd_to_md("$nm.mmd") - markdownToHTML("$nm.md") - twice && markdownToHTML("$nm.md") -end - -process_files(twice=false) = [process_file(nm, twice) for nm in fnames] - - - - -""" -## TODO integrals - -* add in volumes shell??? -* mean value theorem is light? -* could add surface area problems - -""" diff --git a/quarto/integrals/substitution.qmd b/quarto/integrals/substitution.qmd index 7d23348..de45539 100644 --- a/quarto/integrals/substitution.qmd +++ b/quarto/integrals/substitution.qmd @@ -1,33 +1,7 @@ # Substitution -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/surface_area.qmd b/quarto/integrals/surface_area.qmd index 4a95847..f13a93a 100644 --- a/quarto/integrals/surface_area.qmd +++ b/quarto/integrals/surface_area.qmd @@ -1,33 +1,7 @@ # Surface Area -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/integrals/volumes_slice.qmd b/quarto/integrals/volumes_slice.qmd index e1a99d3..44a5fbe 100644 --- a/quarto/integrals/volumes_slice.qmd +++ b/quarto/integrals/volumes_slice.qmd @@ -1,33 +1,7 @@ # Volumes by slicing -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/intro.qmd b/quarto/intro.qmd deleted file mode 100644 index efcf172..0000000 --- a/quarto/intro.qmd +++ /dev/null @@ -1,5 +0,0 @@ -# Introduction - -This is a book created from markdown and executable code. - -See @knuth84 for additional discussion of literate programming. diff --git a/quarto/jmd2qmd.jl b/quarto/jmd2qmd.jl index 72bef2a..8c95dd6 100644 --- a/quarto/jmd2qmd.jl +++ b/quarto/jmd2qmd.jl @@ -9,36 +9,40 @@ Base.show(io::IO, ::MIME"text/qmd", content) = Markdown.plain(io, content) ## Expects title to be very first thing in a jmd file ## Proper way would be to use https://quarto.org/docs/extensions/nbfilter.html function inject_code(io::IO) - println(io, """ -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\\\[") - println(io, sympy.latex(x)) - println(io, "\\\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![\$caption](\$nm)" - Markdown.parse(u) -end - -nothing -``` +println(io, """ +{{< include ../_common_code.qmd >}} """) end +# println(io, """ +# ```{julia} +# #| echo: false + +# import Logging +# Logging.disable_logging(Logging.Info) # or e.g. Logging.Info +# Logging.disable_logging(Logging.Warn) + +# import SymPy +# function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} +# println(io, " ") +# println(io, "\\\\[") +# println(io, sympy.latex(x)) +# println(io, "\\\\]") +# println(io, "") +# end + +# # hack to work around issue +# import Markdown +# import CalculusWithJulia +# function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) +# nm = joinpath("..", string(d), f) +# u = "![\$caption](\$nm)" +# Markdown.parse(u) +# end + +# nothing +# ``` +# """) +# end ## Main function to take a jmd file and turn into an HTML function markdownToHTML(fname::AbstractString; TITLE="", kwargs...) diff --git a/quarto/limits/Project.toml b/quarto/limits/Project.toml deleted file mode 100644 index efe47db..0000000 --- a/quarto/limits/Project.toml +++ /dev/null @@ -1,10 +0,0 @@ -[deps] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/quarto/limits/continuity.qmd b/quarto/limits/continuity.qmd index 0d628d7..a289ec4 100644 --- a/quarto/limits/continuity.qmd +++ b/quarto/limits/continuity.qmd @@ -1,33 +1,7 @@ # Continuity -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/limits/intermediate_value_theorem.qmd b/quarto/limits/intermediate_value_theorem.qmd index 484e8a1..c72e5d3 100644 --- a/quarto/limits/intermediate_value_theorem.qmd +++ b/quarto/limits/intermediate_value_theorem.qmd @@ -1,33 +1,7 @@ # Implications of continuity -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses these add-on packages: diff --git a/quarto/limits/limits.qmd b/quarto/limits/limits.qmd index 9c1710c..3d89e63 100644 --- a/quarto/limits/limits.qmd +++ b/quarto/limits/limits.qmd @@ -1,33 +1,7 @@ # Limits -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: @@ -407,6 +381,43 @@ The graphical approach to limits - plotting $f(x)$ around $c$ and observing if t ##### Example +This example illustrates the same limit a different way. Sliding the $x$ value towards $0$ shows $f(x) = \sin(x)/x$ approaches a value of $1$. + + +```{=html} +
+``` + +```{ojs} +//| echo: false +//| output: false + +JXG = require("jsxgraph") + +b = JXG.JSXGraph.initBoard('jsxgraph', { + boundingbox: [-6, 1.2, 6,-1.2], axis:true +}); + +f = function(x) {return Math.sin(x) / x;}; +graph = b.create("functiongraph", [f, -6, 6]) +seg = b.create("line", [[-6,0], [6,0]], {fixed:true}); + +X = b.create("glider", [2, 0, seg], {name:"x", size:4}); +P = b.create("point", [function() {return X.X()}, function() {return f(X.X())}], {name:""}); +Q = b.create("point", [0, function() {return P.Y();}], {name:"f(x)"}); + +segup = b.create("segment", [P,X], {dash:2}); +segover = b.create("segment", [P, [0, function() {return P.Y()}]], {dash:2}); + + +txt = b.create('text', [2, 1, function() { + return "x = " + X.X().toFixed(4) + ", f(x) = " + P.Y().toFixed(4); +}]); +``` + +##### Example + + Consider now the following limit diff --git a/quarto/limits/limits_extensions.qmd b/quarto/limits/limits_extensions.qmd index 2ccd218..5bb06d8 100644 --- a/quarto/limits/limits_extensions.qmd +++ b/quarto/limits/limits_extensions.qmd @@ -1,33 +1,7 @@ # Limits, issues, extensions of the concept -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: diff --git a/quarto/limits/process.jl b/quarto/limits/process.jl deleted file mode 100644 index 67f63e8..0000000 --- a/quarto/limits/process.jl +++ /dev/null @@ -1,26 +0,0 @@ -using CwJWeaveTpl - -fnames = [ - "limits", - "limits_extensions", - # - "continuity", - "intermediate_value_theorem" - ] - - -process_file(nm; cache=:off) = CwJWeaveTpl.mmd(nm * ".jmd", cache=cache) - -function process_files(;cache=:user) - for f in fnames - @show f - process_file(f, cache=cache) - end -end - - - -""" -## TODO limits - -""" diff --git a/quarto/make_qmd.jl b/quarto/make_qmd.jl index 10c2c45..b898bf9 100644 --- a/quarto/make_qmd.jl +++ b/quarto/make_qmd.jl @@ -38,6 +38,7 @@ for DIR ∈ DIRS qmd_file = joinpath(DIR, fnm * ".qmd") jmd_file = joinpath(dir, f) if mtime(jmd_file) > mtime(qmd_file) + @show :new, qmd_file open(qmd_file, "w") do io jmd2qmd(io, jmd_file) end @@ -45,7 +46,7 @@ for DIR ∈ DIRS else _, ext = splitext(f) ext == ".toml" && continue - @show :cp, f + f == "process.jl" && continue try force = isfile(joinpath(DIR, f)) cp(joinpath(dir,f), joinpath(DIR,f), force=force) diff --git a/quarto/misc/Project.toml b/quarto/misc/Project.toml deleted file mode 100644 index d00b321..0000000 --- a/quarto/misc/Project.toml +++ /dev/null @@ -1,9 +0,0 @@ -[deps] -CalculusWithJulia = "a2e0e22d-7d4c-5312-9169-8b992201a882" -HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49" -ImplicitEquations = "95701278-4526-5785-aba3-513cca398f19" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/quarto/misc/calculus_with_julia.qmd b/quarto/misc/calculus_with_julia.qmd index 0a6589c..aa66f74 100644 --- a/quarto/misc/calculus_with_julia.qmd +++ b/quarto/misc/calculus_with_julia.qmd @@ -1,33 +1,7 @@ # The `CalculusWithJulia` package -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} To run the commands in these notes, some external packages must be installed and loaded. diff --git a/quarto/misc/getting_started_with_julia.qmd b/quarto/misc/getting_started_with_julia.qmd index e2a5e40..5b88f52 100644 --- a/quarto/misc/getting_started_with_julia.qmd +++ b/quarto/misc/getting_started_with_julia.qmd @@ -1,33 +1,7 @@ # Getting started with Julia -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/misc/julia_interfaces.qmd b/quarto/misc/julia_interfaces.qmd index cf6c1d8..ecb43fc 100644 --- a/quarto/misc/julia_interfaces.qmd +++ b/quarto/misc/julia_interfaces.qmd @@ -1,33 +1,7 @@ # Julia interfaces -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/misc/quick_notes.qmd b/quarto/misc/quick_notes.qmd index 2004500..a203ff9 100644 --- a/quarto/misc/quick_notes.qmd +++ b/quarto/misc/quick_notes.qmd @@ -1,33 +1,7 @@ # Quick introduction to Calculus with Julia -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} The `Julia` programming language with a design that makes it well suited as a supplement for the learning of calculus, as this collection of notes is intended to illustrate. diff --git a/quarto/misc/toc.qmd b/quarto/misc/toc.qmd index 1845819..6ab4d2d 100644 --- a/quarto/misc/toc.qmd +++ b/quarto/misc/toc.qmd @@ -10,33 +10,7 @@ txt = """ CalculusWithJulia.WeaveSupport.HTMLoutput(txt) ``` -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} # Calculus with Julia diff --git a/quarto/misc/unicode.qmd b/quarto/misc/unicode.qmd index 15e9873..0638a4b 100644 --- a/quarto/misc/unicode.qmd +++ b/quarto/misc/unicode.qmd @@ -1,33 +1,7 @@ # Usages of Unicode symbols -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} `Julia` allows the use of *Unicode* symbols to replace variable names and for function calls. Unicode operations are entered in this pattern `\name[tab]`. That is a slash, `\`, the name (e.g., `alpha`), and then a press of the `tab` key. diff --git a/quarto/misc/using-pluto.qmd b/quarto/misc/using-pluto.qmd index 06d2e3e..7daf290 100644 --- a/quarto/misc/using-pluto.qmd +++ b/quarto/misc/using-pluto.qmd @@ -1,33 +1,7 @@ # Using Pluto -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} :::{.callout-note} ## Note diff --git a/quarto/precalc/Project.toml b/quarto/precalc/Project.toml deleted file mode 100644 index 74acd04..0000000 --- a/quarto/precalc/Project.toml +++ /dev/null @@ -1,11 +0,0 @@ -[deps] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" -RealPolynomialRoots = "87be438c-38ae-47c4-9398-763eabe5c3be" -Richardson = "708f8203-808e-40c0-ba2d-98a6953ed40d" -Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" diff --git a/quarto/precalc/calculator.qmd b/quarto/precalc/calculator.qmd index fbf8af5..26edd7c 100644 --- a/quarto/precalc/calculator.qmd +++ b/quarto/precalc/calculator.qmd @@ -1,33 +1,7 @@ # From calculator to computer -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/precalc/exp_log_functions.qmd b/quarto/precalc/exp_log_functions.qmd index 5772be4..6716a25 100644 --- a/quarto/precalc/exp_log_functions.qmd +++ b/quarto/precalc/exp_log_functions.qmd @@ -1,33 +1,7 @@ # Exponential and logarithmic functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: diff --git a/quarto/precalc/functions.qmd b/quarto/precalc/functions.qmd index cd7d1cf..fdd6185 100644 --- a/quarto/precalc/functions.qmd +++ b/quarto/precalc/functions.qmd @@ -1,33 +1,7 @@ # Functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section will use the following add-on packages: diff --git a/quarto/precalc/inversefunctions.qmd b/quarto/precalc/inversefunctions.qmd index a245ea9..2f3ec56 100644 --- a/quarto/precalc/inversefunctions.qmd +++ b/quarto/precalc/inversefunctions.qmd @@ -1,33 +1,7 @@ # The Inverse of a Function -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} In this section we will use these add-on packages: diff --git a/quarto/precalc/julia_overview.qmd b/quarto/precalc/julia_overview.qmd index 81c5179..5252ccd 100644 --- a/quarto/precalc/julia_overview.qmd +++ b/quarto/precalc/julia_overview.qmd @@ -1,33 +1,7 @@ # Overview of Julia commands -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/precalc/logical_expressions.qmd b/quarto/precalc/logical_expressions.qmd index 584e1d3..1ec15d8 100644 --- a/quarto/precalc/logical_expressions.qmd +++ b/quarto/precalc/logical_expressions.qmd @@ -1,33 +1,7 @@ # Inequalities, Logical expressions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} In this section we use the following package: diff --git a/quarto/precalc/numbers_types.qmd b/quarto/precalc/numbers_types.qmd index 2e7011c..d2048a5 100644 --- a/quarto/precalc/numbers_types.qmd +++ b/quarto/precalc/numbers_types.qmd @@ -1,33 +1,7 @@ # Number systems -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/precalc/plotting.qmd b/quarto/precalc/plotting.qmd index cda42f0..10cae73 100644 --- a/quarto/precalc/plotting.qmd +++ b/quarto/precalc/plotting.qmd @@ -1,33 +1,7 @@ # The Graph of a Function -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section will use the following packages: diff --git a/quarto/precalc/polynomial.qmd b/quarto/precalc/polynomial.qmd index 3107fb4..3b77c81 100644 --- a/quarto/precalc/polynomial.qmd +++ b/quarto/precalc/polynomial.qmd @@ -1,33 +1,7 @@ # Polynomials -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} In this section we use the following add-on packages: diff --git a/quarto/precalc/polynomial_roots.qmd b/quarto/precalc/polynomial_roots.qmd index 1e20369..366c8fc 100644 --- a/quarto/precalc/polynomial_roots.qmd +++ b/quarto/precalc/polynomial_roots.qmd @@ -1,33 +1,7 @@ # Roots of a polynomial -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} In this section we use the following add on packages: diff --git a/quarto/precalc/polynomials_package.qmd b/quarto/precalc/polynomials_package.qmd index 06834eb..8203def 100644 --- a/quarto/precalc/polynomials_package.qmd +++ b/quarto/precalc/polynomials_package.qmd @@ -1,33 +1,7 @@ # The Polynomials package -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section will use the following add-on packages: diff --git a/quarto/precalc/ranges.qmd b/quarto/precalc/ranges.qmd index ed50fad..60320a5 100644 --- a/quarto/precalc/ranges.qmd +++ b/quarto/precalc/ranges.qmd @@ -1,33 +1,7 @@ # Ranges and Sets -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false diff --git a/quarto/precalc/rational_functions.qmd b/quarto/precalc/rational_functions.qmd index f761b2a..5713104 100644 --- a/quarto/precalc/rational_functions.qmd +++ b/quarto/precalc/rational_functions.qmd @@ -1,33 +1,7 @@ # Rational functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: diff --git a/quarto/precalc/transformations.qmd b/quarto/precalc/transformations.qmd index 345874b..a17b485 100644 --- a/quarto/precalc/transformations.qmd +++ b/quarto/precalc/transformations.qmd @@ -1,33 +1,7 @@ # Function manipulations -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} In this section we will use these add-on packages: diff --git a/quarto/precalc/trig_functions.qmd b/quarto/precalc/trig_functions.qmd index 6594d5b..5bb1a6e 100644 --- a/quarto/precalc/trig_functions.qmd +++ b/quarto/precalc/trig_functions.qmd @@ -1,33 +1,7 @@ # Trigonometric functions -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} This section uses the following add-on packages: diff --git a/quarto/precalc/variables.qmd b/quarto/precalc/variables.qmd index 3b266a9..86f5e22 100644 --- a/quarto/precalc/variables.qmd +++ b/quarto/precalc/variables.qmd @@ -1,33 +1,7 @@ # Variables -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ## Assignment diff --git a/quarto/precalc/vectors.qmd b/quarto/precalc/vectors.qmd index ca53362..9613a54 100644 --- a/quarto/precalc/vectors.qmd +++ b/quarto/precalc/vectors.qmd @@ -1,33 +1,7 @@ # Vectors -```{julia} -#| echo: false - -import Logging -Logging.disable_logging(Logging.Info) # or e.g. Logging.Info -Logging.disable_logging(Logging.Warn) - -import SymPy -function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} - println(io, " ") - println(io, "\\[") - println(io, sympy.latex(x)) - println(io, "\\]") - println(io, "") -end - -# hack to work around issue -import Markdown -import CalculusWithJulia -function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...) - nm = joinpath("..", string(d), f) - u = "![$caption]($nm)" - Markdown.parse(u) -end - -nothing -``` +{{< include ../_common_code.qmd >}} ```{julia} #| echo: false