small edits

This commit is contained in:
jverzani 2022-11-02 13:29:58 -04:00
parent 55747e25ae
commit 1061e0aa03
4 changed files with 190 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
```

View File

@ -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