3080project2 Loops
3080project2 Loops
Amy Nguyen
January 2025
Contents
Problem 1 1
Problem 2 1
Problem 3 2
Problem 1
Write a function that takes a variable number of arguments and prints them with each of the inputs separated
by a new line. (Hint: There is a special character, \n, that represents new lines. The following code should
suggest what to do: cat("hello", "awesome", "world", sep = "\n"))
## hello
## awesome
## world
Problem 2
Write an infix operator that represents logical XOR. In logic, x xor y is true if only one of either x or y are
true; if neither are true or both are true, then it’s false. The following function implements XOR:
Write the infix operator %xor% that allows for the syntax x %xor% y.
1
# Your code here
TRUE %xor% TRUE
## [1] FALSE
## [1] TRUE
## [1] TRUE
## [1] FALSE
## [1] FALSE
## [1] TRUE
## [1] TRUE
## [1] FALSE
Problem 3
Newton’s method is a numerical root-finding technique; that is, given a function f , the objective of the method
is to find an input x such that f (x) = 0. We call such an x a root. The method is iterative. We start with
an initial guess x0 . The algorithm then produces new approximations for the root x via the formula:
f (xn )
xn+1 = xn − .
f ′ (xn )
We need a rule for stopping the algorithm, and we could either stop at some fixed N or when |xn+1 − xn | < ϵ
for some user-selected ϵ > 0. (This represents some tolerable numerical error.)
In this project you will write a function implementing Newton’s method; call the function newton_solver().
Based on the above description this function must take at least the following inputs:
2
• An initial x0 ;
• A function f ;
• The function’s derivative f ′ ;
• A maximum number of iterations N ; and
• A desired numerical tolerance ϵ.
(One may think we need either ϵ or N but in practice we should always have N to ensure the algorithm
terminates.)
We will add additional behavioral constraints to the function.
• There will be a loop where the update algorithm is applied. This loop should terminate immediately if
the numerical tolerance threshold is met; this can be achieved via an if statement and break. But if
the loop hits N iterations, the function should throw a warning.
• f and f ′ should be functions. They should return univariate numeric values. If there ever comes a
time where the input functions don’t return a single number, then newton_solver() should throw an
error.
• It’s possible that f ′ (xn ) could become zero and then a division-by-zero error will occur. newton_solver()
should stop with an error informing the user that the derivative became zero.
• We could have our function return a list with detailed information not just with the obtained root but
also with the value of f at the root or how many iterations of the algorithm went through. But instead,
we will just have the function return the obtained root.
• The maximum number of iterations N should be a positive number; the same should be said for ϵ. If
not, an error should be thrown.
3
x_current <- x0 #Initialize the starting guess
The following code tests whether newton_solver() works as specified. BEWARE: IF THIS CODE
DOES NOT RUN AS ANTICIPATED OR TAKES LONGER THAN 10 SECONDS TO RUN,
YOU WON’T RECEIVE CREDIT!
## [1] 0.0006103516
## [1] -0.0006103516
4
# The following code should produce errors if the function was written correctly
newton_solver(f1, fprime2, x0 = 10)
## Error in newton_solver(f1, fprime2, x0 = 10): The derivative became zero. Cannot continue.
## Error in if (abs(x_next - x_current) < eps) {: the condition has length > 1
# The following code should produce warnings if the function was written
# correctly
newton_solver(f1, fprime3, x0 = 10, N = 2)
## [1] -8190
2. Use newton_solver() to maximize the function g(x) = 1 − x2 . Simple calculus should reveal that
the maximum is g(0) = 1. Maximizing g requires finding a root for g ′ , since the maxima/minima of
differentiable functions occurs where g ′ (x) = 0. Compare the answer obtained by newton_solver() to
the known analytical result.
# Function to maximize
g <- function(x) {1 - xˆ2}
## [1] 1
5
# Calculating the maximum value of g at the root
max_value <- g(root)
print(max_value)
## [1] -2.79794e-11
ex = −x
print(root)
## [1] -0.5671433
print(f(root))
## [1] 0