Sie sind auf Seite 1von 41

C++ exercises (with applications in mathematics&finance)

The present work will be focused on mastering STL(Standard Template Library),object oriented
programming,generic programming(templates),and implementing them in various mathematical
contexts.Here I will present also applications for VBA(DLLs).
In my second part of work, I will present entire projects,done both in C++ and VBA, for Risk
Analysis,Option Pricing,Asset Valuation,and others.
STL(Standard Template Library)(vectors,deque,lists)
1.Vectors
a)display a vector in this order:10 9 8 7 6 5..
b)display in reverse order the vector of square roots;
c)replace the elements of the vector above which have the distance between them and 2 less than
epsilon, with -10
d)insert after the beginning of the vector the number 30
e)insert at 2 positions after the beginning the number 7
f)insert at 4 positions before the end the number 32, 3 times
g1)insert inside vector 2,after the position pos,the vector(100,100);
g2)insert inside vector 2 a vector of the form (x,x,,x)(n times) with n and x as input
g3)insert inside vector 2 a vector w
h)Insert a vector already set, inside v2;
i)Delete from vector v2, starting from position pos1, to pos 2 all elements,but before compute the
sum of the elements.
Solution:
a) vector<double> v1, v2;
for (double x = 0; x<10; ++x)
v1.push_back(10 - x);
for (vector<double>::iterator p = v1.begin(); p<v1.end(); ++p)
cout << *p << ',';

b) cout << endl;


for (vector<double>::reverse_iterator p = v1.rbegin(); p<v1.rend(); ++p)
cout << *p << ',';
for (double x = 1; x <= 10; ++x)
v2.push_back(sqrt(x));
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';
c) for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
if (fabs(*p - 2.0)<0.0001)*p = -10.0;
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';

d) vector<double>::iterator it;
//point d) insert after the beginning of the vector number 30

it = v1.begin();
it = v1.insert(it, 30);
cout << endl;
for (vector<double>::iterator p = v1.begin(); p<v1.end(); ++p)
cout << *p << ',';
it = v1.begin();
v1.insert(it, 32);
cout << endl;
for (vector<double>::iterator p = v1.begin(); p<v1.end(); ++p)
cout << *p << ',';

e) it = v1.begin();
v1.insert(it + 2, 7);
cout << endl;
for (vector<double>::iterator p = v1.begin(); p<v1.end(); ++p)
cout << *p << ',';

f) it = v1.end();
v1.insert(it - 2, 3, 32);
cout << endl;
for (vector<double>::iterator p = v1.begin(); p<v1.end(); ++p)
cout << *p << ',';
cout << endl;

g1) vector<double> v3(2, 100);


int pos;
cout << "Enter the position inside the vector 2 "; cin >> pos;
v2.insert(v2.begin() + pos, v3.begin(), v3.end());
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';

g2) double y; int n, pos2;


cout << endl << "give the input value of the vector "; cin >> y;
cout << endl << "give the number of times you want x to appear"; cin >> n;
cout << endl << "enter again from which position you want the vector to be
pasted:"; cin >> pos2;
vector<double> v4(n, y);
v2.insert(v2.begin() + pos2, v4.begin(), v4.end());
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';

g3) v2.insert(v2.begin()+pos3,w.begin(),w.end());

h) int array[] = { 12.0,13.0,14.1 };


v2.insert(v2.begin(), array, array + 3);
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';
i) cout << endl; int pos1;
cin >> pos1 >> pos2;
double sum = 0;
for (vector<double>::iterator p = v2.begin() + pos1 - 1; p < v2.begin() + pos2;
++p)
sum += *p;
cout << endl << sum;
v2.erase(v2.begin() + pos1-1, v2.begin() + pos2-1);
//for (vector<double>::iterator p = v2.begin() + pos1; p < v2.begin() + pos2; ++p)
//v2.pop_back();is not the proper function
cout << endl;
for (vector<double>::iterator p = v2.begin(); p<v2.end(); ++p)
cout << *p << ' ';

EXERCISE 2
a)Given a vector v of doubles,compute the sum of the elements,starting from position 1 to
position 2,size,its average,and standard deviation
b)Declare a deque and display the following sequences:
1 2 3 4 . 20
20 19 18 17 16 ..3 2 1
c)Inside a deque enter the first n prime numbers;
SOLUTION:
void part2(vector<double> v,int pos1,int pos2)
{
double *sum ,std = 0;
sum = new double; *sum = 0;
for (vector<double>::iterator p = v.begin() + pos1-1; p< v.begin() + pos2; ++p)
*sum += *p;
cout << *sum<<endl;
cout << *sum / (pos2 - pos1 + 1) << endl;
delete sum;
double *avg;
avg = new double;
cout << v.size() << endl;
double sum2 = 0;
for (vector<double>::iterator p = v.begin(); p < v.end(); ++p)
sum2 += *p;
*avg = sum2 / v.size();
for (vector<double>::iterator p = v.begin(); p < v.end(); ++p)
std += (*avg - *p)*(*avg - *p);
delete avg;
cout << sum2 << endl;
cout << sqrt(std)/sqrt(v.size()) << endl;
cout << v.capacity() << endl;
}
b) void part3(int n)
{
deque<double> d1,d2;
for (int i = 1; i <= n; i++)
{
d1.push_back(i);
d2.push_front(i);
}
for (deque<double>::iterator p = d1.begin(); p < d1.end(); ++p)
cout << *p << ',';
cout << endl;
for (deque<double>::iterator p = d2.begin(); p < d2.end(); ++p)
cout << *p << ',';
cout << endl;
}

c) bool prime(int p)
{
bool ok=1;
if (p == 0 || p == 1)ok = 0;
else
for (int d = 2; d <= int(sqrt(p)); d++)
if (p%d == 0) {
ok = 0; break;
}
return ok;
}
deque<int> part4(int n)
{
deque<int> d;
int count = 0,p=1;
while(count<n)
if(prime(p))
{
count++; p++;
d.push_back(p);
}
return d;
}

Exercise 3
Write a function/template that allows outstreaming for containers(deque,vector,list)
Solution:
There are at least 2 ways of doing that:Either,we do like this,
template<typename T>
ostream& Print(ostream& os, const T&container)
{
for (auto i = container.cbegin(); i < container.cend(); ++i)
os << *i << ' ';
return os;
}
template <typename T>
ostream& operator<<(ostream &os, const deque<T>&d) { return Print(os, d); }

or,more directly but more specific,like this:


template<typename T>
ostream& Print(ostream& os, const T&container)
{
for (auto i = container.cbegin(); i < container.cend(); ++i)
os << *i << ' ';
return os;
}
template <typename T>
ostream& operator<<(ostream &os, const deque<T>&d) { return Print(os, d); }

We can the functionality of this outstream through a function like the next one:
void function1()
{
vector<double> v = { 11,12.0,13.2,14.1,9.1,8.5,3.5 };
cout << v;
cout << endl;
}

Or, for deques inside the next function


void function2()
{
deque<int> d1;
for (int i = 0; i < 10; i++)
d1.push_back(i*i + 1);
cout << d1;
}

