# Assignment 5: Inheritance and Derived Classes,

Assignment 5: Inheritance and Derived Classes, Templates

Due: November 22 at 8:30 am
Assignments (both source files and written reports) should be submitted on OWL in the corresponding
assignments under the Assignments tab.
Part A (50%)
In this part of the assignment, your grade will only be based on your source code, which you will submit on
OWL. Your programs will be marked on following:
– Date
– Which problem from the textbook your program is for
– What your program does (briefly, max 15 words)
– Command line compilation for this program (e.g. g++ assignment1.cpp -o assignment1) ❼ Appropriate comments throughout your code
❼ Proper indentation/style
❼ Correctness
❼ Output Readability (for e.g. if you are calculating √
4, then your output should say “The square root
of 4 is 2”, so the marker does not need to guess what the output is for.)
Answer the following problems taken from the end of chapter 7 and 8 from the course textbook. Note that
some questions have been slightly changed. Name the files of your program accordingly.
7.3 In Sect. 7.6, we discussed how abstract classes could be used to write a library for calculating the
numerical solution of initial value ordinary differential equations, i.e. ordinary differential equations of
the form
dydt = f(t, y) ,
for some user specified function f(t, y), where y = Y0 and t = T0 for an initial value Y0 at some initial
time T0. We want to calculate a numerical solution in the time interval T0 < t < T1 where T1 is the
final time. To solve this equation numerically, we require the user to specify an integration step size,
which we denote by h. A large variety of numerical methods exist for solving equations such as these
and in Sect. 7.6 we explain that, as these methods all required very similar inputs, they could be coded
very effectively using an abstract class pattern. We will base the library developed in this exercise on
the abstract class in Listing 7.2: the file has been provided to you on OWL.
In this exercise, we will develop the library to allow you to solve initial value ordinary differential
equations using two methods: the forward Euler method; and a Runge-Kutta method. Using a step
size h, we define the points ti, i = 0, 1, 2, . . . , N by
ti = T0 + ih ,
where h is chosen so that tN = T1. The numerical solution at these points is denoted by yi, i = 0, 1, 2, . . . , N. These values of yi are determined by the numerical technique chosen.
❼ For the forward Euler method, we set y0 = Y0. For i = 1, 2, . . . , N, yi
is given by
yi = yi 1 + hf(ti 1, yi 1) . 1
❼ For the fourth order Runge-Kutta method, we set y0 = Y0. For i = 1, 2, . . . , N, we calculate yi
using the following formulae:
k1 = hf (ti 1, yi 1) , k2 = hf ti 1 + 12
h, yi 1 + 12k1 , k3 = hf ti 1 + 12
h, yi 1 + 12k2 , k4 = hf (ti 1 + h, yi 1 + k3) , yi = yi 1 + 16 (k1 + 2k2 + 2k3 + k4) .
More details on numerical methods for initial value problems may be found in Corless & Fillion (2013).
(a) Write the methods associated with the class AbstractOdeSolver and save these as the file
AbstractOdeSolver.cpp. Note that you do not have to write the pure virtual functions, as
the “= 0” when they are declared in the file AbstractOdeSolver.h means that these are already
written.
(b) Derive a class called EulerMethod that allows the user to specify the function RightHandSide,
and contains a method SolveEquation that uses the forward Euler method to calculate the values
of yi as described above, and writes the values of ti and yi to file. The constructor of this derived
class has been provided to you on OWL.
(c) Test the class ForwardEulerSolver using the initial value ordinary equation
dydt
= 1 + t ,
for the time interval 0 < t < 1, and with initial condition y = 2 at t = 0. This equation has
solution y = (t2 + 2t + 4)/2.
(d) Repeat the two sub-parts above using the fourth order Runge-Kutta method to calculate the
values of yi
. Similar to the EulerMethod derived class, the constructor for the derived class
RungeKutta has been provided to you on OWL.
8.2 Use templates to write a single function that may be used to calculate the absolute value of an integer
of a double precision floating point number.
8.3 Use templates to write a single class called List that may be used to store an array using dynamic
memory allocation. (Feel free to write the template class and main function all in one file) This
template should work with integers, doubles, and our ComplexNumber class that was introduced in
Assignment 4. You may need to add some operator overloads to the ComplexNumber class for it to
work with the template class. Your template should have the following functionalities:
❼ A constructor that takes the argument that dictates the length of the array, and dynamically
allocates space for this array.
❼ A destructor that deletes the memory allocation.
❼ A member function called getLength(). ❼ An overload of the [] operator.
❼ A member function called sum() that returns the sum of all the elements in the array.
❼ A member function called pNorm() that returns the p-norm of the elements in the array. This
function should take an argument p (let it be a type double for this assignment) which is set to
the default value 2.
In your main function, show that the functions that you implemented works for variable types integer,
double, and ComplexNumber.
2
Part B (50%)
In this part of this assignment, you are required to hand in your code and a written component on the
problem below. The written component needs to be printed and handed in at the beginning of class. Both
the written component and the code should to be submitted on OWL in the same location as the code from
accordingly so that the marker can identify with program is for which problem.
x f(x) x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
01234
Figure 1: Subdivision of interval for N = 10
In this assignment, we will be writing a program for various quadrature methods, where we solve the
definite integral
Z ba f(x) dx
by breaking the domain up into many subintervals. See figure 1 for an image of how we divide our domain of
interest. In this assignment, we will be creating a class called Quadrature in which the different quadrature
methods will be derived from. The Quadrature class will store an dynamically allocated array which stores
the values f(xi) at each subinterval xi = a + ih, where h = b a N
is the width of the subintervals. This base
class should have the following features:
❼ A constructor which takes the arguments leftendpoint (left-most value in the domain of interest),
rightendpoint (right-most value in the domain of interest), and N (the number of subintervals). The
constructor should also calculate the subinterval width h. ❼ A destructor which deletes the space allocated to the array.
❼ A function that takes the function pointer as an argument and calculate f(xi) for each corresponding
xi value. As a reminder, to set a function that takes a function pointer, recall
void func tionname (double (✯ f u n c ti o n ) ( double x ) )
{
double y = 2 . 0 ;
// how t o e v a l u a t e t h e f u n c t i o n t h a t i s p a s se d as an argument
f u n c ti o n ( y ) ;
}
double f u n c ti o n t o b e p a s s e d (double x )
{
return 2. 0 ✯ s i n ( x ) ;
3
}
int main ( )
{
// how t o c a l l f u n c t i o n t h a t t a k e s a f u n c t i o n p o i n t e r as argument
func tionname ( f u n c ti o n t o b e p a s s e d ) ;
} ❼ a pure virtual function that performs that numerical integration.
Then, create the following derived classes:
❼ LeftRiemann
❼ RightRiemann
❼ Midpoint
❼ Trapezoid
❼ Simpsons
which evaluates the integral numerically according to the method that the name suggests. The following are
definitions for the quadrature methods needed in this assignment: the left Riemann sum is
Z ba f(x) dx ≈ h NX1 i=0
f(xi) ,
the right Riemann sum is
Z ba f(x) dx ≈ hXNi=1
f(xi) ,
the composite midpoint rule is
Z ba f(x) dx ≈ h NX1 i=0
f 12 (xi + xi+1) ,
the composite trapezoidal rule is
Z ba f(x) dx ≈ h f(a) 2 + f(b) 2 + NX1 i=1
f(xi)! ,
and Simpson’s rule is
Z ba f(x) dx ≈ h3 f(a) + f(b) + 2
N/
X2 1 i=1
f(x2i) + 4
N/
X2 i=1
f(x2i 1) ,
in which N needs to be an even number.
Z 22 x3ex dx ,
which has the exact value 2e2 + 38e 2
for the following N-subintervals:
N = [4, 10, 24, 50, 100, 250, 500, 1000, 5000, 10000] . 4
Output the absolute errors for each number of subintervals, N, for each method in one file: your data
file should be organized so that you have the N values in the first column, the absolute errors of the Left
Riemann sum corresponding to the N values in the second column, the absolute errors of the Right Riemann
sum in the third column, etc. Your data file should also output the errors in scientific notation with 12-digit
precision. From looking at the data file, which method performed the best for this integral? What made
you conclude that this method was the best? Plot the errors of all quadrature methods from the data file
on one log-log plot using your favourite plotting program. Do not forget about giving your plot a title, axes
labels, and legend! From examining this plot, estimate the order of convergence for these methods. Explain
how you arrived to this conclusion.
Repeat the above, but now for this integral:
Z 10 2√π e x2 dx ,
in which its exact solution is the error function evaluated at x = 1, erf(1) (the cmath package has the error
function, erf(x)). Output the absolute errors in the form of a data file and plot the errors on a log-log plot
give results that are acceptable? If the methods do not give acceptable results, provide an explanation as to
why you think this is the case.
Consider the following when writing your report:
❼ Briefly explain the problem that your program solves
❼ Briefly explain the methods that your program uses to solve the problem 