C 精密积分回路的结束条件
我正在尝试使用梯形规则对函数1/((1+x^2)x^0.5)进行积分。我需要尽可能高的精度,因此我将增加条带数N,直到计算机无法识别连续N的总条带数之间的变化。但是,最终条件目前不起作用,导致连续积分。有人有比我现在的代码更好的建议吗 非常感谢,, 贝丝C 精密积分回路的结束条件,c,while-loop,C,While Loop,我正在尝试使用梯形规则对函数1/((1+x^2)x^0.5)进行积分。我需要尽可能高的精度,因此我将增加条带数N,直到计算机无法识别连续N的总条带数之间的变化。但是,最终条件目前不起作用,导致连续积分。有人有比我现在的代码更好的建议吗 非常感谢,, 贝丝 #包括 #包括 #包括 双内(双x,双h,双y,双N,双总计) { 总计=总计+0.5*(1/(1+pow(x,2))*sqrt(x)); x=x+h; 而(x如果你想对你的数值积分进行自动细化,一种方法是观察积分的相对收敛性 double p
#包括
#包括
#包括
双内(双x,双h,双y,双N,双总计)
{
总计=总计+0.5*(1/(1+pow(x,2))*sqrt(x));
x=x+h;
而(x如果你想对你的数值积分进行自动细化,一种方法是观察积分的相对收敛性
double previous = 0;
double current = inter( x, (y-x)/(N-1), y, N, total ); // Solve some baseline
do
{
N = N + 1000;
h = (y-x)/(N-1);
previous = current;
current = inter( x, h, y, N, total );
} while( abs( current - previous ) / current > 0.001 );
当您在估算中观察到小于0.1%的相对细化后,该代码将停止。减小0.001
将有效地提高您的精度。通常比较双精度的最佳方法是通过公差检查,如:
abs( a - b ) < k
abs(a-b)
其中,k
是您希望达到的精度顺序的一些因素。如果您希望对数值积分进行自动细化,一种方法是查看积分的相对收敛性
double previous = 0;
double current = inter( x, (y-x)/(N-1), y, N, total ); // Solve some baseline
do
{
N = N + 1000;
h = (y-x)/(N-1);
previous = current;
current = inter( x, h, y, N, total );
} while( abs( current - previous ) / current > 0.001 );
当您在估算中观察到小于0.1%的相对细化后,该代码将停止。减小0.001
将有效地提高您的精度。通常比较双精度的最佳方法是通过公差检查,如:
abs( a - b ) < k
abs(a-b)
其中,k
是您希望达到的精度顺序的一些因素。由于f(x)->∞ 作为x->0。在本例中,我将范围更改为1到1000。我还使用了求和函数来最小化对大量值求和时的舍入误差。来自wolframalpha的积分~=.487474,此程序将得到~=.487475。使用此链接可以找到精确的积分:
#包括
#包括
#包括
/*清晰阵列*/
无效清除量(双asum[2048])
{
尺寸i;
对于(i=0;i<2048;i++)
asum[i]=0。;
}
/*在数组中添加一个数字*/
void addtosum(双d,双asum[2048])
{
尺寸i;
而(1){
/*i=d的指数*/
i=((size_t)((*(unsigned long*)和d)>>52))&0x7ff;
如果(i==0x7ff){/*最大指数,则可能溢出*/
asum[i]+=d;
返回;
}
if(asum[i]==0。){/*if空插槽存储d*/
asum[i]=d;
返回;
}
d+=asum[i];/*否则将插槽添加到d,清除插槽*/
asum[i]=0./*并继续,直到插槽为空*/
}
}
/*从数组返回和*/
双返回和(双asum[2048])
{
双和=0。;
尺寸i;
对于(i=0;i<2048;i++)
总和+=asum[i];
回报金额;
}
双外汇(双x)
{
返回1./((1.+x*x)*sqrt(x));
}
双内(双x、双y、双n)
{
双asum[2048];/*用于求和函数*/
双h;
双d;
如果(n<1.){
n=1。;
h=0。;
}否则{
h=(y-x)/(n-1.0);
}
y-=h/2。;
晴朗(asum);
d=0.5*h*fx(x);
addtosum(d,asum);
对于(;x
使用辛普森法则,结果更准确,收敛于n的更小值:
#include<stdio.h>
#include<math.h>
#include<float.h>
/* clear array */
void clearsum(double asum[2048])
{
size_t i;
for(i = 0; i < 2048; i++)
asum[i] = 0.;
}
/* add a number into array */
void addtosum(double d, double asum[2048])
{
size_t i;
while(1){
/* i = exponent of d */
i = ((size_t)((*(unsigned long long *)&d)>>52))&0x7ff;
if(i == 0x7ff){ /* max exponent, could be overflow */
asum[i] += d;
return;
}
if(asum[i] == 0.){ /* if empty slot store d */
asum[i] = d;
return;
}
d += asum[i]; /* else add slot to d, clear slot */
asum[i] = 0.; /* and continue until empty slot */
}
}
/* return sum from array */
double returnsum(double asum[2048])
{
double sum = 0.;
size_t i;
for(i = 0; i < 2048; i++)
sum += asum[i];
return sum;
}
double fx(double x)
{
return 1./((1.+x*x)*sqrt(x));
}
double simpson(double x, double y, double n)
{
double asum[2048]; /* for summation functions */
double h;
double a;
if(n < 1.){
n = 1.;
h = 0.;
} else {
h = (y-x)/(n-1.0);
}
y += h/2.;
clearsum(asum);
for( ; x < y; x += h){
a = h/6.*(fx(x) + 4.*fx(x + h/2.) + fx(x + h));
addtosum(a, asum);
}
a = returnsum(asum);
return a;
}
int main()
{
double x,y,n,value,newvalue;
x=1.0;
y=1000.;
value=0.;
for(n = 1000.; 1; n += 1000.)
{
newvalue=simpson(x,y,n);
printf("new value %.16lf %.0lf\n", newvalue, n);
if(fabs(newvalue-value) < (newvalue*1E-10))
break;
value = newvalue;
}
return 0;
}
#包括
#包括
#包括
/*清晰阵列*/
无效清除量(双asum[2048])
{
尺寸i;
对于(i=0;i<2048;i++)
asum[i]=0。;
}
/*在数组中添加一个数字*/
void addtosum(双d,双asum[2048])
{
尺寸i;
而(1){
/*i=d的指数*/
i=((size_t)((*(unsigned long*)和d)>>52))&0x7ff;
如果(i==0x7ff){/*最大指数,则可能溢出*/
asum[i]+=d;
返回;
}
if(asum[i]==0。){/*if空插槽存储d*/
asum[i]=d;
返回;
}
d+=asum[i];/*否则将插槽添加到d,清除插槽*/
asum[i]=0./*并继续,直到插槽为空*/
}
}
/*从数组返回和*/
双返回和(双asum[2048])
{
双和=0。;
尺寸i;
对于(i=0;i<2048;i++)
总和+=asum[i];
回报金额;
}
双外汇(双x)
{
返回1./((1.+x*x)*sqrt(x));
}
双辛普森(双x,双y,双n)
{
双asum[2048];/*用于求和函数*/
双h;
双a;
如果(n<1.){
n=1。;
h=0。;
}否则{
h=(y-x)/(n-1.0);
}
y+=h/2。;
晴朗(asum);
对于(;x
由于f(x)->∞ 如x->0。在本例中,我将范围更改为1到1000。在对大量值求和时,我还使用了求和函数来最小化舍入误差。wolframalpha的积分为~=.487474,此程序得到的结果为~=.487475。使用t可以找到精确的积分