Beruflich Dokumente
Kultur Dokumente
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 << ',';
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;
g3) v2.insert(v2.begin()+pos3,w.begin(),w.end());
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); }
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;
}
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;
}
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;
}
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++)
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]);
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;
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;
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;
int N = 100;
double w;
w = integrale(f3, a, b, N);
return w;
}
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++)
{
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;
}
void normal01(int p)
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;
}
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():
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_;
};
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
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);
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);
}
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);
}
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
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)
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");
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';
}
}
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 ¶m)
{
cout << "int type exception" << endl;
}
catch (char ¶m)
{
cout << "char type exception" << endl;
}
catch (double ¶m) {
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;
}
}
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 ";
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;
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;
}
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:
};
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