# Limits


{{< include ../_common_code.qmd >}}

This section uses the following add-on packages:


```{julia}
using CalculusWithJulia
using Plots
plotly()
using Richardson  # for extrapolation
using SymPy       # for symbolic limits
```


---


An historic problem in the history of math was to find the area under the graph of $f(x)=x^2$ between $[0,1]$.


There wasn't a ready-made formula for the area of this shape, as was known for a triangle or a square. However, [Archimedes](http://en.wikipedia.org/wiki/The_Quadrature_of_the_Parabola) found a method to compute areas enclosed by a parabola and line segments that cross the parabola.


```{julia}
#| hold: true
#| echo: false
#| cache: true
###{{{archimedes_parabola}}}
gr()
f(x) = x^2
colors = [:black, :blue, :orange, :red, :green, :orange, :purple]

## Area of parabola
function make_triangle_graph(n)
    title = "Area of parabolic cup ..."
    n==1 && (title = "\${Area = }1/2\$")
    n==2 && (title = "\${Area = previous }+ 1/8\$")
    n==3 && (title = "\${Area = previous }+ 2\\cdot(1/8)^2\$")
    n==4 && (title = "\${Area = previous }+ 4\\cdot(1/8)^3\$")
    n==5 && (title = "\${Area = previous }+ 8\\cdot(1/8)^4\$")
    n==6 && (title = "\${Area = previous }+ 16\\cdot(1/8)^5\$")
    n==7 && (title = "\${Area = previous }+ 32\\cdot(1/8)^6\$")



    plt = plot(f, 0, 1, legend=false, size = fig_size, linewidth=2)
    annotate!(plt, [(0.05, 0.9, text(title,:left))])  # if in title, it grows funny with gr
    n >= 1 && plot!(plt, [1,0,0,1, 0], [1,1,0,1,1], color=colors[1], linetype=:polygon, fill=colors[1], alpha=.2)
    n == 1 && plot!(plt, [1,0,0,1, 0], [1,1,0,1,1], color=colors[1], linewidth=2)
    for k in 2:n
        xs = range(0,stop=1, length=1+2^(k-1))
        ys = map(f, xs)
        k < n && plot!(plt, xs, ys, linetype=:polygon, fill=:black, alpha=.2)
        if k == n
            plot!(plt, xs, ys, color=colors[k], linetype=:polygon, fill=:black, alpha=.2)
            plot!(plt, xs, ys, color=:black, linewidth=2)
        end
    end
    plt
end


n = 7
anim = @animate for i=1:n
    make_triangle_graph(i)
end

imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)


caption = L"""
The first triangle has area $1/2$, the second has area $1/8$, then $2$ have area $(1/8)^2$, $4$ have area $(1/8)^3$, ...
With some algebra, the total area then should be $1/2 \cdot (1 + (1/4) + (1/4)^2 + \cdots) = 2/3$.
"""

plotly()
ImageFile(imgfile, caption)
```

The figure illustrates a means to compute the area bounded by the parabola, the line $y=1$ and the line $x=0$ using triangles. It suggests that this area can be found by adding the following sum


$$
A = 1/2 + 1/8 + 2 \cdot (1/8)^2 + 4 \cdot (1/8)^3 + \cdots
$$

This value is $2/3$, so the area under the curve would be $1/3$. Forget about this specific value - which through more modern machinery becomes uneventful - and focus for a minute on the method: a problem is solved by a suggestion of an infinite process, in this case the creation of more triangles to approximate the unaccounted for area. This is the so-call method of [exhaustion](http://en.wikipedia.org/wiki/Method_of_exhaustion) known since the 5th century BC.


Archimedes used this method to solve a wide range of area problems related to basic geometric shapes, including a more general statement of what we described above.


The $\cdots$ in the sum expression are the indication that this process continues and that the answer is at the end of an *infinite* process. To make this line of reasoning rigorous requires the concept of a limit. The concept of a limit is then an old one, but it wasn't until the age of calculus that it was formalized.


Next, we illustrate how Archimedes approximated $\pi$ – the ratio of the circumference of a circle to its diameter – using interior and exterior $n$-gons whose perimeters could be computed.


```{julia}
#| hold: true
#| echo: false
## Archimedes approximation for pi
gr()
blue, green, purple, red = :royalblue, :forestgreen, :mediumorchid3, :brown3


function archimedes!(p, n, xy=(0,0), radius=1; color=blue)

    x₀,y₀=xy
    ts = range(0, 2pi, length=100)



    plot!(p, x₀ .+ sin.(ts), y₀ .+ cos.(ts), linewidth=2)

    α = ((2π)/n)/2
    αs = (-pi/2 + α):2α:(3pi/2 + α)
    r = radius/cos(α)

    xs = x₀ .+ r*cos.(αs)
    ys = y₀ .+ r*sin.(αs)

    plot!(p, xs, ys, linewidth=2, alpha=0.6)
    plot!(p, xs, ys,
          fill=true,
          fillcolor=color,
          alpha=0.4)

    r = radius
    xs = x₀ .+ r*cos.(αs)
    ys = y₀ .+ r*sin.(αs)

    plot!(p, xs, ys, linewidth=2, alpha=0.6)
    plot!(p, xs, ys,
          fill=true,
          fillcolor=color,
          alpha=0.8)

    p
end

ns = [4,5,7,9]
xs = [1, 3.5, 1, 3.5]
ys = [3.5, 3.5, 1, 1]
p = plot(;xlims=(-.25, 4.75), ylims=(-0.25, 4.75),
         axis=nothing,
         xaxis=false,
         yaxis=false,
         legend=false,
         padding = (0.0, 0.0),
             background_color = :transparent,
         foreground_color = :black,
         aspect_ratio=:equal)

for (x, y, n, col) ∈ zip(xs, ys, ns, (blue, green, purple, red))
    archimedes!(p, n, (x, y), color=col)
end

caption = L"""
The ratio of the circumference of a circle to its diameter, $\pi$, can be approximated from above and below by computing the perimeters of the inscribed $n$-gons. Archimedes computed the perimeters for $n$ being $12$, $24$, $48$, and $96$ to determine that $3~10/71 \leq \pi \leq 3~1/7$.
"""
plotly()
ImageFile(p, caption)
```

Here Archimedes uses *bounds* to constrain an unknown value. Had he been able to compute these bounds for larger and larger $n$ the value of $\pi$ could be more accurately determined. In a "limit" it would be squeezed in to have a specific value, which we now know is an irrational number.


Continuing these concepts, [Fermat](http://en.wikipedia.org/wiki/Adequality) in the 1600s essentially took a limit to find the slope of a tangent line to a polynomial curve. Newton in the late 1600s, exploited the idea in his development of calculus (as did Leibniz). Yet it wasn't until the 1800s that [Bolzano](http://en.wikipedia.org/wiki/Limit_of_a_function#History), Cauchy and Weierstrass put the idea on a firm footing.


To make things more precise, we begin by discussing the limit of a univariate function as $x$ approaches $c$.


Informally, if a limit exists it is the value that $f(x)$ gets close to as $x$ gets close to - but not equal to - $c$.


The modern formulation is due to Weierstrass:

::: {.callout-note icon=false}
## The $\epsilon-\delta$ Definition of a limit of $f(x)$

The limit of $f(x)$ as $x$ approaches $c$ is $L$ if for every real $\epsilon > 0$, there exists a real $\delta > 0$ such that for all real $x$, $0 < \lvert x − c \rvert < \delta$ implies $\lvert f(x) − L \rvert < \epsilon$. The notation used is $\lim_{x \rightarrow c}f(x) = L$.

:::


We comment on this later.


Cauchy begins his incredibly influential [treatise](http://gallica.bnf.fr/ark:/12148/bpt6k90196z/f17.image) on calculus considering two examples, the limit as $x$ goes to $0$ of


$$
\frac{\sin(x)}{x} \quad\text{and}\quad (1 + x)^{1/x}.
$$

These take the indeterminate forms $0/0$ and $1^\infty$, which are found by just putting $0$ in for $x$. An expression does not need to be defined at $c$, as these two aren't at $c=0$, to discuss its limit. Cauchy illustrates two methods to approach the questions above. The first is to pull out an inequality:


$$
\frac{\sin(x)}{\sin(x)} > \frac{\sin(x)}{x} > \frac{\sin(x)}{\tan(x)}
$$

which is equivalent to:


$$
1 > \frac{\sin(x)}{x} > \cos(x)
$$

This bounds the expression $\sin(x)/x$ between $1$ and $\cos(x)$ and as $x$ gets close to $0$, the value of $\cos(x)$ "clearly" goes to $1$, hence $L$ must be $1$. This is an application of the squeeze theorem, the same idea Archimedes implied when bounding the value for $\pi$ above and below.


The above bound comes from this figure, for small $x > 0$:


```{julia}
#| hold: true
#| echo: false
gr()
p = plot(x -> sqrt(1 - x^2), 0, 1, legend=false, aspect_ratio=:equal,
     linewidth=3, color=:black)
θ = π/6
y,x = sincos(θ)
col=RGBA(0.0,0.0,1.0, 0.25)
plot!(range(0,x, length=2), zero, fillrange=u->y/x*u, color=col)
plot!(range(x, 1, length=50), zero, fillrange = u -> sqrt(1 - u^2), color=col)
plot!([x,x],[0,y], linestyle=:dash, linewidth=3, color=:black)
plot!([x,1],[y,0], linestyle=:dot, linewidth=3, color=:black)
plot!([1,1], [0,y/x], linewidth=3, color=:black)
plot!([0,1], [0,y/x], linewidth=3, color=:black)
plot!([0,1], [0,0], linewidth=3, color=:black)
Δ = 0.05
annotate!([(0,0+Δ,"A"), (x-Δ,y+Δ/4, "B"), (1+Δ/2,y/x, "C"),
           (1+Δ/2,0+Δ/2,"D")])
annotate!([(.2*cos(θ/2), 0.2*sin(θ/2), "θ")])
imgfile = tempname() * ".png"
savefig(p, imgfile)
caption = "Triangle ``ABD`` has less area than the shaded wedge, which has less area than triangle ``ACD``. Their respective areas are ``(1/2)\\sin(\\theta)``, ``(1/2)\\theta``, and ``(1/2)\\tan(\\theta)``. The inequality used to show ``\\sin(x)/x`` is bounded below by ``\\cos(x)`` and above by ``1`` comes from a division by ``(1/2) \\sin(x)`` and taking reciprocals.
"
plotly()
ImageFile(imgfile, caption)
```

To discuss the case of $(1+x)^{1/x}$ it proved convenient to assume $x = 1/m$ for integer values of $m$. At the time of Cauchy, log tables were available to identify the approximate value of the limit. Cauchy computed the following value from logarithm tables:


```{julia}
#| hold: true
x = 1/10000
(1 + x)^(1/x)
```

A table can show the progression to this value:


```{julia}
#| hold: true
f(x) = (1 + x)^(1/x)
xs = [1/10^i for i in 1:5]
[xs f.(xs)]
```

This progression can be seen to be increasing. Cauchy, in his treatise, can see this through:


$$
\begin{align*}
(1 + \frac{1}{m})^n &= 1 + \frac{1}{1} + \frac{1}{1\cdot 2}(1 - \frac{1}{m}) +  \\
& \frac{1}{1\cdot 2\cdot 3}(1 - \frac{1}{m})(1 -  \frac{2}{m}) + \cdots \\
&+
\frac{1}{1 \cdot 2 \cdot \cdots \cdot m}(1 - \frac{1}{m}) \cdot \cdots \cdot (1 - \frac{m-1}{m}).
\end{align*}
$$

These values are clearly increasing as $m$ increases. Cauchy showed the value was bounded between $2$ and $3$ and had the approximate value above. Then he showed the restriction to integers was not necessary. Later we will use this definition for the exponential function:


$$
e^x = \lim_{n \rightarrow \infty} (1 + \frac{x}{n})^n,
$$

with a suitably defined limit.


These two cases illustrate that though the definition of the limit exists, the computation of a limit is generally found by other means and the intuition of the value of the limit can be gained numerically.


### Indeterminate forms


First it should be noted that for most of the functions encountered, the concepts of a limit at a typical point $c$ is nothing more than just function evaluation at $c$. This is because, at a typical point, the functions are nicely behaved (what we will soon call "*continuous*"). However, most questions asked about limits find points that are not typical. For these, the result of evaluating the function at $c$ is typically undefined, and the value comes in one of several *indeterminate forms*: $0/0$, $\infty/\infty$, $0 \cdot \infty$, $\infty - \infty$, $0^0$, $1^\infty$, and $\infty^0$.


`Julia` can help - at times - identify these indeterminate forms, as many such operations produce `NaN`. For example:


```{julia}
0/0, Inf/Inf, 0 * Inf, Inf - Inf
```

However, the values with powers generally do not help, as the IEEE standard has `0^0` evaluating to 1:


```{julia}
0^0, 1^Inf, Inf^0
```

However, this can be unreliable, as floating point issues may mask the true evaluation. However, as a cheap trick it can work. So, the limit as $x$ goes to $1$ of $\sin(x)/x$ is simply found by evaluation:


```{julia}
#| hold: true
x = 1
sin(x) / x
```

But at $x=0$ we get an indicator that there is an issue with just evaluating the function:


```{julia}
#| hold: true
x = 0
sin(x) / x
```

The above is really just a heuristic. For some functions this is just not true. For example, the $f(x) = \sqrt{x}$ is only defined on $[0, \infty)$. There is technically no limit at $0$, per se, as the function is not defined around $0$. Other functions jump at values, and will not have a limit, despite having well defined values. The `floor` function is the function that rounds down to the nearest integer. At integer values there will be a jump (and hence have no limit), even though the function is defined.


## Graphical approaches to limits


Let's return to the function $f(x) = \sin(x)/x$. This function was studied by Euler as part of his solution to the [Basel](http://en.wikipedia.org/wiki/Basel_problem) problem. He knew that near $0$, $\sin(x) \approx x$, so the ratio is close to $1$ if $x$ is near $0$. Hence, the intuition is $\lim_{x \rightarrow 0} \sin(x)/x = 1$, as Cauchy wrote. We can verify this limit graphically two ways. First, a simple graph shows no issue at $0$:


```{julia}
#| hold: true

f(x) = sin(x)/x
plot(f, -pi/2, pi/2;
     seriestype=[:scatter, :line], # show points and line segments
     legend=false)
```

The $y$ values of the graph seem to go to $1$ as the $x$ values get close to $0$. (That the graph looks defined at $0$ is due to the fact that the points sampled to graph do not include $0$.)


We can also verify Euler's intuition through this graph:


```{julia}
#| hold: true
plot(sin, -pi/2,  pi/2)
plot!(identity)    # the function y = x, like how zero is y = 0
```

That the two are indistinguishable near $0$ makes it easy to see that their ratio should be going towards $1$.


A parametric plot shows the same, we see below the slope at $(0,0)$ is *basically* $1$, because the two functions are varying at the same rate when they are each near $0$


```{julia}
#| hold: true
plot(sin, identity, -pi/2, pi/2)  # parametric plot
```

The graphical approach to limits - plotting $f(x)$ around $c$ and observing if the $y$ values seem to converge to an $L$ value when $x$ 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}
<div id="jsxgraph" style="width: 500px; height: 500px;"></div>
```

```{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


$$
\lim_{x \rightarrow 2} \frac{x^2 - 5x + 6}{x^2 +x - 6}
$$

Noting that this is a ratio of nice polynomial functions, we first check whether there is anything to do:


```{julia}
#| hold: true
f(x) = (x^2 - 5x + 6) / (x^2 + x - 6)
c = 2
f(c)
```

The `NaN` indicates that this function is indeterminate at $c=2$. A quick plot gives us an idea that the limit exists and is roughly $-0.2$:


```{julia}
#| hold: true
c, delta = 2, 1
plot(f, c - delta, c + delta)
```

The graph looks "continuous." In fact, the value $c=2$ is termed a *removable singularity* as redefining $f(x)$ to be $-0.2$ when $x=2$ results in a "continuous" function.


As an aside, we can redefine `f` using the "ternary operator":


```{julia}
#| eval: false
f(x) = x == 2.0 ? -0.2 :  (x^2 - 5x + 6) / (x^2 + x - 6)
```

This particular case is a textbook example: one can easily factor $f(x)$ to get:


$$
f(x) = \frac{(x-2)(x-3)}{(x-2)(x+3)}
$$

Written in this form, we clearly see that this is the same function as $g(x) = (x-3)/(x+3)$ when $x \neq 2$. The function $g(x)$ is "continuous" at $x=2$. So were one to redefine $f(x)$ at $x=2$ to be $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 evaluating the function at $1/10000$ by Cauchy can be done much more easily nowadays. As does a graphical approach, a numerical approach can give insight into a limit and often a good numeric estimate.


The basic idea is to create a sequence of $x$ values going towards $c$ and then investigate if the corresponding $y$ values are eventually near some $L$.


Best, to see by example. Suppose we are asked to investigate


$$
\lim_{x \rightarrow 25} \frac{\sqrt{x} - 5}{\sqrt{x - 16} - 3}.
$$

We first define a function and check if there are issues at $25$:


```{julia}
f(x) = (sqrt(x) - 5) / (sqrt(x-16) - 3)
```

```{julia}
c = 25
f(c)
```

So yes, an issue of the indeterminate form $0/0$. We investigate numerically by making a set of numbers getting close to $c$. This is most easily done making numbers getting close to $0$ and adding them to or subtracting them from $c$. Some natural candidates are negative powers of $10$:


```{julia}
hs = [1/10^i for i in 1:8]
```

We can add these to $c$ and then evaluate:


```{julia}
xs = c .+ hs
ys = f.(xs)
```

To visualize, we can put in a table using `[xs ys]` notation:


```{julia}
[xs ys]
```

The $y$-values seem to be getting near $0.6$.


Since limits are defined by the expression $0 < \lvert x-c\rvert < \delta$, we should also look at values smaller than $c$. There isn't much difference (note the `.-` sign in `c .- hs`):


```{julia}
#| hold: true
xs = c .- hs
ys = f.(xs)
[xs ys]
```

Same story. The numeric evidence supports a limit of $L=0.6$.

::: {.callout-note}
### The `lim` function

The `CalculusWithJulia` package provides a convenience function `lim(f, c)` to create tables to showcase limits. The `dir` keyword can be `"+-"` (the default) to show values from both the left and the right; `"+"` to only show values to the right of `c`; and `"-"` to only show values to the left of `c`:

For example:

```{julia}
lim(f, c)
```

The numbers are displayed in decreasing order so the values on the left side of $c$ are read from bottom to top:

```{julia}
lim(f, c; dir="-")  # or even lim(f, c, -)
```

:::

##### Example: the secant line


Let $f(x) = x^x$ and consider the ratio:


$$
\frac{f(c + h) - f(c)}{h}
$$

As $h$ goes to $0$, this will take the form $0/0$ in most cases, and in the particular case of $f(x) = x^x$ and $c=1$ it will be. The expression has a geometric interpretation of being the slope of the secant line connecting the two points $(c,f(c))$ and $(c+h, f(c+h))$.


To look at the limit in this example, we have (recycling the values in `hs`):


```{julia}
#| hold: true
c = 1
f(x) = x^x
sec_line_slope(h) = (f(c+h) - f(c)) / h
lim(sec_line_slope, 0)
```

The limit looks like $L=1$.


### Issues with the numeric approach


The numeric approach often gives a good intuition as to the existence of a limit and its value. However, it can be misleading. Consider this limit question:


$$
\lim_{x \rightarrow 0} \frac{1 - \cos(x)}{x^2}.
$$

We can see that it is indeterminate of the form $0/0$:


```{julia}
g(x) = (1 - cos(x)) / x^2
g(0)
```

What is the value of $L$, if it exists? Getting closer to $0$ numerically than the default yields:


```{julia}
lim(g, 0; n=9)
```

Hmm, the values in `ys` appear to be going to $0.5$, but then end up at $0$. Is the limit $0$ or $1/2$? The answer is $1/2$. The last $0$ is an artifact of floating point arithmetic and the last few deviations from `0.5` due to loss of precision in subtraction. To investigate, we look more carefully at the two ratios:


```{julia}
xs = [1/10^i for i in 1:8]
y1s = [1 - cos(x) for x in xs]
y2s = [x^2 for x in xs]
[xs y1s y2s]
```

Looking at the bottom of the second column reveals the error. The value of `1 - cos(1.0e-8)` is `0` and not a value around `5e-17`, as would be expected from the pattern above it. This is because the smallest floating point value less than `1.0` is more than `5e-17` units away, so `cos(1e-8)` is evaluated to be `1.0`. There just isn't enough granularity to get this close to $0$.


Not that we needed to. The answer would have been clear if we had stopped with `x=1e-6` (with `n=6`) say.


In general, some functions will frustrate the numeric approach. It is best to be wary of results. At a minimum they should confirm what a quick graph shows, though even that isn't enough, as this next example shows.


##### Example


Let $h(x)$ be defined by


$$
h(x) = x^2 + 1 + \log(| 11 \cdot x - 15 |)/99.
$$

The question is to investigate


$$
\lim_{x \rightarrow 15/11} h(x)
$$

A plot shows the answer appears to be straightforward:


```{julia}
h(x) = x^2 + 1 + log(abs(11*x - 15))/99
plot(h, 15/11 - 1, 15/11 + 1)
```

Taking values near $15/11$ shows nothing perhaps too unusual:


```{julia}
#| hold: true
c = 15/11
lim(h, c; n = 16)
```

(Though the graph and table do hint at something a bit odd -- the graph shows a blip, the table doesn't show values in the second column going towards a specific value.)


However the limit in this case is $-\infty$ (or DNE), as there is an aysmptote at $c=15/11$. The problem is the asymptote due to the logarithm is extremely narrow and happens between floating point values to the left and right of $15/11$.


### Richardson extrapolation


The [`Richardson`](https://github.com/JuliaMath/Richardson.jl) package provides a function to extrapolate a function `f(x)` to `f(x0)`, as the numeric limit does. We illustrate its use by example:


```{julia}
#| hold: true
f(x) = sin(x)/x
extrapolate(f, 1)
```

The answer involves two terms, the second being an estimate for the error in the estimation of `f(0)`.


The values the method chooses could be viewed as follows:


```{julia}
#| term: true
extrapolate(1) do x  # using `do` notation for the function
    @show x
    sin(x)/x
end
```

The `extrapolate` function avoids the numeric problems encountered in the following example


```{julia}
#| hold: true
f(x) = (1 - cos(x)) / x^2
extrapolate(f, 1)
```

To find limits at a value of `c` not equal to `0`, we set the `x0` argument. For example,


```{julia}
#| hold: true
f(x) = (sqrt(x) - 5) / (sqrt(x-16) - 3)
c = 25
extrapolate(f, 1, x0=25)
```

This value can also be `Inf`, in anticipation of infinite limits to be discussed in a subsequent section:


```{julia}
#| hold: true
f(x) = (x^2 - 2x + 1)/(x^3 - 3x^2 + 2x + 1)
extrapolate(f, 10, x0=Inf)
```

(The starting value should be to the right of any zeros of the denominator.)


## Symbolic approach to limits


The `SymPy` package provides a `limit` function for finding the limit of an expression in a given variable. It must be loaded, as was done initially. The `limit` function's use requires the expression, the variable and a value for $c$. (Similar to the three things in the notation $\lim_{x \rightarrow c}f(x)$.)


For example, the limit at $0$ of $(1-\cos(x))/x^2$ is easily handled:


```{julia}
@syms x::real
limit((1 - cos(x)) / x^2, x => 0)
```

The pair notation (`x => 0`) is used to indicate the variable and the value it is going to. A `dir` argument is used to indicate $x \rightarrow c+$ (the default, or `dir="+"`), $x \rightarrow c-$ (`dir="-"`), and $x \rightarrow c$ (`dir="+-"`).


##### Example


We look again at this function which despite having a vertical asymptote at $x=15/11$ has the property that it is positive for all floating point values, making both a numeric and graphical approach impossible:


$$
h(x) = x^2 + 1 + \log(| 11 \cdot x - 15 |)/99.
$$

We find the limit symbolically at $c=15/11$ as follows, taking care to use the exact value `15//11` and not the *floating point* approximation returned by `15/11`:


```{julia}
#| hold: true
h(x) = x^2 + 1 + log(abs(11x - 15))/99
limit(h(x), x => 15 // 11)
```

##### Example


Find the [limits](http://en.wikipedia.org/wiki/L%27H%C3%B4pital%27s_rule):


$$
\lim_{x \rightarrow 0} \frac{2\sin(x) - \sin(2x)}{x - \sin(x)}, \quad
\lim_{x \rightarrow 0} \frac{e^x - 1 - x}{x^2}, \quad
\lim_{\rho \rightarrow 1} \frac{x^{1-\rho} - 1}{1 - \rho}.
$$

We have for the first:


```{julia}
limit( (2sin(x) - sin(2x)) / (x - sin(x)), x => 0; dir="+-")
```

(The `dir = "+-"` indicates take both a right and left limit and ensure both exist and are equal.)

The second is similarly done, though here we define a function for variety:


```{julia}
#| hold: true
f(x) = (exp(x) - 1 - x) / x^2
limit(f(x), x => 0; dir="+-")
```

Finally, for the third we define a new variable and proceed:


```{julia}
@syms rho::real
limit( (x^(1-rho) - 1) / (1 - rho), rho => 1; dir="+-")
```

This last limit demonstrates that the `limit` function of `SymPy` can readily evaluate limits that involve parameters, though at times some assumptions on the parameters may be needed, as was done through `rho::real`.


However, for some cases, the assumptions will not be enough, as they are broad. (E.g., something might be true for some values of the parameter and not others and these values aren't captured in the assumptions.)  So the user must be mindful that when parameters are involved, the answer may not reflect all possible cases.


##### Example: floating point conversion issues


The Gruntz [algorithm](http://www.cybertester.com/data/gruntz.pdf) implemented in `SymPy` for symbolic limits is quite powerful. However, some care must be exercised to avoid undesirable conversions from exact values to floating point values.


In a previous example, we used `15//11` and not `15/11`, as the former converts to an *exact* symbolic value for use in `SymPy`, but the latter would be approximated in floating point *before* this conversion so the exactness would be lost.


To illustrate further, let's look at the limit as $x$ goes to $\pi/2$ of $j(x) = \cos(x) / (x - \pi/2)$. We follow our past practice:


```{julia}
j(x) = cos(x) / (x - pi/2)
j(pi/2)
```

The value is not `NaN`, rather `Inf`. This is because `cos(pi/2)` is not exactly $0$ as it should be mathematically, as `pi/2` is rounded to a floating point number. This minor difference is important. If we try and correct for this by using `PI` we have:


```{julia}
limit(j(x), x => PI/2)
```

The value is not right, as this simple graph suggests the limit is in fact $-1$:


```{julia}
plot(j,  pi/4, 3pi/4)
```

The difference between `pi` and `PI` can be significant, and though usually `pi` is silently converted to `PI`, it doesn't happen here as the division by `2` happens first, which turns the symbol into an approximate floating point number. Hence, `SymPy` is giving the correct answer for the problem it is given, it just isn't the problem we wanted to look at.


Trying again, being more aware of how `pi` and `PI` differ, we have:


```{julia}
#| hold: true
f(x) = cos(x) / (x - PI/2)
limit(f(x), x => PI/2)
```

(The value `pi` is able to be exactly converted to `PI` when used in `SymPy`, as it is of type `Irrational`, and is not a floating point value. However, the expression `pi/2` converts `pi` to a floating point value and then divides by `2`, hence the loss of exactness when used symbolically.)


##### Example: left and right limits


Right and left limits will be discussed in the next section; here we give an example of the idea.  The mathematical convention is to say a limit exists if both the left *and* right limits exist and are equal. Informally a right (left) limit at $c$ only considers values of $x$ more (less) than $c$. The `limit` function of `SymPy`  finds directional limits by default, a right limit, where $x > c$.


The left limit can be found by passing the argument `dir="-"`. Passing `dir="+-"` (and not `"-+"`), as done in a few examples above, will compute the mathematical limit, throwing an error in `Python` if no limit exists.


```{julia}
limit(ceil(x), x => 0), limit(ceil(x), x => 0, dir="-")
```

This accurately shows the limit does not exist mathematically, but `limit(ceil(x), x => 0)` does exist (as it finds a right limit).


## Rules for limits


The `limit` function doesn't compute limits from the definition, rather it applies some known facts about functions within a set of rules. Some of these rules are the following. Suppose the individual limits of $f$ and $g$ always exist (and are finite) below.


$$
\begin{align*}
\lim_{x \rightarrow c} (a \cdot f(x) + b \cdot g(x)) &= a \cdot
  \lim_{x \rightarrow c} f(x) + b \cdot \lim_{x \rightarrow c} g(x)
  &\\
%%
\lim_{x \rightarrow c} f(x) \cdot g(x) &= \lim_{x \rightarrow c}
  f(x) \cdot \lim_{x \rightarrow c} g(x)
  &\\
%%
\lim_{x \rightarrow c} \frac{f(x)}{g(x)} &=
  \frac{\lim_{x \rightarrow c} f(x)}{\lim_{x \rightarrow c} g(x)}
  &(\text{provided }\lim_{x \rightarrow c} g(x) \neq 0)\\
\end{align*}
$$

These are verbally described as follows, when the individual limits exist and are finite then:


  * Limits involving sums, differences or scalar multiples of functions *exist* **and** can be **computed** by first doing the individual limits and then combining the answers appropriately.
  * Limits of products exist and can be found by computing the limits of the individual factors and then combining.
  * Limits of ratios *exist* and can be found by computing the limit of the individual terms and then dividing **provided** you don't divide by $0$. The last part is really important, as this rule is no help with the common indeterminate form $0/0$.


In addition, consider the composition:


$$
\lim_{x \rightarrow c} f(g(x))
$$

Suppose that


  * The outer limit, $\lim_{x \rightarrow b} f(x) = L$, exists, and
  * the inner limit, $\lim_{x \rightarrow c} g(x) = b$, exists **and**
  * for some neighborhood around $c$ (not including $c$) $g(x)$ is not $b$,


Then the limit exists and equals $L$:


$\lim_{x \rightarrow c} f(g(x)) = \lim_{u \rightarrow b} f(u) = L.$


An alternative, is to assume $f(x)$ is defined at $b$ and equal to $L$ (which is the definition of continuity), but that isn't the assumption above, hence the need to exclude $g$ from taking on a value of $b$ (where $f$ may not be defined) near $c$.


These rules, together with the fact that our basic algebraic functions have limits that can be found by simple evaluation, mean that many limits are easy to compute.


##### Example: composition


For example, consider for some non-zero $k$ the following limit:


$$
\lim_{x \rightarrow 0} \frac{\sin(kx)}{x}.
$$

This is clearly related to the function $f(x) = \sin(x)/x$, which has a limit of $1$ as $x \rightarrow 0$. We see $g(x) = k f(kx)$ is the limit in question. As $kx \rightarrow 0$, though not taking a value of $0$ except when $x=0$, the limit above is $k \lim_{x \rightarrow 0} f(kx) = k \lim_{u \rightarrow 0} f(u) = k$.


Basically when taking a limit as $x$ goes to $0$ we can multiply $x$ by any constant and figure out the limit for that. (It is as though we "go to" $0$ faster or slower, but are still going to $0$.)


Similarly,


$$
\lim_{x \rightarrow 0} \frac{\sin(x^2)}{x^2} = 1,
$$

as this is the limit of $f(g(x))$ with $f$ as above and  $g(x) = x^2$. We need $x \rightarrow 0$, $g$ is only $0$ at $x=0$, which is the case.


##### Example: products


Consider this more complicated limit found on this [Wikipedia](http://en.wikipedia.org/wiki/L%27H%C3%B4pital%27s_rule) page.


$$
\lim_{x \rightarrow 1/2} \frac{\sin(\pi x)}{\pi x} \cdot \frac{\cos(\pi x)}{1 - (2x)^2}.
$$

We know the first factor has a limit found by evaluation: $2/\pi$, so it is really just a constant. The second we can compute:


```{julia}
l(x) = cos(PI*x) / (1 - (2x)^2)
limit(l(x), x => 1//2)
```

Putting together, we would get $1/2$. Which we could have done directly in this case:


```{julia}
limit(sin(PI*x)/(PI*x) * l(x), x => 1//2)
```

##### Example: ratios


Consider again the limit of $\cos(\pi x) / (1 - (2x)^2)$ at $c=1/2$. A graph of both the top and bottom functions shows the indeterminate, $0/0$, form:


```{julia}
plot(cos(pi*x), 0.4, 0.6)
plot!(1 - (2x)^2)
```

However, following Euler's insight that $\sin(x)/x$ will have a limit at $0$ of $1$ as $\sin(x) \approx x$, and $x/x$ has a limit of $1$ at $c=0$, we can see that $\cos(\pi x)$ looks like $-\pi\cdot (x - 1/2)$ and $(1 - (2x)^2)$ looks like $-4(x-1/2)$ around $x=1/2$:


```{julia}
plot(cos(pi*x), 0.4, 0.6)
plot!(-pi*(x - 1/2))
```

```{julia}
plot(1 - (2x)^2, 0.4, 0.6)
plot!(-4(x - 1/2))
```

So around $c=1/2$ the ratio should look like $-\pi (x-1/2) / ( -4(x -	 1/2)) = \pi/4$, which indeed it does, as that is the limit.


This is the basis of L'Hôpital's rule, which we will return to once the derivative is discussed.


##### Example: sums


If it is known that the following limit exists by some means:


$$
L = 0 = \lim_{x \rightarrow 0} \frac{e^{\csc(x)}}{e^{\cot(x)}} - (1 + \frac{1}{2}x  + \frac{1}{8}x^2)
$$

Then this limit will exist


$$
M = \lim_{x \rightarrow 0} \frac{e^{\csc(x)}}{e^{\cot(x)}}
$$

Why? We can express the function $e^{\csc(x)}/e^{\cot(x)}$ as the above function plus the polynomial $1 + x/2 + x^2/8$. The above is then the sum of two functions whose limits exist and are finite, hence, we can conclude that $M = 0 + 1$.


### The [squeeze](http://en.wikipedia.org/wiki/Squeeze_theorem) theorem


We note one more limit law. Suppose we wish to compute $\lim_{x \rightarrow c}f(x)$ and we have two other functions, $l$ and $u$, satisfying:


  * for all $x$ near $c$ (possibly not including $c$) $l(x) \leq f(x) \leq u(x)$.
  * These limits exist and are equal: $L = \lim_{x \rightarrow c} l(x) = \lim_{x \rightarrow c} u(x)$.


Then the limit of $f$ must also  be $L$.


```{julia}
#| hold: true
#| echo: false
gr()
function squeeze_example(x)
	x₀ = 0.5
	plot(cos, 0, x₀, label="cos")
	plot!(x -> sin(x)/x, label = "sin(x)/x")
	plot!(x -> 1, label = "y=1")
	plot!([x,x], [ cos(x₀), 1], linestyle=:dash, label="")
	scatter!([x,x,x], [cos(x), sin(x)/x, 1], label="")
end

anim = @animate for x ∈ (0.4, 0.3, 0.2, 0.1, 0.05, 0.01)
    squeeze_example(x)
end

imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)


caption = """
As ``x`` goes to ``0``, the values of ``\\sin(x)/x`` are squeezed between ``\\cos(x)`` and ``1`` which both converge to ``1``.
"""
plotly()
ImageFile(imgfile, caption)
```

## Limits from the definition


The formal definition of a limit involves clarifying what it means for $f(x)$ to be "close to $L$" when $x$ is "close to $c$". These are quantified by the inequalities $0 < \lvert x-c\rvert < \delta$ and the $\lvert f(x) - L\rvert < \epsilon$. The second does not have the restriction that it is greater than $0$, as indeed $f(x)$ can equal $L$. The order is important: it says for any idea of close for $f(x)$ to $L$, an idea of close must be found for $x$ to $c$.


The key is identifying a value for $\delta$  for a given value of $\epsilon$.


A simple case is the linear case. Consider the function $f(x) = 3x + 2$. Verify that the limit at $c=1$ is $5$.


We show "numerically" that $\delta = \epsilon/3$.


```{julia}
#| hold: true
f(x) = 3x + 2
c, L = 1, 5
epsilon = rand()                 # some number in (0,1)
delta = epsilon / 3
xs = c .+ delta * rand(100)       # 100 numbers, c < x < c + delta
as = [abs(f(x) - L) < epsilon for x in xs]
all(as)                          # are all the as true?
```

These lines produce a random $\epsilon$, the resulting $\delta$, and then verify for 100 numbers within $(c, c+\delta)$ that the inequality $\lvert f(x) - L \rvert < \epsilon$ holds for each. Running them again and again should always produce `true` if $L$ is the limit and $\delta$ is chosen properly.


(Of course, we should also verify values to the left of $c$.)


(The random numbers are technically in $[0,1)$, so in theory `epsilon` could be `0`. So the above approach would be more solid if some guard, such as  `epsilon = max(eps(), rand())`, was used. As the formal definition is the domain of paper-and-pencil, we don't fuss.)


In this case, $\delta$ is easy to guess, as the function is linear and has slope $3$. This basically says the $y$ scale is 3 times the $x$ scale. For non-linear functions, finding $\delta$ for a given $\epsilon$ can be a challenge. For the function $f(x) = x^3$, illustrated below, a value of $\delta=\epsilon^{1/3}$ is used for $c=0$:


```{julia}
#| hold: true
#| echo: false
#| cache: true
## {{{ limit_e_d }}}
gr()
function make_limit_e_d(n)
    f(x) = x^3

    xs = range(-.9, stop=.9, length=50)
    ys = map(f, xs)


    plt = plot(f, -.9, .9, legend=false, size=fig_size)
    if n == 0
        nothing
    else
        k = div(n+1,2)
        epsilon = 1/2^k
        delta = cbrt(epsilon)
        if isodd(n)
            plot!(plt, xs, 0*xs .+ epsilon, color=:orange)
            plot!(plt, xs, 0*xs .- epsilon, color=:orange)
        else
            plot!(delta * [-1,  1], epsilon * [ 1, 1], color=:orange)
            plot!(delta * [ 1, -1], epsilon * [-1,-1], color=:orange)
            plot!(delta * [-1, -1], epsilon * [-1, 1], color=:red)
            plot!(delta * [ 1,  1], epsilon * [-1, 1], color=:red)
        end
    end
    plt
end


n = 11
anim = @animate for i=1:n
    make_limit_e_d(i-1)
end

imgfile = tempname() * ".gif"
gif(anim, imgfile, fps = 1)


caption = L"""

Demonstration of $\epsilon$-$\delta$ proof of $\lim_{x \rightarrow 0}
x^3 = 0$. For any $\epsilon>0$ (the orange lines) there exists a
$\delta>0$ (the red lines of the box) for which the function $f(x)$
does not leave the top or bottom of the box (except possibly at the
edges). In this example $\delta^3=\epsilon$.

"""
plotly()
ImageFile(imgfile, caption)
```

## Questions


###### Question


From the graph, find the limit:


$$
L = \lim_{x\rightarrow 1}  \frac{x^2−3x+2}{x^2−6x+5}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = (x^2 - 3x +2) / (x^2 - 6x + 5)
plot(f, 0,2)
```

```{julia}
#| hold: true
#| echo: false
answ = 1/4
numericq(answ, 1e-1)
```

###### Question


From the graph, find the limit $L$:


$$
L = \lim_{x \rightarrow -2} \frac{x}{x+1} \frac{x^2}{x^2 + 4}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = x/(x+1)*x^2/(x^2+4)
plot(f, -3, -1.25)
```

```{julia}
#| hold: true
#| echo: false
f(x) = x/(x+1)*x^2/(x^2+4)
val = f(-2)
numericq(val, 1e-1)
```

###### Question


Graphically investigate the limit


$$
L = \lim_{x \rightarrow 0} \frac{e^x - 1}{x}.
$$

What is the value of $L$?


```{julia}
#| hold: true
#| echo: false
f(x) = (exp(x) - 1)/x
p = plot(f, -1, 1)
```

```{julia}
#| hold: true
#| echo: false
val = N(limit((exp(x)-1)/x, x => 0))
numericq(val, 1e-1)
```

###### Question


Graphically investigate the limit


$$
\lim_{x \rightarrow 0} \frac{\cos(x) - 1}{x}.
$$

The limit exists, what is the value?


```{julia}
#| hold: true
#| echo: false
val = 0
numericq(val, 1e-2)
```

###### Question


Select the graph for which there is no limit at $a$.


```{julia}
#| hold: true
#| echo: false
gr()
let
    p1 = plot(;axis=nothing, legend=false)
    title!(p1, "(a)")
    plot!(p1, x -> x^2, 0, 2, color=:black)
    plot!(p1, zero, linestyle=:dash)
    annotate!(p1,[(1,0,"a")])

    p2 = plot(;axis=nothing, legend=false)
    title!(p2, "(b)")
    plot!(p2, x -> 1/(1-x), 0, .95, color=:black)
    plot!(p2, x-> -1/(1-x), 1.05, 2, color=:black)
    plot!(p2, zero, linestyle=:dash)
    annotate!(p2,[(1,0,"a")])

    p3 = plot(;axis=nothing, legend=false)
    title!(p3, "(c)")
    plot!(p3, sinpi, 0, 2, color=:black)
    plot!(p3, zero, linestyle=:dash)
    annotate!(p3,[(1,0,"a")])

    p4 = plot(;axis=nothing, legend=false)
    title!(p4, "(d)")
    plot!(p4, x -> x^x, 0, 2, color=:black)
    plot!(p4, zero, linestyle=:dash)
    annotate!(p4,[(1,0,"a")])

    l = @layout[a b; c d]
    p = plot(p1, p2, p3, p4, layout=l)
    imgfile = tempname() * ".png"
    savefig(p, imgfile)
    hotspotq(imgfile, (1/2,1), (1/2,1))
end
```

```{julia}
#| echo: false
plotly();
```

###### Question


The following limit is commonly used:


$$
\lim_{h \rightarrow 0} \frac{e^{x + h} - e^x}{h} = L.
$$

Factoring out $e^x$ from the top and using rules of limits this becomes,


$$
L = e^x \lim_{h \rightarrow 0} \frac{e^h - 1}{h}.
$$

What is $L$?


```{julia}
#| hold: true
#| echo: false
choices = ["``0``", "``1``", "``e^x``"]
answ = 3
radioq(choices, answ)
```

###### Question


The following limit is commonly used:


$$
\lim_{h \rightarrow 0} \frac{\sin(x + h) - \sin(x)}{h} = L.
$$

The answer should depend on $x$, though it is possible it is a constant.  Using a double angle formula and the rules of limits, this can be written as:


$$
L = \cos(x) \lim_{h \rightarrow 0}\frac{\sin(h)}{h} + \sin(x) \lim_{h \rightarrow 0}\frac{\cos(h)-1}{h}.
$$

Using the last result, what is the value of $L$?


```{julia}
#| hold: true
#| echo: false
choices = ["``\\cos(x)``", "``\\sin(x)``", "``1``", "``0``", "``\\sin(h)/h``"]
answ = 1
radioq(choices, answ)
```

###### Question


Find the limit as $x$ goes to $2$ of


$$
f(x) = \frac{3x^2 - x -10}{x^2 - 4}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = (3x^2 - x - 10)/(x^2 - 4);
val = convert(Float64, N(limit(f(x), x => 2)))
numericq(val)
```

###### Question


Find the limit as $x$ goes to $-2$ of


$$
f(x) = \frac{\frac{1}{x} + \frac{1}{2}}{x^3 + 8}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = ((1/x) + (1/2))/(x^3 + 8)
numericq(-1/48, .001)
```

###### Question


Find the limit as $x$ goes to $27$ of


$$
f(x) = \frac{x - 27}{x^{1/3} - 3}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = (x - 27)/(x^(1//3) - 3)
val = N(limit(f(x), x => 27))
numericq(val)
```

###### Question


Find the limit


$$
L = \lim_{x \rightarrow \pi/2} \frac{\tan (2x)}{x - \pi/2}
$$

```{julia}
#| hold: true
#| echo: false
f(x) = tan(2x)/(x-PI/2)
val = N(limit(f(x), x => PI/2))
numericq(val)
```

###### Question


The limit of $\sin(x)/x$ at $0$ has a numeric value. This depends upon the fact that $x$ is measured in radians. Try to find this limit: `limit(sind(x)/x, x => 0)`. What is the value?


```{julia}
#| hold: true
#| echo: false
choices = [q"0", q"1", q"pi/180", q"180/pi"]
answ = 3
radioq(choices, answ)
```

What is the limit `limit(sinpi(x)/x, x => 0)`?


```{julia}
#| hold: true
#| echo: false
choices = [q"0", q"1", q"pi", q"1/pi"]
answ = 3
radioq(choices, answ)
```

###### Question: limit properties


There are several properties of limits that allow one to break down more complicated problems into smaller subproblems. For example,


$$
\lim (f(x) + g(x)) = \lim f(x) + \lim g(x)
$$

is notation to indicate that one can take a limit of the sum of two function or take the limit of each first, then add and the answer will be unchanged, provided all the limits in question exist.


Use one or the either to find the limit of $f(x) = \sin(x) + \tan(x) + \cos(x)$ as $x$ goes to $0$.


```{julia}
#| hold: true
#| echo: false
f(x) = sin(x) + tan(x) + cos(x)
numericq(f(0), 1e-5)
```

###### Question


The key assumption made above in being able to write


$$
\lim_{x\rightarrow c} f(g(x)) = L,
$$

when $\lim_{x\rightarrow b} f(x) = L$ and $\lim_{x\rightarrow c}g(x) = b$ is *continuity*.


This [example](https://en.wikipedia.org/wiki/Limit_of_a_function#Limits_of_compositions_of_functions) shows why it is important.


Take


$$
f(x) = \begin{cases}
0 & x \neq 0\\
1 & x = 0
\end{cases}
$$

We have $\lim_{x\rightarrow 0}f(x) = 0$, as $0$ is clearly a removable discontinuity. So were the above applicable we would have $\lim_{x \rightarrow 0}f(f(x)) = 0$. But this is not true. What is the limit at $0$ of $f(f(x))$?


```{julia}
#| hold: true
#| echo: false
numericq(1)
```

###### Question


Does this function have a limit as $h$ goes to $0$ from the right (that is, assume $h>0$)?


$$
\frac{h^h - 1}{h}
$$

```{julia}
#| hold: true
#| echo: false
choices = [
"Yes, the value is `-9.2061`",
"Yes, the value is `-11.5123`",
"No, the value heads to negative infinity"
];
answ = 3;
radioq(choices, answ)
```

###### Question


Compute the limit


$$
\lim_{x \rightarrow 1} \frac{x}{x-1} - \frac{1}{\ln(x)}.
$$

```{julia}
#| hold: true
#| echo: false
f(x) = x/(x-1) - 1/log(x)
val = convert(Float64, N(limit(f(x), x => 1)))
numericq(val)
```

###### Question


Compute the limit


$$
\lim_{x \rightarrow 1/2} \frac{1}{\pi} \frac{\cos(\pi x)}{1 - (2x)^2}.
$$

```{julia}
#| hold: true
#| echo: false
f(x) =  1/PI * cos(PI*x)/(1 - (2x)^2)
val = convert(Float64, N(limit(f(x), x => 1//2)))
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 = convert(Float64, 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:


```{julia}
#| hold: true
@syms m::real k::real
ex = (1 + k*x)^(m/x)
```

What is `limit(ex, x => 0)`?


```{julia}
#| hold: true
#| echo: false
choices = ["``e^{km}``", "``e^{k/m}``", "``k/m``", "``m/k``", "``0``"]
answwer = 1
radioq(choices, answwer)
```

###### Question


For a given $a$, what is


$$
L = \lim_{x \rightarrow 0+} (1 + a\cdot (e^{-x} -1))^{(1/x)}
$$

```{julia}
#| hold: true
#| echo: false
choices = ["``e^{-a}``", "``e^a``", "``a``", "``L`` does not exist"]
radioq(choices, 1)
```

###### Question


For positive integers $m$ and $n$ what is


$$
\lim_{x \rightarrow 1} \frac{x^{1/m}-1}{x^{1/n}-1}?
$$

```{julia}
#| hold: true
#| echo: false
choices = ["``m/n``", "``n/m``", "``mn``", "The limit does not exist"]
radioq(choices, 2)
```

###### Question


What does `SymPy` find for the limit of `ex` (`limit(ex, x => 0)`), as defined here:


```{julia}
#| hold: true
@syms x a
ex = (a^x - 1)/x
```

```{julia}
#| hold: true
#| echo: false
choices = ["``\\log(a)``", "``a``", "``e^a``", "``e^{-a}``"]
radioq(choices, 1)
```

Should `SymPy` have needed an assumption like


```{julia}
@syms a::positive
```

```{julia}
#| hold: true
#| echo: false
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


Let's look at the function $f(x) = x \sin(1/x)$. A graph around $0$ can be made with:


```{julia}
#| hold: true
f(x) = x == 0 ? NaN : x * sin(1/x)
c, delta = 0, 1/4
plot(f, c - delta, c + delta)
plot!(abs)
plot!(x -> -abs(x))
```

This graph clearly oscillates near $0$. To the graph of $f$, we added graphs of both $g(x) = \lvert x\rvert$ and $h(x) = - \lvert x\rvert$. From this graph it is easy to see by the "squeeze theorem" that the limit at $x=0$ is $0$. Why?


```{julia}
#| hold: true
#| echo: false
choices=[L"""The functions $g$ and $h$ both have a limit of $0$ at $x=0$ and the function $f$ is in
between both $g$ and $h$, so must to have a limit of $0$.
""",
	L"The functions $g$ and $h$ squeeze each other as $g(x) > h(x)$",
         L"The function $f$ has no limit - it oscillates too much near $0$"]
answ = 1
radioq(choices, answ)
```

(The [Wikipedia](https://en.wikipedia.org/wiki/Squeeze_theorem) entry for the squeeze theorem has this unverified, but colorful detail:


> In many languages (e.g. French, German, Italian, Hungarian and Russian), the squeeze theorem is also known as the two policemen (and a drunk) theorem, or some variation thereof. The story is that if two policemen are escorting a drunk prisoner between them, and both officers go to a cell, then (regardless of the path taken, and the fact that the prisoner may be wobbling about between the policemen) the prisoner must also end up in the cell.



###### Question


Archimedes, in finding bounds on the value of $\pi$ used $n$-gons with sides $12, 24, 48,$ and $96$. This was so the trigonometry involved could be solved exactly for the interior angles (e.g. $n=12$ is an interior angle of $\pi/6$ which has `sin` and `cos` computable by simple geometry. See [Damini and Abhishek](https://arxiv.org/pdf/2008.07995.pdf)) These exact solutions led to subsequent bounds. A more modern approach to bound the circumference of a circle of radius $r$ using a $n$-gon with interior angle $\theta$ would be to use the trigonometric functions. An upper bound would be found with (using the triangle with angle $\theta/2$, opposite side $x$ and adjacent side $r$:


```{julia}
@syms theta::real r::real
```

```{julia}
#| hold: true
x = r * tan(theta/2)
n = 2PI/theta     # using PI to avoid floaing point roundoff in 2pi
# C < n * 2x
upper = n*2x
```

A lower bound would use the triangle with angle $\theta/2$, hypotenuse $r$ and opposite side $x$:


```{julia}
#| hold: true
x = r*sin(theta/2)
n = 2PI/theta
# C > n * 2x
lower = n*2x
```

Using the above, find the limit of `upper` and `lower`. Are the two equal and equal to a familiar value?


```{julia}
#| hold: true
#| echo: false
yesnoq("yes")
```

(If so, then the squeeze theorem would say that $\pi$ is the common limit.)
