Homework #6#
Completing this assignment
For the each of the problems below, write a separate C++ program
named in the problem problemN.cpp, where N is the
problem number.
Important
Make sure your that g++ can compile your code. For some of
the problems here, you will need to use -std=c++20.
Upload your C++ source files (not the executables produced by g++) to Brightspace.
Important
All work must be your own.
You may not use generative AI / large-language models for any part of this assignment.
Function practice I :
Let’s understand different ways that functions can return information. We want to write a function that accepts a
doubleand simply squares it.Our first version, called
square1should accept ourdoubleand return a new double via areturnstatement. So we would call it as:double x{2.0}; double xsq = square1(x);
Note that
xis unchanged here.Our second version, called
square2, will update the data passed in as an argument, with no return value. So we would call it as:double x{2.0}; square2(x);
Note that
xis changed here, and is now \(x^2\) after calling the function.
Function practice II :
In Homework #4, we found the maximum element of a vector. Let’s rewrite that now. We’ll do two slightly different concepts.
Create a function of the form:
double max_element(const std::vector<double>& vec)
That takes a vector,
vec, and returns the maximum value in the vector.Tip
We are taking the vector here as a
constreference. This avoids a potentially expensive copy (so it performs better), but still prevents us from modifying the contents of the vector.Now, let’s instead write a function that returns the index into the vector that contains the maximum element. This function should be:
int max_index(const std::vector<double>& vec)
which returns the index into
vecthat represents the maximum element. E.g.,int idx = max_index(vec);
would tell us that the maximum element in
vecisvec[idx].Tip
Instead of using a ranged-for loop over the vector, you should loop using and integer representing the index, like:
for (int i = 0; i < static_cast<int>(vec.size()); ++i) { // do stuff }
and then you can access the current element of the vector as
vec[i]inside the loop. You will also need to keep track of which index has the maximum element as you go through the loop—you will need to figure out that logic on your own.
Test both of your functions using the same vector as used in Homework 4. You can also (optionally) test this by doing:
double max_val = max_element(vec); int idx = max_index(vec); if (vec[idx] == max_val) { std::cout << "our functions agree" << std::endl; }
Centered difference :
At the end of our discussion on derivatives, we saw the sec:centered-diff. Let’s code this up and explore the error.
We’ll call this discrete approximation to the derivative \(D^c(x)\), so:
\[D^c(x) = \frac{f(x + \Delta x) - f(x - \Delta x)}{2\Delta x}\]Consider the derivative of \(f(x) = \sin(x)\) at \(x=1\).
Compute the centered difference approximation for \(\Delta x = 0.1\), \(0.05\), \(0.025\), and \(0.0125\), and make a table giving \(\Delta x\), \(D^c(x)\), and the error compared to the analytic solution, \(e \equiv |f^\prime(x) - D^c(x)|\).
Your implementation should:
Use C++ functions for \(f(x)\) and \(f^\prime(x)\)
Use a C++ function for \(D^c(x)\) that takes a function as an argument (\(f(x)\)), using the
std::function<>method we discussed in Passing a Function to a Function.Use
std::format()to make the columns line up for the output done with each \(\Delta x\).
Tip
You should see the error drop by a factor of 4 each time \(\Delta x\) is cut in half.