{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# \n",
"\n",
"# Investigating limits with Julia\n",
"\n",
"To get started, we load the `MTH229` package so that we can make plots\n",
"and use some symbolic math:"
],
"id": "491206ae-1911-4e3a-956f-d2ff41f70961"
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"using MTH229\n",
"using Plots\n",
"plotly()"
],
"id": "9aabd026"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"------------------------------------------------------------------------\n",
"\n",
"### Quick background\n",
"\n",
"Read about this material here: [Investigating limits with\n",
"Julia](http://mth229.github.io/limits.html).\n",
"\n",
"The expression\n",
"\n",
"$$\n",
"\\lim_{x \\rightarrow c} f(x) = L\n",
"$$\n",
"\n",
"says that the limit as $x$ goes to $c$ of $f$ is $L$.\n",
"\n",
"> Intuitively, as $x$ gets “close” to $c$, $f(x)$ should be close to\n",
"> $L$.\n",
"\n",
"If $f(x)$ is *continuous* at $x=c$, then $L=f(c)$. This is almost always\n",
"the case for a randomly chosen $c$ - but almost never the case for a\n",
"textbook choice of $c$. Invariably with text book examples—though not\n",
"always—we will have `f(c) = NaN` indicating the function is\n",
"indeterminate at `c`. For such cases we need to do more work to identify\n",
"if any such $L$ exists and when it does, what its value is.\n",
"\n",
"In this project, we investigate limits three ways: graphically, with a\n",
"table of numbers, and analytically, developing the inituition of limits\n",
"along the way.\n",
"\n",
"#### Graphical approach\n",
"\n",
"The graphical approach is to plot the expression *near* $c$ and look\n",
"visually what $f(x)$ goes to as $x$ gets close to $c$.\n",
"\n",
"For example, what is this limit?\n",
"\n",
"$$\n",
"\\lim_{x \\rightarrow \\pi/2} \\frac{1 - \\sin(x)}{(\\pi/2 - x)^2}?\n",
"$$\n",
"\n",
"Here is a graph to investigate the problem. We simply graph near $c$ and\n",
"look:"
],
"id": "8bda4595-2156-41af-b345-a191bdf4b270"
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/html": [
""
]
}
}
],
"source": [
"f(x) = (1-sin(x)) / (pi/2 - x)^2\n",
"c = pi/2\n",
"plot(f, c - pi/6, c + pi/6)"
],
"id": "e0bb78c3"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From the graph, we see clearly that as $x$ is close to $c=\\pi/2$, $f(x)$\n",
"is close to $1/2$. (The fact that `f(pi/2) = NaN` will either not come\n",
"up, as `pi/2` is not among the points sampled or the `NaN` values will\n",
"not be plotted.)\n",
"\n",
"## Using tables to investigate limits\n",
"\n",
"Investigating a limit numerically requires us to operationalize the idea\n",
"of $x$ getting close to $c$ and $f(x)$ getting close to $L$. Here we do\n",
"this manually:"
],
"id": "10190b81-2884-4ede-bc9d-404acd088fc9"
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/plain": [
"(0.9983341664682815, 0.9999833334166665, 0.9999998333333416, 0.9999999983333334, 0.9999999999833332, 0.9999999999998334)"
]
}
}
],
"source": [
"f(x) = sin(x)/x\n",
"f(0.1), f(0.01), f(0.001), f(0.0001), f(0.00001), f(0.000001)"
],
"id": "132df3bb"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From this we see a *right* limit at 0 appears to be $1$.\n",
"\n",
"We can put the above into a column, by wrapping things in square\n",
"brackets (forming a vector):"
],
"id": "141b0f46-c9aa-476a-b987-45981299edcd"
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/plain": [
"6-element Vector{Float64}:\n",
" 0.9983341664682815\n",
" 0.9999833334166665\n",
" 0.9999998333333416\n",
" 0.9999999983333334\n",
" 0.9999999999833332\n",
" 0.9999999999998334"
]
}
}
],
"source": [
"[f(0.1), f(0.01), f(0.001), f(0.0001), f(0.00001), f(0.000001)]"
],
"id": "4d85b4f3"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The style of printing makes it clear, the limit here should be $L=1$.\n",
"\n",
"Limits when $c\\neq 0$ are similar, but require points getting close to\n",
"$c$. For example,\n",
"\n",
"$$\n",
"\\lim_{x \\rightarrow \\pi/2} \\frac{1 - \\sin(x)}{(\\pi/2 - x)^2}\n",
"$$\n",
"\n",
"has a limit of $1/2$. We can investigate with:"
],
"id": "e7840500-b46b-4957-93bc-035f8f2abb8d"
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/plain": [
"5-element Vector{Float64}:\n",
" 0.49958347219742816\n",
" 0.4999999583256134\n",
" 0.5000000413636343\n",
" 0.49960036049791995\n",
" 0.0"
]
}
}
],
"source": [
"c = pi/2\n",
"f(x) = (1 - sin(x))/(pi/2 - x)^2\n",
"[f(c+.1), f(c+.001), f(c+.00001), f(c+.0000001), f(c+.000000001)]"
],
"id": "01dbf765"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wait, is the limit $1/2$ or $0$? At first $1/2$ seems like the answer,\n",
"but the last number is $0$.\n",
"\n",
"Here we see a limitation of tables - when numbers get too small, that\n",
"fact that they are represented in floating point becomes important. In\n",
"this case, for numbers too close to $\\pi/2$ the value on the computer\n",
"for `sin(x)` is just 1 and not a number near 1. Hence the denominator\n",
"becomes $0$, and so then the expression. (Near $1$, the floating point\n",
"values are about $10^{-16}$ apart, so when two numbers are within\n",
"$10^{-16}$ of each other, they can be rounded to the same number.) So\n",
"watch out when seeing what the values of $f(x)$ get close to. Here it is\n",
"clear that the limit is heading towards $0.5$ until we get too close.\n",
"\n",
"For convenience, the `lim` function from the `MTH229` package can make\n",
"the above computations easier to do. Its use follows the common pattern:\n",
"`action(function, arguments...)`. For example, the limit of $1$ is\n",
"clearly suggested below:"
],
"id": "d2deb755-4427-4979-9e2d-79669a70a7ed"
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/html": [
"
0.100000 0.9983341664682815\n",
" 0.010000 0.9999833334166665\n",
" 0.001000 0.9999998333333416\n",
" 0.000100 0.9999999983333334\n",
" 0.000010 0.9999999999833332\n",
" 0.000001 0.9999999999998334\n",
" ⋮ ⋮\n",
" c L?\n",
" ⋮ ⋮\n",
"-0.000001 0.9999999999998334\n",
"-0.000010 0.9999999999833332\n",
"-0.000100 0.9999999983333334\n",
"-0.001000 0.9999998333333416\n",
"-0.010000 0.9999833334166665\n",
"-0.100000 0.9983341664682815"
]
}
}
],
"source": [
"f(x) = sin(x) / x\n",
"lim(f, 0)"
],
"id": "ff30f3de"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The limit of $1/2$ is suggested by the following"
],
"id": "573df535-4b66-4933-99b9-2dab0f65e36a"
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/html": [
"1.670796 0.49958347219742816\n",
"1.580796 0.4999958333473655\n",
"1.571796 0.4999999583256134\n",
"1.570896 0.4999999969613747\n",
"1.570806 0.5000000413636343\n",
"1.570797 0.5000444503734445\n",
" ⋮ ⋮\n",
" c L?\n",
" ⋮ ⋮\n",
"1.570795 0.5000444503734445\n",
"1.570786 0.5000000413636343\n",
"1.570696 0.4999999969613747\n",
"1.569796 0.4999999583256134\n",
"1.560796 0.4999958333473655\n",
"1.470796 0.49958347219742816"
]
}
}
],
"source": [
"f(x) = (1 - sin(x))/(pi/2 - x)^2\n",
"lim(f, pi/2)"
],
"id": "5d827351"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The above will generate values just bigger than `pi/2` and just smaller\n",
"than `pi/2` which are helpful to investigate the limit from *both*\n",
"sides. For just a *left* limit, pass in `dir=\"-\"`, as with"
],
"id": "3b4984ec-0554-4dc2-bed7-b524835d6b14"
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/html": [
" c L?\n",
" ⋮ ⋮\n",
"1.570795 0.5000444503734445\n",
"1.570786 0.5000000413636343\n",
"1.570696 0.4999999969613747\n",
"1.569796 0.4999999583256134\n",
"1.560796 0.4999958333473655\n",
"1.470796 0.49958347219742816"
]
}
}
],
"source": [
"lim(f, pi/2, dir=\"-\")"
],
"id": "fe9fb465"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly, pass in `dir=\"+\"` to get just the right limit.\n",
"\n",
"## Symbolic limits\n",
"\n",
"The add-on package `SymPy` can be used to analytically compute the limit\n",
"of a symbolic expression. The package is loaded when `MTH229` is.\n",
"`SymPy` provides the `limit` function. A sample usage is shown below:"
],
"id": "45870d7f-e502-4fee-81e7-7f92f0db7739"
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"f(x) = sin(x)/x\n",
"@syms x\n",
"limit(f(x), x => 0)"
],
"id": "d0ffe84d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The new command, `@syms x`, creates a symbolic variable named `x`. This\n",
"makes `f(x)` a symbolic expression"
],
"id": "82e0c4ef-57d2-4f64-8910-072a29dbaee6"
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"f(x)"
],
"id": "4eccff9d"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To find the limit of an expression, `ex`, as a symbolic variable, `x`,\n",
"goes towards some value `c`, `0` in the above example, is performed by\n",
"the command `limit(ex, x => c)`.\n",
"\n",
"SymPy finds the *right limit by default*. A left limit can be asked for\n",
"with the additional argument `dir=\"-\"`. Passing `dir=\"+-\"` to SymPy asks\n",
"for both the left and right limit and a test for their equality (e.g.,\n",
"the limit).\n",
"\n",
"------------------------------------------------------------------------"
],
"id": "f2074309-d50c-40e6-b1bb-52bbbc49583c"
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# Your commands go here\n"
],
"id": "4fe72985"
}
],
"nbformat": 4,
"nbformat_minor": 5,
"metadata": {
"kernelspec": {
"name": "julia-1.11",
"display_name": "Julia 1.11.2",
"language": "julia",
"path": "/Users/jverzani/Library/Jupyter/kernels/julia-1.11"
},
"language_info": {
"name": "julia",
"file_extension": ".jl",
"mimetype": "application/julia",
"version": "1.11.2"
}
}
}