Table of Contents

Getting Started

Verify your Name

For this part of the assignment, you should build and run the code in the file assignment0.cpp.

This program will output information generated by the embedded Catch2 test (please read about testing if you have not done so yet). The output will say that your test failed - don’t panic, that is expected. Your task in this assignment will be to make the test pass.

Please note that the program output will be shown in the Terminal window of VSCode.

First, please edit the source code by replacing the string "<your name>" with your name, e.g. "John Doe". Rebuild and rerun the code. The test will still fail, but now it will print the expected value for your name:

FAILED:
  CHECK( base64_encode("John Doe") == "<base64 encoding of your name>" )
with expansion:
  "Sm9obiBEb2U="
  ==
  "<base64 encoding of your name>"

The program generated a hash code that corresponds to your name. That hash code is a special character sequence associated with your name. You can think of your hash code as a “fingerprint” associated with your name that’s unlikely to be the same as anyone else’s fingerprint (in the example above: "Sm9obiBEb2U="). Write this code down; you’ll need it to complete the assignment!

The last step is to replace the string "<base64 encoding of your name>" with this generated code. Rebuild and rerun the assignment program. The test should pass now:

All tests passed (1 assertion in 1 test case)

std::vector

The C++ standard library contains a number of basic data structures – lists, arrays, hash maps, etc. The data structure that will be our workhorse (though we will be wrapping it up in other data structures) is std::vector.

The std::vector is a generic container – meaning it can hold data of any type. However, as we mentioned in lecture, C++ is a compiled and strongly typed language. The generic container can hold any type – but we have to specify the type to the compiler. To create a vector of integers with ten elements, we would use the statement

std::vector<int> x(10);

The type that the vector is holding is specified in the angle brackets; the size of the vector we are creating has 10 elements.

Elements of a std::vector are accessed with square brackets:

int a = x[3];

assigns the value of the element at index 3 to the variable a.

Note that I did not call x[3] the third element! That’s because it is actually the fourth element. This might seem strange at first. Many other programming languages, especially those intended for mathematical operations use “one-based” indexing, meaning the first element is at index location 1. C and its derivative languages, however, use “zero-based” indexing, meaning the first element is at index location 0. Again, this might seem strange and non-intuitive. However, what an index in C++ is specifying is not the ordinality of the element, but rather the distance the element is from the beginning of the vector (or array). Thus the first element, which is at the beginning, is distance zero from the beginning and so is indexed as x[0].

In C++, zero is the indexing base and the base of the indexing is zero.

We can loop through a vector from beginning to end using the square bracket notation:

for (int i = 0; i < 10; ++i) 
{
    x[i] = 2 * i;
}

This loop specifies to assign values 0 to 9 (nine) to i and assign 2*i to each x[i]. Another consequence of zero-based indexing is that the final element in an array is location size - 1.

Now, if you aren't familiar with it, it might seem that zero-based indexing is going to require you to always be adding and subtracting 1 from index values. In fact, zero-based indexing is the natural indexing for computer programming and you will rarely, if ever, see code that is accessing arrays having to add and subtract 1s from index values. On the other hand, you have probably experienced having to do this when programming with Matlab (for instance).

A very common error in C++ programming is to exceed the bounds of an array when reading or writing date from or to it. Unlike interpreted languages, these bounds are not checked when the program is running. However, the above for loop is an extremely common pattern. We begin at the beginning of the vector and loop to the end. The index variable i starts at 0 and the loop continues as long as i is less than 10 (the number of elements we want to loop over). The ++i statement indicates that the value of i should be incremented by one at the end of each loop.

A Non-Trivial First Program

Now, with all of those preliminaries out of the way…

The program I want you to write for this assignment is to plot the value of \(\cos(x)\) with 1024 points for x from 0 to \(4\pi\), inclusive.

I want you to include \(\cos(4\pi)\) as the final value, not "\(\cos\) of almost \(4\pi\)".

Also: be thoughtful about how you index into the std::vector.

A basic skeleton of the program to do this plotting is:

PROVIDED_TEST("Generate plot for cos(x)")
{
    double const pi = std::acos(-1.0);    // C++ does not mandate a value for pi

    plt::figure_size(1280, 960);    // Initialize a 1280 X 960 figure

    std::vector<double> x(1024);    // Create two vectors
    std::vector<double> y(1024);

    // Fill in x with values from 0 to 4*pi (equally spaced)
    double const N = 4.0;
    for (size_t i = 0; i < 1024; ++i)
    {
        // TODO: fill the vector x with the values to be used as the horizontal
        //       component to plot the points of the cos function. 
    }

    // Fill in y with cos of x
    for (size_t i = 0; i < 1024; ++i)
    {
        // TODO: fill the vector y with the values to be used as the vertical
        //       component to plot the points of the cos function. 
    }

    // Make the plot and save it to a file
    plt::plot(x, y);
    plt::save("cosx.png");
}

The code above is contained in the file cos4pi.cpp that is part of the starter code. It additionally contains testing code that verifies some of the values you calculated.

The file relies on matplotlibcpp.h which is also part of the starter library. matplotlibcpp.h is a C++ header file to do plotting and image manipulation (we will be using it several times in this course). It also relies on the file catch.hpp that provides us with facilities to verify the correctness of our code. Before reading on, please take the time to read about testing using the Catch2 library.

There are two places in the file cos4pi.cpp that say “TODO: …”. The first is within a loop that increments a value of i (which value you can use within the loop) from 0 to its limit (what is the limit?). Replace the "TODO: …" with a statement that fills in the vector x with the values from 0 to 4\*pi (equally spaced). You will need to scale the value of i by some constant value to get the equally-spaced points and the correct final value.

In the second "TODO: …" you should fill in the vector y with \(\cos\) of x such that the last value computed will be exactly \(\cos(4\pi)\) (exactly, that is, within floating point precision).

Once we fill the vector of x and y, we call the function plt::plot with the data you want to plot (the vector x and y). plt::plot is a function that will plot the values it is passed, then we save those values to an image file cosx.png using plt::save.

Each “TODO: …” should only require a single line of C++ code.

Now build and run code. This should create the file cosx.png in the build directory. Please submit this file as part of your overall submission, place it into the results directory. You can also view it with the image viewing program of your choice, VSCode should be able to display it as well.

Your plot should look like one of the alphabet letters. If not, you are not doing it right.

The test should pass:

All tests passed (1 assertion in 1 test case)

Congratulations, you are almost done with the assignment. The only step left is to submit your work.

Next: Details and Submission