2015-09-12 3 views
0

У меня возникла проблема с редактированием существующей реализации Bernoulli numbers на Java, которая имеет BigRational helper class. В исходной реализации вычисляется число Бернулли внутри метода Main. Я сделал новый класс, чтобы вернуть расчет для отдельных чисел Бернулли. Что я делаю не так?Java-реализация чисел Бернулли по новому методу

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 для четных чисел.

enter image description here

Метод испытаний, который я создал вычисляет знаменатель этого уравнения через BigDecimal. Я вижу предстоящую проблему, мне нужно будет преобразовать Бернулли 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))); 
    } 

} 
+0

"Что я делаю не так?" слишком широка. Рефакторируйте свой код, разделите его на более мелкий метод (эмпирическое правило: каждый метод должен делать одно и только одно!). Создайте единичный тест для каждого метода и убедитесь, что вы получаете ожидаемый результат. Как только вы это сделаете, вы сократите этот огромный блок кода до определенной части, которая не работает, и будет легче отлаживать и исправлять. Удачи! – alfasin

+0

Я нашел альтернативный способ решения проблемы. – Axion004

ответ

1

Альтернативное решение

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; 
    } 
Смежные вопросы