有限差分法简介: 有限差分方法(FDM)是计算机数值模拟最早采用的方法,至今仍被广泛运用。该方法将求解域划分为差分网格,用有限个网格节点代替连续的求解域。有限差分法以Taylor级数展开等方法,把控制方程中的导数用网格节点上的函数值的差商代替进行离散,从而建立以网格节点上的值为未知数的代数方程组。该方法是一种直接将微分问题变为代数问题的近似数值解法,数学概念直观,表达简单,是发展较早且比较成熟的数值方法。对于有限差分格式,从格式的精度来划分,有一阶格式、二阶格式和高阶格式。从差分的空间形式来考虑,可分为中心格式和逆风格式。考虑时间因子的影响,差分格式还可以分为显格式、隐格式、显隐交替格式等。目前常见的差分格式,主要是上述几种形式的组合,不同的组合构成不同的差分格式。差分方法主要适用于有结构网格,网格的步长一般根据实际地形的情况和柯朗稳定条件来决定。 构造差分的方法有多种形式,目前主要采用的是泰勒级数展开方法。其基本的差分表达式主要有三种形式:一阶向前差分、一阶向后差分、一阶中心差分和二阶中心差分等,其中前两种格式为一阶计算精度,后两种格式为二阶计算精度。通过对时间和空间这几种不同差分格式的组合,可以组合成不同的差分计算格式。 金融工程中的应用: 期权定价中资产价格变化对应的随机微分方程(组)可以转化成为一个偏微分方程(组),确切的说是扩散方程(也叫热传导方程、抛物方程),于是,期权定价问题就转化为求解一个扩散方程(组)初值问题。解扩散方程的有效方法之一就是有限差分法,Duffy曾经说过,金融工程中的计算75%是有限差分法,他本人也写了一本不错的书(见书籍推荐)。 实际应用中有两种格式的差分形式:显式差分,隐式差分。显式差分的实现较隐式差分简单,不涉及解方程组,但效果不如隐式差分,数值解可能不收敛于真实解。 C++程序示例: #include<iostream>
#include<math.h>
#include"runtime.h"
#include"Matrix.h"
using namespace std;
int main()
{
clock_t t1,t2;
t1=clock();
double S0=50,k=50,T=5.0/12,sigma=0.4,r=0.1;
double Smax=200,ds=0.25,dt=T/300;
int M=int(Smax/ds),N=int(T/dt);
ds=Smax/M;
dt=T/N;
Matrix<double> Mat(M+1,N+1,'0');
int i;
for (i=1;i<=M+1;i++)
Mat(i,N+1)=max(0.0,k-(i-1)*ds);
for (i=1;i<=N+1;i++)
{
Mat(1,i)=k*exp(-r*dt*(N+1-i));
Mat(M+1,i)=0.0;
}
Matrix<double> L(M-1,M-1,'0');
for (i=1;i<=M-1;i++)
L(i,i)=1.0+sigma*sigma*dt*(i)*(i)+r*dt;
for (i=1;i<=M-2;i++)
{
L(i+1,i)=0.5*(r*dt*(i+1)-sigma*sigma*dt*(i+1)*(i+1));
L(i,i+1)=-0.5*(r*dt*(i)+sigma*sigma*dt*(i)*(i));
}
Matrix<double> temp(M-1,1,'0');
Matrix<double> O(M-1,1,'0');
Matrix<double> Ta(M-1,1,'0');
Matrix<double> Tb(M-1,1,'0');
for (i=N;i>=1;i--)
{
temp=O;
temp(1,1)=(0.5*(r*dt-sigma*sigma*dt))*Mat(1,i+1);
temp(M-1,1)=(-0.5*(r*dt*(M-1)+sigma*sigma*dt*(M-1)*(M-1)))*Mat(M+1,i+1);
int j;
for (j=1;j<=M-1;j++)
Ta(j,1)=Mat(j+1,i+1);
Ta=Ta-temp;
Tb.tridag_solve(L,Ta,Tb);
for (j=1;j<=M-1;j++)
Mat(j+1,i)=Tb(j,1);
}
t2=clock();
cout<<"price="<<Mat(201,1)<<endl;
runtime(t1-t2);
}
该程序计算的是现价50,执行价50,期限5个月,利率0.1,波动率0.4的欧式看跌期权价格,使用隐式差分格式,可以用MATLAB的blsprice()函数检验下。程序中的tridag_solve()专门用于解决“三对角”线性方程(算法源于Numerical Recipes in C++) |