Exercise 4
a)Display the following deque: 0 1 2 3 n-1 n n-1 n-20
b)Create a deque of numbers 1 3 5 7 92n-1 2n 2n-2 2n-4 0
c)Create 2 lists and concatenate them
SOLUTION:
a) void function3(int n)
{
deque<int> l1;
for (int i = 0; i <= n; i++)
l1.push_front(i);
cout << l1 << endl;
for (int i = 1; i <= n; i++)
l1.push_front(n-i);
cout << l1 << endl;

b) void function4(int n)
{
deque<int>l1;
for (int i = 0; i <= n; i++)
l1.push_front(2 * i);
for (int i = 1; i <= n; i++)
l1.push_front(2 * n - 2 * i + 1);
cout << l1 << endl;
}

c) template <typename T>


ostream& operator<<(ostream &os, list<T>&v)
{
for (auto i = v.begin(); i != v.end(); ++i)//auto is a type self-discovered;
os << *i << ' ';
return os;
}
void function5()
{
list<int> l1 = { 1,3,5,1,3 };
list<int> l2 = { 1,9,2,6 };
list<int>::iterator it; it = l1.end();
cout << l1 << endl;
l1.splice(it, l2);
cout << l1 << endl;
for (it = l1.begin(); it!= l1.end(); ++it)
cout << *it << ' ';
cout << endl;
}

EXERCISE 5
Create a chain of lists l1-l1-l1-l1 etc.
void function6(list<int> &l, int n)
{
list<int> l2 = { 1,2 };
list<int>::iterator it;
for(int i=1;i<=n;i++)
{
it = l.end();
l.splice(it, l2);
}
cout << l;
cout << endl;
}

EXERCISE 6
a)Given a list l erase the element from the position pos
b)Given a list l erase the elements from the position pos1 to position pos2
c)Given a set of numbers compute the sum of numbers of this set
d)Create a set of strings and count the number of unique elements;
SOLUTIONS:
a) list<double> function7(list<double> &l,int pos)
{
list<double>::iterator it;
it = l.begin();
advance(it, pos-1);
it = l.erase(it);
return l;
}

b) list<double> function8(list<double>&l, int pos1,int pos2)


{
list<double>::iterator it1, it2;
it1 = it2 = l.begin();
advance(it1, pos1 - 1); advance(it2, pos2);
l.erase(it1, it2);
return l;
}

c) double sum(set<double> &s)


{
double sum = 0;
for (set<double>::iterator p = s.begin(); p != s.end(); ++p)
sum += *p;
return sum;
}

d) //First,I will give an example to show the functionality of the set template
void sets()
{
set<string> colours;
colours.insert("blue");
colours.insert("red");
colours.insert("yellow");
colours.insert("blue");
colours.insert("green");
cout << colours<<endl;
}
//the conclusion is that the display is made in alphabetically order without repetition

EXERCISE 7
a)Create a stream of chars using cingetline code and return it back then
b)Create a sentence(multiset) starting from different types of strings(in number of n)
SOL:
a) template <typename T>
ostream& operator<<(ostream &os, multiset<T>&l)
{
for (auto i = l.begin(); i != l.end(); ++i)
os << *i << ' ';
return os;
}
void streaming()
{
char name[100], title[100];
cout << "Please enter your name: "; cin.getline(name, 100, '.');
cout << endl;
cout << "Please enter your PHD thesis:"; cin.getline(title, 100, ';');
cout << endl;
cout << name << "'s PHD thesis is " << title << endl;
multiset<string> special;
special.insert(name);
cout << name;
}

b) void sentence(int n)
{
char name[40];
multiset<string>special;
for (int i = 1; i <= n; i++)
{
cin.getline(name, 40, ';'); special.insert(name);
}
cout << special<<endl;
}

EXERCISE 8
a)Create an array of pointers to a vector type (size of array=n);
b)Create a 2D array knowing the elements on the border with the following property:
f(i,j)=(f(I,j+1)+f(i-1,j+1)+f(i+1,j+1))/3,f(0,j)=j*j,f(j,M)=2*j+1,when j<>0,f(N,j)=2*j-
1,j<>M,where the array is f[N+1][M+1];
SOLUTION:
a) void function10(int n,int m)
{
vector<double> *data;
data = new vector<double>[n+1];
for (int i = 0; i <= n; i++)
data[i] = vector<double>( m+1,0);
for (int i = 0; i <= n; i++)

cout << data[i] << endl;}

b)First,we setup the border

double** data1(int n, int m)


{
double **w;
w = new double*[n ];
for (int i = 0; i < n+1; i++)
w[i] = new double[m+1];
for (int i = 0; i < n+1; i++)
for (int j = 0; j < m+1; ++j)
w[i][j] = 0;
for (int j = 0; j < m+1; j++)
w[0][j] = j*j;
for (int i = 1; i <= n; i++)
w[i][m] = 2 * i + 1;
for (int j = 0; j < m; j++)
w[n][j] = 2 * j + 3;
for (int j = m; j >= 0; j--)
{
for (int i = 0; i <= n; i++)
cout << w[i][j] << ' ';
cout << endl;
}
return w;
}

double* data2(int n, int m)


{
double **w;
w = data1(n, m);
for (int j = m - 1; j >= 0; j--)
for (int i = 1; i < n; i++)
w[i][j] = 1 / 3 * (w[i][j + 1] + w[i - 1][j + 1] + w[i + 1][j + 1]);
double *v;
v = new double[n + 1];
for (int i = 0; i <= n; i++)
v[i] = w[i][0];
return v;
}

EXERCISE 9
a)Make a program that solves a tridiagonal system
b)Multiplication of a row of matrix of column
c)Multiplication of a matrix with a vector column
SOLUTION:
a) //b is the diagonal,a is lower, c is upper and d is the column vector of free terms
double* tridiagonal(double *b, double *a, double *c, double *d,int n)
{ //b and d have size n,c and
double *dprime, *cprime, *x;
dprime = new double[n];
cprime = new double[n-1];
x = new double[n];
for (int i = 0; i < n-1; i++)
if (i == 0)
cprime[i] = c[i] / b[i];
else
cprime[i] = c[i] / (b[i] - a[i-1] * cprime[i - 1]);

for (int i = 0; i < n; i++)


if (i == 0)dprime[i] = d[i] / b[i];
else
dprime[i]= (d[i] - a[i-1] * dprime[i - 1]) / (b[i] - a[i-1] *
cprime[i - 1]);
x[n - 1] = dprime[n - 1];
for (int i = n - 2; i >= 0; i--)
x[i] = dprime[i] - cprime[i] * x[i + 1];
return x;
}//Source: wikipediaTridiagonal algorithm(Thomas algorithm)

b) double multiply(double *x, double *y, int n)


{
double s = 0;
for (int i = 0; i < n; i++)
s += x[i] * y[i];
return s;
}
c) double *multiply(double **m, double *x, int n)
{
double *y;
y = new double[n];
for (int i = 0; i < n; i++)
{
y[i] = 0;
for (int j = 0; j < n; j++)
y[i] += m[i][j] * x[j];
}
return y;
}

EXERCISE 10

a)Create a grid typical for Black Scholes and heat equation starting from parameters
S,sigma(volatility),T(time to maturity),M(no.of periods of evaluation),N(no.of grid points for
Sspace axis).This will represent the stock price points as a division, and they will be formed
after the binomial model with M periods.
b)Create a (N+1)x(M+1) matrix having the elements on the first column 0, on the last line the
payoff,on the last column the extremal price of a call, the matrix called V(value)for example and
, meaning the value at time i when the stock price is defined at point a) on the grid.

SOLUTIONS:
a) double* grid1(double S, double sigma, double T, int M,int N)
{
double u = exp(sigma*sqrt(T / M)),d=1/u;
double S_max = S*pow(u, M), S_min = S*pow(d, M);//S has size N+1
double *S_grid;
S_grid = new double[N + 1];
for (int i = 0; i <= N; i++)
S_grid[i] = S_min*pow(u,2.0*i*M/N);//S_grid[i]=S_min*pow(u,2i*M/N)
return S_grid;
}

The result of the grid is actually the binomial model which for M big enough,it is a good
approximation to Black-Scholes. A known fact is that the binomial model converges to the Black
Scholes when the number of steps tends to infinity.
b) double** matrix_call(double S, double K, double T,double sigma, double r, int N, int
M)
{
double **w;
double *S_grid;
S_grid = new double[N + 1];
S_grid= grid1(S, sigma, T, M, N);
w = new double*[M + 1];
for (int i = 0; i <= M; i++)
w[i] = new double [N + 1];
for (int i = 0; i <= M; i++)
for (int j = 0; j <= N; j++)
w[i][j] = 0;
for (int j = 0; j <= N; j++)
w[M][j] = S_grid[j] > K ? S_grid[j] - K : 0;
for (int j = 0; j <= M; j++)
w[j][N] = S_grid[N] - K*exp(-r*T*(M - j) / M);
return w;

Explanations:w[M][j]= terminal value of the call,which is in fact its payoff,namely

Max( , 0).IN that case, = (on the grid),namely []or S_grid[j](as defined above).
(,)
Also,the reason for w[j][N] = S_grid[N] - K*exp(-r*T*(M - j) / M); is that lim
()
= 1.

EXERCISE 11

a)Make integration of a function with the classical approximate method:as a discrete Riemann
sum of finite differences
b)Make integration with trapezoidal method:
Solutions:
a)First, in order to do an integration,as for the differentiation, we must use a template for
functions:
template <typename function>
double integrale(const function& f, double a, double b, int N)
{
double h = (b - a) / N;
double s = 0; vector <double> d(N+1);
for (int i = 0; i <= N; i++)
d.at(i) = a + i*h;

for (int i = 0; i < N; i++)


s += f(d.at(i)) * h;
return s;
}

b) template <typename function>


double integrale_trapeze(const function &f,double a,double b,int N)
{
double h = (b - a) / N;
double s = 0; vector <double> d(N + 1);
for (int i = 0; i <= N; i++)
d.at(i) = a + i*h;
for (int i = 0; i < N; i++)
s += f((d.at(i) + d.at(i + 1)) / 2)*h;
return s;

Now,in order to test if this works we will declare a couple of functions and see if it works:
double f1(double x)
{
return x*x;
}

Int main()

{double a,b;

Std::Cin>>a>>b;

Std::Cout<<integrale(f1,a,b,100)<<endl;

Std::Cout<<integrale_trapeze(f2,a,b,100)<<std::endl;

Compare the two results and make yourself some computations.


EXERCISE 12
a)For a random variable X~N(0,1),compute the probability that X (, ).
b)Using the bisection method solve an equation f(x)=0 for any function f.
c)Calculate the 95% VaR of a normal random variable (meaning that value alpha for which
P(X>alpha)=95%)
SOLUTION:
a) First,we define the pdf(probability distribution function for X)(called here f3).
double f3(double x)
{
double const pi = 3.14;
return 1 / sqrt(2 * pi)*exp(-x*x / 2);
}
Second,
double normal(double a, double b)
{

int N = 100;
double w;
w = integrale(f3, a, b, N);
return w;
}

b) template <typename function>

double bisection(function f, double a, double b)


{
double x1, x2;
double a_min = a, a_max = b;
double x; x = a;
if(f(a)*f(b)<0)
while (fabs(f(x)) > 0.0001)
{
x = (a_min + a_max) / 2;
if (f(a_min)*f(x) < 0)a_max = x;
if (f(a_max)*f(x) < 0) a_min = x;
}
else
{
std::cout << "Try other two numbers: "; std::cin >> x1 >> x2;
bisection(f, x1, x2);
}
return x;
}

c) double normal2(double x)
{
double y;
y = normal(x, 4);
return y;
}
//now we pass to VaR using bisection method
double VaR()
{
double eps = 0.015;
double x = -3;
double diff=1;
while (diff > eps)
{
diff = fabs(normal2(x) - 0.95);
x += .03;
}
return x;
}

EXERCISE 13
double* simulation(double sigma, double h, double k, int T)
{
double *x;
x = new double[T + 1];
int *epsilon;//this is a random variable which takes the values -1 and 1 equally
likely
epsilon = new int[int(T / h)];
for (int i = 0; i <= T / h; i++)
epsilon[i] = pow(-1, i);
for (int t = 0; t <= T; t++)
{

for (int i = 0; i <= t / h; i++)


x[t] += epsilon[i];
x[t] = x[t] * k;
}
return x;
}

EXERCISE 14
//first we test again for prime numbers
bool prime(int p)
{
int ok = 1;
for (int d = 2; d <= int(sqrt(p)); d++)
if (p%d == 0) ok = 0;
return ok;
}
//second we generate a uniform sample from 0 to p
int* uniform_integer(int p)
{
int *a;
a = new int[p];
a[0] = 3;
for (int i = 1; i<p; i++)
a[i] = (3 * a[i - 1]) % p;
//for (int i = 0; i < p; i++)
//std::cout << a[i] << ' ';
return a;
}
//now we take this to numbers between 0 and 1
double *uniform01(int p)
{
double *seq;
seq = new double[p];
int *seq2; seq2 = new int[p];
seq2 = uniform_integer(p);
for (int i = 0; i < p; i++)
seq[i] = seq2[i] / float(p);
std::cout << std::endl;
std::cout << "The uniform sequence is here:";
//for (int i = 0; i < p; i++)
//std::cout << seq[i] << ' ';
return seq;
}

b)Simulation of a uniform U[a,b] random variable.


double *uniform_ab(double a,double b,int p)
{
double *seq;
seq = new double[p];
seq = uniform01(p);
double *seq2; seq2 = new double[p];
for (int i = 0; i < p; i++)
seq2[i] = a + (b - a)*seq[i];
delete[] seq;
for (int i = 0; i < p; i++)
std::cout << seq2[i] << ' ';
return seq2;
}

c) Simulation of a normal random variable using Box-Muller method:

void normal01(int p)

double const pi = 3.14;

int a[100], a2[100];

a[0] = 3; a2[0] = 5; double b2[100], b[100], c2[100];

for (int i = 0; i<p; i++)

a[i] = (3 * a[i - 1]) % p;


for (int i = 0; i<p; i++)

a2[i] = (3 * a2[i - 1]) % p;

for (int i = 0; i<p; i++)

