2014-04-08 14 views
16

Sto cercando una libreria java in grado di calcolare la funzione ipergeometrica generalizzata (http://en.wikipedia.org/wiki/Generalized_hypergeometric_series). Ho guardato Apach Common Math, ma non ho trovato la funzione. In realtà, ho bisogno della funzione per calcolare la funzione di probabilità cumulativa per la distribuzione beta-binomiale (http://en.wikipedia.org/wiki/Beta-binomial_distribution). Se qualcuno conosce un pacchetto java che include la distribuzione, sarebbe un bene per me.java Funzione ipergeometrica generalizzata

Grazie,

risposta

1

È possibile utilizzare questo org.apache.commons.math3.distribution.HypergeometricDistribution da here.

Download link.

+0

Grazie per la risposta. Ho fatto un errore nell'argomento. Dovrebbe essere generalizzata la funzione ipergeometrica, invece della distribuzione ipergeometrica generalizzata. Perdonami per quello. – longread

0

basata sull'articolo wiki che hai postato, penso che si può approssimare i valori della funzione ipergeometrica utilizzando questo codice che ho scritto:

Come passo successivo, può essere possibile stimare l'errore della approssimazione.

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

} 

Se i converge serie (e fornisce quindi una serie ipergeometrica corretta), quindi lim[c_i*x^i] deve essere pari a zero, quindi questo dovrebbe fornire una ragionevole approssimazione, se si prende degreeOfApproximation essere abbastanza grande.

I polinomi A e B sono quelli a cui si fa riferimento nell'articolo wiki e per utilizzare questo codice, è necessario fornire matrici di coefficienti per tali polinomi al costruttore, insieme al grado di approssimazione desiderato.

Spero che questo ti aiuti.

+0

Il problema con tali approssimazioni "ingenue" è che non sono stati testati e quindi i limiti di errore sono sconosciuti. Questi spesso dipendono dai valori specifici a cui viene valutata la funzione, e quindi hanno bisogno di alcune "intelligenze" interne per prendere abbastanza termini da convergere. Inoltre, questo modo di valutare grandi polinomi tende ad essere numericamente instabile .... ed è per questo che anch'io stavo cercando un pacchetto che faccia questo ... Grazie! –

+0

Hai a che fare con coefficienti complessi? Se è così, allora dovrebbe essere in una domanda diversa, perché questa riguarda il beta-binomio.Nel caso reale, la funzione è continuamente differenziabile su un certo raggio di convergenza (vedi wiki). Quindi c'è una serie di Taylor per la funzione che coincide con quella che si sta approssimando, e il teorema di resto di Taylor in realtà dà un limite all'errore. Dove hai letto che il troncamento di una serie di potenze convergenti si chiama approssimazione ingenua? Questo non è un termine reale. – Blake

0

C'è un GNU Scientific Library che implementa hypergeometric functions e many random number distributions - sfortunatamente è una libreria C.

Fortunatamente c'è un JavaCPP preimpostato available che significa che è possibile utilizzarlo da Java facilmente (si impacchetta biblioteca GCL nativo per Windows/Linux/Android all'interno).

Il example non ha funzionato per me (che utilizza la versione 2.4-1.3.4-SNAPSHOT della biblioteca), ma quando modificati per utilizzare la versione 2.2.1-1.3 (che si trova sulla Maven centrale) ha funzionato perfettamente.

mio pom.xml è:

<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: io non sono un matematico quindi per favore non convalidare i miei pensieri.

Buona fortuna!

Problemi correlati