com.sri.ai.util.math.BernoulliNumber Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aic-util Show documentation
Show all versions of aic-util Show documentation
SRI International's AIC Utility Library (for Java 1.6+)
/*
* Copyright (c) 2015, SRI International
* All rights reserved.
* Licensed under the The BSD 3-Clause License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the aic-praise nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sri.ai.util.math;
import java.util.HashMap;
import java.util.Map;
import com.google.common.annotations.Beta;
/**
* Compute Bernoulli number:
* https://en.wikipedia.org/wiki/Bernoulli_number
*
* @author oreilly
*
*/
@Beta
public class BernoulliNumber {
private static final Map _precomputed = new HashMap<>();
static {
_precomputed.put(2, new Rational( 1, 6));
_precomputed.put(4, new Rational( -1, 30));
_precomputed.put(6, new Rational( 1, 42));
_precomputed.put(8, new Rational( -1, 30));
_precomputed.put(10, new Rational( 5, 66));
_precomputed.put(12, new Rational( -691, 2730));
_precomputed.put(14, new Rational( 7, 6));
_precomputed.put(16, new Rational( -3617, 510));
_precomputed.put(18, new Rational( 43867, 798));
_precomputed.put(20, new Rational(-174611, 330));
}
private static final Rational _firstB1 = new Rational(-1, 2);
private static final Rational _secondB1 = new Rational( 1, 2);
/**
* Compute the first Bernoulli numbers (i.e. B1 = -1/2).
* NOTE: Used by Faulhaber's formula.
*
* @param n
* the nth first Bernoulli number to compute.
* @return the first Bernoulli number n.
*/
public static Rational computeFirst(int n) {
return compute(n, _firstB1);
}
/**
* Compute the second Bernoulli numbers (i.e. B1 = 1/2).
*
* @param n
* the nth second Bernoulli number to compute.
* @return the second Bernoulli number n.
*/
public static Rational computeSecond(int n) {
return compute(n, _secondB1);
}
//
// PRIVATE
//
private static Rational compute(int n, Rational b1Value) {
if (n < 0) {
throw new IllegalArgumentException("n must be >= 0");
}
Rational result;
if (n == 0) {
result = Rational.ONE;
}
else if (n == 1) {
result = b1Value;
}
else if (n % 2 == 1) {
result = Rational.ZERO;
}
else {
result = _precomputed.get(n);
if (result == null) {
// NOTE: Simple implementation based on:
// https://en.wikipedia.org/wiki/Bernoulli_number#Algorithmic_description
Rational[] a = new Rational[n+1];
for (int m = 0; m <= n; m++) {
a[m] = Rational.ONE.divide(m+1);
for (int j = m; j >= 1; j--) {
a[j-1] = new Rational(j).multiply(a[j-1].subtract(a[j]));
}
}
result = a[0];
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy