关于收敛性对于精确度的影响,ACM zju1007

leo524891010 2010-02-11 12:11:42
解答说 1/x^3 收敛快,所以精确度更高,不是很理解,请达人告知一下。
原题:Produce a table of the values of the series



Equation 1

for the 2001 values of x, x= 0.000, 0.001, 0.002, ..., 2.000. All entries of the table must have an absolute error less than 0.5e-12 (12 digits of precision). This problem is based on a problem from Hamming (1962), when mainframes were very slow by today's microcomputer standards.

Input

This problem has no input.

Output

The output is to be formatted as two columns with the values of x and ψ(x) printed as in the C printf or the Pascal writeln.

printf("%5.3f %16.12f\n", x, psix ) writeln(x:5:3, psix:16:12)

As an example, here are 4 acceptable lines out of 2001.

0.000 1.644934066848

...

0.500 1.227411277760

...

1.000 1.000000000000

...

2.000 0.750000000000

The values of x should start at 0.000 and increase by 0.001 until the line with x=2.000 is output.

Hint

The problem with summing the sequence in equation 1 is that too many terms may be required to complete the summation in the given time. Additionally, if enough terms were to be summed, roundoff would render any typical double precision computation useless for the desired precision.

To improve the convergence of the summation process note that



Equation 2

which implies ψ(1)=1.0. One can then produce a series for ψ(x) - ψ(1) which converges faster than the original series. This series not only converges much faster, it also reduces roundoff loss.

This process of finding a faster converging series may be repeated to produce sequences which converge more and more rapidly than the previous ones.

The following inequality is helpful in determining how may items are required in summing the series above.



Equation 3

...全文
288 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qinannmj 2011-03-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sosidami 的回复:]
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
double x,sum;
int k;
for(x=0.000; x<=2.000; x+=0.001)
{
sum=0.0;
for(k=1;k<10000;k++)
sum+=1.0/(k*(k+1)*(……
[/Quote]

0.000 - 2.000中的数,按我那个算需要次数的方法,有的是需要大于 13000以上才能算出来的,所以这个程序肯定ac不了啦
qinannmj 2011-03-11
  • 打赏
  • 举报
回复
#include <iostream>
#include <cstring>
#include <stack>
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <stdlib.h>
using namespace std;

double cce(double x){

//根据定积分的定义,1/x的r次方的递减性质,及hint中3式
// 可以得出 1.0/(n+y)/(n+y)/2 < Sigma((1/k/(k+1)/(k+x)) < 1/(n-1)/(n-1)/2
// 根据上式可以 判定出 1/(n-1)/(n-1)/2 - 1.0/((n+y)*(n+y)*2) < 0.5e-12 时,n的次数
// 这时计算 Sigma((1/k/(k+1)/(k+x))的前n次项和 加上 1/(n-1)/(n-1)/2 和1.0/((n+y)*(n+y)*2)中
//的任意一个,便可知结果误差一定处于允许范围内
//判定真实值落在误差内的需要次数
long long n = 2;
double y = x > 1 ? x : 1;
while(true){
double t = 1.0/((n-1)*(n-1)*2);
double b = 1.0/((n+y)*(n+y)*2);
double d = t-b;
if(d < 0.5e-12){
break;
}
n++;
}
double r = 0;
//加上后n项和
r += 1.0/((n+y)*(n+y)*2);
//累加前n项
for(;n>0;n--){
r += 1.0/(n*(x+n)*(n+1));
}
r = r * (1-x);
return r + 1;
}
int main(int argc,char* argv[]){

for(int i = 0 ;i < 2001 ;i++){
double d = ((double)i) / 1000;
printf("%5.3f %16.12f\n", d, cce(d) );
}
}

我的程序。
搭个顺风车,请教这道题更快速的合理解法。对着题里的输出的,凑出结果的就别说了……
qinannmj 2011-03-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sosidami 的回复:]
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
double x,sum;
int k;
for(x=0.000; x<=2.000; x+=0.001)
{
sum=0.0;
for(k=1;k<10000;k++)
sum+=1.0/(k*(k+1)*(……
[/Quote]

我自己做的程序要用4秒多,上面这个程序,不知道是用什么方法判定的0.5e-12这个精确度的?

leo524891010 2010-02-24
  • 打赏
  • 举报
回复
引用 4 楼 sosidami 的回复:
根据hint可以很容易找到解答方案。
1)其F(x),我们可以先求F(x)-F(1)(F(1)的值为1)我们看一下F(x)-F(1)的答案是Sigma((1-x)/k/(k+1)/(k+x))  所以它一定小于Sigma((1-x)/k/k/k)这个是个简单的不等式放缩,
2)根据那个积分不等式,我们得到了当n很大的时候,我们可以用积分公式来近似,判断的标准就在于精度。
3)根据上面两个,可以得到上面的程序。

楼主所谓的估计是哪个2k^2的由来吧,他是1/k^3的积分啊。。而1/k^3的由来是不等式放缩的结果


请问,那我如果不用F(X)-F(1),而直接计算F(X),那样会有怎样的区别呢,谢谢
sosidami 2010-02-12
  • 打赏
  • 举报
回复
根据hint可以很容易找到解答方案。
1)其F(x),我们可以先求F(x)-F(1)(F(1)的值为1)我们看一下F(x)-F(1)的答案是Sigma((1-x)/k/(k+1)/(k+x)) 所以它一定小于Sigma((1-x)/k/k/k)这个是个简单的不等式放缩,
2)根据那个积分不等式,我们得到了当n很大的时候,我们可以用积分公式来近似,判断的标准就在于精度。
3)根据上面两个,可以得到上面的程序。

楼主所谓的估计是哪个2k^2的由来吧,他是1/k^3的积分啊。。而1/k^3的由来是不等式放缩的结果
sosidami 2010-02-12
  • 打赏
  • 举报
回复
#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
double x,sum;
int k;
for(x=0.000; x<=2.000; x+=0.001)
{
sum=0.0;
for(k=1;k<10000;k++)
sum+=1.0/(k*(k+1)*(k+x));
sum=(1-x)*sum+(1-x)/(2*1000*1000)+1.0;
printf("%5.3f %16.12f\n", x, sum);
}

return 0;
}

这个是标准程序!楼主的意思是看不懂推导过程吧,其实很容易
arong1234 2010-02-11
  • 打赏
  • 举报
回复
你给的没有你说的“解答”啊?解答到底怎么说的?
jellodgd 2010-02-11
  • 打赏
  • 举报
回复
看看= =。。。。。。

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