b[i] = float(a[i]) / float(p);

for (int i = 0; i<p; i++)

b2[i] = float(a2[i]) / float(p);

for (int i = 0; i<p; i++)

c2[i] = sqrt(-2 * log(b[i]))*cos(2 * pi*b2[i]);

for (int i = 0; i < p; i++)

cout << c2[i] << ' ';

EXERCISE 15
Define a class called point having the following functions:
a)a constructor point()
b)an access function to the first component and the second component respectively;
c)an ostream operator;d)an adding operator,operator+.
SOLUTION:
template <class T>
class point
{
private:
T x_, y_;
public:
point(T x, T y)
{
x_ = x; y_ = y;
}
point():x_(0),y_(0){}
T getx()
{
return x_;
}
T gety()
{
return y_;
}
};
template <typename T>
ostream& operator<<(ostream&os, point<T> &p)
{
os <<'('<< p.getx() << ' ' << p.gety()<<')'<<endl;
return os;
}
template <typename T>
point<T> operator+(point<T>&p1, point<T>&p2)
{
T a, b;
a = p1.getx() + p2.getx();
b = p1.gety() + p2.gety();
point<T> p3(a,b);
return p3;
}

EXERCISE 16
Define a template class complex embedded with the following member functions:
a)at least one constructor;
b)access to imaginary and real part;
c)sum and multiplication operators
Verify then the functionality of a complex function of your own,having complex variables.
SOLUTION:
template <class T>
class complex
{
protected:
T a_, b_;
public:
complex(T a, T b) { a_ = a; b_ = b; }
complex() { a_ = 0; b_ = 0; }
T real() { return a_; }
T imag() { return b_; }
};
template <typename T>
complex<T> operator+(complex<T> &z1, complex<T> &z2)
{
T x,y;
x = z1.real() + z2.real();
y = z1.imag() + z2.imag();
complex<T> z3(x,y);
return z3;
}
template <typename T>
ostream& operator<<(ostream&os, complex<T> &z)
{
os << z.real() << "+" << "i *" << z.imag()<<endl;
return os;
}

template <typename T>


complex<T> operator*(complex<T> &z1, complex<T> &z2)
{
T x,y;
x = z1.real() * z2.real() - z1.imag()*z2.imag();
y = z1.imag()*z2.real() + z1.real()*z2.imag();
complex<T>z3(x,y);
return z3;
}

The function inside main.cpp file I have chosen is the next one:
template <typename T>
complex<T> fct1(complex<T>z1, complex<T>z2)
{
complex<T> z3;
z3 = z1*z1 + z2*z2*z2;
return z3;
}

Inside main():

complex<int> w(0, 1);


complex <int>z4 = fct1(w, w);
cout << z4 << endl;

EXERCISE 17
Build an algorithm that computes the arcsine of each element of a list, using a functor.
SOLUTION:
We define first a class named Func:
#include <iostream>
#include <cmath>
void Print(double i)
{
std::cout << i << std::endl;
}
class Func
{
public:
Func(double a):a_(a){}
void operator()(double &x)const
{
x = a_ *sin(x);
}
void setA(double a)
{
a_ = a;
}
private:
double a_;
};

Now,lets see inside main() how does this work:


#include <list>
#include <algorithm>
using namespace std;
int main()
{
list<double> l;
for (int i = 0; i < 10; ++i)
l.push_back(i / 10.0);
cout << "List1\n";
for_each(l.begin(), l.end(), Print);//for_each belongs to algorithm file
//inside for_each we use , not ;(like in for loops)
list<double> l2;
for (int i = 0; i < 10; ++i)
l2.push_front(i / 10.0);
cout << "List2\n";
for_each(l2.begin(), l2.end(), Print);
Func asinx(1.0);
for_each(l2.rbegin(), l2.rend(), asinx);
cout << "List3\n";
for_each(l2.begin(), l2.end(), Print);
Func asinx2(2.0);
for_each(l.begin(), l.end(), asinx2);
cout << "List4\n";
for_each(l.begin(), l.end(), Print);
cout << "List5\n";
list<double> l3;
for (int i = 0; i < 10; ++i)
l3.push_back(i / 10.0);
asinx.setA(2.0);
for_each(l3.begin(), l3.end(), asinx);
for_each(l3.begin(), l3.end(), Print);
system("pause");}

Comments:
1)l is displayed first in normal order:0 0.1 0.9
2)l2 is displayed in reverse order: 0.9 0.8 ..
3)for each element of l2 from reverse order meaning that it is starting from 0 we have arcsine of
it.
4)asinx is an object of class Func,do not confuse it with the <cmath> function asin.
5)asinx() passes to the overload operator() from the class Func
6)I can define as many objects of class Func,they will all be able to compute only one
function,that which is represented by the () operator.
7)In order to construct another function that is to be applied for all elements of a container, I will
have to define the () operator for another class.

Exercise 18

Create a functor that computes () = 2 + + (think about a class of functions


depending on , , .

Solution:
We will build a class Func2 with 3 constructors,depending on the number of parameters
declared.
Inside the operator() we will use that function:
class Func2
{
public:
Func2(double a,double b,double c):a_(a),b_(b),c_(c){}
Func2(double a,double b):a_(a),b_(b),c_(0){}
Func2(double a):a_(a),b_(0),c_(0){}
void operator()(double &x)const
{
x = a_*x*x + b_*x + c_;
}
void set(double a, double b, double c)
{
a_ = a; b_ = b; c_ = c;
}
private:
double a_, b_, c_;
};
We will now prove an implementation inside main()
list<double> l;
for (int i = 1; i <= 10; i++)
l.push_back(double(i));
Func2 quad(1.0);
cout << "List1\n";
for_each(l.begin(), l.end(), Print);
for_each(l.begin(), l.end(), quad);
cout << "List2\n";
for_each(l.begin(), l.end(), Print);

Here, quad is a functor(object of class Func2),that depends on the parameter = 1.


The list displayed is 1,4,9,,100.
If,instead of quad,we insert another functor quad2 like the following,specific for = 1, = 1we
obtain:
Func2 quad2(1.0, 1.0);
cout << "List3\n";
for_each(l.begin(), l.end(), quad2);
for_each(l.begin(), l.end(), Print);

The list displayed is 2,6,12,20,30,42,56,72,90,110.

EXERCISE 19
Use bind2nd and transform the same lists as in exercise 16 as follows:
1)first,multiply all elements by 2;
2)then,for the result obtained multiply except the first element,all elements by 2;
3)after,multiply except for the first 2 elements,all elements by 3;

void functor2()
{
std::list<double> l;
for (int i = 0; i < 10; ++i)
l.push_back(i / 10.0);
std::cout << "List1\n";
std::for_each(l.begin(), l.end(), Print);
std::transform(l.begin(), l.end(), l.begin(),
std::bind2nd(std::multiplies<double>(), 2));
std::cout << "List2\n";
std::for_each(l.begin(), l.end(), Print);
std::list<double>::iterator it = l.begin(); ++it;
std::transform(it, l.end(), it , std::bind2nd(std::multiplies<double>(), 3));
std::cout << "List3\n";
std::for_each(l.begin(), l.end(), Print);
++it;
std::transform(it, l.end(), it, std::bind2nd(std::multiplies<double>(), 3));
std::cout << "List4\n";
std::for_each(l.begin(), l.end(), Print);
}

We remark the usage of iterator it,that defines the initial position on the list and then moves one
step of a time,to transform the remaining list to the end,by multiplying by 2 and 3
respectively,each element.

b)Now, multiply the last element by 3, then multiply the last 2 elements 4,and so on.
void functor3()
{
std::list<double> l;
for (int i = 0; i < 10; ++i)
l.push_back(i / 10.0);
std::cout << "List1\n";
std::for_each(l.begin(), l.end(), Print);
std::list<double>::reverse_iterator it = l.rbegin(); ++it;
std::transform(l.rbegin(), it, l.rbegin(), std::bind2nd(std::multiplies<double>(),
3));
std::cout << "List2\n";
std::for_each(l.begin(), l.end(), Print);
++it;
std::transform(l.rbegin(), it, l.rbegin(), std::bind2nd(std::multiplies<double>(),
4));
std::cout << "List3\n";
std::for_each(l.begin(), l.end(), Print);
}
c)Apply the function () = 2 2 , () = 2 to each element of a list.
void functor4()
{
std::list<double>l;
for (int i = 0; i < 10; ++i)
l.push_back(i / 10.0);
std::cout << "List1\n";
std::for_each(l.begin(), l.end(), Print);
std::transform(l.begin(), l.end(), l.begin(),
boost::bind(std::multiplies<double>(), boost::bind(fct, _1), 2));
std::cout << "List2\n";
std::for_each(l.begin(), l.end(), Print);
std::list<double> l2;
for (int i = 0; i < 10; ++i)
l2.push_back(i / 10.0);
std::transform(l2.begin(), l2.end(), l2.begin(), boost::bind(fct, _1));
std::cout << "List3\n";
std::for_each(l2.begin(), l2.end(), Print);
}

EXERCISE 20
a)Given a vector v (-3,-2,,9,10) erase all the elements starting with the second position.
b)Given a vector v(-3,-2,,9,10) erase all the elements from the position pos1 to position pos2.
SOLUTION:
a) void remove_erase()
{
std::vector<int>v;
for (int i = -3; i <= 10; ++i)
v.push_back(i);
std::for_each(v.begin(), v.end(), Print);
std::vector<int>::iterator p = v.begin();
p = p + 2;
v.erase(p, v.end());//erases all elements from the position of p(which is for the
element -1 to the end)
std::cout << "size(v)= " << v.size() << std::endl;
std::for_each(v.begin(), v.end(), Print);
}

b) void erase(int pos1, int pos2)


{
std::vector<int> v;
for (int i = -3; i <= 10; ++i)
v.push_back(i);
std::vector<int>::iterator p1,p2;
p1 = v.begin() + pos1-1;
p2 = v.begin() + pos2-1;
v.erase(p1, p2);
std::cout << "size(v)=" << v.size() << std::endl;
std::for_each(v.begin(), v.end(), Print);
}

EXERCISE 21
a)Copy rhe elements of a list into a vector in reverse order;
b)Copy the elements of a vector into a list in reverse order;
c)Make a function(template) that prints all elements of a list,and also the elements of a vector.
Solutions:
a) void mutating()
{
std::list<int> l;
for (int i = 1; i <= 4; ++i)
l.push_back(i);
for_each(l.begin(), l.end(), Print);
std::cout << std::endl;
std::vector<int> v;
std::back_insert_iterator<std::vector<int>> iter(v);//needs iterator header file
std::reverse_copy(l.begin(), l.end(), iter);
for_each(v.begin(), v.end(), Print);
}

b) void mutating2()
{
std::vector<int> v;
for (int i = 1; i <= 4; ++i)
v.push_back(i);
for_each(v.begin(), v.end(), Print);
std::cout << std::endl;
std::list<int>l;
std::back_insert_iterator<std::list<int>> iter(l);
std::reverse_copy(v.begin(), v.end(), Print);
for_each(l.begin(), l.end(), Print);
}

c)We have 2 ways of building this print(template) functions:


template <typename T>
void PRINT(const std::list<T> &v)
{
for (auto p = v.begin(); p != v.end(); ++p)
std::cout << *p << ",";

std::cout << std::endl;


}
OR,
template<typename T>
void PRINT2(const std::list<T>&v)
{
for (std::list<T>::const_iterator p = v.begin(); p != v.end(); ++p)//must be used
const_Iterator because we
//have as argument a constant list
std::cout << *p << ",";
std::cout << std::endl;
}

We do the same for vector types.


EXERCISE 22
Compute the price of a bond having as parameters the face value,two coupon payments,the
maturity and the payment times. Export this function to EXCEL.
Solution:
We build first a static library (I use Visual Studio)
First step: I build a header file called prices.h
#ifndef prices_h
#define prices_h
//Exercise 23
//a)Knowing that a bond has a face value F, and two coupon payments at time t1,and t2
with the values V1,V2
//compute its price and export it to EXCEL using a message dialog.
#include <cmath>
double price_bond1(double F, double c1, double c2, double T, double t1, double t2, double
r)
{
return F*exp(-r*T) + c1*exp(-r*t1) + c2*exp(-r*t2);
}
#endif

In order for the Library to be created you have to add inside Source Files,a source file,
even if its empty.Then build the solution.That should make it.
Second step:
Create a new project inside the same solution, a DLL project, I call it pricing_dll.
Inside the header files section create a new header file, for example price_dll.h and the content is
the following:
#ifndef price_dll_h
#define price_dll_h
#define M2API __declspec(dllexport)

extern "C"
{

M2API double __stdcall bond_price(double F, double c1, double c2, double T, double
t1, double t2, double r);
}
#endif

The bond_price will be exported to VBA with an alias.


Also inside Source Files create a file price_dll.cpp
The content inside it should be the following:
#include "prices.h"
#include "price_dll.h"
double __stdcall bond_price(double F, double c1, double c2, double T, double t1, double
t2, double r)
{
return price_bond1(F,c1,c2,T,t1,t2,r);
}

I will post a picture about how should look in general this file:
The first project is called pricing_app: this has the role of testing the functionality of the code in
the second project(pricing_cpp_dll which is a static library) and the third project has the role of
connection between the second project and the VBA/Excel Interface.
Two important details inside the C++ projects:
YOU HAVE TO LINK THE PROJECTS. Lets take for example the 2nd and 3rd.
Right Click on the 3rd, pricing_dll Properties.
Now, if you enlarge the windows C/C++ and Linker you can see something like this:
In C/C++ go to General: Inside Additional Include Directories enter the directory where its
located prices.h file(It should be
C:/Users/your_name/Visual_Studio_2015/Projects/your_solution_name/pricing_cpp_dll/)
Then,go to Linker/General/Additional Library Directors:
Enter there the directory where it is your library(////your_solution_name/Debug) and then after
you have built the static library(Build Project/Solution) you go to Linker/Input and inside
Additional Dependencies you enter pricing_cpp_dll.lib or, more generally, name_of_project.lib.
Now the third project recognizes the second project(the static library) and you can go further to
the VBA project.
In my case, inside Sheet3 I work with my data.
The code entered in VBA is the following:
Declare Function bond_price_vba Lib _
"C:\users\theodor\documents\visual studio 2015\Projects\interface2\Debug\pricing_dll.dll" Alias
"_bond_price@56" _
(ByVal F As Double, ByVal c1 As Double, ByVal c2 As Double, ByVal T As Double, ByVal t1
As Double, ByVal t2 As Double, ByVal r As Double) _
As Double

Sub bond_pricing()
Sheet3.Cells(1, 1).Value = bond_price_vba(1000, 0, 0, 1, 0, 0, 0)
Sheet3.Cells(1, 2).Value = bond_price_vba(1000, 0, 0, 1, 0, 0, 0.1)
Sheet3.Cells(2, 1).Value = bond_price_vba(1000, 0, 0, 1, 0, 0, 0.1)
End Sub
Lets analyse this a bit:
First you must declare your function exported from C++ DLL.
After Function you have the name of the function you want to use inside VBA(not the function
from C++ necessarly but you can declare the same).Lib means that you are using a library.
The library is inside the Visual_Studio_2015/Projects/your_solution/Debug folder and must have
the dll extension. The Alias means how is named inside C++.
@56 means the number of bytes occupied by the variables.In my case, I have 7 parameters as
arguments,of type double,each double occupying in VBA 8 bytes.
If I had two, I would declare @16.
Question: How would I declare this function if I had two int parameters,knowing that an int has 4
bytes size?
After this we can compute inside a Sub or a Function the bond price as seen above.
In the first case, I have a zero-coupon-bond with maturity 1 year and no interest rate(the interest
rate is the 7th argument).See the function built in C++ at the beginning of page 21.
I can also extend this to a range of interest rates,or maturities as you can see below:

Just type inside the first cell under Bond_price column =bond_price_vba(1000,0,0,E2,0,0,0.1)

If I want I can build charts:


Sub create_chart()
Dim rng As Range
Dim cht As Object
Set rng = ActiveSheet.Range("F2:F25")
Set cht = ActiveSheet.Shapes.AddChart2
cht.Chart.SetSourceData Source:=rng
cht.Chart.ChartType = xlXYScatterLines
End Sub

The effect after debugging will be this:

Chart Title
1020

1000

980

960

940

920

900
0 5 10 15 20 25 30

As you can see the bond price is a decreasing function (negative slope) of residual maturity.
REMARK:
Make sure that, in case you want to make changes inside the C++ function, you dont leave open
any applications which might use your dll library, for instance EXCEL&VBA.
Close VBA, close EXCEL,make the changes inside C++, rebuild solution and only after that
reopen the Worksheet File and then VBA.

EXERCISE 23
a)Write a message to a txt file using C++
b)Read the lines from a txt file and display them into C++
c)Count the lines from a txt file in C++
SOLUTION:
a) #include <iostream>
#include <fstream>
#include <string>
using namespace std;
void write1()
{
ofstream myfile;
myfile.open("example1.txt");
myfile << "Write this to a file.\n";
myfile.close();
}

b) void write2()
{
int nr = 0;
string line;
ifstream myfile("example1.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{
cout << line << '\n';
system("PAUSE");
++nr;
}
myfile.close();
cout << "the number of lines is: " << nr<<endl;
}
else cout << "Unable to open file";
}

c) void write3()
{
int nr = 0;
string line;
ifstream myfile("example1.txt");

while (getline(myfile, line))


{
if (myfile.eof())
{
cout << line << '\n';
cout << "This is it!" << endl;
cout << "The number of lines is" << nr << endl;
myfile.close();
}
else
{
cout << line << '\n';
++nr;
}
}
}

d)Empty a txt file and write How are you?.


void write4()
{
ofstream myfile;
myfile.open("example1.txt");
myfile.clear();
myfile << "How are you?\n";
myfile.close();
}

EXERCISE 24(Exceptions)
a)Construct an exception function using a try&catch block;
b)Create a divison by zero exception handling;
c)Create a class inherited from exception which overloads the what() member
SOLUTION:
a) void exception1()
{
int n;
cout << "Size="; cin >> n;
try {
int *p = new int[n];
}
catch (exception &e)
{
cout << "exception" << e.what() << endl;
}
try {
cout << "Throwing an integer exception...\n";
throw 42;
}
catch (int i)
{
cout << "The integer exception was caught,with value: " << i << '\n';
}
}

b) double division(int a, int b)


{
if (b == 0)throw " Division by zero condition ";
return (a / b);
}
double square_root(double x)
{
if (x < 0)throw"negative numbers not allowed";
return sqrt(x);
}
void exception2()
{
int x = 50, y = 13, z = 0; double w;
try
{
z = division(x, z);
cout << z << endl;
}
catch (const char* msg) { cerr << msg << endl; cerr << " watch out!"<< endl; }
try
{
w = division(x, y);
cout << w << endl;
}
catch (const char*msg) { cerr << msg << endl; cerr << "watch out again!" << endl;
}
try
{
w = square_root(13);
cout << w << endl;
}
catch (const char*msg) { cerr << msg << endl; }
try
{
w = square_root(-5);
cout << w << endl;
}
catch (const char *msg) { cerr << msg << endl; }
}

c) class MyException :public exception


{public:
const char * what() const throw() { return "C++ Exception"; }
};
void exception3()
{
try { throw MyException(); }
catch(MyException &e)
{
cout << "MyException caught" << endl;
cout << e.what() << endl;
}
}

d)We throw a message text.Using try and catch messages detect the message type
(char,int,string,other type) and display it.
3, = 0
e)For a function f(n)={ 4, = 1 ,using try and catch write the result of it.
2 + 1, 2
SOLUTIONS:
d) void exception4()
{
try
{
throw "Hello";
}
catch(int &param)
{
cout << "int type exception" << endl;
}
catch (char &param)
{
cout << "char type exception" << endl;
}
catch (double &param) {
cout << "double type exception" << endl;
}
catch (...) { cout << "It's something else" << endl; }
}

e) int fct1(int n)
{
if (n == 0)throw 3;
if (n == 1)throw 4;
return n*n + 1;
}
void exception5(int n)
{
try
{
int w = fct1(n);
cout<<w<<endl;
}
catch (const int &msg) {
cout << msg << endl;
}
catch(...)
{
cout << "Something else happened" << endl;
}
}

REMARK: The last branch is never attained.


f)Create a class exception:
class myexception : public exception
{
virtual const char* what() const throw()
{
return "My exception happened";
}
}myex;
void exception6()
{
try
{
throw myex;//myex behaves here as a constructor, the virtual constructor
being called
//If the const before throw() is deleted, "Unknown exception" message is
displayed
//Same if we give up to both const specifiers
//We can give up to the virtual specifier
}
catch (exception &e)
{
cout << e.what() << '\n';
}
}
EXERCISE 25(Strings)
Replace all the vowels(aeiou) with char *
SOLUTION:
void replace_string_with_char()
{
string str = "Hello everybody!My name is Theodor.";
size_t found = str.find_first_of("aeiou");
while (found != string::npos)
{
str[found] = '*';
found = str.find_first_of("aeiou", found + 1);
}
cout << str << endl;
}

EXERCISE 26
a) Append manually two strings(father and mother for instance)
b) Append a string from a certain position to another string;
c) Add n times a letter to a sequence
d) Read from an input stream and then print the lines into a txt file;
e) Add the string la n times to a predetermined string;
f) Extract from a string n characters starting with position pos;
g) Find the position of the first occurrence of char c within a string.
SOLUTIONS:
a) void string_function_1()
{
string str;
string str2 = "Writing";
string str3 = "print the next line";
str.append(str2);
cout << str << '\n';
str.append(str3, 6, 3);
cout << str << '\n';
str.append("the weather is nice", 8);
cout << str << '\n';
str2.append(" a novel");
cout << str2 << '\n';
str2.append(10u, 't');//adds 10 letters 't' to the sequence;
cout << str2 << '\n';
//str2.append(n u,'c'); is not possible
str2.append(5, 0x2E);//adds 5 points to the sequence;
cout << str2 << '\n';
cout << str2.capacity() <<' '<<str2.size()<< endl;
}

d) void string_function_2()
{
string name;
getline(cin, name);//sort of cin; you enter into the console your name and the
variable name gets it
cout << "Hello," << name << " is my name:" << endl;
string str;
getline(cin, str, '\n');
cout << "The sentence is this one:" << str << '\n';

ofstream myfile;
myfile.clear();
myfile.open("example.txt");
for (int i = 1; i <= 5; i++)
{
getline(cin, str, '\n');
myfile << str<<endl;
}
myfile.close();
}

e) void string_function_3(int n)
{
string name = "Theodor"; char name2[20];
name += " Munteanu";
for (int i = 1; i <= n ; i++)
name += " la ";

f) void substract(int n, int pos)


{
string str; getline(cin, str);
string str2 = str.substr(pos, n);
cout << str2 << endl;
}

g) void first_occurence(string s, char c)


{
cout << s.find_first_of(c);
}

EXERCISE 27
Count the words from a string came from an input stream.
SOLUTION:
void word_counter()
{
const string delims(" \t,.;");
string line;
int cnt = 0;
while (getline(cin, line))
{
string::size_type begId, endId;
begId = line.find_first_not_of(delims);
while (begId != string::npos)
{
cnt++;
endId = line.find_first_of(delims, begId);
if (endId != string::npos)
begId = line.find_first_not_of(delims, endId);
else
begId = string::npos;

}
}
cout << cnt << "words\n";
}

EXERCISE 28
a)Swap two predetermined strings;
b)compare two strings and display an adequate message;
c)swap two arbitrary strings;
d)Order a set of words in a string.
SOLUTION:
a) void swap_strings()
{
string buyer("money");
string seller("goods");
cout << "Before the swap,buyer has " << buyer << " and seller has " << seller <<
endl;
seller.swap(buyer);
cout << "After the swap,buyer has" << buyer << " and seller has " << seller <<
endl;
}
b) void compare_strings()
{
string str1("red apple"), str2("green apple");
cout << str1.compare(str2) << endl;
if (str1.compare(str2) < 0)cout << "the first string " << str1 << "is lower";
else if (str1.compare(str2) == 0)cout << "the two strings are equal";
else cout << "the second string " << str2 << " is lower " << endl;
}
c) void swap_strings(string s1,string s2)
{
if (s1.compare(s2) > 0)s2.swap(s1);
cout << s1 << ' ' << s2<<endl;
}

EXERCISE 29
Create a date class which should contain the following:
a)At least 2 constructors
b)An ostream operator,to display the date
c)Comparison operators
d)Add days to a certain date
SOLUTION:
class date
{
protected:
int year_, month_, day_;
public:
date():year_(0),month_(0),day_(0){}
date(int year, int month, int day)
{
try
{
if (month > 12 || month < 0 || day < 0 || day>30)throw "incorrect
data";
year_ = year; month_ = month; day_ = day;
}
catch(char *msg)
{
cerr<<msg<<endl;
}
}
int get_year()
{
return year_;
}
int get_month()
{
return month_;
}
int get_day()
{
return day_;
}
bool operator==(const date&d1)const
{
if (d1.day_ == day_&&d1.month_ == month_&&d1.year_ == year_)
{
cout << "the two dates are the same";
return true;
}
else
{
cout << "the two dates are different";
return false;
}
}
bool operator<(const date& d1)const
{
if (year_ < d1.year_)return true;
else if (year_ == d1.year_)
if (month_ < d1.month_)return true;
else if (month_ == d1.month_)
if (day_ <= d1.day_)return true;
else return false;
else return false;
else return false;

void add_day(int day)


{
day_ = (day_ + day) % 30;
if (month_ < 12)
{
if (day_ + day > 30)month_ = month_ + 1;
}
else
{
if (day_ + day > 30) {
month_ = 1; year_ = year_ + 1;
}
}
}
};
ostream& operator<<(ostream& os, date& d)
{
os << d.get_day() << '/' << d.get_month() << '/' << d.get_year() << endl;
return os;
}

TO TEST THE FUNCTIONALITY,here is the code inside main()


Int main()
{
date d1(1991, 11, 4);
cout << d1;
date d2(1991, 13, 4);//Incorrect date
d1.add_day(15);
cout << d1;//19/11/1991
d1.add_day(20);
cout << d1;
date d3(1991, 10, 4);
if (d1 == d3)
cout << "Y"<<endl;
else
cout<<"N"<<endl;
bool x1 = d3 < d1;
cout << x1 << endl;
bool x2 = d1 < d3;
cout << x2 << endl;
date d4(1991, 11, 14), d5(1991, 11, 15);
cout << (d4 < d5) << endl;
d4.add_day(2);
cout << (d4 < d5) << endl;}

EXERCISE 30
Verify if k is a Fibonacci number among the first N Fibonacci numbers:
SOLUTION:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void fibonacci(int N,int k)
{
vector<int> v;
v.push_back(1);
v.push_back(1);
for (int i = 2; i <= N; ++i)
v.push_back(v[i - 1] + v[i - 2]);
if (binary_search(v.begin(), v.end(), k))
cout << k << "is a Fibonacci number" << endl;
else
cout << k << "is not a Fibonacci number";
}
ACCUMULATE()
void strings2a()
{
vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = accumulate(v.begin(), v.end(), 0);
cout << sum << endl;
int sum2 = accumulate(v.begin(), v.end(), 11);
cout << sum2 << endl;
int prod = accumulate(v.begin(), v.end(), 1, multiplies<int>());
cout << prod << endl;
string s = accumulate(next(v.begin()), v.end(), to_string(v[0]), [](string a, int
b) {return a + '-' + to_string(b); });
cout << "dash-separated string " << s << endl;
//the last accumulate uses a built-inline function
int prod2 = accumulate(next(v.begin()), v.end() - 3, 1, multiplies<int>());
cout << prod2 << endl;
vector<int> v2 = { 3,5,2,11,7 };
int sum3 = accumulate(next(v2.begin()), v2.end(), 0);//passes the first
element,the sum is 25.
cout << sum3 << endl;
cout << accumulate(v2.begin(), v2.end()-1, 0) << endl;
int s2 = accumulate(v.begin(), v.end(), 0, [](int a, int b) {return a + 2 * b;
});//to the previous sum we add2 times
//the number is next
cout << s2 << endl;
int s3 = accumulate(v.begin(), v.begin() + 3, 0, [](int a, int b) {return 2 * a +
b; });
cout << s3 << endl;
int s4 = accumulate(v.begin(), v.begin() + 4, 0, [](int a, int b) {return 2 * a +
b; });
cout << s4 << endl;
}

EXERCISE 31
WRITE a class for a 2D point and then make a template function that compuse the partial
derivatives,and the gradient of a two variable function. Test this on some sample functions after.

SOLUTION:
class point
{
protected:
double x_;
double t_;
public:
point() {}
point(double x, double t) :x_(x), t_(t) {}
double first()
{
return x_;
}
double second()
{
return t_;
}
friend std::ostream & operator<<(std::ostream& os, point &p)
{
os << p.x_ << ',' << p.t_;
return os;
}
};
As for the template functions,we have the following:
template <typename function>
double df1(const function &f, double x, double t, double h)
{
if (h <= 0)throw "invalid step size";
return (f(x + h, t) - f(x, t)) / h;
}
OR, more elegant:
#include "point.h"
template <typename function>
double df1prime(const function &f, point &p, double h)
{
if (h <= 0)throw "invalid step size";
return (f(p.first() + h, p.second()) - f(p.first(), p.second())) / h;
}

template <typename function>


double df2prime(const function &f, point &p, double h)
{
if (h <= 0)throw "invalid step size";
return (f(p.first(), p.second() + h) - f(p.first(), p.second())) / h;
}
template <typename function>
point gradient(const function &f, point &p, double h1, double h2)
{
if (h1 <= 0 || h2 <= 0)throw "invalid step size";
return point(df1prime(f, p, h1), df2prime(f, p, h2));
}

REMARK:
The definition and declaration of point can be done in a more elegant way:
#include <utility>
#include <iostream>
using namespace std;
template <class T,class U>
class point
{
T x_; U y_;
pair<T, U> p;
public:
point():x_(0),y_(0){}
point(T x, U y) { x_ = x; y_ = y; }
T first() { return x_; }
U second() { return y_; }

};
template <typename T,typename U>
ostream& operator<<(ostream&os, point<T,U> &p)//we define an ostream operator for points
{
os << p.first() << ',' << p.second();
return os;
}
Main()
#include "point.h"
using namespace std;
int main()
{
point<int, int> p1(1, 1);
point<int, double> p2(1, 2.1);
cout << p1 << endl;
cout << p2 << endl;
system("pause");
}
TUPLES
void ntuple()
{
auto mytuple = make_tuple(10, 3.1, 2.1);
tuple_element<0, decltype(mytuple)>::type first = get<0>(mytuple);
tuple_element<1, decltype(mytuple)>::type second = get<1>(mytuple);
tuple_element<2, decltype(mytuple)>::type third = get<2>(mytuple);
cout << "mytuple contains: " << first << " , " << second << " and "<<third<<'\n';
vector<int>v = { 2,3,4,5 };
auto mytuple2 = make_tuple(v);

}
EXERCISE 32
BINOMIAL TREES: usage for option pricing;
Solution:
vector<vector<double>> binomial_tree(const double&S0, const double&u, const double &d,
const int&no_steps)
{
vector<vector<double>> tree;
for (int i = 1; i <= no_steps; i++)
{
vector<double> S(i);
for(int j=0;j<i;j++)
{
S[j] = S0*pow(u, j)*pow(d, i - j - 1);
}
tree.push_back(S);
};
return tree;
}
Another solution:

vector<vector<double>> binomial_tree2(double r0, double u, double d, int no_of_steps)


{
vector<vector<double>> tree;
vector<double> r(1); r[0] = r0;
tree.push_back(r);
for (int i = 1; i <= no_of_steps; ++i) {
double rtop = r[r.size()-1] * u;
for (int j = 0; j<i; ++j) {
r[j] = d*r[j];
}
r.push_back(rtop);
tree.push_back(r);
};
return tree;
};
Vasicek binomial tree:
vector<vector<double>> vasicek_binomial_rate(double r0,double a, double b, double sigma,
int no_of_steps,double dt)
{
vector<vector<double>> tree_rate;
// vector<double> prob;
vector<double> r(1); r[0] = r0;
tree_rate.push_back(r);
for (int i = 1; i <= no_of_steps; ++i)
{
double rtop = r[r.size() - 1] + sigma*sqrt(dt);
for (int j = 0; j < i; ++j)
{
r[j] = r[j] - sqrt(dt)*sigma;
}
r.push_back(rtop);
tree_rate.push_back(r);
};
return tree_rate;
}
EXERCISE 33
a)Create uniform samples generating function
b)Create N(0,1) sample generating function
c)Generate a sample of lognormal random variable observations
d)Using Monte-Carlo compute the price of an european call option.
e)Export to VBA the call price function.
SOLUTIONS:
a) double random_uniform_0_1(void)
{
return double(rand()) / double(RAND_MAX);
}
b) double random_normal(void)
{
double U1, U2, V1, V2;
double S = 2;
while (S >= 1)
{
U1 = random_uniform_0_1();//no parameters since it has void as argument;
U2 = random_uniform_0_1();
V1 = 2.0*U1 - 1.0;
V2 = 2.0*U2 - 1.0;
S = pow(V1, 2) + pow(V2, 2);
};
double X1 = V1*sqrt((-2.0*log(S)) / S);
return X1;
}
c) double simulate_lognormal_random_variable(const double&S, const double&r, const
double&sigma, const double&time)
{
double R = (r - 0.5*pow(sigma, 2))*time;
double SD = sigma*sqrt(time);
return S*exp(R + SD*random_normal());
};
d) double option_price_call_european_simulated(const double&S, const double&K, const
double&r, const double& sigma,
const double& time,const int& no_sims)
{
double R = (r - 0.5*pow(sigma, 2))*time;
double SD = sigma*sqrt(time);
double sum_payoffs = 0.0;
for(int n=1;n<=no_sims;n++)
{
double S_T = S*exp(R + SD*random_normal());
sum_payoffs += max(0.0, S_T - K);//if you write max(0,S_T-K) it is not
recognized because it is a maximum between
//an integer and a double
//must use algorithm header

};
return exp(-r*time)*(sum_payoffs / double(no_sims));
};
e) #define M2API __declspec(dllexport)
extern "C"
{M2API double __stdcall option_price_call_european( double S, double K, double r, double
sigma,
double time, int no_sims);
}

INSIDE VBA:
Declare Function call_price Lib _
"C:\Users\theodor\Documents\Visual Studio
2015\Projects\term_structure_dll\Debug\term_structure_c_dll.dll" Alias _
"_option_price_call_european" (ByVal S As Double, ByVal K As Double, ByVal r
As Double, ByVal sigma As Double, ByVal time As Double _
, ByVal no_sims As Integer) As Double
Sub test()
MsgBox call_price(100, 100, 0.1, 0.25, 0.5, 300)
MsgBox Sheet2.Cells(8, 1) / 360#
End Sub

Das könnte Ihnen auch gefallen