Skip to content

Commit

Permalink
Added Kumaraswamy distribution
Browse files Browse the repository at this point in the history
  • Loading branch information
A-Herzog committed May 17, 2024
1 parent 581d0d3 commit 94ccf3e
Show file tree
Hide file tree
Showing 24 changed files with 775 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/**
* Copyright 2024 Alexander Herzog
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package mathtools.distribution;

import java.io.Serializable;

import org.apache.commons.math3.distribution.AbstractRealDistribution;
import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.special.Gamma;

/**
* Klasse zur Abbildung der Kumaraswamy-Verteilung
* @author Alexander Herzog
*/
public class KumaraswamyDistribution extends AbstractRealDistribution implements Cloneable, Serializable, DistributionWithRandom {
/**
* Serialisierungs-ID der Klasse
* @see Serializable
*/
private static final long serialVersionUID=-5073494121705653463L;

/**
* Parameter 1
*/
public final double a;

/**
* Parameter 2
*/
public final double b;

/**
* Untere Grenze des Trägers
*/
public final double c;

/**
* Obere Grenze des Trägers
*/
public final double d;

/**
* Vorab berechneter Erwartungswert
* @see #getNumericalMean()
*/
private final double mean;

/**
* Vorab berechnete Varianz
* @see #getNumericalVariance()
*/
private final double variance;

/**
* Konstruktor
* @param a Erster Parameter
* @param b Zweiter Parameter
* @param c Untere Grenze des Trägers
* @param d Obere Grenze des Trägers
*/
public KumaraswamyDistribution(final double a, final double b, final double c, final double d) {
super(null);
this.a=Math.max(0.0001,a);
this.b=Math.max(0.0001,b);
this.c=c;
this.d=Math.max(this.c+0.0001,d);

final double m1=this.b*Gamma.gamma(1+1/this.a)*Gamma.gamma(this.b)/Gamma.gamma(1+1/this.a+this.b);
mean=m1*(this.d-this.c)+this.c;
final double m2=this.b*Gamma.gamma(1+2/this.a)*Gamma.gamma(this.b)/Gamma.gamma(1+2/this.a+this.b);
variance=(m2-m1*m1)*(this.d-this.c)*(this.d-this.c);
}

/**
* Copy-Konstruktor
* @param source Zu kopierende Ausgangsverteilung
*/
public KumaraswamyDistribution(final KumaraswamyDistribution source) {
this((source==null)?0:source.a,(source==null)?10:source.b,(source==null)?0:source.c,(source==null)?10:source.d);
}

@Override
public double density(double x) {
if (x<c || x>d) return 0;
x=(x-c)/(d-c);
return a*b*Math.pow(x,a-1)*Math.pow(1-Math.pow(x,a),b-1);
}

@Override
public double cumulativeProbability(double x) {
if (x<=c) return 0;
if (x>=d) return 1;
x=(x-c)/(d-c);
return 1-Math.pow(1-Math.pow(x,a),b);
}

@Override
public KumaraswamyDistribution clone() {
return new KumaraswamyDistribution(a,b,c,d);
}

@Override
public double getNumericalMean() {
return mean;
}

@Override
public double getNumericalVariance() {
return variance;
}

@Override
public double getSupportLowerBound() {
return c;
}

@Override
public double getSupportUpperBound() {
return d;
}

@Override
public boolean isSupportLowerBoundInclusive() {
return true;
}

@Override
public boolean isSupportUpperBoundInclusive() {
return true;
}

@Override
public boolean isSupportConnected() {
return true;
}

@Override
public double inverseCumulativeProbability(final double p) throws OutOfRangeException {
if (p<0.0 || p>1.0) throw new OutOfRangeException(p,0,1);

if (p==0.0) return getSupportLowerBound();
if (p==1.0) return getSupportUpperBound();

/*
p=1-(1-x^a)^b
1-x^a=
(1-(1-p)^(1/b))^(1/a)=x
*/
return Math.pow(1-Math.pow(1-p,1/b),1/a)*(d-c)+c;
}

@Override
public double random(final RandomGenerator generator) {
return inverseCumulativeProbability(generator.nextDouble());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import mathtools.distribution.HyperbolicSecantDistributionImpl;
import mathtools.distribution.InverseGaussianDistributionImpl;
import mathtools.distribution.JohnsonDistributionImpl;
import mathtools.distribution.KumaraswamyDistribution;
import mathtools.distribution.LaplaceDistributionImpl;
import mathtools.distribution.LevyDistribution;
import mathtools.distribution.LogLogisticDistributionImpl;
Expand Down Expand Up @@ -84,6 +85,7 @@
import mathtools.distribution.tools.WrapperHyperbolicSecantDistribution;
import mathtools.distribution.tools.WrapperInverseGaussianDistribution;
import mathtools.distribution.tools.WrapperJohnsonDistribution;
import mathtools.distribution.tools.WrapperKumaraswamyDistribution;
import mathtools.distribution.tools.WrapperLaplaceDistribution;
import mathtools.distribution.tools.WrapperLevyDistribution;
import mathtools.distribution.tools.WrapperLogLogisticDistribution;
Expand Down Expand Up @@ -308,6 +310,7 @@ public static int compare(final JDistributionEditorPanelRecord record1, final JD
allRecords.add(new HalfNormalDistributionPanel());
allRecords.add(new UQuadraticDistributionPanel());
allRecords.add(new ReciprocalDistributionPanel());
allRecords.add(new KumaraswamyDistributionPanel());
}

/**
Expand Down Expand Up @@ -1473,6 +1476,39 @@ public AbstractRealDistribution getDistribution(final JTextField[] fields, final
}
}

/** Kumaraswamy-Verteilung */
private static class KumaraswamyDistributionPanel extends JDistributionEditorPanelRecord {
/** Konstruktor der Klasse */
public KumaraswamyDistributionPanel() {
super(new WrapperKumaraswamyDistribution(),new String[]{"a","b",JDistributionEditorPanel.DistUniformStart,JDistributionEditorPanel.DistUniformEnd});
}

@Override
public String[] getEditValues(final double meanD, final String mean, final double stdD, final String std, final String lower, final String upper, final double maxXValue) {
return new String[]{"1","2",lower,upper};
}

@Override
public String[] getValues(final AbstractRealDistribution distribution) {
return new String[] {
NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).a),
NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).b),
NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).c),
NumberTools.formatNumberMax(((KumaraswamyDistribution)distribution).d)
};
}

