Java- 在新方法中实现伯努利数
Java- Implementation of Bernoulli Numbers in new method
我在编辑 Bernoulli numbers in Java which has the BigRational helper class 的现有实现时遇到问题。最初的实现将伯努利数的计算放在 Main 方法中。我对单个伯努利数进行了新的 class 到 return 计算。我做错了什么?
import java.math.BigInteger;
public class Bernoulli {
public static void main(String[] args) {
int N = 20;
System.out.println(bern(N));
}
public static BigRational bern(int N) {
BigInteger[][] binomial = new BigInteger[N+1][N+1];
for (int n = 1; n <= N; n++) binomial[0][n] = BigInteger.ZERO;
for (int n = 0; n <= N; n++) binomial[n][0] = BigInteger.ONE;
for (int n = 1; n <= N; n++)
for (int k = 1; k <= N; k++)
binomial[n][k] = binomial[n-1][k-1].add(binomial[n-1][k]);
BigRational[] bernoulli = new BigRational[N+1];
bernoulli[0] = new BigRational(1, 1);
bernoulli[1] = new BigRational(-1, 2);
for (int k = 2; k < N; k++) {
bernoulli[k] = new BigRational(0, 1);
for (int i = 0; i < k; i++) {
BigRational coef = new BigRational(binomial[k + 1][k + 1 - i],
BigInteger.ONE);
bernoulli[k] = bernoulli[k].minus(coef.times(bernoulli[i]));
}
bernoulli[k] = bernoulli[k].divides(new BigRational(k+1, 1));
}
return bernoulli[N];
}
}
我想这样做是为了计算偶数的 Zeta function。
我创建的一个测试方法通过 BigDecimal 计算这个方程的分母。我看到即将出现的问题,我需要将 Bernoulli BigRational 转换为 BigDecimal 吗?我可能需要调整我找到的 BigRational class。
import java.math.BigDecimal;
import java.math.BigInteger;
public class Test {
public static void main(String[] args) {
int N = Integer.parseInt("20");
// precompute binomial coefficients
BigInteger[][] binomial = new BigInteger[N+1][N+1];
for (int n = 1; n <= N; n++) binomial[0][n] = BigInteger.ZERO;
for (int n = 0; n <= N; n++) binomial[n][0] = BigInteger.ONE;
// bottom-up dynamic programming
for (int n = 1; n <= N; n++)
for (int k = 1; k <= N; k++)
binomial[n][k] = binomial[n-1][k-1].add(binomial[n-1][k]);
// now compute Bernoulli numbers
BigRational[] bernoulli = new BigRational[N+1];
bernoulli[0] = new BigRational(1, 1);
bernoulli[1] = new BigRational(-1, 2);
for (int k = 2; k < N; k++) {
bernoulli[k] = new BigRational(0, 1);
for (int i = 0; i < k; i++) {
BigRational coef = new BigRational(binomial[k + 1][k + 1 - i],
BigInteger.ONE);
bernoulli[k] = bernoulli[k].minus(coef.times(bernoulli[i]));
}
bernoulli[k] = bernoulli[k].divides(new BigRational(k+1, 1));
}
BigDecimal n = new BigDecimal(6);
BigDecimal two = new BigDecimal(2);
System.out.println(fac(n).multiply(two));
System.out.println("\u03A0^2");
}
public static BigDecimal fac(BigDecimal n) {
if (n.equals(BigDecimal.ZERO)) {
return BigDecimal.ONE;
}
return n.multiply(fac(n.subtract(BigDecimal.ONE)));
}
}
备选方案
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Vector;
import org.apache.commons.math3.fraction.BigFraction;
/* Generates the Bernoulli number, B_n, by a double sum.
* @param n The index of the Bernoulli number.
* @return The Bernoulli number at n.
*/
private static BigFraction bernoulli(int n) {
BigFraction result = BigFraction.ZERO;
for (int k = 0; k <= n; k++) {
BigFraction jSum = BigFraction.ZERO;
BigInteger bInt = BigInteger.ONE;
for (int j = 0; j <= k; j++) {
BigInteger jPowN = (new BigInteger("" + j))
.pow(n);
if (j % 2 == 0) {
jSum = jSum.add(bInt.multiply(jPowN));
} else {
jSum = jSum.subtract(bInt.multiply(jPowN));
}
/* update binomial(k,j) recursively
*/
bInt = bInt.multiply(new BigInteger("" + (k - j))).
divide(new BigInteger("" + (j + 1)));
}
result = result.add(jSum.divide(new BigInteger("" + (k + 1)))
);
}
return result;
}
我在编辑 Bernoulli numbers in Java which has the BigRational helper class 的现有实现时遇到问题。最初的实现将伯努利数的计算放在 Main 方法中。我对单个伯努利数进行了新的 class 到 return 计算。我做错了什么?
import java.math.BigInteger;
public class Bernoulli {
public static void main(String[] args) {
int N = 20;
System.out.println(bern(N));
}
public static BigRational bern(int N) {
BigInteger[][] binomial = new BigInteger[N+1][N+1];
for (int n = 1; n <= N; n++) binomial[0][n] = BigInteger.ZERO;
for (int n = 0; n <= N; n++) binomial[n][0] = BigInteger.ONE;
for (int n = 1; n <= N; n++)
for (int k = 1; k <= N; k++)
binomial[n][k] = binomial[n-1][k-1].add(binomial[n-1][k]);
BigRational[] bernoulli = new BigRational[N+1];
bernoulli[0] = new BigRational(1, 1);
bernoulli[1] = new BigRational(-1, 2);
for (int k = 2; k < N; k++) {
bernoulli[k] = new BigRational(0, 1);
for (int i = 0; i < k; i++) {
BigRational coef = new BigRational(binomial[k + 1][k + 1 - i],
BigInteger.ONE);
bernoulli[k] = bernoulli[k].minus(coef.times(bernoulli[i]));
}
bernoulli[k] = bernoulli[k].divides(new BigRational(k+1, 1));
}
return bernoulli[N];
}
}
我想这样做是为了计算偶数的 Zeta function。
我创建的一个测试方法通过 BigDecimal 计算这个方程的分母。我看到即将出现的问题,我需要将 Bernoulli BigRational 转换为 BigDecimal 吗?我可能需要调整我找到的 BigRational class。
import java.math.BigDecimal;
import java.math.BigInteger;
public class Test {
public static void main(String[] args) {
int N = Integer.parseInt("20");
// precompute binomial coefficients
BigInteger[][] binomial = new BigInteger[N+1][N+1];
for (int n = 1; n <= N; n++) binomial[0][n] = BigInteger.ZERO;
for (int n = 0; n <= N; n++) binomial[n][0] = BigInteger.ONE;
// bottom-up dynamic programming
for (int n = 1; n <= N; n++)
for (int k = 1; k <= N; k++)
binomial[n][k] = binomial[n-1][k-1].add(binomial[n-1][k]);
// now compute Bernoulli numbers
BigRational[] bernoulli = new BigRational[N+1];
bernoulli[0] = new BigRational(1, 1);
bernoulli[1] = new BigRational(-1, 2);
for (int k = 2; k < N; k++) {
bernoulli[k] = new BigRational(0, 1);
for (int i = 0; i < k; i++) {
BigRational coef = new BigRational(binomial[k + 1][k + 1 - i],
BigInteger.ONE);
bernoulli[k] = bernoulli[k].minus(coef.times(bernoulli[i]));
}
bernoulli[k] = bernoulli[k].divides(new BigRational(k+1, 1));
}
BigDecimal n = new BigDecimal(6);
BigDecimal two = new BigDecimal(2);
System.out.println(fac(n).multiply(two));
System.out.println("\u03A0^2");
}
public static BigDecimal fac(BigDecimal n) {
if (n.equals(BigDecimal.ZERO)) {
return BigDecimal.ONE;
}
return n.multiply(fac(n.subtract(BigDecimal.ONE)));
}
}
备选方案
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Vector;
import org.apache.commons.math3.fraction.BigFraction;
/* Generates the Bernoulli number, B_n, by a double sum.
* @param n The index of the Bernoulli number.
* @return The Bernoulli number at n.
*/
private static BigFraction bernoulli(int n) {
BigFraction result = BigFraction.ZERO;
for (int k = 0; k <= n; k++) {
BigFraction jSum = BigFraction.ZERO;
BigInteger bInt = BigInteger.ONE;
for (int j = 0; j <= k; j++) {
BigInteger jPowN = (new BigInteger("" + j))
.pow(n);
if (j % 2 == 0) {
jSum = jSum.add(bInt.multiply(jPowN));
} else {
jSum = jSum.subtract(bInt.multiply(jPowN));
}
/* update binomial(k,j) recursively
*/
bInt = bInt.multiply(new BigInteger("" + (k - j))).
divide(new BigInteger("" + (j + 1)));
}
result = result.add(jSum.divide(new BigInteger("" + (k + 1)))
);
}
return result;
}