2015-09-12 67 views
0

我在編輯現有的具有BigRational helper class的Java的Bernoulli numbers實現方面遇到問題。最初的實現將伯努利數的計算放在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的等式的分母。我看到即將出現的問題,是否需要將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))); 
    } 

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