我正在尝试用C编写Riemann Zeta函数,但负几率有很多问题。由于偶数负数在定义上为0。仅用于实数功能,不复杂。因此0..1是未定义。我知道这是我做的一些数学错误,但是我今天开始阅读有关此函数的信息,并且正在尝试学习。
https://en.wikipedia.org/wiki/Riemann_zeta_function
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double zeta(double s, long long int n)
{
double p=0.0;
if(s<0 && fmod(s,2)==0)
{
return p;
}
if(s==0) { return -0.5;}
if(s>0 && s<=1)
{
puts("Undefined. ");
exit(-1);
}
long long int i;
for(i=n; i>0; i--)
{
p+=pow(i,-s);
}
return p;
}
int main()
{
double s;
puts("Enter real number to Zeta function: ");
scanf("%lf",&s);
printf("\n%.15lf",zeta(s,1000000));
return 0;
}
这只是草图...这里没有专业人士!
示例:zeta(-5)= -0.003968253968253 它给出了1.036927755143338 ...
我只遇到 NEGATIVE REAL 的问题... 我使用的是Windows 10,带有GCC的代码块。
该代码已使用@NPE贡献进行了更新,但仍无法解决负真实赔率...
答案 0 :(得分:1)
对不起,我没有参与评论。
按照zeta函数的定义,简单的编码方式是(我只是将代码从s更改为-s,并添加了“会聚度n”作为参数)
double zeta_simple(double s, long long int n)
{
double p=0.0;
long long int i;
for(i=1; i<=n; i++)
{
p+=pow(i,-s);
}
return p;
}
但是问题是您开始在“小”之前添加“大”数字,然后很快就会发生下溢操作。所以你想做的是
double zeta(double s, long long int n)
{
double p=0.0;
long long int i;
for(i=n; i>0; i--)
{
p+=pow(i,-s);
}
return p;
}
您可以使用s = 2收敛到PI ^ 2 / 6.0和s = 4收敛到PI ^ 4 / 90.0来测试收敛性
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679L
int main()
{
long long int n;
for (long long int n=10; n<=100000000; n*=10)
{
printf("%28.16f\t %28.16f\n", zeta(4.0, n), zeta2(4.0, n));
}
printf("%s=%20.16f\n\n","PI^4/90", PI*PI*PI*PI/90.0);
for (long long int n=10; n<=10000000000; n*=10)
{
printf("%28.16f\t %28.16f\n", zeta(2.0, n), zeta2(2.0, n));
}
printf("%s=%20.16f\n","PI^2/6 ", PI*PI/6.0);
}
你得到
1.0820365834937564 1.0820365834937566
1.0823229053444732 1.0823229053444725
1.0823232333783044 1.0823232333783073
1.0823232337108049 1.0823232337108359
1.0823232337111379 1.0823232337109849
1.0823232337111381 1.0823232337109849
1.0823232337111381 1.0823232337109849
1.0823232337111381 1.0823232337109849
PI^4/90= 1.0823232337111379
1.5497677311665408 1.5497677311665408
1.6349839001848929 1.6349839001848925
1.6439345666815597 1.6439345666815606
1.6448340718480596 1.6448340718480665
1.6449240668982261 1.6449240668982523
1.6449330668487265 1.6449330668487985
1.6449339668482315 1.6449339668477756
1.6449340568482265 1.6449340573291047
1.6449340658482263 1.6449340600880324
1.6449340667482264 1.6449340600880324
PI^2/6 = 1.6449340668482264
了解一段时间后zeta_simple
的收敛如何停止...要继续收敛,您必须使用zeta
您还可以看到,对于10000000000次运算(因此使用long long int),对于s = 2,您只能获得9位数字的精度。随着s的增加,收敛速度也随之增加。
因此,为了使小s变得有效,人们使用加速收敛公式。
如果您想进一步挖掘,建议您查看https://math.stackexchange.com/questions/183680/modern-formula-for-calculating-riemann-zeta-function
当您开始接触s
复合物时,wat真的很有趣