📄 integral.inl
字号:
// Integral.inl 数值积分头文件
// Ver 1.0.0.0
// 版权所有(C) 2002
// 最后修改: 2002.5.31.
#ifndef _INTEGRAL_INL //避免多次编译
#define _INTEGRAL_INL
//变步长梯形法求积
template <class _Ty>
_Ty IntegralTrapezia(_Ty a, _Ty b, _Ty eps)
{
_Ty t;
_Ty fa = FunctionValueIT(a);
_Ty fb = FunctionValueIT(b);
int n(1);
_Ty h = b - a;
_Ty t1 = h * (fa + fb) / 2.0;
_Ty p = eps + 1.0;
while(p > eps || FloatEqual(p, eps))
{
_Ty s(0);
for(int k=0; k<n; k++)
{
_Ty x = a + (k + 0.5) * h;
s = s + FunctionValueIT(x);
}
t = (t1 + h * s) / 2.0;
p = Abs(t1 - t);
t1 = t;
n = n + n;
h = h / 2.0;
}
return(t);
}
//变步长辛卜生法求积
template <class _Ty>
_Ty IntegralSimpson1D(_Ty a, _Ty b, _Ty eps)
{
_Ty s2;
int n(1);
_Ty h = b - a; //步长
_Ty t1 = h * (FunctionValueIS1D(a) + FunctionValueIS1D(b)) / 2.0;
_Ty s1 = t1;
_Ty ep = eps + 1.0;
while(ep > eps || FloatEqual(ep, eps))
{
_Ty p(0);
for(int k=0; k<n; k++)
{
_Ty x = a + (k + 0.5) * h;
p = p + FunctionValueIS1D(x);
}
_Ty t2 = (t1 + h * p) / 2.0;
s2 = (4.0 * t2 - t1) / 3.0;
ep = Abs(s2 - s1);
t1 = t2;
s1 = s2;
n = n + n;
h = h / 2.0;
}
return(s2);
}
//自适应梯形法求积
template <class _Ty>
_Ty IntegralTrapeziaSelfAdapt(_Ty a, _Ty b, _Ty eps, _Ty d)
{
valarray<_Ty> t(2);
_Ty h = b - a;
t[0]=0.0;
_Ty f0 = FunctionValueITSA(a);
_Ty f1 = FunctionValueITSA(b);
_Ty t0 = h * (f0 + f1) / 2.0;
ITSA(a,b,h,f0,f1,t0,eps,d,t);
_Ty z = t[0];
return(z);
}
//自适应梯形法求积辅助函数
template <class _Ty>
int ITSA(_Ty x0, _Ty x1, _Ty h, _Ty f0, _Ty f1, _Ty t0,
_Ty eps, _Ty d, valarray<_Ty>& t)
{
_Ty x = x0 + h / 2.0;
_Ty f = FunctionValueITSA(x);
_Ty t1=h*(f0+f)/4.0;
_Ty t2=h*(f+f1)/4.0;
_Ty p=Abs(t0-(t1+t2));
if((p<eps)||(h/2.0<d))
{
t[0]=t[0]+(t1+t2);
return(0);
}
else
{
_Ty g=h/2.0;
_Ty eps1=eps/1.4;
ITSA(x0,x,g,f0,f,t1,eps1,d,t);
ITSA(x,x1,g,f,f1,t2,eps1,d,t);
return(1);
}
}
//龙贝格法求积
template <class _Ty>
_Ty IntegralRomberg(_Ty a, _Ty b, _Ty eps)
{
_Ty y[10], q;
_Ty h = b - a; //步长
y[0] = h * (FunctionValueR(a) + FunctionValueR(b)) / 2.0;
int m(1), n(1);
_Ty ep=eps+1.0;
while((ep>eps || FloatEqual(ep,eps)) && (m <= 9))
{
_Ty p(0);
for(int i=0;i<n;i++)
{
_Ty x = a + (i + 0.5) * h;
p = p + FunctionValueR(x);
}
p = (y[0] + h * p) / 2.0;
_Ty s(1);
for(int k=1; k<=m; k++)
{
s = 4.0 * s;
q = (s * p - y[k-1]) / (s - 1.0);
y[k-1] = p;
p = q;
}
ep = Abs(q - y[m-1]);
m = m + 1;
y[m-1] = q;
n = n + n;
h = h / 2.0;
}
return(q);
}
//一维连分式法求积
template <class _Ty>
_Ty IntegralFraction1D(_Ty a, _Ty b, _Ty eps)
{
valarray<_Ty> h(10), bb(10);
int m(1), n(1), k, l, j;
_Ty g, hh = b - a;
h[0] = hh;
_Ty t1 = hh * (FunctionValueF1D(a) + FunctionValueF1D(b)) / 2.0;
_Ty s1 = t1;
bb[0]=s1;
_Ty ep = 1.0 + eps;
while((ep>eps || FloatEqual(ep,eps)) && (m <= 9))
{
_Ty s(0);
for(k=0; k<n; k++)
{
_Ty x = a + (k + 0.5) * hh;
s = s + FunctionValueF1D(x);
}
_Ty t2 = (t1 + hh * s) / 2.0;
m++;
h[m-1] = h[m-2] / 2.0;
g = t2;
l = 0;
j = 2;
while((l==0) && (j<=m))
{
s = g - bb[j-2];
if(FloatEqual(s,0)) l = 1;
else g = (h[m-1] - h[j-2]) / s;
j++;
}
bb[m-1] = g;
if(l!=0) bb[m-1] = 1.0e+35;
g = bb[m-1];
for(j=m; j>=2; j--) g = bb[j-2] - h[j-2] / g;
ep = Abs(g-s1);
s1 = g;
t1 = t2;
hh = hh / 2.0;
n = n + n;
}
return(g);
}
//高振荡函数法求积
template <class _Ty>
void IntegralSurge(_Ty a, _Ty b, int m, valarray<_Ty>& fa,
valarray<_Ty>& fb, valarray<_Ty>& s)
{
_Ty sa[4],sb[4],ca[4],cb[4];
int n = fa.size(); //给定积分区间两端点上的导数最高阶数+1
int mm=1;
_Ty sma=sin(m*a);
_Ty smb=sin(m*b);
_Ty cma=cos(m*a);
_Ty cmb=cos(m*b);
sa[0] = ca[3] = sma;
sa[1] = ca[0] = cma;
sa[2] = ca[1] = -sma;
sa[3] = ca[2] = -cma;
sb[0] = cb[3] = smb;
sb[1] = cb[0] = cmb;
sb[2] = cb[1] = -smb;
sb[3] = cb[2] = -cmb;
s[0] = s[1] = 0.0;
for(int k=0; k<n; k++)
{
int j = k;
while(j>=4) j = j - 4;
mm = mm * m;
s[0] = s[0]+(fb[k]*sb[j]-fa[k]*sa[j])/(1.0*mm);
s[1] = s[1]+(fb[k]*cb[j]-fa[k]*ca[j])/(1.0*mm);
}
s[1] = -s[1];
}
//勒让德-高斯法求积
template <class _Ty>
_Ty IntegralLegendreGauss(_Ty a, _Ty b, _Ty eps)
{
_Ty t[5] =
{
-0.9061798459, -0.5384693101, 0.0, 0.5384693101, 0.9061798459
};
_Ty c[5] =
{
0.2369268851, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268851
};
int m(1);
_Ty g;
_Ty h = b - a;
_Ty s = Abs(0.001 * h);
_Ty p = 1.0e+35;
_Ty ep = eps + 1.0;
while((ep > eps || FloatEqual(ep,eps)) && (Abs(h) > s))
{
g = 0;
for(int i=1; i<=m; i++)
{
_Ty aa = a + (i - 1.0) * h;
_Ty bb = a + i * h;
_Ty w(0);
for(int j=0; j<5; j++)
{
_Ty x = ((bb - aa) * t[j] + (bb + aa)) / 2.0;
w = w + FunctionValueLegG(x) * c[j];
}
g += w;
}
g = g * h / 2.0;
ep = Abs(g - p) / (1.0 + Abs(g));
p = g;
m++;
h = (b - a) / m;
}
return(g);
}
//拉盖尔-高斯法求积
template <class _Ty>
void IntegralLaguerreGauss(_Ty& dValue)
{
_Ty x;
dValue = 0.0;
long double t[5] =
{
0.26355990, 1.41340290, 3.59642600, 7.08580990, 12.64080000
};
long double c[5] =
{
0.6790941054, 1.638487956, 2.769426772, 4.315944000, 7.104896230
};
for(int i=0; i<5; i++)
{
x = t[i];
dValue = dValue + c[i] * FunctionValueLagG(x);
}
}
//埃尔米特-高斯法求积
template <class _Ty >
void IntegralHermiteGauss(_Ty& dValue)
{
_Ty t[5] =
{
-2.02018200, -0.95857190, 0.0, 0.95857190, 2.02018200
};
_Ty c[5] =
{
1.181469599, 0.9865791417,0.9453089237, 0.9865791417,1.181469599
};
dValue = 0;
for(int i=0; i<5; i++)
{
_Ty x = t[i];
dValue = dValue + c[i] * FunctionValueHG(x);
}
}
//切比雪夫法求积
template <class _Ty >
_Ty IntegralChebyshev(_Ty a, _Ty b, _Ty eps)
{
_Ty t[5]={-0.8324975, -0.3745414, 0.0, 0.3745414, 0.8324975};
int m(1);
_Ty g;
_Ty h = b - a;
_Ty d = Abs(0.001 * h);
_Ty p = 1.0e+35;
_Ty ep = eps + 1.0;
while((ep > eps || FloatEqual(ep,eps)) && (Abs(h) > d))
{
g = 0.0;
for(int i=1; i<=m; i++)
{
_Ty aa = a + (i - 1.0) * h;
_Ty bb = a + i * h;
_Ty s(0);
for(int j=0; j<5; j++)
{
_Ty x = ((bb - aa) * t[j] + (bb + aa)) / 2.0;
s = s + FunctionValueCb(x);
}
g += s;
}
g = g * h / 5.0;
ep = Abs(g - p) / (1.0 + Abs(g));
p = g;
m++;
h = (b - a) / m;
}
return(g);
}
//一维蒙特卡洛法求积
template <class _Ty >
_Ty IntegralMonteCarlo1D(_Ty a, _Ty b)
{
_Ty r(1), s(0), d(10000);
for(int m=0; m<10000; m++)
{
_Ty x = a + (b - a) * rand_01_One(r); //取随机数
s = s + FunctionValueMC1D(x) / d; //调用被积函数值
}
s = s * (b - a);
return(s);
}
//二重变步长辛卜生法求积
template <class _Ty>
_Ty IntegralSimpson2D(_Ty a, _Ty b, _Ty eps)
{
int n(1);
_Ty h = 0.5 * (b - a); //步长
_Ty d = Abs((b - a) * 1.0e-06);
_Ty s1 = IntegralSimp2(a, eps); //调用IntegralSimp2函数
_Ty s2 = IntegralSimp2(b, eps);
_Ty t1 = h * (s1 + s2);
_Ty s0(1.0e+35), s;
_Ty ep = eps + 1.0;
while((ep>eps||FloatEqual(ep,eps))&&((Abs(h)>d)||(n<16)))
{
_Ty x = a - h;
_Ty t2 = 0.5 * t1;
for(int j=1; j<=n; j++)
{
x = x + 2.0 * h;
t2 = t2 + h * IntegralSimp2(x,eps);
}
s = (4.0 * t2 - t1) / 3.0;
ep = Abs(s - s0) / (1.0 + Abs(s));
n = n + n;
s0 = s;
t1 = t2;
h = h * 0.5;
}
return(s);
}
//二重变步长辛卜生法求积辅助函数
template <class _Ty>
_Ty IntegralSimp2(_Ty x, _Ty eps)
{
valarray<_Ty> y(2);
int n(1);
FunctionBoundaryIS2D(x, y);
_Ty h = 0.5 *(y[1] - y[0]);
_Ty d = Abs(h * 2.0e-06);
_Ty t1 = h * (FunctionValueIS2D(x, y[0]) + FunctionValueIS2D(x, y[1]));
_Ty ep = 1.0 + eps;
_Ty g0(1.0e+35), g;
while((ep>eps||FloatEqual(ep,eps))&&((Abs(h)>d)||(n<16)))
{
_Ty yy = y[0] - h;
_Ty t2 = 0.5 * t1;
for(int i=1; i<=n; i++)
{
yy = yy + 2.0 * h;
t2 = t2 + h * FunctionValueIS2D(x, yy);
}
g = (4.0 * t2 - t1) / 3.0;
ep = Abs(g - g0) / (1.0 + Abs(g));
n = n + n;
g0 = g;
t1 = t2;
h = 0.5 * h;
}
return(g);
}
//多重高斯法求积
template <class _Ty >
_Ty IntegralGaussMD(valarray<_Ty>& js)
{
valarray<_Ty> y(2);
_Ty p, s;
_Ty t[5] =
{
-0.9061798459,-0.5384693101,0.0, 0.5384693101,0.9061798459
};
_Ty c[5] =
{
0.2369268851,0.4786286705,0.5688888889, 0.4786286705,0.2369268851
};
int n = js.size(); //积分重数
valarray<int> is(2*(n+1));
valarray<_Ty> x(n);
valarray<_Ty> a(2*(n+1));
valarray<_Ty> b(n+1);
int m(1), l(1);
a[n] = a[2*n+1] = 1.0;
while(l==1)
{
for(int j=m; j<=n; j++)
{
FunctionBoundaryGMD(j-1,x,y);
a[j-1]=0.5*(y[1]-y[0])/js[j-1];
b[j-1]=a[j-1]+y[0];
x[j-1]=a[j-1]*t[0]+b[j-1];
a[n+j]=0.0;
is[j-1]=1; is[n+j]=1;
}
j = n;
int q = 1;
while(q==1)
{
int k = is[j-1];
if(j==n) p = FunctionValueGMD(x);
else p = 1.0;
a[n+j]=a[n+j+1]*a[j]*p*c[k-1]+a[n+j];
is[j-1] = is[j-1] + 1;
if(is[j-1] > 5)
if(is[n+j] >= js[j-1])
{
j = j - 1;
q = 1;
if(j==0)
{
s = a[n+1] * a[0];
return(s);
}
}
else
{
is[n+j]=is[n+j]+1;
b[j-1]=b[j-1]+a[j-1]*2.0;
is[j-1]=1; k=is[j-1];
x[j-1]=a[j-1]*t[k-1]+b[j-1];
if(j==n) q = 1;
else q = 0;
}
else
{
k = is[j-1];
x[j-1] = a[j-1]*t[k-1]+b[j-1];
if(j==n) q = 1;
else q = 0;
}
}
m = j + 1;
}
}
//二重连分式法求积
template <class _Ty >
_Ty IntegralFraction2D(_Ty a, _Ty b, _Ty eps)
{
_Ty bb[10],h[10],x,s;
int m(1), n(1);
_Ty hh = b - a;
h[0] = hh;
_Ty s1 = IntegralFraction2D2(a, eps);
_Ty s2 = IntegralFraction2D2(b, eps);
_Ty t1 = hh * (s1 + s2) / 2.0;
_Ty s0 = t1;
bb[0] = t1;
_Ty ep = 1.0 + eps;
while((ep > eps || FloatEqual(ep,eps)) && ( m <= 9))
{
_Ty t2 = 0.5 * t1;
for(int k=0; k<n; k++)
{
x = a + (k + 0.5) * hh;
s1 = IntegralFraction2D2(x,eps);
t2 = t2 + 0.5 * s1 * hh;
}
m = m + 1;
h[m-1] = h[m-2] / 2.0;
_Ty g = t2;
int l(0), j(2);
while((l==0)&&(j<=m))
{
s = g - bb[j-2];
if(FloatEqual(s,0)) l = 1;
else g = (h[m-1] - h[j-2]) / s;
j = j + 1;
}
bb[m-1] = g;
if(l!=0) bb[m-1] = 1.0e+35;
s = bb[m-1];
for(j=m; j>=2; j--) s = bb[j-2] -h [j-2] / s;
ep = Abs(s-s0) / (1.0 + Abs(s));
n = n + n;
t1 = t2;
s0 = s;
hh = hh / 2.0;
}
return(s);
}
//二重连分式法求积辅助函数
template <class _Ty>
_Ty IntegralFraction2D2(_Ty x, _Ty eps)
{
_Ty b[10],h[10],yy,s;
valarray<_Ty> y(2);
int m(1), n(1);
FunctionBoundaryF2D(x, y);
_Ty hh = y[1] - y[0];
h[0] = hh;
_Ty t1=0.5*hh*(FunctionValueF2D(x,y[0])+FunctionValueF2D(x,y[1]));
_Ty s0 = t1;
b[0] = t1;
_Ty ep = 1.0 + eps;
while((ep > eps || FloatEqual(ep, eps)) && (m <= 9))
{
_Ty t2 = 0.5 * t1;
for(int k=0; k<n; k++)
{
yy = y[0] +(k + 0.5) * hh;
t2 = t2 + 0.5 * hh * FunctionValueF2D(x, yy);
}
m = m + 1;
h[m-1] = h[m-2] / 2.0;
_Ty g = t2;
int l(0), j(2);
while((l==0)&&(j<=m))
{
s = g - b[j-2];
if(FloatEqual(s,0)) l = 1;
else g = (h[m-1] - h[j-2]) / s;
j = j + 1;
}
b[m-1] = g;
if(l!=0) b[m-1] = 1.0e+35;
s = b[m-1];
for(j=m; j>=2; j--) s = b[j-2] - h[j-2] / s;
ep = Abs(s - s0) / (1.0 + Abs(s));
n = n + n;
t1 = t2;
s0 = s;
hh = 0.5 * hh;
}
return(s);
}
//多重蒙特卡洛法求积
template <class _Ty >
_Ty IntegralMonteCarlo2D(valarray<_Ty>& a, valarray<_Ty>& b)
{
int i;
int n = a.size(); //积分的重数
valarray<_Ty> x(n);
_Ty r(1), d(10000), s(0);
for(int m=0; m<10000; m++)
{
for(i=0; i<n; i++)
x[i] = a[i] + (b[i] - a[i]) * rand_01_One(r);
s = s + FunctionValueMC2D(n, x) / d;
}
for(i=0; i<n; i++) s = s * (b[i] - a[i]);
return(s);
}
#endif // _INTEGRAL_INL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -