Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
cantaro86
GitHub Repository: cantaro86/Financial-Models-Numerical-Methods
Path: blob/master/src/C/PDE_solver.c
1700 views
1
#include "PDE_solver.h"
2
3
4
5
6
double PDE_SOR(int Ns, int Nt, double S, double K, double T, double sig, double r, double w)
7
{
8
9
const double eps = 1e-10;
10
const int N_max = 600;
11
12
double S_max = 3*K;
13
double S_min = K/3;
14
double x_max = log(S_max);
15
double x_min = log(S_min);
16
17
double dx = (x_max - x_min)/(Ns-1);
18
double dt = T/Nt;
19
20
double sig2 = sig*sig;
21
double dxx = dx * dx;
22
double aa = ( (dt/2) * ( (r-0.5*sig2)/dx - sig2/dxx ) );
23
double bb = ( 1 + dt * ( sig2/dxx + r ) );
24
double cc = (-(dt/2) * ( (r-0.5*sig2)/dx + sig2/dxx ) );
25
26
27
// array allocations
28
double *x = calloc(Ns, sizeof(double) );
29
double *x_old = calloc(Ns-2, sizeof(double) );
30
double *x_new = calloc(Ns-2, sizeof(double) );
31
double *help_ptr = calloc(Ns-2, sizeof(double) );
32
double *temp;
33
34
for (unsigned int i=0; i<Ns; ++i) // price vector
35
x[i] = exp(x_min + i * dx);
36
37
for (unsigned int i=0; i<Ns-2; ++i) // payoff
38
x_old[i] = fmax( x[i+1] - K, 0 );
39
40
41
// Backward iteration
42
for (int k=Nt-1; k>=0; --k)
43
{
44
x_old[Ns-3] -= cc * ( S_max - K * exp( -r*(T-k*dt) ) ); // offset
45
x_new = SOR_aabbcc(aa, bb, cc, x_old, help_ptr, x_new, Ns-2, w, eps, N_max); //SOR solver
46
// x_new = SOR_abc(aa, bb, cc, x_old, Ns-2, w, eps, N_max); //SOR solver
47
48
if (k != 0) // swap the pointers (we don't need to allocate new memory)
49
{
50
temp = x_old;
51
x_old = x_new;
52
x_new = temp;
53
}
54
}
55
free(help_ptr);
56
free(x_old);
57
58
// x_new is the solution!!
59
60
// binary search: Search for the points for the interpolation
61
62
int low = 1;
63
int high = Ns-2;
64
int mid;
65
double result = -1;
66
67
if (S > x[high] || S < x[low])
68
{
69
printf("error: Price S out of grid.\n");
70
free(x_new);
71
free(x);
72
return result;
73
}
74
75
while ( (low+1) != high)
76
{
77
78
mid = (low + high) / 2;
79
80
if ( fabs(x[mid]-S)< 1e-10 )
81
{
82
result = x_new[mid-1];
83
free(x_new);
84
free(x);
85
return result;
86
}
87
else if ( x[mid] < S)
88
{
89
low = mid;
90
}
91
else
92
{
93
high = mid;
94
}
95
}
96
97
// linear interpolation
98
result = x_new[low-1] + (S - x[low]) * (x_new[high-1] - x_new[low-1]) / (x[high] - x[low]) ;
99
free(x_new);
100
free(x);
101
return result;
102
}
103
104