Homework #8#
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.
File I/O : Update your projectile motion code from the previous homework (Homework #7) to write the output to a file. Have your
mainfunction do the integration for both \(C=0\) and \(C=0.3\), writing each integration to a separate file.Lambda practice : Consider the following code:
#include <iostream> #include <algorithm> #include <vector> #include <cmath> bool is_perfect_square(int x) { int xroot = static_cast<int>(std::sqrt(x)); return x == xroot * xroot; } int main() { std::vector<int> vec{1, 5, 9, 16, 21, 32, 36, 49, 60, 64}; auto num = std::ranges::count_if(vec, is_perfect_square); std::cout << "there are " << num << " perfect squares in vec" << std::endl; }
This counts how many elements in the vector
vecare perfect squares, using the std::ranges::count_if algorithm.Rewrite this code to using a lambda function (review Lambda Functions) in the
std::ranges::count_ifcall, in place of theis_perfect_squarefunction above.Transforming : std::ranges::transform takes a range (vector for us), an output iterator (where to start writing the result), and an operator (the function to apply to each element).
For instance, given a vector
vofdouble, we could do:std::ranges::transform(v, v.begin(), f)
where
fis a function of the formdouble f(double e), and the result would be to applyf(e)to each element,e, ofv, updating our vector in-place.Let’s use this to convert a vector of indices into \(x\) values.
Start with:
std::vector<double> is{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
and define \(x_\mathrm{min} = 1\), \(x_\mathrm{max} = 2\), and \(\Delta x = (x_\mathrm{max} - x_\mathrm{min}) / (N-1)\), where \(N\) is the number of elements in the vector.
Now, apply the transformation: \(f(e) = x_\mathrm{min} + e \Delta x\) to the vector, using
std::ranges::transform.Note
You can use either a standard C++ function or a lambda-function for \(f(e)\).
Finally, loop over the vector and output the updated elements.
Bounds : An operation we often want to do is search through a sorted list of numbers and find the interval that contains an desired value. This comes up in interpolation, for example.
Consider the following vector:
std::vector<double> temp_vec{0.1, 0.2, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 7.5, 10.0};
For a value
T0, we want to find the index into the vector,i, such thattemp_vec[i-1] < T0 <= temp_vec[i]. We can get an iterator totemp_vec[i]using std::ranges::lower_bound.Note
There is a similar function,
std::ranges::upper_bound—they differ only in how they handle the case where we are searching for a value that is in our vector:std::ranges::lower_boundreturns an iterator to the first element \(\ge\)T0std::ranges::upper_boundreturns an iterator to the first element \(>\)T0
Write a code that finds the index for:
T0 = 1.2T0 = 3.0—note: this is one of the data points in the vector.
Tip
You’ll want to use
std::distanceto convert the iterator into a distance from the beginning of the container, just like we did in class.Also check what happens in the case that our
T0is out of the limits of ourtemp_vecby finding the index for:T0 = 0.05T0 = 20