Path: blob/master/src/C/PDE_solver.c
1700 views
#include "PDE_solver.h"12345double PDE_SOR(int Ns, int Nt, double S, double K, double T, double sig, double r, double w)6{78const double eps = 1e-10;9const int N_max = 600;1011double S_max = 3*K;12double S_min = K/3;13double x_max = log(S_max);14double x_min = log(S_min);1516double dx = (x_max - x_min)/(Ns-1);17double dt = T/Nt;1819double sig2 = sig*sig;20double dxx = dx * dx;21double aa = ( (dt/2) * ( (r-0.5*sig2)/dx - sig2/dxx ) );22double bb = ( 1 + dt * ( sig2/dxx + r ) );23double cc = (-(dt/2) * ( (r-0.5*sig2)/dx + sig2/dxx ) );242526// array allocations27double *x = calloc(Ns, sizeof(double) );28double *x_old = calloc(Ns-2, sizeof(double) );29double *x_new = calloc(Ns-2, sizeof(double) );30double *help_ptr = calloc(Ns-2, sizeof(double) );31double *temp;3233for (unsigned int i=0; i<Ns; ++i) // price vector34x[i] = exp(x_min + i * dx);3536for (unsigned int i=0; i<Ns-2; ++i) // payoff37x_old[i] = fmax( x[i+1] - K, 0 );383940// Backward iteration41for (int k=Nt-1; k>=0; --k)42{43x_old[Ns-3] -= cc * ( S_max - K * exp( -r*(T-k*dt) ) ); // offset44x_new = SOR_aabbcc(aa, bb, cc, x_old, help_ptr, x_new, Ns-2, w, eps, N_max); //SOR solver45// x_new = SOR_abc(aa, bb, cc, x_old, Ns-2, w, eps, N_max); //SOR solver4647if (k != 0) // swap the pointers (we don't need to allocate new memory)48{49temp = x_old;50x_old = x_new;51x_new = temp;52}53}54free(help_ptr);55free(x_old);5657// x_new is the solution!!5859// binary search: Search for the points for the interpolation6061int low = 1;62int high = Ns-2;63int mid;64double result = -1;6566if (S > x[high] || S < x[low])67{68printf("error: Price S out of grid.\n");69free(x_new);70free(x);71return result;72}7374while ( (low+1) != high)75{7677mid = (low + high) / 2;7879if ( fabs(x[mid]-S)< 1e-10 )80{81result = x_new[mid-1];82free(x_new);83free(x);84return result;85}86else if ( x[mid] < S)87{88low = mid;89}90else91{92high = mid;93}94}9596// linear interpolation97result = x_new[low-1] + (S - x[low]) * (x_new[high-1] - x_new[low-1]) / (x[high] - x[low]) ;98free(x_new);99free(x);100return result;101}102103104