Scalable Cross-Platform Software Design: Generic Programming Coursework#1
25% of the module mark in total: Marking Scheme and submission deadline is on Moodle
Please Note:
-
No report is required. Just submit 1 file per task, all zipped together.
-
All questions are drawn from actual codes I have written for clients – just to reassure you of their “reality”
-
In file comments. I will not mark you down for no comments, but, if, as an experienced coder, I cannot
immediately understand what you are doing and why, imagining that I were tasked with maintaining it in the future, you will lose marks on that task. Subsequently sending me an “explanation” – well that’s not the real world – will not be acceptable.
-
I require you to write a test main for each task that demonstrates example use. I will compile and test on MSYS2.
-
A gentle warning: I am very good at spotting codes that have been lifted from the internet or written by computer scientist friends. To protect the integrity of the assessment and the efforts of the vast majority of students who will do the assessment themselves I am obliged to report any such violations of the University’s plagiarism rules.
-
Be careful of cutting & pasting from pdfs into code – it can sometimes embed hidden control characters causing
weird compiler errors.
Marks and feedback will be provided 15 working days after the submission deadline; each student will receive an individual copy of the marking rubric posted on Moodle by email. If required, further individual feedback is then available by requesting a one-to-one meeting.
Task1: Demonstrate basic implementation of a templated function (25% of the assessment mark)
Write a templated function, called wrapAround, that accepts one unsigned integer argument, i. The intention is that i is being used by the function caller to index elements in an array.
The return value is to be i+N unless i+N is greater than or equal to M, in which case, the return value wraps around back to 0 and beyond. We can assume(!) that i is positive and less than M. N and M can take any unsigned integer values.
Example: N=2, M=3
i=0, returns 2 i=1, returns 0 i=2, returns 1
Example: N=3, M=5
i=0, returns 3 i=1, returns 4 i=2, returns 0 i=3, returns 1 i=4, returns 2
Task 2: Demonstrate basic implementation of simple functors (25% of the assessment mark)
A 2D geometry manipulation code uses templated functions and classes to generate lines in the “x-y” plane, e.g.
template<typename CURVE> void plot(const CURVE & c){
float x,y;
for(float t=0; t<1;t+=0.01) {
c(t,x,y); // Given t, evaluate x and y values cout<< ”\n”<<t<<” “<<x<<" “<<y;
} }
t is a value ranging from 0 to 1 that “sweeps” the extent of the curve.
Angle, a, in radians t=1
y
x
t=0 radius
Origin(x,y)
Write a functor called circularArc which could be used by this code to generate the x,y coordinates for a circular arc if it were instantiated with CURVE being circularArc.
A circularArc object is characterised by an origin, radius and an angle, a, and we will assume all arcs have a tangent parallel to the y axis at the origin as shown.
The client insists that no assumptions regarding default constructor etc are made and wishes to see them explicitly declared and defined.
Task 3: Demonstrate technique selection and implementation skills 1 (25% of the assessment mark)
An iterative numerical process repeats a calculation process until the error is sufficiently small. An existing code for this is illustrated by the function,
double iterativeAlgorithm(const double* const inputDataArray, const double maximumError){
double error(1e50);
double result(0);
int iterationNumber(0);
while(error>maximumError){
// Do the calculations and evaluate the latest values of result and error
++ iterationNumber;
// Report on progress here
}
return(error); }
Ideally, the error reduces as the iterations proceed and the algorithm works as intended. However, sometimes this is not the case. The client wishes us to modify the existing code to permit monitoring of the iterations and possibly to terminate the iterations prematurely; however they cannot yet specify exactly how at the moment.
Convert the above code to a templated class, iterativeAlgorithmObject that
-
(i) Overloads the function operator to perform the iterations above.
-
(ii) Contains an instance of a monitoring object. The monitoring object is required to be a functor that must have
has a member function with the interface.
void operator()(const double result, const double maximumError, const int iterations) const;
that is called where Report on progress here appears in the above code. Other than this requirement, the exact nature of the monitoring object is to be left as flexible as possible.
Task 4: Demonstrate technique selection and implementation skills 2 (25% of the assessment mark)
3D points are stored in 3 element arrays holding the x, y, z values. A geometrical plane is defined by three 3D points it contains, labelled A, B and C. The return value of the code provided below, indicates which side of the plane a point D lies.
bool orient3d(const float* const pa, const float* const pb, const float* const pc,
const float* const pd) {
const float adx(pa[0]-pd[0]); const float bdx(pb[0]-pd[0]); const float cdx(pc[0]-pd[0]); const float ady(pa[1]-pd[1]);
// a pointer indicating a 3 element array containing the data of A // a pointer indicating a 3 element array containing the data of B // a pointer indicating a 3 element array containing the data of C // a pointer indicating a 3 element array containing the data of D
const float bdy(pb[1]-pd[1]); const float cdy(pc[1]-pd[1]); const float adz(pa[2]-pd[2]); const float bdz(pb[2]-pd[2]); const float cdz(pc[2]-pd[2]);
return(adx*(bdy*cdz-bdz*cdy)+bdx*(cdy*adz-cdz*ady)+cdx*(ady*bdz-adz*bdy)>0); }
Convert this code into a templated version that can be used to instantiate versions for any numerical type storing
In another code, the 3D points are held in a structs defined as,
struct point { double x,y,z;
};
Introduce a specialisation of your template that manages this special case; i.e.
bool orient3d(const point* const pa, const point* const pb, const point* const pc,
const point* const pd) ;
// a pointer to a “point” instance containing the data of A // a pointer to a “point” instance containing the data of B // a pointer to a “point” instance containing the data of C // a pointer to a “point” instance containing the data of D