繁体   English   中英

Java-用新方法实现伯努利数

[英]Java- Implementation of Bernoulli Numbers in new method

我在用BigRational助手类编辑Java中现有的伯努利数字实现时遇到麻烦。 原始实现将伯努利数的计算放入Main方法中。 我创建了一个新类,以返回单个伯努利数字的计算结果。 我究竟做错了什么?

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函数

在此处输入图片说明

我创建的一种Test方法通过BigDecimal计算该方程的分母。 我看到一个即将到来的问题,是否需要将Bernoulli BigRational转换为BigDecimal? 我可能需要调整我发现的BigRational类

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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM