```
using MTH229
using Plots
plotly()
```

`Plots.PlotlyBackend()`

A notebook for this material: ipynb

We load the `MTH229`

package and plotting package for this section:

```
using MTH229
using Plots
plotly()
```

`Plots.PlotlyBackend()`

This project explores the relationship between a function, \(f(x)\) and its first and second derivatives.

The following definitions describe features of functions over an interval:

- The function \(f(x)\) is
*positive*on an interval \(I=(a,b)\) if \(f(x) > 0\) for any \(x\) in \((a,b)\). - The function \(f(x)\) is
*increasing*(strictly) on an interval \(I=(a,b)\) if \(f(x) < f(y)\) whenever \(a < x < y < b\). - The function \(f(x)\) is
*concave up*on an interval \(I=(a,b)\) if any secant line between values \(x\) and \(y\) with \(a < x < y < b\) lies above the graph of \(f(x)\).

Note

There are similar definitions for *negative*, *decreasing*, and *concave down*.

You may be more familiar with these implications for functions with derivatives:

- An increasing function will have the property that any secant line connecting \(x\) and \(y\) with \(a < x < y < b\) will have positive slope.
- An increasing function on \(I\) that is differentiable has \(f'(x) \geq 0\) on \(I\).
- If \(f'(x)\) exists and is positive on \(I=(a,b)\), then \(f(x)\) is
*increasing*on \(I\). - If \(f'(x)\) exists and is increasing on \(I=(a,b)\), then \(f(x)\) is concave up on \(I\).
- If \(f''(x)\) exists and is positive on \(I=(a,b)\), then \(f'(x)\) is increasing on \(I\), and so \(f(x)\) is concave up on \(I\).

Positive and negative

Pay attention to the difference between positive and non-negative. For example, an increasing, differentiable function on *I=(a,b)* is only guaranteed to have a *non-negative* derivative – not a *positive* derivative on *I*.

A common task in this subject is identifying where a function is positive, negative, zero, or undefined.

A theoretical tool is the *intermediate value theorem* which can be used to say that a continuous function has only one sign (positive or negative) between adjacent zeros. That is, if \(a\) and \(b\) are zeros of \(f(x)\), a continuous function with say \(a < b\) and there is *no* \(c\) with \(a < c < b\) such that \(f(c) = 0\), then \(f(x)\) for \(x\) in \((a,b)\) is either always positive or always negative.

This gives a technique to identify where a function is *positive*:

- find all the zeros of \(f(x)\) and sort them in increasing order
- check the sign between adjacent zeros at
*one*point, a test point (often chosen conveniently to make evaluation easier). - Also check the sign to the left of the smallest zero and the right of the largest zero by using two test points.

Wherever one of the test points is positive, the interval between the two adjacent zeros will correspond to an interval where the function is positive.

If the function is not continuous, say at a finite set of points, then include the points of discontinuity in the consideration. In fact, only discontinuities where the function jumps over the \(y\) axis need consideration.

We can graphically identify when a function is positive with the strategy above. Consider the following function over the interval \([-2, 1]\):

\[ f(x) = e^{-x} \cdot (\sin(3x) + \sin(5x)). \]

A plot shows *roughly* that this function is positive between \(-2\) and \(-0.8\), save near \(-1.57\) where \(f\) is \(0\) and between \(0.0\) and \(0.8\).

```
f(x) = exp(-x) * (sin(3x) + sin(5x))
plot(f, -2, 1)
plot!(zero)
```

The `MTH229`

package loads a *convenience* function, `plotif`

, to show the graph of `f`

highlighting when a second function, `g`

is *nonnegative*. In this case, to see where `f`

is non-negative, we want `g`

to be `f`

:

`plotif(f, f, -2, 1)`

The `plotif`

function shows when `g`

is non-negative, not just positive, so wouldn’t show a different color for the graph near \(-1.57\) where `f`

is zero but doesn’t cross the \(x\) axis.

`find_zeros`

functionWe have discussed two means to find zeros of a function \(f\):

when the zero is

*between*two values which form a bracketing interval. The zero in the graph above between \(-1\) and \(-0.5\) is an example. Such zeros are readily identified through*bisection*when a zero is

*near*a value, such as these four which are near \(-1.5\), \(-0.75\), \(0.0\) and \(0.8\). Such zeros may typically be found with*Newton’s*method (or`find_zero`

)

The `Roots`

package, exported with `MTH229`

, provides a convenience function, `find_zeros`

, which uses bisection or `fzero`

to identify *heuristically* all zeros in an interval \([a,b]\). It is easy to use: the interval is specified by pairing off the interval:

`find_zeros(f, (-2, 1)) # note the s in find_zeros`

```
4-element Vector{Float64}:
-1.570796326120076
-0.7853981633974483
0.0
0.7853981633974483
```

The algorithm isn’t guaranteed to always work the way bisection is, but works fairly well to identify all the zeros except for cases where there are *many* zeros in the interval or the interval chosen is *too wide*. (A bracketing interval specified to bisection may be infinite, but such wide intervals can be problematic with `find_zeros`

, though can work in some cases.)

Here is another example, find the zeros of \(f(x) = e^x - x^4\) over \([-10, 10]\):

```
f(x) = exp(x) - x^4
find_zeros(f, -10, 10)
```

```
3-element Vector{Float64}:
-0.8155534188089606
1.4296118247255556
8.613169456441398
```

The above also shows the interval can also be specified using two values, as is done with `plot`

.

A related problem might be find all zeros of \(f(x) = e^x - x^6\). Where should one look to ensure all of the zeros are identified? Too big an interval and the values of \(e^x\) will be infinite (numerically) and that may cause problems. Too small an interval and zeros may be excluded. In this case a bit of analysis can help: any zero must be bigger than \(-1\), as to the left of \(-1\) the exponential is smaller than \(1\) and the polynomial bigger than \(1\) in absolute value. Further, as exponentials *eventually* dominate polynomials, the interval need not be too large. We could quickly check that \(e^{20}\) is bigger than \(20^6\) but instead we just try a somewhat larger right limit:

```
f(x) = exp(x) - x^6
find_zeros(f, (-1, 50))
```

```
3-element Vector{Float64}:
-0.8656497043253173
1.2268886960394931
16.99888735229605
```

The algorithm used by `find_zeros`

relies on both bisection and a method like Newton’s method. The bisection implementation will pick up on places where the function changes sign, even if not continuous. In the example below, the two vertical asymptotes at \(3\) and \(4\) are found:

```
f(x) = (x-1)*(x-2) / ((x-3)*(x-4))
= find_zeros(f, -10, 10) zs
```

```
4-element Vector{Float64}:
1.0
2.0
2.9999999999999996
3.9999999999999996
```

The values at the `zs`

can easily be checked using broadcasting:

`f.(zs) # using the broadcasting syntax -- the dot.`

```
4-element Vector{Float64}:
-0.0
0.0
4.503599627370491e15
-1.351079888211149e16
```

Programmatically, the `filter`

function might be used to screen these out, or in this example a comprehension:

`in zs if abs(f(z)) <= 10] [z for z `

```
2-element Vector{Float64}:
1.0
2.0
```

However, for our usage below it is quite helpful that these points are identified.

`sign_chart`

functionThe technique above to find where a function is positive can be automated if `find_zeros`

is used to find the zeros. This is done in `sign_chart`

.

For example,

```
f(x) = exp(x) - x^6
sign_chart(f, -1, 20)
```

3-element Vector{NamedTuple{(:zero_oo_NaN, :sign_change)}}: (zero_oo_NaN = -0.865649704325, sign_change = - to +) (zero_oo_NaN = 1.22688869604, sign_change = + to -) (zero_oo_NaN = 16.9988873523, sign_change = - to +)

The output shows how the sign changes at the identified zeros (or other points). In this case we can infer that the function is positive on \((-0.8656\dots, 1.22688869\dots)\) and again on \((16.998887\dots, \infty)\).

Returning to the example function

`f(x) = exp(-x) * (sin(3x) + sin(5x))`

`f (generic function with 1 method)`

we apply `sign_chart`

over \((-2,1)\):

`sign_chart(f, -2, 1)`

4-element Vector{NamedTuple{(:zero_oo_NaN, :sign_change)}}: (zero_oo_NaN = -1.57079632612, sign_change = + to +) (zero_oo_NaN = -0.785398163397, sign_change = + to -) (zero_oo_NaN = 0.0, sign_change = - to +) (zero_oo_NaN = 0.785398163397, sign_change = + to -)

The output matches the graph produced above with `plotif`

. The zero at \(-1.57\dots\) does not have a sign change, the others do in agreement with the graph.

How many zeros are found between \(-2\) and \(1\) for

\[ f(x) = e^{-x/2} \cdot (\sin(11x) + \sin(13x)) \]

What is the largest value identified in \([-2,1]\) by `find_zeros`

for the function

\[ f(x) = e^{-x/2} \cdot (\sin(11x) + \sin(13x)) \]

For \(f(x) = e^{-x/2} \cdot (\sin(11x) + \sin(13x))\) Consider the output of `sign_chart(f, -2, 1)`

. What is the sign of \(f\) at \(-1\)?

Consider \(f(x) = \sin(3x) + \sin(5x)\) over \([-2, 1]\). What does `sign_chart`

identify at the *smallest* zero?

As seen, the `plotif`

function loaded with the `MTH229`

package makes it easy for us to highlight when a function is non negative, as it shows in a separate color when the second function is non-negative.

For example, consider \(f(x) = x^3 - 2x - 1/2\).

This graph shows where \(f(x)\) is positive over \((-2,2)\):

```
f(x) = x^3 - 2x - 1/2
plotif(f, f, -2, 2)
plot!(zero)
```

In this graph, we estimate graphically that the intervals \((-1.2, 0.2)\) and \((1.5, 2)\) are where \(f\) is positive within this viewing window.

If we change the screening function to the derivative of \(f(x)\), then our graph will show when the function is increasing (or flat):

`plotif(f, f', -2, 2)`

Again, we eyeball from the graph to estimate that this occurs on \((-2, -0.8)\) and \((0.8, 2)\).

Using when the second derivative is non-negative indicates where `f`

is concave up:

`plotif(f, f'', -2, 2)`

We can see the function is concave up on \((0, 2)\) and changes concavity at the inflection point \(x=0\).

Graphically identify when the function \(f(x) = x^x\) is increasing on \((0,2)\)

Graphically identify when the function \(f(x) = \sqrt{|1 - x^2|}\) is increasing on the interval \([-2, 2]\).

Graphically identify when the function \(f(x) = x^2 \cdot e^{-x}\) is concave up on the interval \((0,10)\).

Consider the function below:

`f(x) = x < -1 ? -x - 1 : x > 1 ? x - 1 : 0`

What does the output of `plotif(f, f', -5, 5)`

show?

The `find_zeros`

function can readily identify when some function is zero (or undefined). It can be used, as seen, to find zeros. However, if passed `f'`

it will identify critical points. When passed `f''`

it will find when \(f''(x) = 0\) (or undefined). Such points are *candidates* for inflection points, though a check on whether the concavity changes is necessary to say such is an inflection point.

In the following we use `scatter!`

to show these values on the graph.

```
f(x) = exp(-x/2) * (sin(3x) + sin(5x))
= find_zeros(f, -2, 1)
zs = find_zeros(f', -2, 1)
cps = find_zeros(f'', -2, 1)
ips
plot(f, -2, 1)
scatter!(zs, f.(zs), markercolor="blue", markersize=7)
scatter!(cps, f.(cps), markercolor="red", markersize=3)
scatter!(ips, f.(ips), markercolor="green", markershape=:diamond)
```

An attempt to distinguish the points using color, marker size and shape is made, showing that the value at \(-1.5707963267\dots\) is both a zero and a critical point.

The graph also shows that the candidates for inflection points are indeed inflection points. This could also be verified with `sign_chart`

where the second derivative changes sign at each:

`sign_chart(f'', -2, 1)`

5-element Vector{NamedTuple{(:zero_oo_NaN, :sign_change)}}: (zero_oo_NaN = -1.86089851657, sign_change = - to +) (zero_oo_NaN = -1.33370970092, sign_change = + to -) (zero_oo_NaN = -0.739296253922, sign_change = - to +) (zero_oo_NaN = -0.0524780565601, sign_change = + to -) (zero_oo_NaN = 0.645452569404, sign_change = - to +)

Suppose we only know indirect things about a function \(f(x)\), how much can we say?

We previously mentioned two basic relationships:

If \(f'(x) > 0\) on an interval \((a,b)\) then the function \(f(x)\) is

increasingon \((a,b)\). (It may also increase when \(f'(x)=0\), but it isn’t guaranteed.)

If \(f''(x) > 0\) on \((a,b)\) then the function \(f(x)\) is

concave upon \((a,b)\).

Similar statements can be made for negative values of the derivative and second derivative.

For example, lets suppose we know that the derivative of \(f(x)\) is \(f'(x) = \exp(x)\). What can we say about \(f(x)\) on the interval \((0,4)\)?

We make two graphs:

```
fp(x) = exp(x)
plotif(fp, fp, 0, 4)
```

`plotif(fp, fp', 0, 4)`

From the graphs we see that \(f'(x)\) is always *positive* and *increasing*.

From the first fact (\(f'(x) > 0\)) we know that \(f(x)\) is increasing on this interval.

From the second fact (\(f'(x)\) is increasing) we know that \(f(x)\) is concave up on this interval.

Do we know any specific values, or even less ambitiously, when \(f(x)\) is positive? The answer must be *no* – we could always add a constant to \(f(x)\) and not effect its derivative.

Now suppose we have a different \(f(x)\). In this case all we know is the second derivative is \(f''(x) = x^2 - 2x\). What can we say about \(f(x)\) on the interval \((-1,3)\)?

A plot to see where the second derivative is positive will show that this \(f''(x)\) is positive on \((-1, 0)\) and \((2,3)\):

```
fpp(x) = x^2 - 2x
plotif(fpp, fpp, -1, 3)
```

This means \(f(x)\) is concave up on these same intervals.

Can we tell if our unknown \(f(x)\) is increasing? Nope, we have no such ability. We could always add a term \(mx\) to \(f(x)\) and keep the same second derivative. So we *can’t* tell if the function \(f(x)\) is increasing and we *can’t* tell where the function \(f(x)\) is positive, but we **can** say where it is concave up when we all we know is a second derivative.

You know that \(f'(x) = |x|\). Over \([-1,1]\) where if \(f(x)\) increasing and where is it concave up?

Suppose \(f'(x) = (x^4 - x^2 + 2)/(x^4 - 2x^2 + 1)\). When is \(f(x)\) increasing on \((-2, 2)\)?

If \(f'(x) = \tan(x) - 3x/2\). When is \(f(x)\) concave down on the interval \((-\pi/3, \pi/3)\)?

The first- and second-derivative tests are a means to classify if a critical point is also a local extrema. A local extrema will always correspond to a critical point – but not necessarily vice versa. There are two theorems that ensure a critical point will be a local extrema:

The first derivative testIf \(c\) is a critical point

and\(f'(x)\) changes sign at \(x=c\), then \((c,f( c))\) will be a local extrema. (If the sign change is from positive to negative, it will be a local maximum.) If there isnosign change, the critical point isnota local extrema.

The second derivative testIf \(c\) is a critical point

and\(f''(x) \neq 0\) then \((c,f( c))\) will be a local extrema. If \(f''( c) > 0\) this will be a local minimum and if \(f''( c) < 0\) a local maximum. (Nothing conclusive can be said when \(f''(c)=0\).)

For example, let \(f(x) = 2\sin(x) + \cos(2x)\). Find all critical points on \([0, 2\pi]\).

As \(f(x)\) is everywhere differentiable, these critical points would be where the derivative is \(0\). A plot helps us identify how many and roughly where:

```
f(x) = 2sin(x) + cos(2x)
plot(f', 0, 2pi)
```

We see four: one near \(0.8\), one near \(1.5\), one near \(2.5\) and one near \(5\).

As explained, we could use `find_zeros`

to identify these more precisely:

`= find_zeros(f', 0, 6) cps `

```
4-element Vector{Float64}:
0.5235987755982988
1.5707963267948966
2.617993877991494
4.71238898038469
```

From the graph of `f'`

we can see at the first critical point the derivative is changing sign from positive to negative at the first one (hence a local maximum), and this alternates as we go along.

However, we can do this numerically, using the `sign_chart`

function.

`sign_chart(f', 0, 4)`

3-element Vector{NamedTuple{(:zero_oo_NaN, :sign_change)}}: (zero_oo_NaN = 0.523598775598, sign_change = + to -) (zero_oo_NaN = 1.57079632679, sign_change = - to +) (zero_oo_NaN = 2.61799387799, sign_change = + to -)

So by the first derivative test we have a max, min, max, min which we see when we plot `f`

:

`plot(f, 0, 2pi)`

To get the same classification from the second derivative test, we evaluate \(f''(x)\) at these four critical points:

`''.(cps) f`

```
4-element Vector{Float64}:
-3.0000000000000004
2.0
-2.9999999999999982
6.0
```

Where using the dot broadcasts `f''`

over all the values in `cps`

.

The following graphic is to illustrate why the second derivative test works as it does:

```
plot(f, 0, 2pi; legend=false, linewidth=4)
= find_zeros(f', 0, 2pi)
cps plot_parabola!(c, fc, fppc) = plot!(x -> fc + fppc * (x - c)^2/2, c-3/4, c+3/4; linewidth=2)
plot_parabola!.(cps, f.(cps), f''.(cps))
current()
```

Each critical point is matched with a parabola with quadratic term one-half the second derivative. We can see at a relative minimum, then the parabola opens upward just like the graph of `f`

; at a relative maximum, the approximating parabola opens downward.

Let \(f'(x) = x^4 - 4x^2 + 1\). Classify all relative extrema of \(f(x)\) on the interval \((-1, 1)\).

Let `fp(x) = (2x-1)/cbrt(x^2 - x - 2)^2`

. Over the interval \((-1.5,1.5)\) identify all relative maxima and minima of \(f(x)\).

Suppose, \(f(x)\) has a critical at \(0\) and \(1\). If possible, classify them as relative maximum or minimum assuming \(f''(x) = 1 - 2x - \sin(x)\)

Environment of

`Julia`

when generated
`Julia`

version:

`VERSION`

`v"1.10.4"`

Packages and versions:

```
using Pkg
Pkg.status()
```

```
Status `~/work/mth229.github.io/mth229.github.io/Project.toml`
[a2e0e22d] CalculusWithJulia v0.2.6
[7073ff75] IJulia v1.25.0
[b964fa9f] LaTeXStrings v1.3.1
[ebaf19f5] MTH229 v0.3.2
[91a5bcdd] Plots v1.40.4
[f27b6e38] Polynomials v4.0.11
[438e738f] PyCall v1.96.4
[612c44de] QuizQuestions v0.3.23
[295af30f] Revise v3.5.14
[f2b01f46] Roots v2.1.5
[24249f21] SymPy v2.1.1
[56ddb016] Logging
```