2014-04-08 10 views
16

Szukam biblioteki Java, która może obliczyć uogólnioną funkcję hipergeometryczną (http://en.wikipedia.org/wiki/Generalized_hypergeometric_series). Spojrzałem na Apache Common Math, ale nie znalazłem funkcji. W rzeczywistości potrzebuję funkcji do obliczenia skumulowanej funkcji prawdopodobieństwa dla rozkładu beta-dwumianowego (http://en.wikipedia.org/wiki/Beta-binomial_distribution). Jeśli ktokolwiek zna pakiet java zawierający dystrybucję, byłby dla mnie dobry.java Uogólniona funkcja hipergeometryczna

Dzięki,

Odpowiedz

1

można użyć tej org.apache.commons.math3.distribution.HypergeometricDistribution z here.

Download link.

+0

Dzięki za odpowiedź. Popełniłem błąd w temacie. Powinna to być uogólniona funkcja hipergeometryczna, zamiast uogólnionej dystrybucji hipergeometrycznej. Przepraszam za to. – longread

0

Na podstawie artykułu wiki, który pisał, że można zbliżyć wartości funkcji hypergeometric użyciu tego kodu, który napisałem:

Jako następny krok, może być możliwe do oszacowania Błąd przybliżenie.

/** 
* The generalized hypergeometric function is a convergent power series \sum_{i=0}^{\infty} c_i x^i 
* where the coefficients satisfy c_{n+1}/c_n = A(n)/B(n) for some polynomials A and B in n. 
* It is customary to factor out the leading term, so c_0 is assumed to be 1 
*/ 

public class HypergeometricFunction { 
    private final int degreeOfApproximation; 
    private final double[] coefficientsOfA; 
    private final double[] coefficientsOfB; 
    private final double[] coefficientsOfHypergeometricFunction; 

    public HypergeometricFunction(int degreeOfApproximation, double[] coefficientsOfA, double[] coefficientsOfB) { 
     this.degreeOfApproximation = degreeOfApproximation; 
     this.coefficientsOfA = coefficientsOfA; 
     this.coefficientsOfB = coefficientsOfB; 
     this.coefficientsOfHypergeometricFunction = generateCoefficients(); 
    } 

    /** 
    * @param x input 
    * @return Approximation to the hypergeometric function by taking the first 
    * {@code degreeOfApproximation} terms from the series. 
    */ 
    public double approximate(double x){ 
     return evaluatePolynomial(x, coefficientsOfHypergeometricFunction); 
    } 


    private double[] generateCoefficients() { 
     double[] coefficients = new double[degreeOfApproximation]; 
     coefficients[0] = 1; 
     for (int i = 1; i < degreeOfApproximation; i++) 
      coefficients[i] = (evaluatePolynomial(i, coefficientsOfA)/evaluatePolynomial(i, coefficientsOfB)) * coefficients[i - 1]; 
     return coefficients; 
    } 

    private double evaluatePolynomial(double n, double[] coefficients) { 
     int length = coefficients.length; 
     double out = 0.0D; 
     for (int i = 0; i < length; i++) { 
      out += coefficients[i] * pow(n, i); 
     } 
     return out; 
    } 

    private double pow(double a, int b) { 
     double out = 1; 
     for (int i = 0; i < b; i++) out *= a; 
     return out; 
    } 

} 

Jeśli zbieżny serii (a tym samym zapewnia prawidłowe funkcjonowanie hipergeometryczny), następnie lim[c_i*x^i] musi wynosić zero, więc powinno to stanowić przybliżenie jeśli wziąć degreeOfApproximation być wystarczająco duża.

Wielomiany A i B są tymi, o których mowa w artykule wiki, i aby użyć tego kodu, należy dostarczyć tablice współczynników dla tych wielomianów do konstruktora, wraz z pożądanym stopniem przybliżenia.

Mam nadzieję, że to pomoże.

+0

Problem z takimi "naiwnymi" przybliżeniami polega na tym, że nie zostały one przetestowane, a zatem granice błędu są nieznane. Często zależą one od konkretnych wartości, na których funkcja jest oceniana, a więc potrzebują pewnych wewnętrznych "sprytów", aby przyjąć wystarczającą liczbę terminów do zejścia. Również ten sposób oceniania dużych wielomianów wydaje się być niestabilny numerycznie ... Dlatego właśnie ja również szukałem pakietu, który to robi ... Dzięki! –

+0

Czy masz do czynienia ze złożonymi współczynnikami? Jeśli tak, to powinno być w innym pytaniu, ponieważ ten dotyczy beta-dwumianu.W rzeczywistym przypadku funkcja jest ciągle różniczkowalna w pewnym promieniu zbieżności (patrz wiki). Tak więc istnieje seria Taylora dla funkcji, która pokrywa się z funkcją, którą chciałbyś przybliżyć, a pozostałe twierdzenia Taylora faktycznie dają błąd. Gdzie przeczytałeś, że obcinanie konwergentnej serii mocy nazywa się naiwną aproksymacją? To nie jest prawdziwy termin. – Blake

0

Istnieje GNU Scientific Library implementujący hypergeometric functions i many random number distributions - niestety jest to biblioteka języka C.

szczęście istnieje JavaCPP zadana available który oznacza, że ​​można go używać z Java łatwo (to wiązki natywną GCL biblioteki dla Windows/Linux/Android wewnątrz).

example nie działa dla mnie (używa wersji 2.4-1.3.4-SNAPSHOT biblioteki), ale kiedy zmodyfikowane do wykorzystania w wersji 2.2.1-1.3 (który jest na Maven centralne) to działało bez zarzutu.

Moje pom.xml jest:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>test</groupId> 
    <artifactId>test-gsl-java</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <properties> 
     <exec.mainClass>Example</exec.mainClass> 
    </properties> 
    <dependencies> 
     <dependency> 
      <groupId>org.bytedeco.javacpp-presets</groupId> 
      <artifactId>gsl-platform</artifactId> 
      <version>2.2.1-1.3</version> 
     </dependency> 
    </dependencies> 
</project> 

Disclaimer: Nie jestem matematykiem, więc proszę potwierdzić moje myśli.

Powodzenia!

Powiązane problemy