diff --git a/quarto/_quarto.yml b/quarto/_quarto.yml index cd9d5de..a42072d 100644 --- a/quarto/_quarto.yml +++ b/quarto/_quarto.yml @@ -138,15 +138,16 @@ format: number-depth: 3 toc-depth: 3 link-external-newwindow: true -# pdf: -# documentclass: scrbook -# classoption: [oneside] -# geometry: -# - top=30mm -# - left=10mm -# - right=10mm -# - heightrounded -# colorlinks: true + pdf: + documentclass: scrbook + classoption: [oneside] + keep-tex: true + geometry: + - top=30mm + - left=10mm + - right=10mm + - heightrounded + colorlinks: true execute: error: true diff --git a/quarto/limits/limits.qmd b/quarto/limits/limits.qmd index a62305e..8b3b665 100644 --- a/quarto/limits/limits.qmd +++ b/quarto/limits/limits.qmd @@ -1532,6 +1532,43 @@ numericq(val) ###### Question +Compute the limit + + +$$ +\lim_{x \rightarrow 0} \frac{x\sin(\sin(x)) - \sin^2(x)}{x^6}. +$$ + +```{julia} +#| hold: true +#| echo: false +f(x) = (x * sin(sin(x))- sin(x)^2)/x^6 +val = N(limit(f(x), x => 0)) +numericq(val) +``` + + +###### Question + + +Compute the limit + + +$$ +\lim_{x \rightarrow 0} \frac{\tan(x) - 24 * \tan(x/2)}{4 \sin(x) - 5 x}. +$$ + +```{julia} +#| hold: true +#| echo: false +f(x) = (tan(x) - 24 * tan(x/2)) / (4 * sin(x) - 5 * x) +val = N(limit(f(x), x => 0)) +numericq(val) +``` + +###### Question + + Some limits involve parameters. For example, suppose we define `ex` as follows: @@ -1616,6 +1653,47 @@ Should `SymPy` have needed an assumption like yesnoq("yes") ``` +###### Question + +The limit + +$$ +L= \lim_{x \rightarrow 0} \left(\frac{(a^x - x \log(a)}{b^x - x\log(b)}\right)^{1/x^2} +$$ + +For $a=3$ and $b=2$ + +Can be computed symbolically *two* different ways: + +```{julia} +@syms x +a, b = 3, 2 +f(x) = ((a^x - x*log(a))/(b^x - x*log(b)))^(1/x^2) +limit(f(x), x=>0) +``` + +*or* + +```{julia} +@syms x a b +f(x) = ((a^x - x*log(a))/(b^x - x*log(b)))^(1/x^2) +L = limit(f(x), x=>0) +L(a => 3, b=>2) +``` + +Which is correct? + +```{julia} +#| echo: false +choices = ["The first one", "The second one"] +explanation = """ +The first one is incorrect, as `log(3)` is evaluated numerically, and not symbolically. The difference between a floating point approximation and the symbolic expression is enough to make the first limit infinite, despite the actual limit being finite. +""" +buttonq(choices, 2; explanation=explanation) +``` + + + ###### Question: The squeeze theorem diff --git a/quarto/precalc/calculator.qmd b/quarto/precalc/calculator.qmd index 5553e4c..04193c6 100644 --- a/quarto/precalc/calculator.qmd +++ b/quarto/precalc/calculator.qmd @@ -1093,3 +1093,39 @@ choices = [ answ=1 radioq(choices, answ) ``` + + + +##### Question + +(From [stackoverflow](https://discourse.julialang.org/t/the-speed-of-light-is-an-integer-why-should-we-care/40108/).) + +Since 1983, the speed of light is defined to be exactly equal to 299,792,458 meters per second. This can be used to find the value of the Planck [length](https://en.wikipedia.org/wiki/Planck_units#Planck_length) using the formula + +$$ +l_p = \sqrt{\frac{\hbar\cdot G}{c^3}} +$$ + +Attempting to compute this, we have: + +```{julia} +c = 299_792_458; # the speed of light +G = 6.67430e-11; # Gravitational constant +h = 6.62607015e-34; # Planck's contant +h_bar = h / (2*pi); +planck_length = sqrt(h_bar * G / c^3) +``` + +That all seems great, but the Wikipedia article says this value is around $10^{-35}$ **not** $10^{-32}$. What is a possible answer? + +```{julia} +#| echo: false +choices = ["The Wikipedia article must be incorrect.", + "The difference is very *small*. It must be due to rounding errors", + "`Julia` computes this value incorrectly" + ] +explanation = raw""" +Yes, this is computed incorrectly. The value `c^3` *overflows* as the actual value is around $10^{25}$, but the computed value is only around $10^{18}$. With `c` defined as above, it will be parsed as an integer, which by default (on most machines) will be stored with $64$ bits. Operations with 64-bit integers that mathematically produce values bigger than about $10^{18}$ will be incorrectly computed, as `Julia` uses a silent means to handle the [overflow](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Overflow-behavior). (This allows integer computations to be faster.) The suggested approach is to use floating point values to define such values. Floating point can store integer values accurately up to values of $2^{53}$ (about $10^{15}$) and gracefully for larger values, such as $c^3$ in this problem. With `c` defined by `c = 299792458.0` the computed value for the Planck length is `1.6162550244237053e-35`, in agreement with the Wikipedia value. +""" +buttonq(choices, 3; explanation=explanation) +``` diff --git a/quarto/precalc/plotting.qmd b/quarto/precalc/plotting.qmd index b493adf..981c210 100644 --- a/quarto/precalc/plotting.qmd +++ b/quarto/precalc/plotting.qmd @@ -486,6 +486,72 @@ For plotting points with `scatter`, or `scatter!` the markers can be adjusted vi Of course, zero, one, or more of these can be used on any given call to `plot`, `plot!`, `scatter` or `scatter!`. +#### Example: Bresenham's algorithm + + +In plotting a primitive, like a line, some mapping of the mathematical object to a collection of pixels must be made. For the case of a line [Bresenhams's line algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm) can be used. + +In the simplest case, let's assume a few things: + +* we have a line with slope $-1 < m < 0$. +* the pixels have integer coordinates (e.g., the pixel $(1, -1)$ would cover the region $[1,2] \times [-1, -2]$ when lit.) +* we start at point $(x_0, y_0)$, $f(x_0) = y_0$, with integer coordinates and end a point $(x_1, y_1)$, also with integer coordinates. The pixel $(x_0,y_0)$ is lit. + +With these assumptions, we have an initial decision to make: + +> moving to the right, is the pixel $(x_0+1, y_0)$ or $(x_0 + 1, y_0 - 1)$ lit? + +We re-express our equation $y=f(x)= mx+b$ in general form $f(x,y) = 0 = Ax + By + C$. Using the other point on the line $A=-(y_1-y_0)$, $B=(x_1-x_0)$, and $C = -x_1y_0 + x_0 y_1$. In particular, by assumption both $A$ and $B$ are positive. + + +With this, we have $f(x_0,y_0) = 0$. But moreover, any point with $y>y_0$ will have $f(x_0,y)>0$ and if $y < y_0$ the opposite. That is this equation divides the plane into two pieces depending on whether $f$ is positive, the line is the dividing boundary. + +For the algorithm, we start at $(x_0, y_0)$ and ask if the pixel $(x_0 + 1, y_0)$ or $(x_0 + 1, y_0 - 1)$ will be lit, then we continue to the right. + +To check, we ask if $f(x_0 + 1, y_0 - 1/2)$ is positive. If so, then the actual line is below this value so the pixel below is chosen. Otherwise, the pixel above is chosen. + +This last check can be done a bit more efficiently, but for now let's see it in action: + +```{julia} +f(x) = -(1/3) * x + 1 +x₀, x₁ = 0, 14 +y₀, y₁ = f(x₀), f(x₁) + +A,B,C = -(y₁ - y₀), (x₁-x₀), -x₁*y₀ + x₀*y₁ + +f(x,y) = A*x + B*y + C + +xs = [(x₀, y₀)] +for i ∈ 1:(x₁ - 1) + xᵢ, yᵢ = xs[end] + xᵢ₊₁ = xᵢ + 1 + Δ = f(xᵢ+1, yᵢ-1/2) > 0 ? 1 : 0 + yᵢ₊₁ = yᵢ - Δ + push!(xs, (xᵢ₊₁, yᵢ₊₁)) +end + +xs +``` + +We can visualize with the following: + +```{julia} +p = plot(f, x₀, x₁; legend=false, aspect_ratio=:equal, + xticks=0:x₁, yticks = (floor(Int, f(x₁))-1):(1 + ceil(Int, f(x₀)))) +col = RGBA(.64,.64,.64, 0.25) +for xy ∈ xs + x, y = xy + scatter!([x], [y]; markersize=5) + scatter!([x+1], [y - 1/2], markersize=5, markershape=:star7) + plot!(Shape(x .+ [0, 1, 1, 0], y .+ [0, 0, -1, -1]), color=col) +end +p +``` + +We see a number of additional arguments used: different marker sizes and shapes and a transparent color. As well, the `Shape` primitive is used to represent a pixel. + +Of course, generalizations for positive slope and slope with magnitude greater than $1$ are needed. As well, this basic algorithm could be optimized, especially if it is part of a lower-level drawing primitive. But this illustrates the considerations involved. + ## Graphs of parametric equations