gpt4 book ai didi

java - Java 中的黎曼 Zeta 函数 - 具有函数形式的无限递归

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:28:36 26 4
gpt4 key购买 nike

注:更新于 06/17/2015。当然这是可能的。请参阅下面的解决方案。

即使有人复制并粘贴此代码,您仍然需要做很多清理工作。另请注意,在从 Re(s) = 0 到 Re(s) = 1 :) 的关键地带内,您会遇到问题。但这是一个好的开始。

import java.util.Scanner;

public class NewTest{

public static void main(String[] args) {
RiemannZetaMain func = new RiemannZetaMain();
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater than 1.");
}
start = System.currentTimeMillis();
if (s <= 0)
System.out.println("Value for the Zeta Function = " + riemannFuncForm(s));
else if (s == 1)
System.out.println("The zeta funxtion is undefined for Re(s) = 1.");
else if(s >= 2)
System.out.println("Value for the Zeta Function = " + getStandardSum(s));
else
System.out.println("Value for the Zeta Function = " + getNewSum(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}

// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;

while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}

public static double getStandardSum(double s){
return standardZeta(s);
}

//New Form
// zeta(s) = 2^(-1+2 s)/((-2+2^s) Gamma(1+s)) integral_0^infinity t^s sech^2(t) dt for Re(s)>-1
public static double Integrate(double start, double end) {
double currentIntegralValue = 0;
double dx = 0.0001d; // The size of delta x in the approximation
double x = start; // A = starting point of integration, B = ending point of integration.

// Ending conditions for the while loop
// Condition #1: The value of b - x(i) is less than delta(x).
// This would throw an out of bounds exception.
// Condition #2: The value of b - x(i) is greater than 0 (Since you start at A and split the integral
// up into "infinitesimally small" chunks up until you reach delta(x)*n.
while (Math.abs(end - x) >= dx && (end - x) > 0) {
currentIntegralValue += function(x) * dx; // Use the (Riemann) rectangle sums at xi to compute width * height
x += dx; // Add these sums together
}
return currentIntegralValue;
}

private static double function(double s) {
double sech = 1 / Math.cosh(s); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(s, 0.5)) * squared);
}

public static double getNewSum(double s){
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*(gamma(1+s)));
return constant*Integrate(0, 1000);
}

// Gamma Function - Lanczos approximation
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
int g = 7;
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)*gamma(1-s));

s -= 1;
double a = p[0];
double t = s+g+0.5;
for(int i = 1; i < p.length; i++){
a += p[i]/(s+i);
}

return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)*Math.exp(-t)*a;
}

//Binomial Co-efficient - NOT CURRENTLY USING
/*
public static double binomial(int n, int k)
{
if (k>n-k)
k=n-k;

long b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
} */

// Riemann's Functional Equation
// Tried this initially and utterly failed.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
double nextTerm = Math.pow(2, (1-s))*Math.pow(Math.PI, (1-s)-1)*(Math.sin((Math.PI*(1-s))/2))*gamma(1-(1-s));
double error = Math.abs(term - nextTerm);

if(s == 1.0)
return 0;
else
return Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)*standardZeta(1-s);
}

最佳答案

好吧,我们已经知道对于这个特定的函数,因为它的这种形式实际上不是无限级数,所以我们不能使用递归来近似。然而黎曼 Zeta 级数的无穷和(1\(n^s) where n = 1 to infinity)可以通过这种方法求解。

此外,此方法还可用于查找任何无限级数的总和、乘积或极限。

如果您执行当前拥有的代码,您将得到无限递归 1-(1-s) = s(例如 1-s = t1-t = s 所以你将无限地在 s 的两个值之间来回切换。

下面我说一下级数的和。看来您正在计算该系列的产品。以下概念适用于任何一个。

除此之外,黎曼 Zeta 函数是一个 infinite series .这意味着它只有一个限制,并且永远不会达到真正的总和(在有限的时间内),因此您无法通过递归得到准确的答案。

但是,如果您引入一个“阈值”因子,您可以获得一个您喜欢的近似值。随着每一项的增加,总和将增加/减少。一旦总和稳定下来,您就可以退出递归并返回您的近似总和。 “稳定”是使用您的阈值因子定义的。一旦总和的变化量小于此阈值因子(您已定义),您的总和就稳定了。

阈值越小,近似值越好,但计算时间也越长。

(注意:此方法仅在您的系列收敛时有效,如果它有可能不收敛,您可能还想构建一个 maxSteps 变量以在系列尚未收敛时停止执行在 maxSteps 个递归步骤后收敛到您满意的程度。)

这是一个示例实现,请注意您必须使用 thresholdmaxSteps 来确定合适的值:

/* Riemann's Functional Equation
* threshold - if two terms differ by less than this absolute amount, return
* currSteps/maxSteps - if currSteps becomes maxSteps, give up on convergence and return
* currVal - the current product, used to determine threshold case (start at 1)
*/
public static double riemannFuncForm(double s, double threshold, int currSteps, int maxSteps, double currVal) {
double nextVal = currVal*(Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)); //currVal*term
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else if (Math.abs(currVal-nextVal) < threshold) //When a term will change the current answer by less than threshold
return nextVal; //Could also do currVal here (shouldn't matter much as they differ by < threshold)
else if (currSteps == maxSteps)//When you've taken the max allowed steps
return nextVal; //You might want to print something here so you know you didn't converge
else //Otherwise just keep recursing
return riemannFuncForm(1-s, threshold, ++currSteps, maxSteps, nextVal);
}
}

关于java - Java 中的黎曼 Zeta 函数 - 具有函数形式的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30795379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com