summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/math/statistics/distribution
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/math/statistics/distribution')
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java115
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java79
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java67
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java70
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java63
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java41
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java71
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java75
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java78
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java69
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java66
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java59
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java51
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java147
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java72
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java65
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java85
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java60
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java56
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java224
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java67
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java64
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java79
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java23
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java2
40 files changed, 1982 insertions, 357 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java
new file mode 100644
index 00000000..30481d00
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/AbstractDistribution.java
@@ -0,0 +1,115 @@
+package de.lmu.ifi.dbs.elki.math.statistics.distribution;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
+
+/**
+ * Abstract base class for distributions.
+ *
+ * @author Erich Schubert
+ */
+public abstract class AbstractDistribution implements Distribution {
+ /**
+ * Random source.
+ */
+ final protected Random random;
+
+ /**
+ * Constructor.
+ *
+ * @param rnd Random source
+ */
+ public AbstractDistribution(RandomFactory rnd) {
+ super();
+ this.random = rnd.getRandom();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param rnd Random source
+ */
+ public AbstractDistribution(Random rnd) {
+ super();
+ this.random = rnd;
+ }
+
+ @Override
+ public double nextRandom() {
+ return quantile(random.nextDouble());
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public abstract static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Parameter to specify the random seeding source.
+ */
+ public static final OptionID RANDOM_ID = new OptionID("distribution.random", "Random generation data source.");
+
+ /**
+ * Location parameter.
+ */
+ public static final OptionID LOCATION_ID = new OptionID("distribution.location", "Distribution location parameter");
+
+ /**
+ * Scale parameter.
+ */
+ public static final OptionID SCALE_ID = new OptionID("distribution.scale", "Distribution scale parameter");
+
+ /**
+ * Shape parameter.
+ */
+ public static final OptionID SHAPE_ID = new OptionID("distribution.shape", "Distribution shape parameter");
+
+ /**
+ * Random source.
+ */
+ RandomFactory rnd;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ RandomParameter randomP = new RandomParameter(RANDOM_ID);
+ if (config.grab(randomP)) {
+ rnd = randomP.getValue();
+ }
+ }
+
+ @Override
+ abstract protected Distribution makeInstance();
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
index c48583ea..04d55262 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/BetaDistribution.java
@@ -2,7 +2,11 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/*
This file is part of ELKI:
@@ -34,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
* @author Jan Brusis
* @author Erich Schubert
*/
-public class BetaDistribution implements Distribution {
+public class BetaDistribution extends AbstractDistribution {
/**
* Numerical precision to use
*/
@@ -66,11 +70,6 @@ public class BetaDistribution implements Distribution {
private final double beta;
/**
- * For random number generation
- */
- private Random random;
-
- /**
* Log beta(a, b) cache
*/
private double logbab;
@@ -82,7 +81,7 @@ public class BetaDistribution implements Distribution {
* @param b shape Parameter b
*/
public BetaDistribution(double a, double b) {
- this(a, b, new Random());
+ this(a, b, (Random) null);
}
/**
@@ -93,7 +92,25 @@ public class BetaDistribution implements Distribution {
* @param random Random generator
*/
public BetaDistribution(double a, double b, Random random) {
- super();
+ super(random);
+ if (a <= 0.0 || b <= 0.0) {
+ throw new IllegalArgumentException("Invalid parameters for Beta distribution.");
+ }
+
+ this.alpha = a;
+ this.beta = b;
+ this.logbab = logBeta(a, b);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param a shape Parameter a
+ * @param b shape Parameter b
+ * @param random Random generator
+ */
+ public BetaDistribution(double a, double b, RandomFactory random) {
+ super(random);
if (a <= 0.0 || b <= 0.0) {
throw new IllegalArgumentException("Invalid parameters for Beta distribution.");
}
@@ -101,7 +118,6 @@ public class BetaDistribution implements Distribution {
this.alpha = a;
this.beta = b;
this.logbab = logBeta(a, b);
- this.random = random;
}
@Override
@@ -457,7 +473,8 @@ public class BetaDistribution implements Distribution {
} else {
double r = beta + beta;
double t = 1. / (9. * beta);
- t = r * Math.pow(1. - t + y * Math.sqrt(t), 3.0);
+ final double a = 1. - t + y * Math.sqrt(t);
+ t = r * a * a * a;
if (t <= 0.) {
x = 1. - Math.exp((Math.log1p(-p) + Math.log(beta) + logbeta) / beta);
} else {
@@ -525,4 +542,46 @@ public class BetaDistribution implements Distribution {
// Not converged in Newton-Raphson
throw new AbortException("Beta quantile computation did not converge.");
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Alpha parameter.
+ */
+ public static final OptionID ALPHA_ID = new OptionID("distribution.beta.alpha", "Beta distribution alpha parameter");
+
+ /**
+ * Beta parameter.
+ */
+ public static final OptionID BETA_ID = new OptionID("distribution.beta.beta", "Beta distribution beta parameter");
+
+ /** Parameters. */
+ double alpha, beta;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter alphaP = new DoubleParameter(ALPHA_ID);
+ if (config.grab(alphaP)) {
+ alpha = alphaP.doubleValue();
+ }
+
+ DoubleParameter betaP = new DoubleParameter(BETA_ID);
+ if (config.grab(betaP)) {
+ beta = betaP.doubleValue();
+ }
+ }
+
+ @Override
+ protected BetaDistribution makeInstance() {
+ return new BetaDistribution(alpha, beta, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
index c218a37f..2b5d4949 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/CauchyDistribution.java
@@ -25,12 +25,17 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Cauchy distribution.
*
* @author Erich Schubert
*/
-public class CauchyDistribution implements Distribution {
+public class CauchyDistribution extends AbstractDistribution {
/**
* The location (x0) parameter.
*/
@@ -42,18 +47,13 @@ public class CauchyDistribution implements Distribution {
final double shape;
/**
- * The random generator.
- */
- private Random random;
-
- /**
* Constructor with default random.
*
* @param location Location (x0)
* @param shape Shape (gamma)
*/
public CauchyDistribution(double location, double shape) {
- this(location, shape, new Random());
+ this(location, shape, (Random) null);
}
/**
@@ -64,10 +64,22 @@ public class CauchyDistribution implements Distribution {
* @param random Random generator
*/
public CauchyDistribution(double location, double shape, Random random) {
- super();
+ super(random);
+ this.location = location;
+ this.shape = shape;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param location Location (x0)
+ * @param shape Shape (gamma)
+ * @param random Random generator
+ */
+ public CauchyDistribution(double location, double shape, RandomFactory random) {
+ super(random);
this.location = location;
this.shape = shape;
- this.random = random;
}
@Override
@@ -132,4 +144,41 @@ public class CauchyDistribution implements Distribution {
public String toString() {
return "CauchyDistribution(location=" + location + ", shape=" + shape + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Shape parameter gamma.
+ */
+ public static final OptionID SHAPE_ID = new OptionID("distribution.cauchy.shape", "Cauchy distribution gamma/shape parameter.");
+
+ /** Parameters. */
+ double location, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locP)) {
+ location = locP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected CauchyDistribution makeInstance() {
+ return new CauchyDistribution(location, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
index a552e413..5f144946 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiDistribution.java
@@ -1,8 +1,5 @@
package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
-
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -26,6 +23,14 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Chi distribution.
*
@@ -33,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
*
* @apiviz.composedOf ChiSquaredDistribution
*/
-public class ChiDistribution implements Distribution {
+public class ChiDistribution extends AbstractDistribution {
/**
* Degrees of freedom. Usually integer.
*/
@@ -50,9 +55,31 @@ public class ChiDistribution implements Distribution {
* @param dof Degrees of freedom. Usually integer.
*/
public ChiDistribution(double dof) {
- super();
+ this(dof, (Random) null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dof Degrees of freedom. Usually integer.
+ * @param random Random number generator.
+ */
+ public ChiDistribution(double dof, Random random) {
+ super(random);
this.dof = dof;
- this.chisq = new ChiSquaredDistribution(dof);
+ this.chisq = new ChiSquaredDistribution(dof, random);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dof Degrees of freedom. Usually integer.
+ * @param random Random number generator.
+ */
+ public ChiDistribution(double dof, RandomFactory random) {
+ super(random);
+ this.dof = dof;
+ this.chisq = new ChiSquaredDistribution(dof, random);
}
@Override
@@ -73,7 +100,7 @@ public class ChiDistribution implements Distribution {
* @return Pdf value
*/
public static double pdf(double val, double dof) {
- if(val < 0) {
+ if (val < 0) {
return 0.0;
}
return Math.sqrt(ChiSquaredDistribution.pdf(val, dof));
@@ -105,4 +132,31 @@ public class ChiDistribution implements Distribution {
public String toString() {
return "ChiDistribution(dof=" + dof + ")";
}
-} \ No newline at end of file
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double dof;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter dofP = new DoubleParameter(ChiSquaredDistribution.Parameterizer.DOF_ID);
+ if (config.grab(dofP)) {
+ dof = dofP.doubleValue();
+ }
+ }
+
+ @Override
+ protected ChiDistribution makeInstance() {
+ return new ChiDistribution(dof, rnd);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
index 235367cd..6fd432b2 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ChiSquaredDistribution.java
@@ -1,7 +1,5 @@
package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
-
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -24,6 +22,13 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Chi-Squared distribution (a specialization of the Gamma distribution).
@@ -37,7 +42,27 @@ public class ChiSquaredDistribution extends GammaDistribution {
* @param dof Degrees of freedom.
*/
public ChiSquaredDistribution(double dof) {
- super(.5 * dof, .5);
+ this(dof, (Random) null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dof Degrees of freedom.
+ * @param random Random generator.
+ */
+ public ChiSquaredDistribution(double dof, Random random) {
+ super(.5 * dof, .5, random);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param dof Degrees of freedom.
+ * @param random Random generator.
+ */
+ public ChiSquaredDistribution(double dof, RandomFactory random) {
+ super(.5 * dof, .5, random);
}
/**
@@ -95,4 +120,36 @@ public class ChiSquaredDistribution extends GammaDistribution {
public String toString() {
return "ChiSquaredDistribution(dof=" + (2 * getK()) + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Degrees of freedom parameter.
+ */
+ public static final OptionID DOF_ID = new OptionID("distribution.chi.dof", "Chi distribution degrees of freedom parameter.");
+
+ /** Parameters. */
+ double dof;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter dofP = new DoubleParameter(DOF_ID);
+ if (config.grab(dofP)) {
+ dof = dofP.doubleValue();
+ }
+ }
+
+ @Override
+ protected ChiSquaredDistribution makeInstance() {
+ return new ChiSquaredDistribution(dof, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
index 35d5294f..b31eaa3d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ConstantDistribution.java
@@ -1,5 +1,10 @@
package de.lmu.ifi.dbs.elki.math.statistics.distribution;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -56,11 +61,43 @@ public class ConstantDistribution implements Distribution {
@Override
public double cdf(double val) {
- return (val >= c) ? 1.0 : 0.0;
+ return (c < val) ? 0. : (c > val) ? 1. : .5;
}
@Override
public double quantile(double val) {
return c;
}
-} \ No newline at end of file
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Constant value parameter
+ */
+ public static final OptionID CONSTANT_ID = new OptionID("distribution.constant", "Constant value.");
+
+ /** Parameters. */
+ double constant;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter constP = new DoubleParameter(CONSTANT_ID);
+ if (config.grab(constP)) {
+ constant = constP.doubleValue();
+ }
+ }
+
+ @Override
+ protected ConstantDistribution makeInstance() {
+ return new ConstantDistribution(constant);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
index 519ba0b3..0c60e02f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/Distribution.java
@@ -23,12 +23,14 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
+
/**
* Statistical distributions, with their common functions.
*
* @author Erich Schubert
*/
-public interface Distribution {
+public interface Distribution extends Parameterizable {
/**
* Return the density of an existing value
*
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
index e5af3e5b..33d8e853 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentialDistribution.java
@@ -25,17 +25,17 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Exponential distribution.
*
* @author Erich Schubert
*/
-public class ExponentialDistribution implements Distribution {
- /**
- * Random generator.
- */
- Random rnd;
-
+public class ExponentialDistribution extends AbstractDistribution {
/**
* Rate, inverse of mean
*/
@@ -52,7 +52,7 @@ public class ExponentialDistribution implements Distribution {
* @param rate Rate parameter (1/scale)
*/
public ExponentialDistribution(double rate) {
- this(rate, 0.0, null);
+ this(rate, 0.0, (Random) null);
}
/**
@@ -62,7 +62,7 @@ public class ExponentialDistribution implements Distribution {
* @param location Location parameter
*/
public ExponentialDistribution(double rate, double location) {
- this(rate, location, null);
+ this(rate, location, (Random) null);
}
/**
@@ -83,10 +83,22 @@ public class ExponentialDistribution implements Distribution {
* @param random Random generator
*/
public ExponentialDistribution(double rate, double location, Random random) {
- super();
+ super(random);
+ this.rate = rate;
+ this.location = location;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param rate Rate parameter (1/scale)
+ * @param location Location parameter
+ * @param random Random generator
+ */
+ public ExponentialDistribution(double rate, double location, RandomFactory random) {
+ super(random);
this.rate = rate;
this.location = location;
- this.rnd = random;
}
@Override
@@ -160,11 +172,48 @@ public class ExponentialDistribution implements Distribution {
*/
@Override
public double nextRandom() {
- return -Math.log(rnd.nextDouble()) / rate + location;
+ return -Math.log(random.nextDouble()) / rate + location;
}
@Override
public String toString() {
return "ExponentialDistribution(rate=" + rate + ", location=" + location + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Shape parameter gamma.
+ */
+ public static final OptionID RATE_ID = new OptionID("distribution.exponential.rate", "Exponential distribution rate (lambda) parameter (inverse of scale).");
+
+ /** Parameters. */
+ double location, rate;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locP)) {
+ location = locP.doubleValue();
+ }
+
+ DoubleParameter rateP = new DoubleParameter(RATE_ID);
+ if (config.grab(rateP)) {
+ rate = rateP.doubleValue();
+ }
+ }
+
+ @Override
+ protected ExponentialDistribution makeInstance() {
+ return new ExponentialDistribution(rate, location, rnd);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
index 01e91777..22e75e3d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/ExponentiallyModifiedGaussianDistribution.java
@@ -25,9 +25,13 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Exponentially modified Gaussian (EMG) distribution (ExGaussian distribution)
@@ -36,7 +40,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
* @author Erich Schubert
*/
@Alias({ "exgaussian" })
-public class ExponentiallyModifiedGaussianDistribution implements Distribution {
+public class ExponentiallyModifiedGaussianDistribution extends AbstractDistribution {
/**
* Mean value for the generator
*/
@@ -53,9 +57,19 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
private double lambda;
/**
- * Random generator.
+ * Constructor for ExGaussian distribution
+ *
+ * @param mean Mean
+ * @param stddev Standard Deviation
+ * @param lambda Rate
+ * @param random Random
*/
- private Random rnd;
+ public ExponentiallyModifiedGaussianDistribution(double mean, double stddev, double lambda, Random random) {
+ super(random);
+ this.mean = mean;
+ this.stddev = stddev;
+ this.lambda = lambda;
+ }
/**
* Constructor for ExGaussian distribution
@@ -63,14 +77,13 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
* @param mean Mean
* @param stddev Standard Deviation
* @param lambda Rate
- * @param rnd Random
+ * @param random Random
*/
- public ExponentiallyModifiedGaussianDistribution(double mean, double stddev, double lambda, Random rnd) {
- super();
+ public ExponentiallyModifiedGaussianDistribution(double mean, double stddev, double lambda, RandomFactory random) {
+ super(random);
this.mean = mean;
this.stddev = stddev;
this.lambda = lambda;
- this.rnd = rnd;
}
/**
@@ -81,7 +94,7 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
* @param lambda Rate
*/
public ExponentiallyModifiedGaussianDistribution(double mean, double stddev, double lambda) {
- this(mean, stddev, lambda, null);
+ this(mean, stddev, lambda, (Random) null);
}
@Override
@@ -105,8 +118,8 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
@Override
public double nextRandom() {
- double no = mean + rnd.nextGaussian() * stddev;
- double ex = -Math.log(rnd.nextDouble()) / lambda;
+ double no = mean + random.nextGaussian() * stddev;
+ double ex = -Math.log(random.nextDouble()) / lambda;
return no + ex;
}
@@ -147,8 +160,9 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
*/
public static double pdf(double x, double mu, double sigma, double lambda) {
final double dx = x - mu;
- final double erfc = NormalDistribution.erfc(lambda * sigma * sigma - dx);
- return .5 * lambda * Math.exp(lambda * (lambda * sigma * sigma * .5 - dx)) * erfc;
+ final double lss = lambda * sigma * sigma;
+ final double erfc = NormalDistribution.erfc((lss - dx) / (sigma * MathUtil.SQRT2));
+ return .5 * lambda * Math.exp(lambda * (lss * .5 - dx)) * erfc;
}
/**
@@ -185,4 +199,41 @@ public class ExponentiallyModifiedGaussianDistribution implements Distribution {
// FIXME: implement!
throw new NotImplementedException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mean, stddev, lambda;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locP = new DoubleParameter(LOCATION_ID);
+ if(config.grab(locP)) {
+ mean = locP.doubleValue();
+ }
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if(config.grab(scaleP)) {
+ stddev = scaleP.doubleValue();
+ }
+
+ DoubleParameter rateP = new DoubleParameter(ExponentialDistribution.Parameterizer.RATE_ID);
+ if(config.grab(rateP)) {
+ lambda = rateP.doubleValue();
+ }
+ }
+
+ @Override
+ protected ExponentiallyModifiedGaussianDistribution makeInstance() {
+ return new ExponentiallyModifiedGaussianDistribution(mean, stddev, lambda, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
index 1b9e2b42..850b0e3a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GammaDistribution.java
@@ -27,14 +27,18 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Gamma Distribution, with random generation and density functions.
*
* @author Erich Schubert
*/
-public class GammaDistribution implements Distribution {
+public class GammaDistribution extends AbstractDistribution {
/**
* Euler–Mascheroni constant
*/
@@ -77,9 +81,21 @@ public class GammaDistribution implements Distribution {
private final double theta;
/**
- * The random generator.
+ * Constructor for Gamma distribution.
+ *
+ * @param k k, alpha aka. "shape" parameter
+ * @param theta Theta = 1.0/Beta aka. "scaling" parameter
+ * @param random Random generator
*/
- private Random random;
+ public GammaDistribution(double k, double theta, Random random) {
+ super(random);
+ if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
+ throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
+ }
+
+ this.k = k;
+ this.theta = theta;
+ }
/**
* Constructor for Gamma distribution.
@@ -88,15 +104,14 @@ public class GammaDistribution implements Distribution {
* @param theta Theta = 1.0/Beta aka. "scaling" parameter
* @param random Random generator
*/
- public GammaDistribution(double k, double theta, Random random) {
- super();
+ public GammaDistribution(double k, double theta, RandomFactory random) {
+ super(random);
if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
}
this.k = k;
this.theta = theta;
- this.random = random;
}
/**
@@ -106,7 +121,7 @@ public class GammaDistribution implements Distribution {
* @param theta Theta = 1.0/Beta aka. "scaling" parameter
*/
public GammaDistribution(double k, double theta) {
- this(k, theta, new Random());
+ this(k, theta, (Random) null);
}
@Override
@@ -631,12 +646,13 @@ public class GammaDistribution implements Distribution {
// (Math.log(alpha) + g);
// return Math.exp((lgam1pa + logp) / alpha + MathUtil.LOG2);
// This is literal AS 91, above is the GNU R variant.
- return Math.pow(p * k * Math.exp(g + k * MathUtil.LOG2), 1 / k);
+ return Math.pow(p * k * Math.exp(g + k * MathUtil.LOG2), 1. / k);
} else if (nu > 0.32) {
// Wilson and Hilferty estimate: - AS 91 at 3
final double x = NormalDistribution.quantile(p, 0, 1);
final double p1 = 2. / (9. * nu);
- double ch = nu * Math.pow(x * Math.sqrt(p1) + 1 - p1, 3);
+ final double a = x * Math.sqrt(p1) + 1 - p1;
+ double ch = nu * a * a * a;
// Better approximation for p tending to 1:
if (ch > 2.2 * nu + 6) {
@@ -890,4 +906,48 @@ public class GammaDistribution implements Distribution {
return trigamma(x + 1.) - 1. / (x * x);
}
}
+
+ /**
+ * Parameterization class
+ *
+ * TODO: allow alternate parameterization, with alpha+beta?
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * K parameter.
+ */
+ public static final OptionID K_ID = new OptionID("distribution.gamma.k", "Gamma distribution k = alpha parameter.");
+
+ /**
+ * Theta parameter.
+ */
+ public static final OptionID THETA_ID = new OptionID("distribution.gamma.theta", "Gamma distribution theta = 1/beta parameter.");
+
+ /** Parameters. */
+ double k, theta;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter kP = new DoubleParameter(K_ID);
+ if (config.grab(kP)) {
+ k = kP.doubleValue();
+ }
+
+ DoubleParameter thetaP = new DoubleParameter(THETA_ID);
+ if (config.grab(thetaP)) {
+ theta = thetaP.doubleValue();
+ }
+ }
+
+ @Override
+ protected GammaDistribution makeInstance() {
+ return new GammaDistribution(k, theta, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
index 9cd6cb4e..0d3fd4f8 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedExtremeValueDistribution.java
@@ -1,7 +1,5 @@
package de.lmu.ifi.dbs.elki.math.statistics.distribution;
-import java.util.Random;
-
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -25,6 +23,12 @@ import java.util.Random;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Generalized Extreme Value (GEV) distribution, also known as Fisher–Tippett
* distribution.
@@ -37,16 +41,22 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class GeneralizedExtremeValueDistribution implements Distribution {
+public class GeneralizedExtremeValueDistribution extends AbstractDistribution {
/**
* Parameters (location, scale, shape)
*/
final double mu, sigma, k;
/**
- * Random number generator.
+ * Constructor.
+ *
+ * @param mu Location parameter mu
+ * @param sigma Scale parameter sigma
+ * @param k Shape parameter k
*/
- Random random;
+ public GeneralizedExtremeValueDistribution(double mu, double sigma, double k) {
+ this(mu, sigma, k, (Random) null);
+ }
/**
* Constructor.
@@ -54,9 +64,13 @@ public class GeneralizedExtremeValueDistribution implements Distribution {
* @param mu Location parameter mu
* @param sigma Scale parameter sigma
* @param k Shape parameter k
+ * @param random Random number generator
*/
- public GeneralizedExtremeValueDistribution(double mu, double sigma, double k) {
- this(mu, sigma, k, null);
+ public GeneralizedExtremeValueDistribution(double mu, double sigma, double k, RandomFactory random) {
+ super(random);
+ this.mu = mu;
+ this.sigma = sigma;
+ this.k = k;
}
/**
@@ -68,11 +82,10 @@ public class GeneralizedExtremeValueDistribution implements Distribution {
* @param random Random number generator
*/
public GeneralizedExtremeValueDistribution(double mu, double sigma, double k, Random random) {
- super();
+ super(random);
this.mu = mu;
this.sigma = sigma;
this.k = k;
- this.random = random;
}
/**
@@ -156,12 +169,44 @@ public class GeneralizedExtremeValueDistribution implements Distribution {
}
@Override
- public double nextRandom() {
- return quantile(random.nextDouble());
- }
-
- @Override
public String toString() {
return "GeneralizedExtremeValueDistribution(sigma=" + sigma + ", mu=" + mu + ", k=" + k + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mu, sigma, k;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter muP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(muP)) {
+ mu = muP.doubleValue();
+ }
+
+ DoubleParameter sigmaP = new DoubleParameter(SCALE_ID);
+ if (config.grab(sigmaP)) {
+ sigma = sigmaP.doubleValue();
+ }
+
+ DoubleParameter kP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(kP)) {
+ k = kP.doubleValue();
+ }
+ }
+
+ @Override
+ protected GeneralizedExtremeValueDistribution makeInstance() {
+ return new GeneralizedExtremeValueDistribution(mu, sigma, k, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
index 467d6aae..eb5e1b1a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticAlternateDistribution.java
@@ -24,6 +24,10 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
*/
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Generalized logistic distribution.
*
@@ -33,7 +37,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class GeneralizedLogisticAlternateDistribution implements Distribution {
+public class GeneralizedLogisticAlternateDistribution extends AbstractDistribution {
/**
* Parameters: location and scale
*/
@@ -45,9 +49,15 @@ public class GeneralizedLogisticAlternateDistribution implements Distribution {
double shape;
/**
- * Random number generator
+ * Constructor.
+ *
+ * @param location Location
+ * @param scale Scale
+ * @param shape Shape parameter
*/
- Random random;
+ public GeneralizedLogisticAlternateDistribution(double location, double scale, double shape) {
+ this(location, scale, shape, (Random) null);
+ }
/**
* Constructor.
@@ -55,9 +65,16 @@ public class GeneralizedLogisticAlternateDistribution implements Distribution {
* @param location Location
* @param scale Scale
* @param shape Shape parameter
+ * @param random Random number generator
*/
- public GeneralizedLogisticAlternateDistribution(double location, double scale, double shape) {
- this(location, scale, shape, null);
+ public GeneralizedLogisticAlternateDistribution(double location, double scale, double shape, Random random) {
+ super(random);
+ this.location = location;
+ this.scale = scale;
+ this.shape = shape;
+ if (!(shape > -1.) || !(shape < 1.)) {
+ throw new ArithmeticException("Invalid shape parameter - must be -1 to +1, is: " + shape);
+ }
}
/**
@@ -68,12 +85,11 @@ public class GeneralizedLogisticAlternateDistribution implements Distribution {
* @param shape Shape parameter
* @param random Random number generator
*/
- public GeneralizedLogisticAlternateDistribution(double location, double scale, double shape, Random random) {
- super();
+ public GeneralizedLogisticAlternateDistribution(double location, double scale, double shape, RandomFactory random) {
+ super(random);
this.location = location;
this.scale = scale;
this.shape = shape;
- this.random = random;
if (!(shape > -1.) || !(shape < 1.)) {
throw new ArithmeticException("Invalid shape parameter - must be -1 to +1, is: " + shape);
}
@@ -159,4 +175,41 @@ public class GeneralizedLogisticAlternateDistribution implements Distribution {
public String toString() {
return "GeneralizedLogisticAlternateDistribution(location=" + location + ", scale=" + scale + ", shape=" + shape + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double location, scale, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locationP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locationP)) {
+ location = locationP.doubleValue();
+ }
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected GeneralizedLogisticAlternateDistribution makeInstance() {
+ return new GeneralizedLogisticAlternateDistribution(location, scale, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
index 76f71107..467ad4f9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GeneralizedLogisticDistribution.java
@@ -24,6 +24,10 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
*/
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Generalized logistic distribution. (Type I, Skew-logistic distribution)
*
@@ -37,7 +41,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class GeneralizedLogisticDistribution implements Distribution {
+public class GeneralizedLogisticDistribution extends AbstractDistribution {
/**
* Parameters: location and scale
*/
@@ -49,9 +53,15 @@ public class GeneralizedLogisticDistribution implements Distribution {
double shape;
/**
- * Random number generator
+ * Constructor.
+ *
+ * @param location Location
+ * @param scale Scale
+ * @param shape Shape parameter
*/
- Random random;
+ public GeneralizedLogisticDistribution(double location, double scale, double shape) {
+ this(location, scale, shape, (Random) null);
+ }
/**
* Constructor.
@@ -59,9 +69,13 @@ public class GeneralizedLogisticDistribution implements Distribution {
* @param location Location
* @param scale Scale
* @param shape Shape parameter
+ * @param random Random number generator
*/
- public GeneralizedLogisticDistribution(double location, double scale, double shape) {
- this(location, scale, shape, null);
+ public GeneralizedLogisticDistribution(double location, double scale, double shape, Random random) {
+ super(random);
+ this.location = location;
+ this.scale = scale;
+ this.shape = shape;
}
/**
@@ -72,12 +86,11 @@ public class GeneralizedLogisticDistribution implements Distribution {
* @param shape Shape parameter
* @param random Random number generator
*/
- public GeneralizedLogisticDistribution(double location, double scale, double shape, Random random) {
- super();
+ public GeneralizedLogisticDistribution(double location, double scale, double shape, RandomFactory random) {
+ super(random);
this.location = location;
this.scale = scale;
this.shape = shape;
- this.random = random;
}
/**
@@ -181,4 +194,41 @@ public class GeneralizedLogisticDistribution implements Distribution {
public String toString() {
return "GeneralizedLogisticDistribution(location=" + location + ", scale=" + scale + ", shape=" + shape + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double location, scale, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locationP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locationP)) {
+ location = locationP.doubleValue();
+ }
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected GeneralizedLogisticDistribution makeInstance() {
+ return new GeneralizedLogisticDistribution(location, scale, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
index 15b4ca24..9f42b7e2 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/GumbelDistribution.java
@@ -25,12 +25,16 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Gumbel distribution, also known as Log-Weibull distribution.
*
* @author Erich Schubert
*/
-public class GumbelDistribution implements Distribution {
+public class GumbelDistribution extends AbstractDistribution {
/**
* Mode parameter mu.
*/
@@ -42,18 +46,26 @@ public class GumbelDistribution implements Distribution {
double beta;
/**
- * Random number generator.
+ * Constructor.
+ *
+ * @param mu Mode
+ * @param beta Shape
*/
- Random random;
+ public GumbelDistribution(double mu, double beta) {
+ this(mu, beta, (Random) null);
+ }
/**
* Constructor.
*
* @param mu Mode
* @param beta Shape
+ * @param random Random number generator
*/
- public GumbelDistribution(double mu, double beta) {
- this(mu, beta, null);
+ public GumbelDistribution(double mu, double beta, Random random) {
+ super(random);
+ this.mu = mu;
+ this.beta = beta;
}
/**
@@ -63,11 +75,10 @@ public class GumbelDistribution implements Distribution {
* @param beta Shape
* @param random Random number generator
*/
- public GumbelDistribution(double mu, double beta, Random random) {
- super();
+ public GumbelDistribution(double mu, double beta, RandomFactory random) {
+ super(random);
this.mu = mu;
this.beta = beta;
- this.random = random;
}
/**
@@ -131,4 +142,36 @@ public class GumbelDistribution implements Distribution {
public String toString() {
return "GumbelDistribution(mu=" + mu + ", beta=" + beta + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mean, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter meanP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(meanP)) {
+ mean = meanP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected GumbelDistribution makeInstance() {
+ return new GumbelDistribution(mean, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
index 145744db..c16bb498 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/HaltonUniformDistribution.java
@@ -27,7 +27,10 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.Primes;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Halton sequences are a pseudo-uniform distribution. The data is actually too
@@ -162,7 +165,6 @@ public class HaltonUniformDistribution implements Distribution {
* @param max Maximum value
*/
public HaltonUniformDistribution(double min, double max) {
- // TODO: use different starting primes?
this(min, max, new Random());
}
@@ -175,11 +177,22 @@ public class HaltonUniformDistribution implements Distribution {
* @param rnd Random generator
*/
public HaltonUniformDistribution(double min, double max, Random rnd) {
- // TODO: use different starting primes?
this(min, max, choosePrime(rnd), rnd.nextDouble());
}
/**
+ * Constructor for a halton pseudo uniform distribution on the interval [min,
+ * max[
+ *
+ * @param min Minimum value
+ * @param max Maximum value
+ * @param rnd Random generator
+ */
+ public HaltonUniformDistribution(double min, double max, RandomFactory rnd) {
+ this(min, max, rnd.getRandom());
+ }
+
+ /**
* Choose a random prime. We try to avoid the later primes, as they are known
* to cause too correlated data.
*
@@ -310,4 +323,38 @@ public class HaltonUniformDistribution implements Distribution {
public double getMax() {
return max;
}
+
+ /**
+ * Parameterization class
+ *
+ * TODO: allow manual parameterization of sequence parameters!
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double min, max;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter minP = new DoubleParameter(UniformDistribution.Parameterizer.MIN_ID);
+ if (config.grab(minP)) {
+ min = minP.doubleValue();
+ }
+
+ DoubleParameter maxP = new DoubleParameter(UniformDistribution.Parameterizer.MAX_ID);
+ if (config.grab(maxP)) {
+ max = maxP.doubleValue();
+ }
+ }
+
+ @Override
+ protected HaltonUniformDistribution makeInstance() {
+ return new HaltonUniformDistribution(min, max, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
index 9414767c..156bf325 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/KappaDistribution.java
@@ -24,6 +24,11 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
*/
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Kappa distribution, by Hosking.
*
@@ -31,7 +36,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class KappaDistribution implements Distribution {
+public class KappaDistribution extends AbstractDistribution {
/**
* Parameters: location and scale
*/
@@ -43,11 +48,6 @@ public class KappaDistribution implements Distribution {
double shape1, shape2;
/**
- * Random number generator
- */
- Random random;
-
- /**
* Constructor.
*
* @param location Location
@@ -56,7 +56,7 @@ public class KappaDistribution implements Distribution {
* @param shape2 Shape parameter
*/
public KappaDistribution(double location, double scale, double shape1, double shape2) {
- this(location, scale, shape1, shape2, null);
+ this(location, scale, shape1, shape2, (Random) null);
}
/**
@@ -69,19 +69,43 @@ public class KappaDistribution implements Distribution {
* @param random Random number generator
*/
public KappaDistribution(double location, double scale, double shape1, double shape2, Random random) {
- super();
+ super(random);
this.location = location;
this.scale = scale;
this.shape1 = shape1;
this.shape2 = shape2;
- this.random = random;
- if(shape2 >= 0.) {
- if(shape1 < -1.) {
+ if (shape2 >= 0.) {
+ if (shape1 < -1.) {
throw new ArithmeticException("Invalid shape1 parameter - must be greater than -1 if shape2 >= 0.!");
}
+ } else {
+ if (shape1 < 1. || shape1 > 1. / shape2) {
+ throw new ArithmeticException("Invalid shape1 parameter - must be -1 to +1/shape2 if shape2 < 0.!");
+ }
}
- else {
- if(shape1 < 1. || shape1 > 1. / shape2) {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param location Location
+ * @param scale Scale
+ * @param shape1 Shape parameter
+ * @param shape2 Shape parameter
+ * @param random Random number generator
+ */
+ public KappaDistribution(double location, double scale, double shape1, double shape2, RandomFactory random) {
+ super(random);
+ this.location = location;
+ this.scale = scale;
+ this.shape1 = shape1;
+ this.shape2 = shape2;
+ if (shape2 >= 0.) {
+ if (shape1 < -1.) {
+ throw new ArithmeticException("Invalid shape1 parameter - must be greater than -1 if shape2 >= 0.!");
+ }
+ } else {
+ if (shape1 < 1. || shape1 > 1. / shape2) {
throw new ArithmeticException("Invalid shape1 parameter - must be -1 to +1/shape2 if shape2 < 0.!");
}
}
@@ -100,9 +124,9 @@ public class KappaDistribution implements Distribution {
public static double pdf(double val, double loc, double scale, double shape1, double shape2) {
final double c = cdf(val, loc, scale, shape1, shape2);
val = (val - loc) / scale;
- if(shape1 != 0.) {
+ if (shape1 != 0.) {
val = 1 - shape1 * val;
- if(val < 1e-15) {
+ if (val < 1e-15) {
return 0.;
}
val = (1. - 1. / shape1) * Math.log(val);
@@ -128,24 +152,22 @@ public class KappaDistribution implements Distribution {
*/
public static double cdf(double val, double loc, double scale, double shape1, double shape2) {
val = (val - loc) / scale;
- if(shape1 != 0.) {
+ if (shape1 != 0.) {
double tmp = 1. - shape1 * val;
- if(tmp < 1e-15) {
+ if (tmp < 1e-15) {
return (shape1 < 0.) ? 0. : 1.;
}
val = Math.exp(Math.log(tmp) / shape1);
- }
- else {
+ } else {
val = Math.exp(-val);
}
- if(shape2 != 0.) {
+ if (shape2 != 0.) {
double tmp = 1. - shape2 * val;
- if(tmp < 1e-15) {
+ if (tmp < 1e-15) {
return 0.;
}
val = Math.exp(Math.log(tmp) / shape2);
- }
- else {
+ } else {
val = Math.exp(-val);
}
return val;
@@ -167,39 +189,36 @@ public class KappaDistribution implements Distribution {
* @return Quantile
*/
public static double quantile(double val, double loc, double scale, double shape1, double shape2) {
- if(!(val >= 0.) || !(val <= 1.)) {
+ if (!(val >= 0.) || !(val <= 1.)) {
return Double.NaN;
}
- if(val == 0.) {
- if(shape2 <= 0.) {
- if(shape1 < 0.) {
+ if (val == 0.) {
+ if (shape2 <= 0.) {
+ if (shape1 < 0.) {
return loc + scale / shape1;
- }
- else {
+ } else {
return Double.NEGATIVE_INFINITY;
}
- }
- else {
- if(shape1 != 0.) {
+ } else {
+ if (shape1 != 0.) {
return loc + scale / shape1 * (1. - Math.pow(shape2, -shape1));
- }
- else {
+ } else {
return loc + scale * Math.log(shape2);
}
}
}
- if(val == 1.) {
- if(shape1 <= 0.) {
+ if (val == 1.) {
+ if (shape1 <= 0.) {
return Double.NEGATIVE_INFINITY;
}
return loc + scale / shape1;
}
val = -Math.log(val);
- if(shape2 != 0.) {
+ if (shape2 != 0.) {
val = (1 - Math.exp(-shape2 * val)) / shape2;
}
val = -Math.log(val);
- if(shape1 != 0.) {
+ if (shape1 != 0.) {
val = (1 - Math.exp(-shape1 * val)) / shape1;
}
return loc + scale * val;
@@ -220,4 +239,56 @@ public class KappaDistribution implements Distribution {
public String toString() {
return "KappaDistribution(location=" + location + ", scale=" + scale + ", shape1=" + shape1 + ", shape2=" + shape2 + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * First shape parameter.
+ */
+ public static final OptionID SHAPE1_ID = new OptionID("distribution.kappa.shape1", "First shape parameter of kappa distribution.");
+
+ /**
+ * Second shape parameter.
+ */
+ public static final OptionID SHAPE2_ID = new OptionID("distribution.kappa.shape2", "Second shape parameter of kappa distribution.");
+
+ /** Parameters. */
+ double location, scale, shape1, shape2;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locationP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locationP)) {
+ location = locationP.doubleValue();
+ }
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+
+ DoubleParameter shape1P = new DoubleParameter(SHAPE1_ID);
+ if (config.grab(shape1P)) {
+ shape1 = shape1P.doubleValue();
+ }
+
+ DoubleParameter shape2P = new DoubleParameter(SHAPE2_ID);
+ if (config.grab(shape2P)) {
+ shape2 = shape2P.doubleValue();
+ }
+ }
+
+ @Override
+ protected KappaDistribution makeInstance() {
+ return new KappaDistribution(location, scale, shape1, shape2, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
index eb238a20..18a6ffbe 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LaplaceDistribution.java
@@ -26,6 +26,10 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Laplace distribution also known as double exponential distribution
@@ -33,12 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias;
* @author Erich Schubert
*/
@Alias("DoubleExponentialDistribution")
-public class LaplaceDistribution implements Distribution {
- /**
- * Random generator.
- */
- Random rnd;
-
+public class LaplaceDistribution extends AbstractDistribution {
/**
* Rate, inverse of mean
*/
@@ -55,7 +54,7 @@ public class LaplaceDistribution implements Distribution {
* @param rate Rate parameter (1/scale)
*/
public LaplaceDistribution(double rate) {
- this(rate, 0.0, null);
+ this(rate, 0., (Random) null);
}
/**
@@ -65,7 +64,7 @@ public class LaplaceDistribution implements Distribution {
* @param location Location parameter
*/
public LaplaceDistribution(double rate, double location) {
- this(rate, location, null);
+ this(rate, location, (Random) null);
}
/**
@@ -75,7 +74,7 @@ public class LaplaceDistribution implements Distribution {
* @param random Random generator
*/
public LaplaceDistribution(double rate, Random random) {
- this(rate, 0.0, random);
+ this(rate, 0., random);
}
/**
@@ -86,10 +85,22 @@ public class LaplaceDistribution implements Distribution {
* @param random Random generator
*/
public LaplaceDistribution(double rate, double location, Random random) {
- super();
+ super(random);
+ this.rate = rate;
+ this.location = location;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param rate Rate parameter (1/scale)
+ * @param location Location parameter
+ * @param random Random generator
+ */
+ public LaplaceDistribution(double rate, double location, RandomFactory random) {
+ super(random);
this.rate = rate;
this.location = location;
- this.rnd = random;
}
@Override
@@ -157,7 +168,7 @@ public class LaplaceDistribution implements Distribution {
*/
@Override
public double nextRandom() {
- double val = rnd.nextDouble();
+ double val = random.nextDouble();
if (val < .5) {
return Math.log(2 * val) / rate + location;
} else {
@@ -169,4 +180,41 @@ public class LaplaceDistribution implements Distribution {
public String toString() {
return "LaplaceDistribution(rate=" + rate + ", location=" + location + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Shape parameter gamma.
+ */
+ public static final OptionID RATE_ID = new OptionID("distribution.laplace.rate", "Laplace distribution rate (lambda) parameter (inverse of scale).");
+
+ /** Parameters. */
+ double location, rate;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter locP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locP)) {
+ location = locP.doubleValue();
+ }
+
+ DoubleParameter rateP = new DoubleParameter(RATE_ID);
+ if (config.grab(rateP)) {
+ rate = rateP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LaplaceDistribution makeInstance() {
+ return new LaplaceDistribution(rate, location, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
index 496e6867..90902ae0 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaAlternateDistribution.java
@@ -25,6 +25,11 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Alternate Log-Gamma Distribution, with random generation and density
* functions.
@@ -35,7 +40,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class LogGammaAlternateDistribution implements Distribution {
+public class LogGammaAlternateDistribution extends AbstractDistribution {
/**
* Alpha == k.
*/
@@ -52,9 +57,23 @@ public class LogGammaAlternateDistribution implements Distribution {
private final double shift;
/**
- * The random generator.
+ * Constructor for Gamma distribution.
+ *
+ * @param k k, alpha aka. "shape" parameter
+ * @param shift Location offset
+ * @param theta Theta = 1.0/Beta aka. "scaling" parameter
+ * @param random Random generator
*/
- private Random random;
+ public LogGammaAlternateDistribution(double k, double theta, double shift, Random random) {
+ super(random);
+ if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
+ throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
+ }
+
+ this.k = k;
+ this.theta = theta;
+ this.shift = shift;
+ }
/**
* Constructor for Gamma distribution.
@@ -64,8 +83,8 @@ public class LogGammaAlternateDistribution implements Distribution {
* @param theta Theta = 1.0/Beta aka. "scaling" parameter
* @param random Random generator
*/
- public LogGammaAlternateDistribution(double k, double theta, double shift, Random random) {
- super();
+ public LogGammaAlternateDistribution(double k, double theta, double shift, RandomFactory random) {
+ super(random);
if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
}
@@ -73,7 +92,6 @@ public class LogGammaAlternateDistribution implements Distribution {
this.k = k;
this.theta = theta;
this.shift = shift;
- this.random = random;
}
/**
@@ -84,7 +102,7 @@ public class LogGammaAlternateDistribution implements Distribution {
* @param shift Location offset
*/
public LogGammaAlternateDistribution(double k, double theta, double shift) {
- this(k, theta, shift, null);
+ this(k, theta, shift, (Random) null);
}
@Override
@@ -206,4 +224,46 @@ public class LogGammaAlternateDistribution implements Distribution {
public static double quantile(double p, double k, double theta, double shift) {
return Math.log(GammaDistribution.quantile(p, k, 1.)) / theta + shift;
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Shifting offset parameter.
+ */
+ public static final OptionID SHIFT_ID = new OptionID("distribution.loggamma.shift", "Shift offset parameter.");
+
+ /** Parameters. */
+ double k, theta, shift;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter kP = new DoubleParameter(GammaDistribution.Parameterizer.K_ID);
+ if (config.grab(kP)) {
+ k = kP.doubleValue();
+ }
+
+ DoubleParameter thetaP = new DoubleParameter(GammaDistribution.Parameterizer.THETA_ID);
+ if (config.grab(thetaP)) {
+ theta = thetaP.doubleValue();
+ }
+
+ DoubleParameter shiftP = new DoubleParameter(SHIFT_ID);
+ if (config.grab(shiftP)) {
+ shift = shiftP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LogGammaAlternateDistribution makeInstance() {
+ return new LogGammaAlternateDistribution(k, theta, shift, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
index db3a2b3f..76b10dde 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogGammaDistribution.java
@@ -25,6 +25,11 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Log-Gamma Distribution, with random generation and density functions.
*
@@ -34,7 +39,7 @@ import java.util.Random;
*
* @author Erich Schubert
*/
-public class LogGammaDistribution implements Distribution {
+public class LogGammaDistribution extends AbstractDistribution {
/**
* Alpha == k.
*/
@@ -51,9 +56,23 @@ public class LogGammaDistribution implements Distribution {
private final double shift;
/**
- * The random generator.
+ * Constructor for Gamma distribution.
+ *
+ * @param k k, alpha aka. "shape" parameter
+ * @param shift Location offset
+ * @param theta Theta = 1.0/Beta aka. "scaling" parameter
+ * @param random Random generator
*/
- private Random random;
+ public LogGammaDistribution(double k, double theta, double shift, Random random) {
+ super(random);
+ if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
+ throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
+ }
+
+ this.k = k;
+ this.theta = theta;
+ this.shift = shift;
+ }
/**
* Constructor for Gamma distribution.
@@ -63,8 +82,8 @@ public class LogGammaDistribution implements Distribution {
* @param theta Theta = 1.0/Beta aka. "scaling" parameter
* @param random Random generator
*/
- public LogGammaDistribution(double k, double theta, double shift, Random random) {
- super();
+ public LogGammaDistribution(double k, double theta, double shift, RandomFactory random) {
+ super(random);
if (!(k > 0.0) || !(theta > 0.0)) { // Note: also tests for NaNs!
throw new IllegalArgumentException("Invalid parameters for Gamma distribution: " + k + " " + theta);
}
@@ -72,7 +91,6 @@ public class LogGammaDistribution implements Distribution {
this.k = k;
this.theta = theta;
this.shift = shift;
- this.random = random;
}
/**
@@ -83,7 +101,7 @@ public class LogGammaDistribution implements Distribution {
* @param shift Location offset
*/
public LogGammaDistribution(double k, double theta, double shift) {
- this(k, theta, shift, null);
+ this(k, theta, shift, (Random) null);
}
@Override
@@ -191,4 +209,46 @@ public class LogGammaDistribution implements Distribution {
public static double quantile(double p, double k, double theta, double shift) {
return Math.exp(GammaDistribution.quantile(p, k, theta)) + shift;
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Shifting offset parameter.
+ */
+ public static final OptionID SHIFT_ID = new OptionID("distribution.loggamma.shift", "Shift offset parameter.");
+
+ /** Parameters. */
+ double k, theta, shift;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter kP = new DoubleParameter(GammaDistribution.Parameterizer.K_ID);
+ if (config.grab(kP)) {
+ k = kP.doubleValue();
+ }
+
+ DoubleParameter thetaP = new DoubleParameter(GammaDistribution.Parameterizer.THETA_ID);
+ if (config.grab(thetaP)) {
+ theta = thetaP.doubleValue();
+ }
+
+ DoubleParameter shiftP = new DoubleParameter(SHIFT_ID);
+ if (config.grab(shiftP)) {
+ shift = shiftP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LogGammaDistribution makeInstance() {
+ return new LogGammaDistribution(k, theta, shift, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
index cb75561d..fe8557b3 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogLogisticDistribution.java
@@ -24,30 +24,44 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
*/
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Log-Logistic distribution also known as Fisk distribution.
*
* @author Erich Schubert
*/
-public class LogLogisticDistribution implements Distribution {
+@Alias({ "fisk", "loglog" })
+public class LogLogisticDistribution extends AbstractDistribution {
/**
* Parameters: scale and shape
*/
double scale, shape;
/**
- * Random number generator
+ * Constructor.
+ *
+ * @param scale Scale
+ * @param shape Shape
*/
- Random random;
+ public LogLogisticDistribution(double scale, double shape) {
+ this(scale, shape, (Random) null);
+ }
/**
* Constructor.
*
* @param scale Scale
* @param shape Shape
+ * @param random Random number generator
*/
- public LogLogisticDistribution(double scale, double shape) {
- this(scale, shape, null);
+ public LogLogisticDistribution(double scale, double shape, Random random) {
+ super(random);
+ this.scale = scale;
+ this.shape = shape;
}
/**
@@ -57,11 +71,10 @@ public class LogLogisticDistribution implements Distribution {
* @param shape Shape
* @param random Random number generator
*/
- public LogLogisticDistribution(double scale, double shape, Random random) {
- super();
+ public LogLogisticDistribution(double scale, double shape, RandomFactory random) {
+ super(random);
this.scale = scale;
this.shape = shape;
- this.random = random;
}
/**
@@ -73,7 +86,7 @@ public class LogLogisticDistribution implements Distribution {
* @return PDF
*/
public static double pdf(double val, double scale, double shape) {
- if(val < 0) {
+ if (val < 0) {
return 0;
}
val = Math.abs(val / scale);
@@ -96,7 +109,7 @@ public class LogLogisticDistribution implements Distribution {
* @return CDF
*/
public static double cdf(double val, double scale, double shape) {
- if(val < 0) {
+ if (val < 0) {
return 0;
}
return 1. / (1. + Math.pow(val / scale, -shape));
@@ -134,4 +147,36 @@ public class LogLogisticDistribution implements Distribution {
public String toString() {
return "LogLogisticDistribution(scale=" + scale + ", shape=" + shape + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double scale, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LogLogisticDistribution makeInstance() {
+ return new LogLogisticDistribution(scale, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
index 4c3d9aa0..ca2fbbab 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogNormalDistribution.java
@@ -26,6 +26,11 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Log-Normal distribution.
@@ -40,7 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias;
* @author Erich Schubert
*/
@Alias({ "lognormal" })
-public class LogNormalDistribution implements Distribution {
+public class LogNormalDistribution extends AbstractDistribution {
/**
* Mean value for the generator
*/
@@ -57,9 +62,19 @@ public class LogNormalDistribution implements Distribution {
private double shift = 0.;
/**
- * The random generator.
+ * Constructor for Log-Normal distribution
+ *
+ * @param logmean Mean
+ * @param logstddev Standard Deviation
+ * @param shift Shifting offset
+ * @param random Random generator
*/
- private Random random;
+ public LogNormalDistribution(double logmean, double logstddev, double shift, Random random) {
+ super(random);
+ this.logmean = logmean;
+ this.logstddev = logstddev;
+ this.shift = shift;
+ }
/**
* Constructor for Log-Normal distribution
@@ -69,12 +84,11 @@ public class LogNormalDistribution implements Distribution {
* @param shift Shifting offset
* @param random Random generator
*/
- public LogNormalDistribution(double logmean, double logstddev, double shift, Random random) {
- super();
+ public LogNormalDistribution(double logmean, double logstddev, double shift, RandomFactory random) {
+ super(random);
this.logmean = logmean;
this.logstddev = logstddev;
this.shift = shift;
- this.random = random;
}
/**
@@ -85,7 +99,7 @@ public class LogNormalDistribution implements Distribution {
* @param shift Shifting offset
*/
public LogNormalDistribution(double logmean, double logstddev, double shift) {
- this(logmean, logstddev, shift, null);
+ this(logmean, logstddev, shift, (Random) null);
}
@Override
@@ -117,7 +131,7 @@ public class LogNormalDistribution implements Distribution {
* @return PDF of the given normal distribution at x.
*/
public static double pdf(double x, double mu, double sigma) {
- if (x <= 0.) {
+ if(x <= 0.) {
return 0.;
}
final double x_mu = Math.log(x) - mu;
@@ -134,7 +148,7 @@ public class LogNormalDistribution implements Distribution {
* @return The CDF of the given normal distribution at x.
*/
public static double cdf(double x, double mu, double sigma) {
- if (x <= 0.) {
+ if(x <= 0.) {
return 0.;
}
return .5 * (1 + NormalDistribution.erf((Math.log(x) - mu) / (MathUtil.SQRT2 * sigma)));
@@ -162,4 +176,57 @@ public class LogNormalDistribution implements Distribution {
public String toString() {
return "LogNormalDistribution(logmean=" + logmean + ", logstddev=" + logstddev + ", shift=" + shift + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * LogMean parameter
+ */
+ public static final OptionID LOGMEAN_ID = new OptionID("distribution.lognormal.logmean", "Mean of the distribution before logscaling.");
+
+ /**
+ * LogScale parameter
+ */
+ public static final OptionID LOGSTDDEV_ID = new OptionID("distribution.lognormal.logstddev", "Standard deviation of the distribution before logscaling.");
+
+ /**
+ * Shift parameter
+ */
+ public static final OptionID SHIFT_ID = new OptionID("distribution.lognormal.shift", "Shifting offset, so the distribution does not begin at 0.");
+
+ /** Parameters. */
+ double shift, logmean, logsigma;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter logmeanP = new DoubleParameter(LOGMEAN_ID);
+ if(config.grab(logmeanP)) {
+ logmean = logmeanP.doubleValue();
+ }
+
+ DoubleParameter logsigmaP = new DoubleParameter(LOGSTDDEV_ID);
+ logsigmaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(logsigmaP)) {
+ logsigma = logsigmaP.doubleValue();
+ }
+
+ DoubleParameter shiftP = new DoubleParameter(SHIFT_ID, 0.);
+ if(config.grab(shiftP)) {
+ shift = shiftP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LogNormalDistribution makeInstance() {
+ return new LogNormalDistribution(logmean, logsigma, shift, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
index 052847d6..12307a36 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/LogisticDistribution.java
@@ -25,31 +25,44 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Logistic distribution.
*
* @author Erich Schubert
*/
-public class LogisticDistribution implements Distribution {
+@Alias({ "log" })
+public class LogisticDistribution extends AbstractDistribution {
/**
* Parameters: location and scale
*/
double location, scale;
/**
- * Random number generator
+ * Constructor.
+ *
+ * @param location Location
+ * @param scale Scale
*/
- Random random;
+ public LogisticDistribution(double location, double scale) {
+ this(location, scale, (Random) null);
+ }
/**
* Constructor.
*
* @param location Location
* @param scale Scale
+ * @param random Random number generator
*/
- public LogisticDistribution(double location, double scale) {
- this(location, scale, null);
+ public LogisticDistribution(double location, double scale, Random random) {
+ super(random);
+ this.location = location;
+ this.scale = scale;
}
/**
@@ -59,11 +72,10 @@ public class LogisticDistribution implements Distribution {
* @param scale Scale
* @param random Random number generator
*/
- public LogisticDistribution(double location, double scale, Random random) {
- super();
+ public LogisticDistribution(double location, double scale, RandomFactory random) {
+ super(random);
this.location = location;
this.scale = scale;
- this.random = random;
}
/**
@@ -183,4 +195,36 @@ public class LogisticDistribution implements Distribution {
public String toString() {
return "LogisticDistribution(location=" + location + ", scale=" + scale + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double location, scale;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+
+ DoubleParameter locationP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(locationP)) {
+ location = locationP.doubleValue();
+ }
+ }
+
+ @Override
+ protected LogisticDistribution makeInstance() {
+ return new LogisticDistribution(location, scale, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
index c4ae7b6c..0a0d3d4e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/NormalDistribution.java
@@ -27,6 +27,10 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Gaussian distribution aka normal distribution
@@ -34,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.Alias;
* @author Erich Schubert
*/
@Alias({ "GaussianDistribution", "normal", "gauss" })
-public class NormalDistribution implements Distribution {
+public class NormalDistribution extends AbstractDistribution {
/**
* Coefficients for erf approximation.
*
@@ -123,9 +127,17 @@ public class NormalDistribution implements Distribution {
private double stddev;
/**
- * The random generator.
+ * Constructor for Gaussian distribution
+ *
+ * @param mean Mean
+ * @param stddev Standard Deviation
+ * @param random Random generator
*/
- private Random random;
+ public NormalDistribution(double mean, double stddev, RandomFactory random) {
+ super(random);
+ this.mean = mean;
+ this.stddev = stddev;
+ }
/**
* Constructor for Gaussian distribution
@@ -135,10 +147,9 @@ public class NormalDistribution implements Distribution {
* @param random Random generator
*/
public NormalDistribution(double mean, double stddev, Random random) {
- super();
+ super(random);
this.mean = mean;
this.stddev = stddev;
- this.random = random;
}
/**
@@ -148,7 +159,7 @@ public class NormalDistribution implements Distribution {
* @param stddev Standard Deviation
*/
public NormalDistribution(double mean, double stddev) {
- this(mean, stddev, new Random());
+ this(mean, stddev, (Random) null);
}
@Override
@@ -368,4 +379,37 @@ public class NormalDistribution implements Distribution {
return (((((ERFINV_A[0] * r + ERFINV_A[1]) * r + ERFINV_A[2]) * r + ERFINV_A[3]) * r + ERFINV_A[4]) * r + ERFINV_A[5]) * q / (((((ERFINV_B[0] * r + ERFINV_B[1]) * r + ERFINV_B[2]) * r + ERFINV_B[3]) * r + ERFINV_B[4]) * r + 1);
}
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mu, sigma;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter muP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(muP)) {
+ mu = muP.doubleValue();
+ }
+
+ DoubleParameter sigmaP = new DoubleParameter(SCALE_ID);
+ sigmaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if (config.grab(sigmaP)) {
+ sigma = sigmaP.doubleValue();
+ }
+ }
+
+ @Override
+ protected NormalDistribution makeInstance() {
+ return new NormalDistribution(mu, sigma, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
index f6b2e0ca..b6b70b34 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/PoissonDistribution.java
@@ -22,10 +22,18 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Random;
+
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
* INCOMPLETE implementation of the poisson distribution.
@@ -40,7 +48,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
*
* @author Erich Schubert
*/
-public class PoissonDistribution implements Distribution {
+public class PoissonDistribution extends AbstractDistribution {
/**
* Number of tries
*/
@@ -108,86 +116,91 @@ public class PoissonDistribution implements Distribution {
/**
* Constructor.
*
- * Private: API not yet completely implemented!
- *
* @param n Number of tries
* @param p Success probability
*/
public PoissonDistribution(int n, double p) {
- super();
+ this(n, p, (Random) null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param n Number of tries
+ * @param p Success probability
+ * @param random Random generator
+ */
+ public PoissonDistribution(int n, double p, Random random) {
+ super(random);
+ this.n = n;
+ this.p = p;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param n Number of tries
+ * @param p Success probability
+ * @param random Random generator
+ */
+ public PoissonDistribution(int n, double p, RandomFactory random) {
+ super(random);
this.n = n;
this.p = p;
}
/**
- * Poisson PMF for integer values.
+ * Poisson probability mass function (PMF) for integer values.
*
* @param x integer values
* @return Probability
*/
- @Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
public double pmf(int x) {
- // Invalid values
- if (x < 0 || x > n) {
- return 0.0;
- }
- // Extreme probabilities
- if (p <= 0d) {
- return x == 0 ? 1.0 : 0.0;
- }
- if (p >= 1d) {
- return x == n ? 1.0 : 0.0;
- }
- // Extreme values of x
- if (x == 0) {
- if (p < 0.1) {
- return Math.exp(-devianceTerm(n, n * (1.0 - p)) - n * p);
- } else {
- return Math.exp(n * Math.log(1.0 - p));
- }
- }
- if (x == n) {
- if (p > 0.9) {
- return Math.exp(-devianceTerm(n, n * p) - n * (1 - p));
- } else {
- return Math.exp(n * Math.log(p));
- }
- }
-
- final double lc = stirlingError(n) - stirlingError(x) - stirlingError(n - x) - devianceTerm(x, n * p) - devianceTerm(n - x, n * (1.0 - p));
- final double f = (MathUtil.TWOPI * x * (n - x)) / n;
- return Math.exp(lc) / Math.sqrt(f);
+ return pmf(x, n, p);
}
@Override
- @Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
public double pdf(double x) {
+ // FIXME: return 0 for non-integer x?
+ return pmf(x, n, p);
+ }
+
+ /**
+ * Poisson probability mass function (PMF) for integer values.
+ *
+ * @param x integer values
+ * @return Probability
+ */
+ @Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
+ public static double pmf(double x, int n, double p) {
// Invalid values
- if (x < 0 || x > n) {
- return 0.0;
+ if(x < 0 || x > n) {
+ return 0.;
}
// Extreme probabilities
- if (p <= 0d) {
- return x == 0 ? 1.0 : 0.0;
+ if(p <= 0.) {
+ return x == 0 ? 1. : 0.;
}
- if (p >= 1d) {
- return x == n ? 1.0 : 0.0;
+ if(p >= 1.) {
+ return x == n ? 1. : 0.;
}
final double q = 1 - p;
// FIXME: check for x to be integer, return 0 otherwise?
// Extreme values of x
- if (x == 0) {
- if (p < 0.1) {
+ if(x == 0) {
+ if(p < .1) {
return Math.exp(-devianceTerm(n, n * q) - n * p);
- } else {
+ }
+ else {
return Math.exp(n * Math.log(q));
}
}
- if (x == n) {
- if (p > 0.9) {
+ if(x == n) {
+ if(p > .9) {
return Math.exp(-devianceTerm(n, n * p) - n * q);
- } else {
+ }
+ else {
return Math.exp(n * Math.log(p));
}
}
@@ -224,15 +237,16 @@ public class PoissonDistribution implements Distribution {
* @return pdf
*/
public static double poissonPDFm1(double x_plus_1, double lambda) {
- if (Double.isInfinite(lambda)) {
+ if(Double.isInfinite(lambda)) {
return 0.;
}
- if (x_plus_1 > 1) {
+ if(x_plus_1 > 1) {
return rawProbability(x_plus_1 - 1, lambda);
}
- if (lambda > Math.abs(x_plus_1 - 1) * MathUtil.LOG2 * Double.MAX_EXPONENT / 1e-14) {
+ if(lambda > Math.abs(x_plus_1 - 1) * MathUtil.LOG2 * Double.MAX_EXPONENT / 1e-14) {
return Math.exp(-lambda - GammaDistribution.logGamma(x_plus_1));
- } else {
+ }
+ else {
return rawProbability(x_plus_1, lambda) * (x_plus_1 / lambda);
}
}
@@ -247,15 +261,16 @@ public class PoissonDistribution implements Distribution {
* @return pdf
*/
public static double logpoissonPDFm1(double x_plus_1, double lambda) {
- if (Double.isInfinite(lambda)) {
+ if(Double.isInfinite(lambda)) {
return Double.NEGATIVE_INFINITY;
}
- if (x_plus_1 > 1) {
+ if(x_plus_1 > 1) {
return rawLogProbability(x_plus_1 - 1, lambda);
}
- if (lambda > Math.abs(x_plus_1 - 1) * MathUtil.LOG2 * Double.MAX_EXPONENT / 1e-14) {
+ if(lambda > Math.abs(x_plus_1 - 1) * MathUtil.LOG2 * Double.MAX_EXPONENT / 1e-14) {
return -lambda - GammaDistribution.logGamma(x_plus_1);
- } else {
+ }
+ else {
return rawLogProbability(x_plus_1, lambda) + Math.log(x_plus_1 / lambda);
}
}
@@ -271,18 +286,18 @@ public class PoissonDistribution implements Distribution {
@Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
private static double stirlingError(int n) {
// Try to use a table value:
- if (n < 16) {
+ if(n < 16) {
return STIRLING_EXACT_ERROR[n << 1];
}
final double nn = n * n;
// Use the appropriate number of terms
- if (n > 500) {
+ if(n > 500) {
return (S0 - S1 / nn) / n;
}
- if (n > 80) {
+ if(n > 80) {
return ((S0 - (S1 - S2 / nn)) / nn) / n;
}
- if (n > 35) {
+ if(n > 35) {
return ((S0 - (S1 - (S2 - S3 / nn) / nn) / nn) / n);
}
return ((S0 - (S1 - (S2 - (S3 - S4 / nn) / nn) / nn) / nn) / n);
@@ -298,23 +313,24 @@ public class PoissonDistribution implements Distribution {
*/
@Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
private static double stirlingError(double n) {
- if (n < 16.0) {
+ if(n < 16.0) {
// Our table has a step size of 0.5
final double n2 = 2.0 * n;
- if (Math.floor(n2) == n2) { // Exact match
+ if(Math.floor(n2) == n2) { // Exact match
return STIRLING_EXACT_ERROR[(int) n2];
- } else {
+ }
+ else {
return GammaDistribution.logGamma(n + 1.0) - (n + 0.5) * Math.log(n) + n - MathUtil.LOGSQRTTWOPI;
}
}
final double nn = n * n;
- if (n > 500.0) {
+ if(n > 500.0) {
return (S0 - S1 / nn) / n;
}
- if (n > 80.0) {
+ if(n > 80.0) {
return ((S0 - (S1 - S2 / nn)) / nn) / n;
}
- if (n > 35.0) {
+ if(n > 35.0) {
return ((S0 - (S1 - (S2 - S3 / nn) / nn) / nn) / n);
}
return ((S0 - (S1 - (S2 - (S3 - S4 / nn) / nn) / nn) / nn) / n);
@@ -331,15 +347,15 @@ public class PoissonDistribution implements Distribution {
*/
@Reference(title = "Fast and accurate computation of binomial probabilities", authors = "C. Loader", booktitle = "", url = "http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf")
private static double devianceTerm(double x, double np) {
- if (Math.abs(x - np) < 0.1 * (x + np)) {
+ if(Math.abs(x - np) < 0.1 * (x + np)) {
final double v = (x - np) / (x + np);
double s = (x - np) * v;
double ej = 2.0d * x * v;
- for (int j = 1;; j++) {
+ for(int j = 1;; j++) {
ej *= v * v;
final double s1 = s + ej / (2 * j + 1);
- if (s1 == s) {
+ if(s1 == s) {
return s1;
}
s = s1;
@@ -359,17 +375,17 @@ public class PoissonDistribution implements Distribution {
*/
public static double rawProbability(double x, double lambda) {
// Extreme lambda
- if (lambda == 0) {
+ if(lambda == 0) {
return ((x == 0) ? 1. : 0.);
}
// Extreme values
- if (Double.isInfinite(lambda) || x < 0) {
+ if(Double.isInfinite(lambda) || x < 0) {
return 0.;
}
- if (x <= lambda * Double.MIN_NORMAL) {
+ if(x <= lambda * Double.MIN_NORMAL) {
return Math.exp(-lambda);
}
- if (lambda < x * Double.MIN_NORMAL) {
+ if(lambda < x * Double.MIN_NORMAL) {
double r = -lambda + x * Math.log(lambda) - GammaDistribution.logGamma(x + 1);
return Math.exp(r);
}
@@ -389,17 +405,17 @@ public class PoissonDistribution implements Distribution {
*/
public static double rawLogProbability(double x, double lambda) {
// Extreme lambda
- if (lambda == 0) {
+ if(lambda == 0) {
return ((x == 0) ? 1. : Double.NEGATIVE_INFINITY);
}
// Extreme values
- if (Double.isInfinite(lambda) || x < 0) {
+ if(Double.isInfinite(lambda) || x < 0) {
return Double.NEGATIVE_INFINITY;
}
- if (x <= lambda * Double.MIN_NORMAL) {
+ if(x <= lambda * Double.MIN_NORMAL) {
return -lambda;
}
- if (lambda < x * Double.MIN_NORMAL) {
+ if(lambda < x * Double.MIN_NORMAL) {
return -lambda + x * Math.log(lambda) - GammaDistribution.logGamma(x + 1);
}
final double f = MathUtil.TWOPI * x;
@@ -411,4 +427,56 @@ public class PoissonDistribution implements Distribution {
public String toString() {
return "PoissonDistribution(n=" + n + ", p=" + p + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Number of trials.
+ */
+ public static final OptionID N_ID = new OptionID("distribution.poisson.n", "Number of trials.");
+
+ /**
+ * Success probability.
+ */
+ public static final OptionID PROB_ID = new OptionID("distribution.poisson.probability", "Success probability.");
+
+ /**
+ * Number of trials.
+ */
+ int n;
+
+ /**
+ * Success probability.
+ */
+ double p;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter nP = new IntParameter(N_ID);
+ nP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(nP)) {
+ n = nP.intValue();
+ }
+
+ DoubleParameter probP = new DoubleParameter(PROB_ID);
+ probP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ probP.addConstraint(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
+ if(config.grab(probP)) {
+ p = probP.doubleValue();
+ }
+ }
+
+ @Override
+ protected PoissonDistribution makeInstance() {
+ return new PoissonDistribution(n, p, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
index 31faf8ed..68870f1a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/RayleighDistribution.java
@@ -25,16 +25,20 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Rayleigh distribution.
*
* @author Erich Schubert
*/
-public class RayleighDistribution implements Distribution {
+public class RayleighDistribution extends AbstractDistribution {
/**
- * Position parameter.
+ * Location parameter.
*/
- double mu = 0.0;
+ double mu = 0.;
/**
* Scale parameter.
@@ -42,17 +46,12 @@ public class RayleighDistribution implements Distribution {
double sigma;
/**
- * Random number generator.
- */
- Random random;
-
- /**
* Constructor.
*
* @param sigma Scale parameter
*/
public RayleighDistribution(double sigma) {
- this(0., sigma, null);
+ this(0., sigma, (Random) null);
}
/**
@@ -62,7 +61,7 @@ public class RayleighDistribution implements Distribution {
* @param sigma Scale parameter
*/
public RayleighDistribution(double mu, double sigma) {
- this(mu, sigma, null);
+ this(mu, sigma, (Random) null);
}
/**
@@ -83,10 +82,22 @@ public class RayleighDistribution implements Distribution {
* @param random Random number generator
*/
public RayleighDistribution(double mu, double sigma, Random random) {
- super();
+ super(random);
+ this.mu = mu;
+ this.sigma = sigma;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param mu Position parameter
+ * @param sigma Scale parameter
+ * @param random Random number generator
+ */
+ public RayleighDistribution(double mu, double sigma, RandomFactory random) {
+ super(random);
this.mu = mu;
this.sigma = sigma;
- this.random = random;
}
@Override
@@ -162,4 +173,36 @@ public class RayleighDistribution implements Distribution {
public String toString() {
return "RayleighDistribution(mu=" + mu + ", sigma=" + sigma + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mean, scale;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter meanP = new DoubleParameter(LOCATION_ID, 0.);
+ if (config.grab(meanP)) {
+ mean = meanP.doubleValue();
+ }
+
+ DoubleParameter scaleP = new DoubleParameter(SCALE_ID);
+ if (config.grab(scaleP)) {
+ scale = scaleP.doubleValue();
+ }
+ }
+
+ @Override
+ protected RayleighDistribution makeInstance() {
+ return new RayleighDistribution(mean, scale, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
index f04e776b..76931029 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/SkewGeneralizedNormalDistribution.java
@@ -26,6 +26,11 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Generalized Gaussian distribution by adding a skew term, similar to lognormal
@@ -36,7 +41,7 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
*
* @author Erich Schubert
*/
-public class SkewGeneralizedNormalDistribution implements Distribution {
+public class SkewGeneralizedNormalDistribution extends AbstractDistribution {
/**
* Mean value for the generator
*/
@@ -53,9 +58,19 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
private double skew;
/**
- * The random generator.
+ * Constructor for Gaussian distribution
+ *
+ * @param mean Mean
+ * @param stddev Standard Deviation
+ * @param skew Skew
+ * @param random Random generator
*/
- private Random random;
+ public SkewGeneralizedNormalDistribution(double mean, double stddev, double skew, Random random) {
+ super(random);
+ this.mean = mean;
+ this.stddev = stddev;
+ this.skew = skew;
+ }
/**
* Constructor for Gaussian distribution
@@ -65,12 +80,11 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
* @param skew Skew
* @param random Random generator
*/
- public SkewGeneralizedNormalDistribution(double mean, double stddev, double skew, Random random) {
- super();
+ public SkewGeneralizedNormalDistribution(double mean, double stddev, double skew, RandomFactory random) {
+ super(random);
this.mean = mean;
this.stddev = stddev;
this.skew = skew;
- this.random = random;
}
/**
@@ -81,7 +95,7 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
* @param skew Skew
*/
public SkewGeneralizedNormalDistribution(double mean, double stddev, double skew) {
- this(mean, stddev, skew, null);
+ this(mean, stddev, skew, (Random) null);
}
@Override
@@ -102,7 +116,7 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
@Override
public double nextRandom() {
double y = random.nextGaussian();
- if (Math.abs(skew) > 0.) {
+ if(Math.abs(skew) > 0.) {
y = (1. - Math.exp(-skew * y)) / skew;
}
return mean + stddev * y;
@@ -124,7 +138,7 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
*/
public static double pdf(double x, double mu, double sigma, double skew) {
x = (x - mu) / sigma;
- if (Math.abs(skew) > 0.) {
+ if(Math.abs(skew) > 0.) {
x = -Math.log(1. - skew * x) / skew;
}
return MathUtil.SQRTHALF * Math.exp(-.5 * x * x) / sigma / (1 - skew * x);
@@ -140,9 +154,9 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
*/
public static double cdf(double x, double mu, double sigma, double skew) {
x = (x - mu) / sigma;
- if (Math.abs(skew) > 0.) {
+ if(Math.abs(skew) > 0.) {
double tmp = 1 - skew * x;
- if (tmp < 1e-15) {
+ if(tmp < 1e-15) {
return (skew < 0.) ? 0. : 1.;
}
x = -Math.log(tmp) / skew;
@@ -161,9 +175,52 @@ public class SkewGeneralizedNormalDistribution implements Distribution {
*/
public static double quantile(double x, double mu, double sigma, double skew) {
x = NormalDistribution.standardNormalQuantile(x);
- if (Math.abs(skew) > 0.) {
+ if(Math.abs(skew) > 0.) {
x = (1. - Math.exp(-skew * x)) / skew;
}
return mu + sigma * x;
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Skew parameter
+ */
+ public static final OptionID SKEW_ID = new OptionID("distribution.skewgnormal.skew", "Skew of the distribution.");
+
+ /** Parameters. */
+ double mean, sigma, skew;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter meanP = new DoubleParameter(LOCATION_ID);
+ if(config.grab(meanP)) {
+ mean = meanP.doubleValue();
+ }
+
+ DoubleParameter sigmaP = new DoubleParameter(SCALE_ID);
+ sigmaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(sigmaP)) {
+ sigma = sigmaP.doubleValue();
+ }
+
+ DoubleParameter skewP = new DoubleParameter(SKEW_ID);
+ if(config.grab(skewP)) {
+ skew = skewP.doubleValue();
+ }
+ }
+
+ @Override
+ protected SkewGeneralizedNormalDistribution makeInstance() {
+ return new SkewGeneralizedNormalDistribution(mean, sigma, skew, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
index 442df2e2..ef9f06d4 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/StudentsTDistribution.java
@@ -23,17 +23,23 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
/**
* Student's t distribution.
*
- * FIXME: add quantile function!
+ * FIXME: add quantile and random function!
*
* @author Jan Brusis
*/
-public class StudentsTDistribution implements Distribution {
+public class StudentsTDistribution extends AbstractDistribution {
/**
* Degrees of freedom
*/
@@ -45,6 +51,28 @@ public class StudentsTDistribution implements Distribution {
* @param v Degrees of freedom
*/
public StudentsTDistribution(int v) {
+ this(v, (Random) null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param v Degrees of freedom
+ * @param random Random generator
+ */
+ public StudentsTDistribution(int v, Random random) {
+ super(random);
+ this.v = v;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param v Degrees of freedom
+ * @param random Random generator
+ */
+ public StudentsTDistribution(int v, RandomFactory random) {
+ super(random);
this.v = v;
}
@@ -98,4 +126,36 @@ public class StudentsTDistribution implements Distribution {
public String toString() {
return "StudentsTDistribution(v=" + v + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Degrees of freedom.
+ */
+ public static final OptionID NU_ID = new OptionID("distribution.studentst.nu", "Degrees of freedom.");
+
+ /** Parameters. */
+ int nu;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ IntParameter nuP = new IntParameter(NU_ID);
+ if (config.grab(nuP)) {
+ nu = nuP.intValue();
+ }
+ }
+
+ @Override
+ protected StudentsTDistribution makeInstance() {
+ return new StudentsTDistribution(nu, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
index efae5080..db2e2fb2 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/UniformDistribution.java
@@ -25,12 +25,17 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Uniform distribution.
*
* @author Erich Schubert
*/
-public class UniformDistribution implements Distribution {
+public class UniformDistribution extends AbstractDistribution {
/**
* Minimum
*/
@@ -47,9 +52,30 @@ public class UniformDistribution implements Distribution {
private double len;
/**
- * The random generator.
+ * Constructor for a uniform distribution on the interval [min, max[
+ *
+ * @param min Minimum value
+ * @param max Maximum value
+ * @param random Random generator
*/
- private Random random;
+ public UniformDistribution(double min, double max, RandomFactory random) {
+ super(random);
+ if (Double.isInfinite(min) || Double.isInfinite(max)) {
+ throw new ArithmeticException("Infinite values given for uniform distribution.");
+ }
+ if (Double.isNaN(min) || Double.isNaN(max)) {
+ throw new ArithmeticException("NaN values given for uniform distribution.");
+ }
+ // Swap parameters if they were given incorrectly.
+ if (min > max) {
+ double tmp = min;
+ min = max;
+ max = tmp;
+ }
+ this.min = min;
+ this.max = max;
+ this.len = max - min;
+ }
/**
* Constructor for a uniform distribution on the interval [min, max[
@@ -59,7 +85,7 @@ public class UniformDistribution implements Distribution {
* @param random Random generator
*/
public UniformDistribution(double min, double max, Random random) {
- super();
+ super(random);
if (Double.isInfinite(min) || Double.isInfinite(max)) {
throw new ArithmeticException("Infinite values given for uniform distribution.");
}
@@ -75,7 +101,6 @@ public class UniformDistribution implements Distribution {
this.min = min;
this.max = max;
this.len = max - min;
- this.random = random;
}
/**
@@ -85,7 +110,7 @@ public class UniformDistribution implements Distribution {
* @param max Maximum value
*/
public UniformDistribution(double min, double max) {
- this(min, max, null);
+ this(min, max, (Random) null);
}
@Override
@@ -135,4 +160,46 @@ public class UniformDistribution implements Distribution {
public double getMax() {
return max;
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /**
+ * Minimum value
+ */
+ public static final OptionID MIN_ID = new OptionID("distribution.min", "Minimum value of distribution.");
+
+ /**
+ * Maximum value
+ */
+ public static final OptionID MAX_ID = new OptionID("distribution.max", "Maximum value of distribution.");
+
+ /** Parameters. */
+ double min, max;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter minP = new DoubleParameter(MIN_ID);
+ if (config.grab(minP)) {
+ min = minP.doubleValue();
+ }
+
+ DoubleParameter maxP = new DoubleParameter(MAX_ID);
+ if (config.grab(maxP)) {
+ max = maxP.doubleValue();
+ }
+ }
+
+ @Override
+ protected UniformDistribution makeInstance() {
+ return new UniformDistribution(min, max, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
index ec0ea712..123ece95 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WaldDistribution.java
@@ -27,8 +27,11 @@ import java.util.Random;
import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.utilities.Alias;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
/**
* Inverse Gaussian distribution aka Wald distribution
@@ -36,9 +39,9 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.NotImplementedException;
* @author Erich Schubert
*/
@Alias({ "InverseGaussianDistribution", "invgauss" })
-public class WaldDistribution implements Distribution {
+public class WaldDistribution extends AbstractDistribution {
/**
- * Mean value
+ * Location value
*/
private double mean;
@@ -48,9 +51,17 @@ public class WaldDistribution implements Distribution {
private double shape;
/**
- * The random generator.
+ * Constructor for wald distribution
+ *
+ * @param mean Mean
+ * @param shape Shape parameter
+ * @param random Random generator
*/
- private Random random;
+ public WaldDistribution(double mean, double shape, Random random) {
+ super(random);
+ this.mean = mean;
+ this.shape = shape;
+ }
/**
* Constructor for wald distribution
@@ -59,11 +70,10 @@ public class WaldDistribution implements Distribution {
* @param shape Shape parameter
* @param random Random generator
*/
- public WaldDistribution(double mean, double shape, Random random) {
- super();
+ public WaldDistribution(double mean, double shape, RandomFactory random) {
+ super(random);
this.mean = mean;
this.shape = shape;
- this.random = random;
}
/**
@@ -73,7 +83,7 @@ public class WaldDistribution implements Distribution {
* @param shape Shape parameter
*/
public WaldDistribution(double mean, double shape) {
- this(mean, shape, null);
+ this(mean, shape, (Random) null);
}
@Override
@@ -170,4 +180,36 @@ public class WaldDistribution implements Distribution {
// FIXME: implement!
throw new NotImplementedException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double mean, shape;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter meanP = new DoubleParameter(LOCATION_ID);
+ if (config.grab(meanP)) {
+ mean = meanP.doubleValue();
+ }
+
+ DoubleParameter shapeP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(shapeP)) {
+ shape = shapeP.doubleValue();
+ }
+ }
+
+ @Override
+ protected WaldDistribution makeInstance() {
+ return new WaldDistribution(mean, shape, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
index 165f536a..9b7af6d8 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/WeibullDistribution.java
@@ -25,16 +25,20 @@ package de.lmu.ifi.dbs.elki.math.statistics.distribution;
import java.util.Random;
+import de.lmu.ifi.dbs.elki.utilities.RandomFactory;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+
/**
* Weibull distribution.
*
* @author Erich Schubert
*/
-public class WeibullDistribution implements Distribution {
+public class WeibullDistribution extends AbstractDistribution {
/**
* Shift offset.
*/
- double theta = 0.0;
+ double theta = 0.;
/**
* Shape parameter k.
@@ -47,18 +51,13 @@ public class WeibullDistribution implements Distribution {
double lambda;
/**
- * Random number generator.
- */
- Random random;
-
- /**
* Constructor.
*
* @param k Shape parameter
* @param lambda Scale parameter
*/
public WeibullDistribution(double k, double lambda) {
- this(k, lambda, 0.0, null);
+ this(k, lambda, 0.0, (Random) null);
}
/**
@@ -69,7 +68,7 @@ public class WeibullDistribution implements Distribution {
* @param theta Shift offset parameter
*/
public WeibullDistribution(double k, double lambda, double theta) {
- this(k, lambda, theta, null);
+ this(k, lambda, theta, (Random) null);
}
/**
@@ -80,7 +79,7 @@ public class WeibullDistribution implements Distribution {
* @param random Random number generator
*/
public WeibullDistribution(double k, double lambda, Random random) {
- this(k, lambda, 0.0, random);
+ this(k, lambda, 0., random);
}
/**
@@ -92,11 +91,25 @@ public class WeibullDistribution implements Distribution {
* @param random Random number generator
*/
public WeibullDistribution(double k, double lambda, double theta, Random random) {
- super();
+ super(random);
+ this.k = k;
+ this.lambda = lambda;
+ this.theta = theta;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param k Shape parameter
+ * @param lambda Scale parameter
+ * @param theta Shift offset parameter
+ * @param random Random number generator
+ */
+ public WeibullDistribution(double k, double lambda, double theta, RandomFactory random) {
+ super(random);
this.k = k;
this.lambda = lambda;
this.theta = theta;
- this.random = random;
}
@Override
@@ -179,4 +192,41 @@ public class WeibullDistribution implements Distribution {
public String toString() {
return "WeibullDistribution(k=" + k + ", lambda=" + lambda + ", theta=" + theta + ")";
}
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractDistribution.Parameterizer {
+ /** Parameters. */
+ double theta, k, lambda;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ DoubleParameter thetaP = new DoubleParameter(LOCATION_ID, 0.);
+ if (config.grab(thetaP)) {
+ theta = thetaP.doubleValue();
+ }
+
+ DoubleParameter lambdaP = new DoubleParameter(SCALE_ID);
+ if (config.grab(lambdaP)) {
+ lambda = lambdaP.doubleValue();
+ }
+
+ DoubleParameter kP = new DoubleParameter(SHAPE_ID);
+ if (config.grab(kP)) {
+ k = kP.doubleValue();
+ }
+ }
+
+ @Override
+ protected WeibullDistribution makeInstance() {
+ return new WeibullDistribution(theta, k, lambda, rnd);
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
index d41881f0..9e47e81d 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/GammaChoiWetteEstimator.java
@@ -72,7 +72,7 @@ public class GammaChoiWetteEstimator implements DistributionEstimator<GammaDistr
meanlogx += deltalogx / (i + 1.);
}
// Initial approximation
- final double logmeanx = Math.log(meanx);
+ final double logmeanx = (meanx > 0) ? Math.log(meanx) : meanlogx;
final double diff = logmeanx - meanlogx;
double k = (3 - diff + Math.sqrt((diff - 3) * (diff - 3) + 24 * diff)) / (12 * diff);
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
index 1e31af28..4026fdc5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceLMMEstimator.java
@@ -30,7 +30,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*
- * @apiviz.has ExponentialDistribution
+ * @apiviz.has LaplaceDistribution
*/
public class LaplaceLMMEstimator extends AbstractLMMEstimator<LaplaceDistribution> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
index d4671362..6fe6da0f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMADEstimator.java
@@ -38,7 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*
- * @apiviz.has ExponentialDistribution
+ * @apiviz.has LaplaceDistribution
*/
@Reference(title = "Applied Robust Statistics", authors = "D. J. Olive", booktitle = "Applied Robust Statistics", url="http://lagrange.math.siu.edu/Olive/preprints.htm")
public class LaplaceMADEstimator extends AbstractMADEstimator<LaplaceDistribution> {
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
index f44e2b3a..8d2c5707 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/LaplaceMLEEstimator.java
@@ -42,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*
- * @apiviz.has ExponentialDistribution
+ * @apiviz.has LaplaceDistribution
*/
@Reference(title = "The Double Exponential Distribution: Using Calculus to Find a Maximum Likelihood Estimator", authors = "R. M. Norton", booktitle = "The American Statistician 38 (2)", url = "http://dx.doi.org/10.2307%2F2683252")
public class LaplaceMLEEstimator implements DistributionEstimator<LaplaceDistribution> {
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
index e9870884..11bb8231 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/UniformMinMaxEstimator.java
@@ -74,7 +74,8 @@ public class UniformMinMaxEstimator implements DistributionEstimator<UniformDist
/**
* Estimate parameters from minimum and maximum observed.
*
- * @param mm Minimum and Maximum
+ * @param min Minimum
+ * @param max Maximum
* @return Estimation
*/
public Distribution estimate(double min, double max) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
index dee3cbb3..8d57e0b7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/BestFitEstimator.java
@@ -87,11 +87,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
*
* @author Erich Schubert
*
- * @apiviz.composedOf MOMDistributionEstimator
- * @apiviz.composedOf MADDistributionEstimator
- * @apiviz.composedOf LMMDistributionEstimator
- * @apiviz.composedOf LogMOMDistributionEstimator
- * @apiviz.composedOf LogMADDistributionEstimator
+ * @apiviz.uses MOMDistributionEstimator
+ * @apiviz.uses MADDistributionEstimator
+ * @apiviz.uses LMMDistributionEstimator
+ * @apiviz.uses LogMOMDistributionEstimator
+ * @apiviz.uses LogMADDistributionEstimator
*/
public class BestFitEstimator implements DistributionEstimator<Distribution> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
index 5c1cf448..a78d9760 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/TrimmedEstimator.java
@@ -31,8 +31,7 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil;
import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.LessConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -43,6 +42,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses DistributionEstimator
+ *
* @param <D> Distribution type
*/
public class TrimmedEstimator<D extends Distribution> implements DistributionEstimator<D> {
@@ -75,7 +76,7 @@ public class TrimmedEstimator<D extends Distribution> implements DistributionEst
final int cut = ((int) (len * trim)) >> 1;
// X positions of samples
double[] x = new double[len];
- for (int i = 0; i < len; i++) {
+ for(int i = 0; i < len; i++) {
final double val = adapter.getDouble(data, i);
x[i] = val;
}
@@ -136,14 +137,14 @@ public class TrimmedEstimator<D extends Distribution> implements DistributionEst
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<DistributionEstimator<D>> innerP = new ObjectParameter<>(INNER_ID, DistributionEstimator.class);
- if (config.grab(innerP)) {
+ if(config.grab(innerP)) {
inner = innerP.instantiateClass(config);
}
DoubleParameter trimP = new DoubleParameter(TRIM_ID);
- trimP.addConstraint(new GreaterConstraint(0.));
- trimP.addConstraint(new LessConstraint(0.5));
- if (config.grab(trimP)) {
+ trimP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ trimP.addConstraint(CommonConstraints.LESS_THAN_HALF_DOUBLE);
+ if(config.grab(trimP)) {
trim = trimP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
index 0ef6318d..47fe427e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/WinsorisingEstimator.java
@@ -31,8 +31,7 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.LessConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
@@ -53,6 +52,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses DistributionEstimator
+ *
* @param <D> Distribution type
*/
@Reference(authors = "C. Hastings, F. Mosteller, J. W. Tukey, C. P. Winsor", title = "Low moments for small samples: a comparative study of order statistics", booktitle = "The Annals of Mathematical Statistics, 18(3)", url = "http://dx.doi.org/10.1214/aoms/1177730388")
@@ -86,7 +87,7 @@ public class WinsorisingEstimator<D extends Distribution> implements Distributio
final int cut = ((int) (len * winsorize)) >> 1;
// X positions of samples
double[] x = new double[len];
- for (int i = 0; i < len; i++) {
+ for(int i = 0; i < len; i++) {
final double val = adapter.getDouble(data, i);
x[i] = val;
}
@@ -95,7 +96,7 @@ public class WinsorisingEstimator<D extends Distribution> implements Distributio
double max = QuickSelect.quickSelect(x, cut, len, len - 1 - cut);
// Winsorize by replacing the smallest and largest values.
// QuickSelect ensured that these are correctly in place.
- for (int i = 0, j = len - 1; i < cut; i++, j--) {
+ for(int i = 0, j = len - 1; i < cut; i++, j--) {
x[i] = min;
x[j] = max;
}
@@ -146,14 +147,14 @@ public class WinsorisingEstimator<D extends Distribution> implements Distributio
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<DistributionEstimator<D>> innerP = new ObjectParameter<>(INNER_ID, DistributionEstimator.class);
- if (config.grab(innerP)) {
+ if(config.grab(innerP)) {
inner = innerP.instantiateClass(config);
}
DoubleParameter trimP = new DoubleParameter(WINSORIZE_ID);
- trimP.addConstraint(new GreaterConstraint(0.));
- trimP.addConstraint(new LessConstraint(0.5));
- if (config.grab(trimP)) {
+ trimP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ trimP.addConstraint(CommonConstraints.LESS_THAN_HALF_DOUBLE);
+ if(config.grab(trimP)) {
winsorize = trimP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java
index c4b75f2d..c06be5d7 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/meta/package-info.java
@@ -3,4 +3,27 @@
*
* @author Erich Schubert
*/
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
index 62c98262..9a9f0993 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/distribution/estimator/package-info.java
@@ -2,6 +2,8 @@
* Estimators for statistical distributions.
*
* @author Erich Schubert
+ *
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta.*
*/
package de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator;