{ "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": "b290d0d9-8a87-4d9f-8bab-c410dacd955f" }, { "cell_type": "code", "execution_count": 0, "metadata": {}, "outputs": [], "source": [ "using MTH229\n", "using Plots\n", "plotly()" ], "id": "2" }, { "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": "b88d965f-785d-4e9e-8f0d-81b4d70a2a1d" }, { "cell_type": "code", "execution_count": 1, "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": "6" }, { "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": "0ee2f4e3-8596-41f2-be23-74b7982accfa" }, { "cell_type": "code", "execution_count": 1, "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": "8" }, { "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": "180599a8-4bbf-47fb-b917-5499c1d9651a" }, { "cell_type": "code", "execution_count": 1, "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": "10" }, { "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": "b19863f6-d196-4c7f-b23e-7be0900e9e65" }, { "cell_type": "code", "execution_count": 1, "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": "12" }, { "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": "1dc48865-567d-41ae-991e-39677842ab67" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
 0.1        0.9983341664682815\n",
              " 0.01       0.9999833334166665\n",
              " 0.001      0.9999998333333416\n",
              " 0.0001     0.9999999983333334\n",
              " 1.0e-5     0.9999999999833332\n",
              " 1.0e-6     0.9999999999998334\n",
              "   ⋮          ⋮\n",
              "   c          L?\n",
              "   ⋮          ⋮\n",
              "-1.0e-6     0.9999999999998334\n",
              "-1.0e-5     0.9999999999833332\n",
              "-0.0001     0.9999999983333334\n",
              "-0.001      0.9999998333333416\n",
              "-0.01       0.9999833334166665\n",
              "-0.1        0.9983341664682815
" ] } } ], "source": [ "f(x) = sin(x) / x\n", "lim(f, 0)" ], "id": "14" }, { "cell_type": "markdown", "metadata": {}, "source": [ "The limit of $1/2$ is suggested by the following" ], "id": "612d342f-b4e4-451b-b845-44929e8e4885" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
1.6707963267948966     0.49958347219742816\n",
              "1.5807963267948966     0.4999958333473655\n",
              "1.5717963267948964     0.4999999583256134\n",
              "1.5708963267948965     0.4999999969613747\n",
              "1.5708063267948966     0.5000000413636343\n",
              "1.5707973267948965     0.5000444503734445\n",
              "         ⋮                      ⋮\n",
              "         c                      L?\n",
              "         ⋮                      ⋮\n",
              "1.5707953267948966     0.5000444503734445\n",
              "1.5707863267948965     0.5000000413636343\n",
              "1.5706963267948966     0.4999999969613747\n",
              "1.5697963267948967     0.4999999583256134\n",
              "1.5607963267948965     0.4999958333473655\n",
              "1.4707963267948965     0.49958347219742816
" ] } } ], "source": [ "f(x) = (1 - sin(x))/(pi/2 - x)^2\n", "lim(f, pi/2)" ], "id": "16" }, { "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": "15d9f74e-3f62-4c0e-9c85-dc7cb0897c8d" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/html": [ "
         c                      L?\n",
              "         ⋮                      ⋮\n",
              "1.5707953267948966     0.5000444503734445\n",
              "1.5707863267948965     0.5000000413636343\n",
              "1.5706963267948966     0.4999999969613747\n",
              "1.5697963267948967     0.4999999583256134\n",
              "1.5607963267948965     0.4999958333473655\n",
              "1.4707963267948965     0.49958347219742816
" ] } } ], "source": [ "lim(f, pi/2, dir=\"-\")" ], "id": "18" }, { "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": "fc06ecda-a57c-4215-8647-c5c1dc94086d" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/plain": [ "1" ] } } ], "source": [ "f(x) = sin(x)/x\n", "@syms x\n", "limit(f(x), x => 0)" ], "id": "20" }, { "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": "87f72744-0015-4dc7-a296-3ed24151bda2" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "output_type": "display_data", "metadata": {}, "data": { "text/plain": [ "sin(x)\n", "──────\n", " x " ] } } ], "source": [ "f(x)" ], "id": "22" }, { "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": "9eb9dd1c-4507-46f8-ba54-34793cec2ad7" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Your commands go here\n", "\n" ], "id": "24" } ], "nbformat": 4, "nbformat_minor": 5, "metadata": { "kernel_info": { "name": "julia" }, "kernelspec": { "name": "julia", "display_name": "Julia", "language": "julia" }, "language_info": { "name": "julia", "codemirror_mode": "julia", "version": "1.10.0" } } }