C中的Riemann Zeta函数可得出负数的奇数实数

时间:2018-09-11 22:53:45

标签: c function math gcc discrete-mathematics

我正在尝试用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贡献进行了更新,但仍无法解决负真实赔率...

1 个答案:

答案 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真的很有趣