summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/math
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/math')
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MathUtil.java74
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/Mean.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MeanVariance.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java39
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java9
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java39
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java29
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java28
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java20
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/scales/Scales.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java10
-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
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java23
69 files changed, 2289 insertions, 536 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
index 27de942e..9a7d4770 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
@@ -227,7 +227,6 @@ public final class MathUtil {
*/
public static double mahalanobisDistance(Matrix weightMatrix, Vector o1_minus_o2) {
double sqrDist = o1_minus_o2.transposeTimesTimes(weightMatrix, o1_minus_o2);
-
if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
sqrDist = Math.abs(sqrDist);
}
@@ -243,7 +242,6 @@ public final class MathUtil {
*/
public static double mahalanobisDistance(double[][] weightMatrix, double[] o1_minus_o2) {
double sqrDist = VMath.transposeTimesTimes(o1_minus_o2, weightMatrix, o1_minus_o2);
-
if (sqrDist < 0 && Math.abs(sqrDist) < 0.000000001) {
sqrDist = Math.abs(sqrDist);
}
@@ -546,17 +544,26 @@ public final class MathUtil {
* @return Angle
*/
public static double angle(double[] v1, double[] v2) {
+ final int mindim = (v1.length >= v2.length) ? v1.length : v2.length;
// Essentially, we want to compute this:
// v1.transposeTimes(v2) / (v1.euclideanLength() * v2.euclideanLength());
// We can just compute all three in parallel.
double s = 0, e1 = 0, e2 = 0;
- for (int k = 0; k < v1.length; k++) {
+ for (int k = 0; k < mindim; k++) {
final double r1 = v1[k];
final double r2 = v2[k];
s += r1 * r2;
e1 += r1 * r1;
e2 += r2 * r2;
}
+ for (int k = mindim; k < v1.length; k++) {
+ final double r1 = v1[k];
+ e1 += r1 * r1;
+ }
+ for (int k = mindim; k < v2.length; k++) {
+ final double r2 = v2[k];
+ e2 += r2 * r2;
+ }
return Math.sqrt((s / e1) * (s / e2));
}
@@ -581,18 +588,30 @@ public final class MathUtil {
* @return Angle
*/
public static double angle(double[] v1, double[] v2, double[] o) {
+ final int mindim = (v1.length >= v2.length) ? v1.length : v2.length;
// Essentially, we want to compute this:
// v1' = v1 - o, v2' = v2 - o
// v1'.transposeTimes(v2') / (v1'.euclideanLength()*v2'.euclideanLength());
// We can just compute all three in parallel.
double s = 0, e1 = 0, e2 = 0;
- for (int k = 0; k < v1.length; k++) {
- final double r1 = v1[k] - o[k];
- final double r2 = v2[k] - o[k];
+ for (int k = 0; k < mindim; k++) {
+ final double ok = (k < o.length) ? o[k] : 0;
+ final double r1 = v1[k] - ok;
+ final double r2 = v2[k] - ok;
s += r1 * r2;
e1 += r1 * r1;
e2 += r2 * r2;
}
+ for (int k = mindim; k < v1.length; k++) {
+ final double ok = (k < o.length) ? o[k] : 0;
+ final double r1 = v1[k] - ok;
+ e1 += r1 * r1;
+ }
+ for (int k = mindim; k < v2.length; k++) {
+ final double ok = (k < o.length) ? o[k] : 0;
+ final double r2 = v2[k] - ok;
+ e2 += r2 * r2;
+ }
return Math.sqrt((s / e1) * (s / e2));
}
@@ -850,4 +869,47 @@ public final class MathUtil {
public static double log1mexp(double x) {
return (x > -LOG2) ? Math.log(-Math.expm1(x)) : Math.log1p(-Math.exp(x));
}
+
+ /**
+ * Fast loop for computing {@code Math.pow(x, p)} for p >= 0 integer.
+ *
+ * @param x Base
+ * @param p Exponent
+ * @return {@code Math.pow(x, p)}
+ */
+ public static double powi(double x, int p) {
+ if (p < 0) { // Fallback for negative integers.
+ return Math.pow(x, p);
+ }
+ double ret = 1.;
+ for (; p > 0; p >>= 1) {
+ if ((p & 1) == 1) {
+ ret *= x;
+ }
+ x *= x;
+ }
+ return ret;
+ }
+
+ /**
+ * Fast loop for computing {@code Math.pow(x, p)} for p >= 0 integer and x
+ * integer.
+ *
+ * @param x Base
+ * @param p Exponent
+ * @return {@code Math.pow(x, p)}
+ */
+ public static int ipowi(int x, int p) {
+ if (p < 0) { // Fallback for negative integers.
+ return (int) Math.pow(x, p);
+ }
+ int ret = 1;
+ for (; p > 0; p >>= 1) {
+ if ((p & 1) == 1) {
+ ret *= x;
+ }
+ x *= x;
+ }
+ return ret;
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/Mean.java b/src/de/lmu/ifi/dbs/elki/math/Mean.java
index 5b943a2f..5e70938f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/Mean.java
+++ b/src/de/lmu/ifi/dbs/elki/math/Mean.java
@@ -55,7 +55,7 @@ public class Mean {
/**
* Mean of values - first moment.
*/
- protected double m1 = 0.0;
+ protected double m1 = 0.;
/**
* Weight sum (number of samples).
@@ -147,7 +147,7 @@ public class Mean {
*/
public static Mean[] newArray(int dimensionality) {
Mean[] arr = new Mean[dimensionality];
- for(int i = 0; i < dimensionality; i++) {
+ for (int i = 0; i < dimensionality; i++) {
arr[i] = new Mean();
}
return arr;
@@ -165,4 +165,19 @@ public class Mean {
m1 = 0;
n = 0;
}
-} \ No newline at end of file
+
+ /**
+ * Static helper function.
+ *
+ * @param data Data to compute the mean for.
+ * @return Mean
+ */
+ public static double of(double[] data) {
+ // FIXME: what is numerically best. Kahan summation?
+ double sum = 0.;
+ for (double v : data) {
+ sum += v;
+ }
+ return sum / data.length;
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
index 7723daa4..b229d5d8 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MeanVariance.java
@@ -240,7 +240,7 @@ public class MeanVariance extends Mean {
@Override
public String toString() {
- return "MeanVariance(mean=" + getMean() + ",var=" + getSampleVariance() + ")";
+ return "MeanVariance(mean=" + getMean() + ",var=" + ((n > 1.) ? getSampleVariance() : "n/a") + ")";
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
index efc12b5c..9168fe7e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
+++ b/src/de/lmu/ifi/dbs/elki/math/dimensionsimilarity/HiCSDimensionSimilarity.java
@@ -44,7 +44,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.tests.KolmogorovSmirnovTest;
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.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
+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;
@@ -112,16 +112,16 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
@Override
public void computeDimensionSimilarites(Database database, Relation<? extends NumberVector<?>> relation, DBIDs subset, DimensionSimilarityMatrix matrix) {
- final Random random = rnd.getRandom();
+ final Random random = rnd.getSingleThreadedRandom();
final int dim = matrix.size();
// FIXME: only compute indexes necessary.
ArrayList<ArrayDBIDs> subspaceIndex = buildOneDimIndexes(relation, subset, matrix);
// compute two-element sets of subspaces
- for (int x = 0; x < dim; x++) {
+ for(int x = 0; x < dim; x++) {
final int i = matrix.dim(x);
- for (int y = x + 1; y < dim; y++) {
+ for(int y = x + 1; y < dim; y++) {
final int j = matrix.dim(y);
matrix.set(x, y, calculateContrast(relation, subset, subspaceIndex.get(x), subspaceIndex.get(y), i, j, random));
}
@@ -143,7 +143,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
ArrayList<ArrayDBIDs> subspaceIndex = new ArrayList<>(dim);
SortDBIDsBySingleDimension comp = new VectorUtil.SortDBIDsBySingleDimension(relation);
- for (int i = 0; i < dim; i++) {
+ for(int i = 0; i < dim; i++) {
ArrayModifiableDBIDs amDBIDs = DBIDUtil.newArray(ids);
comp.setDimension(matrix.dim(i));
amDBIDs.sort(comp);
@@ -166,21 +166,22 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
* @return Contrast
*/
private double calculateContrast(Relation<? extends NumberVector<?>> relation, DBIDs subset, ArrayDBIDs subspaceIndex1, ArrayDBIDs subspaceIndex2, int dim1, int dim2, Random random) {
- final double alpha1 = Math.pow(alpha, .5);
+ final double alpha1 = Math.sqrt(alpha);
final int windowsize = (int) (relation.size() * alpha1);
// TODO: speed up by keeping marginal distributions prepared.
// Instead of doing the random switch, do half-half.
double deviationSum = 0.0;
- for (int i = 0; i < m; i++) {
+ for(int i = 0; i < m; i++) {
// Randomly switch dimensions
final int cdim1;
ArrayDBIDs cindex1, cindex2;
- if (random.nextDouble() > .5) {
+ if(random.nextDouble() > .5) {
cdim1 = dim1;
cindex1 = subspaceIndex1;
cindex2 = subspaceIndex2;
- } else {
+ }
+ else {
cdim1 = dim2;
cindex1 = subspaceIndex2;
cindex2 = subspaceIndex1;
@@ -189,7 +190,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
DBIDArrayIter iter = cindex2.iter();
HashSetModifiableDBIDs conditionalSample = DBIDUtil.newHashSet();
iter.seek(random.nextInt(subset.size() - windowsize));
- for (int k = 0; k < windowsize && iter.valid(); k++, iter.advance()) {
+ for(int k = 0; k < windowsize && iter.valid(); k++, iter.advance()) {
conditionalSample.add(iter);
}
// Project the data
@@ -198,10 +199,10 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
{
int l = 0, s = 0;
// Note: we use the sorted index sets.
- for (DBIDIter id = cindex1.iter(); id.valid(); id.advance(), l++) {
+ for(DBIDIter id = cindex1.iter(); id.valid(); id.advance(), l++) {
final double val = relation.get(id).doubleValue(cdim1);
fullValues[l] = val;
- if (conditionalSample.contains(id)) {
+ if(conditionalSample.contains(id)) {
sampleValues[s] = val;
s++;
}
@@ -209,7 +210,7 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
assert (s == conditionalSample.size());
}
double contrast = statTest.deviation(fullValues, sampleValues);
- if (Double.isNaN(contrast)) {
+ if(Double.isNaN(contrast)) {
i--;
continue;
}
@@ -254,24 +255,24 @@ public class HiCSDimensionSimilarity implements DimensionSimilarity<NumberVector
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
final IntParameter mP = new IntParameter(HiCS.Parameterizer.M_ID, 50);
- mP.addConstraint(new GreaterConstraint(1));
- if (config.grab(mP)) {
+ mP.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
+ if(config.grab(mP)) {
m = mP.intValue();
}
final DoubleParameter alphaP = new DoubleParameter(HiCS.Parameterizer.ALPHA_ID, 0.1);
- alphaP.addConstraint(new GreaterConstraint(0));
- if (config.grab(alphaP)) {
+ alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
final ObjectParameter<GoodnessOfFitTest> testP = new ObjectParameter<>(HiCS.Parameterizer.TEST_ID, GoodnessOfFitTest.class, KolmogorovSmirnovTest.class);
- if (config.grab(testP)) {
+ if(config.grab(testP)) {
statTest = testP.instantiateClass(config);
}
final RandomParameter rndP = new RandomParameter(HiCS.Parameterizer.SEED_ID);
- if (config.grab(rndP)) {
+ if(config.grab(rndP)) {
rnd = rndP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
index de31f92e..887b5012 100644
--- a/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
+++ b/src/de/lmu/ifi/dbs/elki/math/geometry/PrimsMinimumSpanningTree.java
@@ -43,7 +43,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @author Erich Schubert
*
- * @apiviz.uses Adapter
+ * @apiviz.composedOf Adapter
*/
@Reference(authors = "R. C. Prim", title = "Shortest connection networks and some generalizations", booktitle = "Bell System Technical Journal, 36 (1957)")
public class PrimsMinimumSpanningTree {
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
index 69023328..345f2a42 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/CovarianceMatrix.java
@@ -97,19 +97,19 @@ public class CovarianceMatrix {
assert (val.length == mean.length);
final double nwsum = wsum + 1.0;
// Compute new means
- for(int i = 0; i < mean.length; i++) {
+ for (int i = 0; i < mean.length; i++) {
final double delta = val[i] - mean[i];
nmea[i] = mean[i] + delta / nwsum;
}
// Update covariance matrix
- for(int i = 0; i < mean.length; i++) {
- for(int j = i; j < mean.length; j++) {
+ for (int i = 0; i < mean.length; i++) {
+ for (int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val[i] - nmea[i]) * (val[j] - mean[j]);
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if(i != j) {
+ if (i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -130,20 +130,20 @@ public class CovarianceMatrix {
assert (val.length == mean.length);
final double nwsum = wsum + weight;
// Compute new means
- for(int i = 0; i < mean.length; i++) {
+ for (int i = 0; i < mean.length; i++) {
final double delta = val[i] - mean[i];
final double rval = delta * weight / nwsum;
nmea[i] = mean[i] + rval;
}
// Update covariance matrix
- for(int i = 0; i < mean.length; i++) {
- for(int j = i; j < mean.length; j++) {
+ for (int i = 0; i < mean.length; i++) {
+ for (int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val[i] - nmea[i]) * (val[j] - mean[j]) * weight;
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if(i != j) {
+ if (i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -182,19 +182,19 @@ public class CovarianceMatrix {
assert (val.getDimensionality() == mean.length);
final double nwsum = wsum + 1.0;
// Compute new means
- for(int i = 0; i < mean.length; i++) {
+ for (int i = 0; i < mean.length; i++) {
final double delta = val.doubleValue(i) - mean[i];
nmea[i] = mean[i] + delta / nwsum;
}
// Update covariance matrix
- for(int i = 0; i < mean.length; i++) {
- for(int j = i; j < mean.length; j++) {
+ for (int i = 0; i < mean.length; i++) {
+ for (int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]);
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if(i != j) {
+ if (i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -205,6 +205,16 @@ public class CovarianceMatrix {
}
/**
+ * Get the weight sum, to test whether the covariance matrix can be
+ * materialized.
+ *
+ * @return Weight sum.
+ */
+ public double getWeight() {
+ return wsum;
+ }
+
+ /**
* Add data with a given weight.
*
* @param val data
@@ -214,20 +224,20 @@ public class CovarianceMatrix {
assert (val.getDimensionality() == mean.length);
final double nwsum = wsum + weight;
// Compute new means
- for(int i = 0; i < mean.length; i++) {
+ for (int i = 0; i < mean.length; i++) {
final double delta = val.doubleValue(i) - mean[i];
final double rval = delta * weight / nwsum;
nmea[i] = mean[i] + rval;
}
// Update covariance matrix
- for(int i = 0; i < mean.length; i++) {
- for(int j = i; j < mean.length; j++) {
+ for (int i = 0; i < mean.length; i++) {
+ for (int j = i; j < mean.length; j++) {
// We DO want to use the new mean once and the old mean once!
// It does not matter which one is which.
double delta = (val.doubleValue(i) - nmea[i]) * (val.doubleValue(j) - mean[j]) * weight;
elements[i][j] = elements[i][j] + delta;
// Optimize via symmetry
- if(i != j) {
+ if (i != j) {
elements[j][i] = elements[j][i] + delta;
}
}
@@ -268,7 +278,7 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix makeSampleMatrix() {
- if(wsum <= 1.0) {
+ if (wsum <= 1.0) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements);
@@ -286,7 +296,7 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix makeNaiveMatrix() {
- if(wsum <= 0.0) {
+ if (wsum <= 0.0) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements);
@@ -304,7 +314,7 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix destroyToSampleMatrix() {
- if(wsum <= 1.0) {
+ if (wsum <= 1.0) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements).timesEquals(1.0 / (wsum - 1));
@@ -323,7 +333,7 @@ public class CovarianceMatrix {
* @return New matrix
*/
public Matrix destroyToNaiveMatrix() {
- if(wsum <= 0.0) {
+ if (wsum <= 0.0) {
throw new IllegalStateException(ERR_TOO_LITTLE_WEIGHT);
}
Matrix mat = new Matrix(elements).timesEquals(1.0 / wsum);
@@ -340,7 +350,7 @@ public class CovarianceMatrix {
public static CovarianceMatrix make(Matrix mat) {
CovarianceMatrix c = new CovarianceMatrix(mat.getRowDimensionality());
int n = mat.getColumnDimensionality();
- for(int i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
// TODO: avoid constructing the vector objects?
c.put(mat.getCol(i));
}
@@ -355,7 +365,7 @@ public class CovarianceMatrix {
*/
public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation) {
CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation));
- for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
+ for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
c.put(relation.get(iditer));
}
return c;
@@ -370,9 +380,9 @@ public class CovarianceMatrix {
*/
public static CovarianceMatrix make(Relation<? extends NumberVector<?>> relation, DBIDs ids) {
CovarianceMatrix c = new CovarianceMatrix(RelationUtil.dimensionality(relation));
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
c.put(relation.get(iter));
}
return c;
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
index f58cd86f..61401b18 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/EigenvalueDecomposition.java
@@ -44,6 +44,11 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
*/
public class EigenvalueDecomposition implements java.io.Serializable {
/**
+ * Epsilon.
+ */
+ private static final double EPS = Math.pow(2.0, -52.0);
+
+ /**
* Serial version
*/
private static final long serialVersionUID = 1L;
@@ -215,7 +220,7 @@ public class EigenvalueDecomposition implements java.io.Serializable {
double f = 0.0;
double tst1 = 0.0;
- double eps = Math.pow(2.0, -52.0);
+ double eps = EPS;
for (int l = 0; l < n; l++) {
// Find small subdiagonal element
tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l]));
@@ -442,7 +447,7 @@ public class EigenvalueDecomposition implements java.io.Serializable {
int n = nn - 1;
int low = 0;
int high = nn - 1;
- double eps = Math.pow(2.0, -52.0);
+ double eps = EPS;
double exshift = 0.0;
double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
index f9ac4c4c..3f513720 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/Matrix.java
@@ -1448,10 +1448,10 @@ public class Matrix {
final StreamTokenizer tokenizer = new StreamTokenizer(input);
// Although StreamTokenizer will parse numbers, it doesn't recognize
- // scientific notation (E or D); however, Double.valueOf does.
+ // scientific notation (E or D); however, FormatUtil.parseDouble does.
// The strategy here is to disable StreamTokenizer's number parsing.
// We'll only get whitespace delimited words, EOL's and EOF's.
- // These words should all be numbers, for Double.valueOf to parse.
+ // These words should all be numbers, for FormatUtil.parseDouble to parse.
tokenizer.resetSyntax();
tokenizer.wordChars(0, 255);
@@ -1467,7 +1467,7 @@ public class Matrix {
throw new java.io.IOException("Unexpected EOF on matrix read.");
}
do {
- v.add(Double.parseDouble(tokenizer.sval)); // Read & store 1st
+ v.add(FormatUtil.parseDouble(tokenizer.sval)); // Read & store 1st
// row.
}
while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
@@ -1484,7 +1484,7 @@ public class Matrix {
if (j >= n) {
throw new java.io.IOException("Row " + v.size() + " is too long.");
}
- row[j++] = Double.parseDouble(tokenizer.sval);
+ row[j++] = FormatUtil.parseDouble(tokenizer.sval);
}
while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
if (j < n) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
index 4a496b5c..dc94754a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/SingularValueDecomposition.java
@@ -42,6 +42,8 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
* @apiviz.uses Matrix - - transforms
*/
public class SingularValueDecomposition {
+ private static final double EPS = Math.pow(2.0, -52.0);
+
/**
* Arrays for internal storage of U and V.
*
@@ -268,7 +270,7 @@ public class SingularValueDecomposition {
int pp = p - 1;
int iter = 0;
- double eps = Math.pow(2.0, -52.0);
+ double eps = EPS;
while(p > 0) {
int k, kase;
@@ -545,7 +547,7 @@ public class SingularValueDecomposition {
* @return Number of non-negligible singular values.
*/
public int rank() {
- double eps = Math.pow(2.0, -52.0);
+ double eps = EPS;
double tol = Math.max(m, n) * s[0] * eps;
int r = 0;
for(int i = 0; i < s.length; i++) {
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
index efac8ff0..6b8cdc31 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/VMath.java
@@ -214,7 +214,7 @@ public final class VMath {
*
* @param v1 first vector
* @param v2 another vector
- * @param s2 scalar vor v2
+ * @param s2 scalar factor for v2
* @return v1 = v1 + v2 * s2
*/
public static final double[] plusTimesEquals(final double[] v1, final double[] v2, final double s2) {
@@ -229,7 +229,7 @@ public final class VMath {
* Computes v1 = v1 * s1 + v2, overwriting v1
*
* @param v1 first vector
- * @param s1 scalar for v1
+ * @param s1 scalar factor for v1
* @param v2 another vector
* @return v1 = v1 * s1 + v2
*/
@@ -460,7 +460,7 @@ public final class VMath {
}
/**
- * Computes v1 = v1 * s1, overwritings v1
+ * Computes v1 = v1 * s1, overwriting v1
*
* @param v1 original vector
* @param s scalar
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
index 22cefa87..7a2917c5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/DropEigenPairFilter.java
@@ -30,7 +30,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenPair;
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint;
+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;
@@ -133,7 +133,7 @@ public class DropEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter walphaP = new DoubleParameter(WeakEigenPairFilter.EIGENPAIR_FILTER_WALPHA, DEFAULT_WALPHA);
- walphaP.addConstraint(new GreaterEqualConstraint(0.0));
+ walphaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
if (config.grab(walphaP)) {
walpha = walphaP.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
index f613e067..79ee4ea6 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/FirstNEigenPairFilter.java
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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.GreaterEqualConstraint;
+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.IntParameter;
@@ -122,7 +122,7 @@ public class FirstNEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
IntParameter nP = new IntParameter(EIGENPAIR_FILTER_N);
- nP.addConstraint(new GreaterEqualConstraint(0));
+ nP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_INT);
if(config.grab(nP)) {
n = nP.intValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
index b3bd04b3..4d9e7331 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/LimitEigenPairFilter.java
@@ -34,9 +34,8 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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.WrongParameterValueException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GlobalParameterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.LessEqualConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterFlagGlobalConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
@@ -98,26 +97,27 @@ public class LimitEigenPairFilter implements EigenPairFilter {
@Override
public FilteredEigenPairs filter(SortedEigenPairs eigenPairs) {
StringBuilder msg = new StringBuilder();
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("delta = ").append(delta);
}
// determine limit
double limit;
- if (absolute) {
+ if(absolute) {
limit = delta;
- } else {
+ }
+ else {
double max = Double.NEGATIVE_INFINITY;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
double eigenValue = Math.abs(eigenPair.getEigenvalue());
- if (max < eigenValue) {
+ if(max < eigenValue) {
max = eigenValue;
}
}
limit = max * delta;
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\nlimit = ").append(limit);
}
@@ -126,16 +126,17 @@ public class LimitEigenPairFilter implements EigenPairFilter {
List<EigenPair> weakEigenPairs = new ArrayList<>();
// determine strong and weak eigenpairs
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
double eigenValue = Math.abs(eigenPair.getEigenvalue());
- if (eigenValue >= limit) {
+ if(eigenValue >= limit) {
strongEigenPairs.add(eigenPair);
- } else {
+ }
+ else {
weakEigenPairs.add(eigenPair);
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\nstrong EigenPairs = ").append(strongEigenPairs);
msg.append("\nweak EigenPairs = ").append(weakEigenPairs);
LOG.debugFine(msg.toString());
@@ -166,16 +167,16 @@ public class LimitEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
Flag absoluteF = new Flag(EIGENPAIR_FILTER_ABSOLUTE);
- if (config.grab(absoluteF)) {
+ if(config.grab(absoluteF)) {
absolute = absoluteF.isTrue();
}
DoubleParameter deltaP = new DoubleParameter(EIGENPAIR_FILTER_DELTA, DEFAULT_DELTA);
- deltaP.addConstraint(new GreaterEqualConstraint(0));
- if (config.grab(deltaP)) {
+ deltaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(deltaP)) {
delta = deltaP.doubleValue();
// TODO: make this a global constraint?
- if (absolute && deltaP.tookDefaultValue()) {
+ if(absolute && deltaP.tookDefaultValue()) {
config.reportError(new WrongParameterValueException("Illegal parameter setting: " + "Flag " + absoluteF.getName() + " is set, " + "but no value for " + deltaP.getName() + " is specified."));
}
}
@@ -187,10 +188,8 @@ public class LimitEigenPairFilter implements EigenPairFilter {
List<ParameterConstraint<? super Double>> cons = new ArrayList<>();
// TODO: Keep the constraint here - applies to non-conditional case as
// well, and is set above.
- ParameterConstraint<Number> aboveNull = new GreaterEqualConstraint(0.);
- cons.add(aboveNull);
- ParameterConstraint<Number> underOne = new LessEqualConstraint(1.);
- cons.add(underOne);
+ cons.add(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ cons.add(CommonConstraints.LESS_EQUAL_ONE_DOUBLE);
GlobalParameterConstraint gpc = new ParameterFlagGlobalConstraint<>(deltaP, cons, absoluteF, false);
config.checkConstraint(gpc);
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
index 2318b72d..670b4559 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PCAFilteredRunner.java
@@ -32,8 +32,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
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.GreaterEqualConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.LessGlobalConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
@@ -207,20 +206,20 @@ public class PCAFilteredRunner<V extends NumberVector<?>> extends PCARunner<V> {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
ObjectParameter<EigenPairFilter> filterP = new ObjectParameter<>(PCA_EIGENPAIR_FILTER, EigenPairFilter.class, PercentageEigenPairFilter.class);
- if (config.grab(filterP)) {
+ if(config.grab(filterP)) {
eigenPairFilter = filterP.instantiateClass(config);
}
- DoubleParameter bigP = new DoubleParameter(BIG_ID, 1.0);
- bigP.addConstraint(new GreaterConstraint(0));
- if (config.grab(bigP)) {
+ DoubleParameter bigP = new DoubleParameter(BIG_ID, 1.);
+ bigP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ if(config.grab(bigP)) {
big = bigP.doubleValue();
}
- DoubleParameter smallP = new DoubleParameter(SMALL_ID, 0.0);
- smallP.addConstraint(new GreaterEqualConstraint(0));
- if (config.grab(smallP)) {
+ DoubleParameter smallP = new DoubleParameter(SMALL_ID, 0.);
+ smallP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(smallP)) {
small = smallP.doubleValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
index 85e29867..5602228e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/PercentageEigenPairFilter.java
@@ -33,8 +33,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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;
@@ -90,7 +89,7 @@ public class PercentageEigenPairFilter implements EigenPairFilter {
@Override
public FilteredEigenPairs filter(SortedEigenPairs eigenPairs) {
StringBuilder msg = new StringBuilder();
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("alpha = ").append(alpha);
msg.append("\nsortedEigenPairs = ").append(eigenPairs);
}
@@ -101,32 +100,34 @@ public class PercentageEigenPairFilter implements EigenPairFilter {
// determine sum of eigenvalues
double totalSum = 0;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
totalSum += eigenPair.getEigenvalue();
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\ntotalSum = ").append(totalSum);
}
// determine strong and weak eigenpairs
double currSum = 0;
boolean found = false;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
currSum += eigenPair.getEigenvalue();
- if (currSum / totalSum >= alpha) {
- if (!found) {
+ if(currSum / totalSum >= alpha) {
+ if(!found) {
found = true;
strongEigenPairs.add(eigenPair);
- } else {
+ }
+ else {
weakEigenPairs.add(eigenPair);
}
- } else {
+ }
+ else {
strongEigenPairs.add(eigenPair);
}
}
- if (LOG.isDebugging()) {
+ if(LOG.isDebugging()) {
msg.append("\nstrong EigenPairs = ").append(strongEigenPairs);
msg.append("\nweak EigenPairs = ").append(weakEigenPairs);
LOG.debugFine(msg.toString());
@@ -153,9 +154,9 @@ public class PercentageEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter alphaP = new DoubleParameter(ALPHA_ID, DEFAULT_ALPHA);
- alphaP.addConstraint(new GreaterConstraint(0.0));
- alphaP.addConstraint(new LessConstraint(1.0));
- if (config.grab(alphaP)) {
+ alphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ alphaP.addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
+ if(config.grab(alphaP)) {
alpha = alphaP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
index b99de2e1..4f412257 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/ProgressiveEigenPairFilter.java
@@ -32,9 +32,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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.GreaterEqualConstraint;
-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;
@@ -133,7 +131,7 @@ public class ProgressiveEigenPairFilter implements EigenPairFilter {
// determine sum of eigenvalues
double totalSum = 0;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
totalSum += eigenPair.getEigenvalue();
}
@@ -143,35 +141,35 @@ public class ProgressiveEigenPairFilter implements EigenPairFilter {
double currSum = 0;
boolean found = false;
int i;
- for (i = 0; i < eigenPairs.size(); i++) {
+ for(i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
// weak Eigenvector?
- if (eigenPair.getEigenvalue() < expectedVariance) {
+ if(eigenPair.getEigenvalue() < expectedVariance) {
break;
}
currSum += eigenPair.getEigenvalue();
// calculate progressive alpha level
double alpha = 1.0 - (1.0 - palpha) * (1.0 - (i + 1) / eigenPairs.size());
- if (currSum / totalSum >= alpha || i == eigenPairs.size() - 1) {
+ if(currSum / totalSum >= alpha || i == eigenPairs.size() - 1) {
found = true;
strongEigenPairs.add(eigenPair);
break;
}
}
// if we didn't hit our alpha level, we consider all vectors to be weak!
- if (!found) {
+ if(!found) {
assert (weakEigenPairs.size() == 0);
weakEigenPairs = strongEigenPairs;
strongEigenPairs = new ArrayList<>();
}
- for (; i < eigenPairs.size(); i++) {
+ for(; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
weakEigenPairs.add(eigenPair);
}
// the code using this method doesn't expect an empty strong set,
// if we didn't find any strong ones, we make all vectors strong
- if (strongEigenPairs.size() == 0) {
+ if(strongEigenPairs.size() == 0) {
return new FilteredEigenPairs(new ArrayList<EigenPair>(), weakEigenPairs);
}
return new FilteredEigenPairs(weakEigenPairs, strongEigenPairs);
@@ -200,15 +198,15 @@ public class ProgressiveEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter palphaP = new DoubleParameter(EIGENPAIR_FILTER_PALPHA, DEFAULT_PALPHA);
- palphaP.addConstraint(new GreaterConstraint(0.0));
- palphaP.addConstraint(new LessConstraint(1.0));
- if (config.grab(palphaP)) {
+ palphaP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE);
+ palphaP.addConstraint(CommonConstraints.LESS_THAN_ONE_DOUBLE);
+ if(config.grab(palphaP)) {
palpha = palphaP.getValue();
}
DoubleParameter walphaP = new DoubleParameter(WeakEigenPairFilter.EIGENPAIR_FILTER_WALPHA, DEFAULT_WALPHA);
- walphaP.addConstraint(new GreaterEqualConstraint(0.0));
- if (config.grab(walphaP)) {
+ walphaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(walphaP)) {
walpha = walphaP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
index 3e9bccf7..2b369a32 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RANSACCovarianceMatrixBuilder.java
@@ -38,7 +38,7 @@ 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.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.CommonConstraints;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter;
@@ -107,31 +107,31 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab
DBIDs best = DBIDUtil.EMPTYDBIDS;
double tresh = ChiSquaredDistribution.quantile(0.85, dim);
- for (int i = 0; i < iterations; i++) {
+ for(int i = 0; i < iterations; i++) {
DBIDs sample = DBIDUtil.randomSample(ids, dim + 1, rnd);
CovarianceMatrix cv = CovarianceMatrix.make(relation, sample);
Vector centroid = cv.getMeanVector();
Matrix p = cv.destroyToSampleMatrix().inverse();
ModifiableDBIDs support = DBIDUtil.newHashSet();
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
Vector vec = relation.get(id).getColumnVector().minusEquals(centroid);
double sqlen = vec.transposeTimesTimes(p, vec);
- if (sqlen < tresh) {
+ if(sqlen < tresh) {
support.add(id);
}
}
- if (support.size() > best.size()) {
+ if(support.size() > best.size()) {
best = support;
}
- if (support.size() >= ids.size()) {
+ if(support.size() >= ids.size()) {
break; // Can't get better than this!
}
}
// logger.warning("Consensus size: "+best.size()+" of "+ids.size());
// Fall back to regular PCA
- if (best.size() <= dim) {
+ if(best.size() <= dim) {
return CovarianceMatrix.make(relation, ids).destroyToSampleMatrix();
}
// Return estimation based on consensus set.
@@ -172,12 +172,12 @@ public class RANSACCovarianceMatrixBuilder<V extends NumberVector<?>> extends Ab
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
IntParameter iterP = new IntParameter(ITER_ID, 1000);
- iterP.addConstraint(new GreaterConstraint(0));
- if (config.grab(iterP)) {
+ iterP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(iterP)) {
iterations = iterP.intValue();
}
RandomParameter rndP = new RandomParameter(SEED_ID);
- if (config.grab(rndP)) {
+ if(config.grab(rndP)) {
rnd = rndP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
index 12da3fdf..32092ce9 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/RelativeEigenPairFilter.java
@@ -32,7 +32,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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.GreaterEqualConstraint;
+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;
@@ -93,21 +93,21 @@ public class RelativeEigenPairFilter implements EigenPairFilter {
// find the last eigenvector that is considered 'strong' by the weak rule
// applied to the remaining vectors only
double eigenValueSum = eigenPairs.getEigenPair(eigenPairs.size() - 1).getEigenvalue();
- for (int i = eigenPairs.size() - 2; i >= 0; i--) {
+ for(int i = eigenPairs.size() - 2; i >= 0; i--) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
eigenValueSum += eigenPair.getEigenvalue();
double needEigenvalue = eigenValueSum / (eigenPairs.size() - i) * ralpha;
- if (eigenPair.getEigenvalue() >= needEigenvalue) {
+ if(eigenPair.getEigenvalue() >= needEigenvalue) {
contrastAtMax = i;
break;
}
}
- for (int i = 0; i <= contrastAtMax /* && i < eigenPairs.size() */; i++) {
+ for(int i = 0; i <= contrastAtMax /* && i < eigenPairs.size() */; i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
strongEigenPairs.add(eigenPair);
}
- for (int i = contrastAtMax + 1; i < eigenPairs.size(); i++) {
+ for(int i = contrastAtMax + 1; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
weakEigenPairs.add(eigenPair);
}
@@ -129,8 +129,8 @@ public class RelativeEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter ralphaP = new DoubleParameter(EIGENPAIR_FILTER_RALPHA, DEFAULT_RALPHA);
- ralphaP.addConstraint(new GreaterEqualConstraint(0.0));
- if (config.grab(ralphaP)) {
+ ralphaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(ralphaP)) {
ralpha = ralphaP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
index 73044b59..6219f77f 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/SignificantEigenPairFilter.java
@@ -31,7 +31,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint;
+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;
@@ -87,32 +87,32 @@ public class SignificantEigenPairFilter implements EigenPairFilter {
double maxContrast = 0.0;
// calc the eigenvalue sum.
double eigenValueSum = 0.0;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
eigenValueSum += eigenPair.getEigenvalue();
}
double weakEigenvalue = eigenValueSum / eigenPairs.size() * walpha;
// now find the maximum contrast.
double currSum = eigenPairs.getEigenPair(eigenPairs.size() - 1).getEigenvalue();
- for (int i = eigenPairs.size() - 2; i >= 0; i--) {
+ for(int i = eigenPairs.size() - 2; i >= 0; i--) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
currSum += eigenPair.getEigenvalue();
// weak?
- if (eigenPair.getEigenvalue() < weakEigenvalue) {
+ if(eigenPair.getEigenvalue() < weakEigenvalue) {
continue;
}
double contrast = eigenPair.getEigenvalue() / (currSum / (eigenPairs.size() - i));
- if (contrast > maxContrast) {
+ if(contrast > maxContrast) {
maxContrast = contrast;
contrastMaximum = i;
}
}
- for (int i = 0; i <= contrastMaximum /* && i < eigenPairs.size() */; i++) {
+ for(int i = 0; i <= contrastMaximum /* && i < eigenPairs.size() */; i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
strongEigenPairs.add(eigenPair);
}
- for (int i = contrastMaximum + 1; i < eigenPairs.size(); i++) {
+ for(int i = contrastMaximum + 1; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
weakEigenPairs.add(eigenPair);
}
@@ -134,8 +134,8 @@ public class SignificantEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter walphaP = new DoubleParameter(WeakEigenPairFilter.EIGENPAIR_FILTER_WALPHA, DEFAULT_WALPHA);
- walphaP.addConstraint(new GreaterEqualConstraint(0.0));
- if (config.grab(walphaP)) {
+ walphaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(walphaP)) {
walpha = walphaP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
index 66bcba30..92e1e32e 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/pca/WeakEigenPairFilter.java
@@ -32,7 +32,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
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.GreaterEqualConstraint;
+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;
@@ -85,25 +85,26 @@ public class WeakEigenPairFilter implements EigenPairFilter {
// determine sum of eigenvalues
double totalSum = 0;
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
totalSum += eigenPair.getEigenvalue();
}
double expectEigenvalue = totalSum / eigenPairs.size() * walpha;
// determine strong and weak eigenpairs
- for (int i = 0; i < eigenPairs.size(); i++) {
+ for(int i = 0; i < eigenPairs.size(); i++) {
EigenPair eigenPair = eigenPairs.getEigenPair(i);
- if (eigenPair.getEigenvalue() > expectEigenvalue) {
+ if(eigenPair.getEigenvalue() > expectEigenvalue) {
strongEigenPairs.add(eigenPair);
- } else {
+ }
+ else {
weakEigenPairs.add(eigenPair);
}
}
// the code using this method doesn't expect an empty strong set,
// if we didn't find any strong ones, we make all vectors strong
- if (strongEigenPairs.size() == 0) {
+ if(strongEigenPairs.size() == 0) {
return new FilteredEigenPairs(new ArrayList<EigenPair>(), weakEigenPairs);
}
return new FilteredEigenPairs(weakEigenPairs, strongEigenPairs);
@@ -127,8 +128,8 @@ public class WeakEigenPairFilter implements EigenPairFilter {
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
DoubleParameter walphaP = new DoubleParameter(EIGENPAIR_FILTER_WALPHA, DEFAULT_WALPHA);
- walphaP.addConstraint(new GreaterEqualConstraint(0.0));
- if (config.grab(walphaP)) {
+ walphaP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE);
+ if(config.grab(walphaP)) {
walpha = walphaP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
index 292fb002..e7f8198a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AbstractRandomProjectionFamily.java
@@ -51,7 +51,7 @@ public abstract class AbstractRandomProjectionFamily implements RandomProjection
*/
public AbstractRandomProjectionFamily(RandomFactory random) {
super();
- this.random = random.getRandom();
+ this.random = random.getSingleThreadedRandom();
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
index 50610cf9..c07a9590 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/AchlioptasRandomProjectionFamily.java
@@ -26,7 +26,7 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
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.constraints.GreaterEqualConstraint;
+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;
@@ -61,7 +61,7 @@ public class AchlioptasRandomProjectionFamily extends AbstractRandomProjectionFa
super(random);
this.sparsity = sparsity;
}
-
+
@Override
public Projection generateProjection(int idim, int odim) {
final double pPos = .5 / sparsity;
@@ -69,15 +69,17 @@ public class AchlioptasRandomProjectionFamily extends AbstractRandomProjectionFa
double baseValuePart = Math.sqrt(this.sparsity);
Matrix projectionMatrix = new Matrix(odim, idim);
- for (int i = 0; i < odim; ++i) {
- for (int j = 0; j < idim; ++j) {
+ for(int i = 0; i < odim; ++i) {
+ for(int j = 0; j < idim; ++j) {
final double r = random.nextDouble();
final double value;
- if (r < pPos) {
+ if(r < pPos) {
value = baseValuePart;
- } else if (r < pNeg) {
+ }
+ else if(r < pNeg) {
value = -baseValuePart;
- } else {
+ }
+ else {
value = 0.;
}
@@ -110,8 +112,8 @@ public class AchlioptasRandomProjectionFamily extends AbstractRandomProjectionFa
super.makeOptions(config);
DoubleParameter sparsP = new DoubleParameter(SPARSITY_ID);
sparsP.setDefaultValue(3.);
- sparsP.addConstraint(new GreaterEqualConstraint(1.));
- if (config.grab(sparsP)) {
+ sparsP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_DOUBLE);
+ if(config.grab(sparsP)) {
sparsity = sparsP.doubleValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
index d5192086..94a4a29c 100644
--- a/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
+++ b/src/de/lmu/ifi/dbs/elki/math/linearalgebra/randomprojections/RandomSubsetProjectionFamily.java
@@ -101,7 +101,7 @@ public class RandomSubsetProjectionFamily extends AbstractRandomProjectionFamily
*
* FIXME: move to shared code.
*
- * @param existing Existing array
+ * @param out Existing output array
* @param random Random generator.
* @return Same array.
*/
diff --git a/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
index 67a4e748..bf258d99 100644
--- a/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
+++ b/src/de/lmu/ifi/dbs/elki/math/scales/Scales.java
@@ -67,7 +67,11 @@ public final class Scales {
for (DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) {
O v = db.get(iditer);
for (int d = 0; d < dim; d++) {
- minmax[d].put(v.doubleValue(d));
+ final double val = v.doubleValue(d);
+ if(val != val) {
+ continue; // NaN
+ }
+ minmax[d].put(val);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
index 72c50869..de756520 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/KernelDensityEstimator.java
@@ -34,7 +34,7 @@ import de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions.KernelDensityFunction
*
* @author Erich Schubert
*
- * @apiviz.uses de.lmu.ifi.dbs.elki.math.statistics.KernelDensityFunction
+ * @apiviz.uses KernelDensityFunction
*/
public class KernelDensityEstimator {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
index 0d37ca67..37718358 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/MultipleLinearRegression.java
@@ -123,7 +123,8 @@ public class MultipleLinearRegression {
// sum of square totals: sst
sum = 0;
for(int i = 0; i < y.getDimensionality(); i++) {
- sum += Math.pow((y.get(i) - y_mean), 2);
+ final double diff = y.get(i) - y_mean;
+ sum += diff * diff;
}
sst = sum;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
index 12dfe28c..c478142a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/PolynomialRegression.java
@@ -23,6 +23,7 @@ package de.lmu.ifi.dbs.elki.math.statistics;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.math.MathUtil;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Matrix;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
@@ -67,7 +68,7 @@ public class PolynomialRegression extends MultipleLinearRegression {
Matrix result = new Matrix(n, p + 1);
for(int i = 0; i < n; i++) {
for(int j = 0; j < p + 1; j++) {
- result.set(i, j, Math.pow(x.get(i), j));
+ result.set(i, j, MathUtil.powi(x.get(i), j));
}
}
return result;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
index c783f5f1..b74ba06a 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/ProbabilityWeightedMoments.java
@@ -52,7 +52,8 @@ public class ProbabilityWeightedMoments {
* Compute the alpha_r factors using the method of probability-weighted
* moments.
*
- * @param sorted <b>Presorted</b> data array.
+ * @param data <b>Presorted</b> data array.
+ * @param adapter Array adapter.
* @param nmom Number of moments to compute
* @return Alpha moments (0-indexed)
*/
@@ -75,7 +76,8 @@ public class ProbabilityWeightedMoments {
* Compute the beta_r factors using the method of probability-weighted
* moments.
*
- * @param sorted <b>Presorted</b> data array.
+ * @param data <b>Presorted</b> data array.
+ * @param adapter Array adapter.
* @param nmom Number of moments to compute
* @return Beta moments (0-indexed)
*/
@@ -99,7 +101,8 @@ public class ProbabilityWeightedMoments {
* probability-weighted moments. Usually cheaper than computing them
* separately.
*
- * @param sorted <b>Presorted</b> data array.
+ * @param data <b>Presorted</b> data array.
+ * @param adapter Array adapter.
* @param nmom Number of moments to compute
* @return Alpha and Beta moments (0-indexed, interleaved)
*/
@@ -125,6 +128,7 @@ public class ProbabilityWeightedMoments {
* Compute the sample L-Moments using probability weighted moments.
*
* @param sorted <b>Presorted</b> data array.
+ * @param adapter Array adapter.
* @param nmom Number of moments to compute
* @return Array containing Lambda1, Lambda2, Tau3 ... TauN
*/
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;
diff --git a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java
index adcadcaf..219509a5 100644
--- a/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/math/statistics/kernelfunctions/package-info.java
@@ -1,4 +1,27 @@
/**
* Kernel functions from statistics.
*/
+
+/*
+ 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.kernelfunctions; \ No newline at end of file