{ "hash": "38c114c653a0c94ca4cbef8ec3c61239", "result": { "markdown": "# Function manipulations\n\n\n\nIn this section we will use these add-on packages:\n\n``` {.julia .cell-code}\nusing CalculusWithJulia\nusing Plots\n```\n\n\n\n\n---\n\n\nThinking of functions as objects themselves that can be manipulated - rather than just blackboxes for evaluation - is a major abstraction of calculus. The main operations to come: the limit *of a function*, the derivative *of a function*, and the integral *of a function* all operate on functions. Hence the idea of an [operator](http://tinyurl.com/n5gp6mf). Here we discuss manipulations of functions from pre-calculus that have proven to be useful abstractions.\n\n\n## The algebra of functions\n\n\nWe can talk about the algebra of functions. For example, the sum of functions $f$ and $g$ would be a function whose value at $x$ was just $f(x) + g(x)$. More formally, we would have:\n\n\n\n$$\n(f + g)(x) = f(x) + g(x),\n$$\n\n\nWe have given meaning to a new function $f+g$ by defining what is does to $x$ with the rule on the right hand side. Similarly, we can define operations for subtraction, multiplication, addition, and powers.\n\n\nThese mathematical concepts aren't defined for functions in base `Julia`, though they could be if desired, by a commands such as:\n\n::: {.cell execution_count=4}\n``` {.julia .cell-code}\nimport Base: +\nf::Function + g::Function = x -> f(x) + g(x)\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n```\n+ (generic function with 314 methods)\n```\n:::\n:::\n\n\nThis adds a method to the generic `+` function for functions. The type annotations `::Function` ensure this applies only to functions. To see that it would work, we could do odd-looking things like:\n\n::: {.cell execution_count=5}\n``` {.julia .cell-code}\nss = sin + sqrt\nss(4)\n```\n\n::: {.cell-output .cell-output-display execution_count=6}\n```\n1.2431975046920718\n```\n:::\n:::\n\n\nDoing this works, as Julia treats functions as first class objects, lending itself to [higher](https://en.wikipedia.org/wiki/Higher-order_programming) order programming. However, this definition in general is kind of limiting, as functions in mathematics and Julia can be much more varied than just the univariate functions we have defined addition for. We won't pursue this further.\n\n\n### Composition of functions\n\n\nAs seen, just like with numbers, it can make sense mathematically to define addition, subtraction, multiplication and division of functions. Unlike numbers though, we can also define a new operation on functions called **composition** that involves chaining the output of one function to the input of another. Composition is a common practice in life, where the result of some act is fed into another process. For example, making a pie from scratch involves first making a crust, then composing this with a filling. A better abstraction might be how we \"surf\" the web. The output of one search leads us to another search whose output then is a composition.\n\n\nMathematically, a composition of univariate functions $f$ and $g$ is written $f \\circ g$ and defined by what it does to a value in the domain of $g$ by:\n\n\n\n$$\n(f \\circ g)(x) = f(g(x)).\n$$\n\n\nThe output of $g$ becomes the input of $f$.\n\n\nComposition depends on the order of things. There is no guarantee that $f \\circ g$ should be the same as $g \\circ f$. (Putting on socks then shoes is quite different from putting on shoes then socks.) Mathematically, we can see this quite clearly with the functions $f(x) = x^2$ and $g(x) = \\sin(x)$. Algebraically we have:\n\n\n\n$$\n(f \\circ g)(x) = \\sin(x)^2, \\quad (g \\circ f)(x) = \\sin(x^2).\n$$\n\n\nThough they may be *typographically* similar don't be fooled, the following graph shows that the two functions aren't even close except for $x$ near $0$ (for example, one composition is always non-negative, whereas the other is not):\n\n::: {.cell hold='true' execution_count=6}\n``` {.julia .cell-code}\nf(x) = x^2\ng(x) = sin(x)\nfg = f ā g # typed as f \\circ[tab] g\ngf = g ā f # typed as g \\circ[tab] f\nplot(fg, -2, 2, label=\"fāg\")\nplot!(gf, label=\"gāf\")\n```\n\n::: {.cell-output .cell-output-display execution_count=7}\n{}\n:::\n:::\n\n\n:::{.callout-note}\n## Note\nUnlike how the basic arithmetic operations are treated, `Julia` defines the infix Unicode operator `\\\\circ[tab]` to represent composition of functions, mirroring mathematical notation. This infix operations takes in two functions and returns an anonymous function. It can be useful and will mirror standard mathematical usage up to issues with precedence rules.\n\n:::\n\nStarting with two functions and composing them requires nothing more than a solid grasp of knowing the rules of function evaluation. If $f(x)$ is defined by some rule involving $x$, then $f(g(x))$ just replaces each $x$ in the rule with a $g(x)$.\n\n\nSo if $f(x) = x^2 + 2x - 1$ and $g(x) = e^x - x$ then $f \\circ g$ would be (before any simplification)\n\n\n\n$$\n(f \\circ g)(x) = (e^x - x)^2 + 2(e^x - x) - 1.\n$$\n\n\nIf can be helpful to think of the argument to $f$ as a \"box\" that gets filled in by $g$:\n\n\n\n$$\n\\begin{align*}\ng(x) &=e^x - x\\\\\nf(\\square) &= (\\square)^2 + 2(\\square) - 1\\\\\nf(g(x)) &= (g(x))^2 + 2(g(x)) - 1 = (e^x - x)^2 + 2(e^x - x) - 1.\n\\end{align*}\n$$\n\n\nHere we look at a few compositions:\n\n\n * The function $h(x) = \\sqrt{1 - x^2}$ can be seen as $f\\circ g$ with $f(x) = \\sqrt{x}$ and $g(x) = 1-x^2$.\n * The function $h(x) = \\sin(x/3 + x^2)$ can be viewed as $f\\circ g$ with $f(x) = \\sin(x)$ and $g(x) = x/3 + x^2$.\n * The function $h(x) = e^{-1/2 \\cdot x^2}$ can be viewed as $f\\circ g$ with $f(x) = e^{-x}$ and $g(x) = (1/2) \\cdot x^2$.\n\n\nDecomposing a function into a composition of functions is not unique, other compositions could have been given above. For example, the last function is also $f(x) = e^{-x/2}$ composed with $g(x) = x^2$.\n\n\n:::{.callout-note}\n## Note\nThe real value of composition is to break down more complicated things into a sequence of easier steps. This is good mathematics, but also good practice more generally. For example, when we approach a problem with the computer, we generally use a smallish set of functions and piece them together (that is, compose them) to find a solution.\n\n:::\n\n### Shifting and scaling graphs\n\n\nIt is very useful to mentally categorize functions within families. The difference between $f(x) = \\cos(x)$ and $g(x) = 12\\cos(2(x - \\pi/4))$ is not that much - both are cosine functions, one is just a simple enough transformation of the other. As such, we expect bounded, oscillatory behaviour with the details of how large and how fast the oscillations are to depend on the specifics of the function. Similarly, both these functions $f(x) = 2^x$ and $g(x)=e^x$ behave like exponential growth, the difference being only in the rate of growth. There are families of functions that are qualitatively similar, but quantitatively different, linked together by a few basic transformations.\n\n\nThere is a set of operations of functions, which does not really change the type of function. Rather, it basically moves and stretches how the functions are graphed. We discuss these four main transformations of $f$:\n\n::: {.cell execution_count=7}\n\n::: {.cell-output .cell-output-display execution_count=8}\n```{=html}\n\n
| Transformation | Description |
|---|---|
vertical shifts \n | The function \\(h(x) = k + f(x)\\) will have the same graph as \\(f\\) shifted up by \\(k\\) units. \n |
horizontal shifts \n | The function \\(h(x) = f(x - k)\\) will have the same graph as \\(f\\) shifted right by \\(k\\) units. \n |
stretching \n | The function \\(h(x) = kf(x)\\) will have the same graph as \\(f\\) stretched by a factor of \\(k\\) in the \\(y\\) direction. \n |
scaling \n | The function \\(h(x) = f(kx)\\) will have the same graph as \\(f\\) compressed horizontally by a factor of \\(1\\) over \\(k\\). \n |