47 Operations on functions
Block 1 introduced the idea of mathematical modeling: creating a representation of some aspect of the world out of mathematical “stuff.” The relevant “stuff” includes the concept of a function with its inputs and output, units and dimensions of quantities, frameworks such as the basic modeling functions and ways of combining functions via linear combination, composition, and multiplication.
Our emphasis in calculus has been and will continue to be functions. This contrasts with high-school algebra where the emphasis was on equations and manipulations such as the movement of quantities from one side of the equal sign to another.
It pays to think a little about what equations mean and what information they are intended to convey. Consider an equation like
A simple equation like
“Find
“Solve for
This chapter looks at a small list of mathematical tasks, calling them operations on functions. These operations, combined in various ways, enable you to extract relevant information from the functions you build in your models. A simple important part of this introduction is to give a name to each task. That way, confronted with a mathematical problem, you will be able to look down the short mental menu of opertions to decide which ones are applicable to your circumstance. Even better, once each operation has a name, you can tell a computer to do it for you.
Here are four common mathematical tasks that you’ve already encountered in Blocks 1 through 3 of this book:
- Given a function and specific values for the inputs, apply the function to the inputs to produce an output. This is also called evaluating a function on inputs.
- Given a function and the name of a with-respect-to input, construct a new function that is the derivative of the given function. The name for this task is to differentiate the function.
- Like (2), given a function and the name of a with-respect-to input, anti-differentiate the function.
- Given a function and an interval of the domain of that function, accumulate the function on that interval. This is named to integrate the function on the interval. (You may recognize that you can perform this task by breaking it down into task (3) and then applying task (1) twice to the result. That is,
.)
In this chapter, we focus on the following operations on functions that you may not yet have mastered.
- Given a function and an output value from the function, find values for an input (or inputs) which will generate that output value. This is the solving task. A closely related task is zero-finding, which is to find an input that will cause the function to produce the output zero.
- Given a function and an interval of the domain, find an input value that will produce an output value that is higher than would be produced for nearby inputs. As you might recognize, this is called finding an argmax. The problem of finding an argmin is the same kind of problem, and can be solved by finding the argmax of the negative of the function.
- Given a function and an input value, iterate the function to produce a new input that will be better than the original for some purpose.
These seven tasks allow you to perform the mathematical work of extracting useful information from a model. Human judgement and creativity is needed to construct the model. And judgement and experience is needed to figure out which tasks to perform and in what order. But carrying out the tasks does not require judgement, experience, or creativity. Performing the tasks requires only an algorithm and the tools to step through the algorithm. Computers are excellent for this; you just have to give them the function and whatever additional input is required (e.g. the name of a with-respect-to input), and then tell the computer which task it is to perform.
47.1 Task: Solve
Starting materials:
- a function
,
- a known output value
, and
- a candidate for a suitable input value
Ideal result from the algorithm: A new candidate
Realistic result from the algorithm: The new candidate
One algorithm for the operation involves approximating the function
You saw in Block 2 how to construct the straight-line approximation to a function
Because
Although
This (hopefully) improved solution
Each round of improvement—that is, “iteration”—calculates a new value solve_step()
:
This particular form of solve_step() is called a Newton step. The idea is to take successive steps, each refining the previous approximation, to get closer and closer (hopefully!) to the actual answer
Construct the Newton-step function for finding zeros of the function
Since
The algorithm requires a starting guess. We will use solve_step()
, we will print out the refined value as well as the function output at that refined value.
<- 2
x0
<- solve_step(x0)
x1 f(x1)
## [1] 4.444444
<- solve_step(x1)
x2 f(x2)
## [1] 4.010519
<- solve_step(x2)
x3 f(x3)
## [1] 4.000006
The output
After the first Newton step, producing
Newton’s method involves creating a custom solve_step()
function for each new problem. The process is simple enough that we can create such functions automatically:
<- function(tilde, v) {
make_solve_step_fun <- makeFun(tilde)
f <- D(tilde)
df <- function(z) {z + (v-f(z))/df(z)}
custom_fun
return(custom_fun)
}
Let’s test it out with this function:
<- makeFun(x^2 - x ~ x) f
Construct the take-a-step function:
<- make_solve_step_fun(f(x) ~ x, v=4) take_step
Take three steps starting at
<- 3
x0 <- take_step(x0)
x1 <- take_step(x1)
x2 <- take_step(x2)
x3 f(x3)
## [1] 4
The Newton-step process is not guaranteed to work. By exploring cases where it fails, computational mathematicians1 have developed strategies for increasing the range of situations for which it works. Some of these strategies are incorporated in the R/mosaic function Zeros()
.
Zeros()
takes two arguments: a function and a domain. The function is specified, as with other R/mosaic operators such as D()
, slice_plot()
, etc., as a tilde expression. Zeros()
searches the domain for an input which makes the value of the function zero. If, instead, you want to find an input that makes the function value some other value, say f(x) - v ~ x
. Finding the zero of the intermediate function corresponds to finding
Sometimes there will be multiple zeros on the specified domain. To handle such situations, Zeros()
returns a data frame with two columns. The first gives input values that correspond to an output near zero. The second column, named .output.
calculates the output (and will be near zero). We will illustrate by solving
Zeros(x^3 - 6 ~ x, bounds(x=c(1,6)))
## # A tibble: 1 × 2
## x .output.
## <dbl> <dbl>
## 1 1.82 0.000000203
47.2 Task: Argmax
The task of finding the input value that corresponds to a local maximum is called argmax finding. We don’t need to know the value of the local maximum to solve this problem. Instead, we designate a locale by specifying an initial guess
To accomplish this, we will approximate
Remember that
}1} +
f’’(x_0) _{2 } = 0
$$
This gives
In other words, our new guess
Use the R/mosaic argM()
function to find argmaxes and argmins. Like other R/mosaic calculus functions, the first argument is a tilde expression defining the objective function. The second argument is the domain to search.
To illustrate, the following code creates a randomly shaped function (displayed in ?fig-argm-ex1) and calls argM()
to generate the argmaxes and argmins.
<- rfun(~ x, 3215) f
argM(f(x) ~ x, bounds(x = -5:5))
## # A tibble: 2 × 3
## x .output. concavity
## <dbl> <dbl> <dbl>
## 1 1.03 -26.5 1
## 2 -2.95 3.80 -1
Notice that argM()
identified both a local maximum and a local minimum, that is, one argmax and one argmin. Visually, it is easy to tell which one is which. In terms of the data frame returned by argM()
, the sign of the concavity does the identification for you: positive concavity points to an argmin, negative concavity to an argmax. The name argM()
refers to this versatility of finding both argmins and argmaxes.
47.3 Task: Iterate
In everyday language, to iterate means simply to repeat: to do something over and over again. In mathematics and in computing, “iterate” has a more specific meaning: to repeatedly perform an operation, each time taking the output from the previous round as the input to the current round.
For our purposes, it suffices to define iteration in terms of the use of a function
Or, you might choose to iterate for ten steps:
However many iteration steps you take, the output from the final step is what you work with.
Iteration is the mathematical engine behind many function operations. You’ve already seen it at work for the “solve” task and the “argmax” task.
The R/mosaic function Iterate()
provides a very simple way to see the results of iteration. Typically when iteration is used as part of a function operation, the software has been written specifically for that task and includes logic about when to stop or start over or handle a variety of troublesome cases. The function Iterate()
is provided in R/mosaic just for demonstration purposes.
Iterate()
takes arguments specifying the function to be iterated (as a tilde expression), the starting
Eventually reaching a fixed point: ::: {.cell layout-align=“center” fig.showtext=‘false’}
Iterate(2*x*(1-x) ~ x, x0=0.3, n=10)
## n x
## 1 0 0.3000000
## 2 1 0.4200000
## 3 2 0.4872000
## 4 3 0.4996723
## 5 4 0.4999998
## 6 5 0.5000000
## 7 6 0.5000000
## 8 7 0.5000000
## 9 8 0.5000000
## 10 9 0.5000000
## 11 10 0.5000000
Eventually reaching a periodic oscillation: ::: {.cell layout-align=“center” fig.showtext=‘false’}
Iterate(3.2*x*(1-x) ~ x, x0=0.3, n=50) |> tail()
## n x
## 46 45 0.5130445
## 47 46 0.7994555
## 48 47 0.5130445
## 49 48 0.7994555
## 50 49 0.5130445
## 51 50 0.7994555
:::
A never-ending, random-seeming fluctuation, called mathematical chaos:
Iterate(4.0*x*(1-x) ~ x, x0=0.3, n=5000) |> tail()
## n x
## 4996 4995 0.56824790
## 4997 4996 0.98136889
## 4998 4997 0.07313595
## 4999 4998 0.27114833
## 5000 4999 0.79050766
## 5001 5000 0.66242119
:::
47.4 Software for the tasks
Evaluation of a function—number one in the list at the head of this chapter—is so central to the use of computer languages generally that every language provides a direct means for doing so. In R, as you know, the evaluation syntax involves following the name of the functions by a pair of parentheses, placing in those parenthesis the values for the various arguments to the function. Example: log(5)
The other six operations on functions listed above, there is one (or sometimes more) specific R/mosaic functions. Every one of them takes, as a first argument, a tilde expression describing the function on which the operation is to be formed; on the left side is a formula for the function (which can be in terms of other, previously defined functions), on the right side is the with-respect-to input.
- Differentiate:
D()
. Returns a function. - Anti-differentiate:
antiD()
. Returns a function. - Integrate:
Integrate()
. Returns a number. - Solve:
Zeros()
. Returns a data frame with one row for each solution found. - Argmax:
argM()
Finds one argmax and one argmin in the domain.local_argM()
looks for all the local argmaxes and argmins. Returns a data frame with one row for each argmax or argmin found. - Iterate:
Iterate()
Returns a data frame with the value of the initial input and the output after each iteration.
Each of operations 4-6 involves the specification of a domain. For Integrate()
, this is, naturally, the domain of integration: the upper and lower bounds of the integral
For Zeros()
and argM()
the domain specifies where to search for the answer. Iterate()
is slightly different. After the tilde expression comes an initial value n=
which you use to set the number of times to iterate.
47.5 Exercises
Exercise 47.01
Create a function, which iterated sufficiently from a starting guess, will implement Newton’s method to calculate
Part A Which of these functions is appropriate to use in Newton’s method for calculating
Now you will translate
Part B What is the function
Part C Which of these is the correct form for the Newtons-method iterator
In a SANDBOX, implement
Part D Using
5.5 3.659091 3.141593 3.196005 3.162456 3.162354 3.162278
Part E Modify N()
to find N()
to get an answer right to within 1% of the true number?
- After 2 steps we get 4.202
- After 3 steps we get 4.713.
- After 3 steps we get 4.472.
- After 4 steps we get 4.472.
- After 4 steps we get 4.478.
Part F Modify your N()
once again to find
2.154 2.320 2.875 2.912
Exercise 47.03
- Write a Newton-step
better()
function to solve for in the equation . Start with the guess and iteratebetter()
enough times to get .
To help, we will give the hint that
- Suppose we hadn’t told you the answer
. How could you know, just from your iterations ofbetter()
, that you are very close to the true answer.
Exercise 47.04
We introduced Newton’s method as a technique for finding zeros of functions. For instance, for finding zeros of
A. Suppose your goal is not to find a zero of
B. Imagine that
C. Taking into account the dimension of the input
Exercise 47.05
Part A Which of the following R/mosaic functions takes an initial condition as one of the inputs?
antiD()
D()
Iterate()
Part B Which of the following R/mosaic functions requires that you specify a domain as one of the inputs to the function?
antiD()
D()
Iterate()
Solve()
Part C The R/mosaic functions Solve()
and argM()
return what kind of computer object?
a number a function a graph a data frame
Exercise 47.06
A simple robot arm to move things in the
Each link is moved by a digitally-controlled motor. To position the robot, commands are sent to the two motors to set their respective angles. For instance, in the diagram the motor-1 angle,
The problem faced by the robot designer is to allow the user to input a series of
For simplicity, assume that the link lengths are both
At this point, play with the problem a bit. Mark a point on your desk or paper. This will be the location of the base of the robot. Take two pencils, let’s call them “yellow” and “green,” putting the eraser of yellow at the base location and the eraser of green at the tip of yellow. Now, pick another point on your desk or paper to be the target for the robot arm. (This must be closer to the base than the sum of lengths of the two pencils.) Change the orientation of the pencils, keeping yellow attached to the base and green attached to the tip of yellow. Your job is to find an orientation that will place the tip of green on the target. Try different target points until you feel comfortable that you understand how to solve the problem.
Now to create a mathematical model of the situation so that we can automate the solution. The purpose of this model is to find
From your experience using pencils as the model of the robot, you may have noticed that the location of the “elbow” of the robot arm is key to the solution. Find the right position for the elbow and the angles can be calculated from trigonometry.
Note that the position of the elbow, which we will denote with coordinates
Write down a formula for the
and for the position of the elbow as a function of (taking the base as the origin). Hint: sine and cosine functions are relevant.Implement the formulas from (1) into two functions, one called
elbow_u(theta1)
and the otherelbow_v(theta1)
.Write another function,
elbow_to_target_dist(theta1, x, y)
that will useelbow_u()
andelbow_v()
to calculate the distance from the elbow to the target point . (The distance will be .)Write yet another function,
dist_at_theta(theta1, x, y)
that, given an angle theta, will return the distance from the elbow to the target. The logic is to useelbow_u()
andelbow_v()
to find the location of the elbow and and then give these as the argments toelbow_to_target_dist()
.The next phase of the solution is to use
elbow_to_target_dist(theta1, x, y)
to find a value oftheta1
that will make the distance equal to the length of link2. When you have found thistheta1
, you will know the position of the elbow that is consistent with reaching the target from the base with the two links.- Pick a target location. This can be anything within distance
from the base. We will call the coordinates of your targettarget_x
andtarget_y
. - Plot out
elbow_to_target_dist(theta1, x=target_x, y=target_y)
as a function oftheta1
over the domain . - Locate a value of
where the output of the function is .
- Pick a target location. This can be anything within distance
Write another function,
elbow_theta1(x, y)
that takes the position as input and produces as output suitable value(s) of . To do this within theelbow_theta1(x, y)
function, useZeros(dist_at_theta(theta1) - L, bounds(theta1=-pi:pi))
.
A traditional name for such a person is “numerical analyst.”↩︎