@Override
public AbstractRealDistribution getDistribution(final JTextField[] fields, final double maxXValue) {
final Double d1=NumberTools.getPositiveDouble(fields[0],true); if (d1==null) return null;
final Double d2=NumberTools.getPositiveDouble(fields[1],true); if (d2==null) return null;
final Double d3=NumberTools.getPositiveDouble(fields[2],true); if (d3==null) return null;
final Double d4=NumberTools.getPositiveDouble(fields[3],true); if (d4==null) return null;
if (d3>=d4) return null;
return new KumaraswamyDistribution(d1,d2,d3,d4);
}
}

/** Hypergeometrische Verteilung */
private static class HyperGeomDistributionPanel extends JDistributionEditorPanelRecord {
/** Konstruktor der Klasse */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ public final class DistributionTools {
/** Wikipedia-Seite Reziproke Verteilung */
public static String DistReciprocalWikipedia="https://en.wikipedia.org/wiki/Reciprocal_distribution";

/** Kumaraswamy Verteilung */
public static String[] DistKumaraswamy=new String[]{"Kumaraswamy-Verteilung"};

/** Wikipedia-Seite Kumaraswamy-Verteilung */
public static String DistKumaraswamyWikipedia="https://en.wikipedia.org/wiki/Kumaraswamy_distribution";

/** Warnung "unbekannte Verteilung" */
public static String DistUnknown="unbekannte Verteilung";

Expand Down Expand Up @@ -417,7 +423,8 @@ private DistributionTools() {
new WrapperDiscreteUniformDistribution(),
new WrapperHalfNormalDistribution(),
new WrapperUQuadraticDistribution(),
new WrapperReciprocalDistribution()
new WrapperReciprocalDistribution(),
new WrapperKumaraswamyDistribution()
};
}

Expand Down
Loading

0 comments on commit 94ccf3e

Please sign in to comment.