summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/data/synthetic
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/synthetic')
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java21
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java97
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java56
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java305
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java127
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java116
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java27
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java2
12 files changed, 105 insertions, 786 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
index 3c5853ed..363c6c3b 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterface.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,6 +25,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
import java.util.List;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
@@ -66,19 +67,15 @@ public interface GeneratorInterface {
public abstract double getDensity(Vector p);
/**
- * Get points.
- *
- * NOTE: The list may be modified by the caller, it is not immutable.
- * The class should not return a copy, but should allow modification.
- * However when removing points, the called is expected to call setDiscarded.
- *
- * @return points
- */
- public List<Vector> getPoints();
-
- /**
* Get cluster name
* @return cluster name
*/
public String getName();
+
+ /**
+ * Make a cluster model for this cluster.
+ *
+ * @return Cluster model
+ */
+ public Model makeModel();
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
index 240cda31..cd3f18b7 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorInterfaceDynamic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
/**
* Interface for a dynamic cluster generator.
*
@@ -41,15 +40,14 @@ public interface GeneratorInterfaceDynamic extends GeneratorInterface {
public int getDiscarded();
/**
- * Indicate that points were discarded.
- *
- * @param discarded number of points that were discarded.
- */
- public void addDiscarded(int discarded);
-
- /**
* Retrieve remaining number of retries.
+ *
* @return remaining number of retries
*/
public int getRetries();
-}
+
+ /**
+ * Increment the number of elements discarded.
+ */
+ public void incrementDiscarded();
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
index eef7b13d..6870fcaa 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -31,6 +31,7 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.data.ClassLabel;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
@@ -91,26 +92,41 @@ public class GeneratorMain {
* @throws UnableToComplyException when model not satisfiable or no clusters
* specified.
*/
- public void generate() throws UnableToComplyException {
+ public MultipleObjectsBundle generate() throws UnableToComplyException {
// we actually need some clusters.
if(generators.size() < 1) {
throw new UnableToComplyException("No clusters specified.");
}
// Assert that cluster dimensions agree.
final int dim = generators.get(0).getDim();
- for(GeneratorInterface c : generators) {
- if(c.getDim() != dim) {
- throw new UnableToComplyException("Cluster dimensions do not agree.");
+ {
+ for(GeneratorInterface c : generators) {
+ if(c.getDim() != dim) {
+ throw new UnableToComplyException("Cluster dimensions do not agree.");
+ }
}
}
+ // Vector factory. TODO: make configurable
+ final DoubleVector factory = new DoubleVector(new double[dim]);
+ // Prepare result bundle
+ MultipleObjectsBundle bundle = new MultipleObjectsBundle();
+ VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dim, factory);
+ bundle.appendColumn(type, new ArrayList<Object>());
+ bundle.appendColumn(TypeUtil.CLASSLABEL, new ArrayList<Object>());
+ bundle.appendColumn(TypeUtil.MODEL, new ArrayList<Model>());
+
// generate clusters
for(GeneratorInterface curclus : generators) {
- while(curclus.getPoints().size() < curclus.getSize()) {
+ ClassLabel l = new SimpleClassLabel(curclus.getName());
+ Model model = curclus.makeModel();
+ int kept = 0;
+ while(kept < curclus.getSize()) {
// generate the "missing" number of points
- List<Vector> newp = curclus.generate(curclus.getSize() - curclus.getPoints().size());
+ List<Vector> newp = curclus.generate(curclus.getSize() - kept);
if(curclus instanceof GeneratorInterfaceDynamic) {
GeneratorInterfaceDynamic cursclus = (GeneratorInterfaceDynamic) curclus;
for(Vector p : newp) {
+ boolean keep = true;
if(testAgainstModel) {
double max = 0.0;
double is = 0.0;
@@ -125,20 +141,23 @@ public class GeneratorMain {
}
// Only keep the point if the largest density was the cluster it
// was generated for
- if(is >= max) {
- cursclus.getPoints().add(p);
- }
- else {
- cursclus.addDiscarded(1);
+ if(is < max) {
+ keep = false;
}
}
+ if(keep) {
+ DoubleVector dv = new DoubleVector(p);
+ bundle.appendSimple(dv, l, model);
+ ++kept;
+ }
else {
- cursclus.getPoints().add(p);
+ cursclus.incrementDiscarded();
}
}
}
}
}
+ return bundle;
}
/**
@@ -167,27 +186,4 @@ public class GeneratorMain {
public List<GeneratorInterface> getGenerators() {
return Collections.unmodifiableList(generators);
}
-
- /**
- * Get the objects bundle
- *
- * @return Bundle
- */
- public MultipleObjectsBundle getBundle() {
- final int dim = generators.get(0).getDim();
- final DoubleVector factory = new DoubleVector(new double[dim]);
- MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dim, factory);
- bundle.appendColumn(type, new ArrayList<Object>());
- bundle.appendColumn(TypeUtil.CLASSLABEL, new ArrayList<Object>());
-
- for(GeneratorInterface generator : generators) {
- ClassLabel l = new SimpleClassLabel(generator.getName());
- for(Vector v : generator.getPoints()) {
- DoubleVector dv = new DoubleVector(v);
- bundle.appendSimple(dv, l);
- }
- }
- return bundle;
- }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
index 3d54d937..f9818916 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorSingleCluster.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,12 +23,14 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.math.linearalgebra.AffineTransformation;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
/**
@@ -41,11 +43,11 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
* @apiviz.composedOf Distribution
* @apiviz.composedOf AffineTransformation
*/
-public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
+public class GeneratorSingleCluster implements GeneratorInterfaceDynamic, Model {
/**
* The distribution generators for each axis
*/
- private LinkedList<Distribution> axes = new LinkedList<Distribution>();
+ private List<Distribution> axes = new ArrayList<Distribution>();
/**
* The transformation matrix
@@ -91,11 +93,6 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
private int discarded = 0;
/**
- * The generated cluster points.
- */
- public LinkedList<Vector> points = new LinkedList<Vector>();
-
- /**
* Random generator (used for initializing random generators)
*/
private Random random;
@@ -121,7 +118,8 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
* so far!
*
* @param gen Distribution generator
- * @throws UnableToComplyException thrown when no new generators may be added anymore
+ * @throws UnableToComplyException thrown when no new generators may be added
+ * anymore
*/
public void addGenerator(Distribution gen) throws UnableToComplyException {
if(trans != null) {
@@ -168,23 +166,23 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
*/
public void setClipping(Vector min, Vector max) throws UnableToComplyException {
// if only one dimension was given, expand to all dimensions.
- if(min.getRowDimensionality() == 1 && max.getRowDimensionality() == 1) {
+ if(min.getDimensionality() == 1 && max.getDimensionality() == 1) {
if(min.get(0) >= max.get(0)) {
throw new UnableToComplyException("Clipping range empty.");
}
clipmin = new Vector(dim);
clipmax = new Vector(dim);
for(int i = 0; i < dim; i++) {
- clipmin.set(i, 0, min.get(0));
- clipmax.set(i, 0, max.get(0));
+ clipmin.set(i, min.get(0));
+ clipmax.set(i, max.get(0));
}
return;
}
- if(dim != min.getRowDimensionality()) {
- throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + min.getRowDimensionality());
+ if(dim != min.getDimensionality()) {
+ throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + min.getDimensionality());
}
- if(dim != max.getRowDimensionality()) {
- throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + max.getRowDimensionality());
+ if(dim != max.getDimensionality()) {
+ throw new UnableToComplyException("Clipping vector dimensionalities do not match: " + dim + " vs. " + max.getDimensionality());
}
for(int i = 0; i < dim; i++) {
if(min.get(i) >= max.get(i)) {
@@ -215,7 +213,7 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
if(clipmin == null || clipmax == null) {
return false;
}
- for(int i = 0; i < p.getRowDimensionality(); i++) {
+ for(int i = 0; i < p.getDimensionality(); i++) {
if(p.get(i) < clipmin.get(i)) {
return true;
}
@@ -232,13 +230,13 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
* @see de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorInterface#generate(int)
*/
@Override
- public LinkedList<Vector> generate(int count) throws UnableToComplyException {
- LinkedList<Vector> result = new LinkedList<Vector>();
+ public List<Vector> generate(int count) throws UnableToComplyException {
+ ArrayList<Vector> result = new ArrayList<Vector>(count);
while(result.size() < count) {
double[] d = new double[dim];
int i = 0;
for(Distribution axis : axes) {
- d[i] = axis.generate();
+ d[i] = axis.nextRandom();
i++;
}
Vector p = new Vector(d);
@@ -272,27 +270,18 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
double density = 1.0;
int i = 0;
for(Distribution axis : axes) {
- density = density * axis.explain(o.get(i));
+ density = density * axis.pdf(o.get(i));
i++;
}
return density * densitycorrection;
}
/**
- * Get axis generators. Used for printing model information
- *
- * @return list of distributions
- */
- public LinkedList<Distribution> getAxes() {
- return axes;
- }
-
- /**
* Get transformation
*
* @return transformation matrix, may be null.
*/
- public AffineTransformation getTrans() {
+ public AffineTransformation getTransformation() {
return trans;
}
@@ -321,23 +310,6 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
}
/**
- * Return the list of points (no copy)
- */
- @Override
- public LinkedList<Vector> getPoints() {
- return points;
- }
-
- /**
- * Set the list of points in the cluster
- *
- * @param points New list of points in this cluster.
- */
- public void setPoints(LinkedList<Vector> points) {
- this.points = points;
- }
-
- /**
* Return the size
*
* @return size of this cluster.
@@ -369,12 +341,10 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
/**
* Increase number of discarded points
- *
- * @param discarded number of points discarded.
*/
@Override
- public void addDiscarded(int discarded) {
- this.discarded += discarded;
+ public void incrementDiscarded() {
+ ++this.discarded;
}
/**
@@ -413,4 +383,23 @@ public class GeneratorSingleCluster implements GeneratorInterfaceDynamic {
public Random getNewRandomGenerator() {
return new Random(random.nextLong());
}
+
+ /**
+ * Make a cluster model for this cluster.
+ *
+ * @return Model
+ */
+ public Model makeModel() {
+ return this;
+ }
+
+ /**
+ * Get distribution along (generator) axis i.
+ *
+ * @param i Generator axis i
+ * @return Distribution
+ */
+ public Distribution getDistribution(int i) {
+ return axes.get(i);
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
index 6c44eaca..7075bcb4 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorStatic.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,12 +23,12 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
-import java.util.LinkedList;
+import java.util.Collections;
import java.util.List;
+import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
+import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
/**
* Class for static clusters, that is an implementation of GeneratorInterface
@@ -45,7 +45,7 @@ public class GeneratorStatic implements GeneratorInterface {
/**
* Cluster points
*/
- public LinkedList<Vector> points;
+ public List<Vector> points;
/**
* Construct generator using given name and points
@@ -53,7 +53,7 @@ public class GeneratorStatic implements GeneratorInterface {
* @param name Cluster name
* @param points Cluster points
*/
- public GeneratorStatic(String name, LinkedList<Vector> points) {
+ public GeneratorStatic(String name, List<Vector> points) {
super();
this.name = name;
this.points = points;
@@ -67,12 +67,9 @@ public class GeneratorStatic implements GeneratorInterface {
*/
@Override
public List<Vector> generate(int count) {
- return new ArrayList<Vector>(points);
+ return Collections.unmodifiableList(points);
}
- /**
- * Get density at a given coordinate.
- */
@Override
public double getDensity(Vector p) {
for(Vector my : points) {
@@ -83,54 +80,23 @@ public class GeneratorStatic implements GeneratorInterface {
return 0.0;
}
- /**
- * Get cluster dimensionality
- */
@Override
public int getDim() {
- return points.getFirst().getDimensionality();
+ return points.get(0).getDimensionality();
}
- /**
- * Get number of discarded points
- *
- * @return number of discarded points
- */
- public int getDiscarded() {
- return 0;
- }
-
- /**
- * Get cluster name
- */
@Override
public String getName() {
return name;
}
- /**
- * Get cluster points
- */
- @Override
- public List<Vector> getPoints() {
- return points;
- }
-
- /**
- * Get cluster size
- */
@Override
public int getSize() {
return points.size();
}
- /**
- * Notify cluster of discarded points. Not supported for static generators.
- *
- * @param discarded parameter not supported.
- * @throws UnableToComplyException always thrown, since the static generator doesn't supprot discards.
- */
- public void setDiscarded(int discarded) throws UnableToComplyException {
- throw new UnableToComplyException("Points in static clusters may never be discarded.");
+ @Override
+ public Model makeModel() {
+ return ClusterModel.CLUSTER;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java
deleted file mode 100644
index f93a6459..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/Distribution.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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/>.
- */
-
-
-/**
- * Interface for a simple distribution generator
- * with a PDF, i.e. it can also compute a density
- *
- * @author Erich Schubert
- */
-public interface Distribution {
- /**
- * Generate a new random value
- * @return new generated value
- */
- public double generate();
- /**
- * Return the density of an existing value
- * @param val existing value
- * @return distribution density
- */
- public double explain(double val);
-
- /**
- * Describe the generator
- * @return description
- */
- @Override
- public String toString();
-}
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java
deleted file mode 100644
index 156ac3c4..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/GammaDistribution.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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.math.MathUtil;
-
-/**
- * Simple generator for a Gamma Distribution
- *
- * @author Erich Schubert
- */
-public final class GammaDistribution implements Distribution {
- /**
- * Alpha == k
- */
- private final double k;
-
- /**
- * Theta == 1 / Beta
- */
- private final double theta;
-
- /**
- * The random generator.
- */
- private Random random;
-
- /**
- * Constructor for Gamma distribution generator
- *
- * @param k k, alpha aka. "shape" parameter
- * @param theta Theta = 1.0/Beta aka. "scaling" parameter
- * @param random Random generator
- */
- public GammaDistribution(double k, double theta, Random random) {
- super();
- if(k <= 0.0 || theta <= 0.0) {
- throw new IllegalArgumentException("Invalid parameters for Gamma distribution.");
- }
-
- this.k = k;
- this.theta = theta;
- this.random = random;
- }
-
- /**
- * Gamma distribution PDF (with 0.0 for x &lt; 0)
- *
- * @param x query value
- * @param k Alpha
- * @param theta Thetha = 1 / Beta
- * @return probability density
- */
- public static double pdf(double x, double k, double theta) {
- if(x < 0) {
- return 0.0;
- }
- if(x == 0) {
- if(k == 1.0) {
- return theta;
- }
- else {
- return 0.0;
- }
- }
- if(k == 1.0) {
- return Math.exp(-x * theta) * theta;
- }
-
- return Math.exp((k - 1.0) * Math.log(x * theta) - x * theta - MathUtil.logGamma(k)) * theta;
- }
-
- /**
- * Return the PDF of the generators distribution
- */
- @Override
- public double explain(double val) {
- return pdf(val, k, theta);
- }
-
- /**
- * Generate a random value with the generators parameters.
- *
- * Along the lines of
- *
- * - J.H. Ahrens, U. Dieter (1974): Computer methods for sampling from gamma,
- * beta, Poisson and binomial distributions, Computing 12, 223-246.
- *
- * - J.H. Ahrens, U. Dieter (1982): Generating gamma variates by a modified
- * rejection technique, Communications of the ACM 25, 47-54.
- */
- @Override
- public double generate() {
- /* Constants */
- final double q1 = 0.0416666664, q2 = 0.0208333723, q3 = 0.0079849875;
- final double q4 = 0.0015746717, q5 = -0.0003349403, q6 = 0.0003340332;
- final double q7 = 0.0006053049, q8 = -0.0004701849, q9 = 0.0001710320;
- final double a1 = 0.333333333, a2 = -0.249999949, a3 = 0.199999867;
- final double a4 = -0.166677482, a5 = 0.142873973, a6 = -0.124385581;
- final double a7 = 0.110368310, a8 = -0.112750886, a9 = 0.104089866;
- final double e1 = 1.000000000, e2 = 0.499999994, e3 = 0.166666848;
- final double e4 = 0.041664508, e5 = 0.008345522, e6 = 0.001353826;
- final double e7 = 0.000247453;
-
- if(k < 1.0) { // Base case, for small k
- final double b = 1.0 + 0.36788794412 * k; // Step 1
- while(true) {
- final double p = b * random.nextDouble();
- if(p <= 1.0) { // when gds <= 1
- final double gds = Math.exp(Math.log(p) / k);
- if(Math.log(random.nextDouble()) <= -gds) {
- return (gds / theta);
- }
- }
- else { // when gds > 1
- final double gds = -Math.log((b - p) / k);
- if(Math.log(random.nextDouble()) <= ((k - 1.0) * Math.log(gds))) {
- return (gds / theta);
- }
- }
- }
- }
- else {
- // Step 1. Preparations
- final double ss, s, d;
- if(k != -1.0) {
- ss = k - 0.5;
- s = Math.sqrt(ss);
- d = 5.656854249 - 12.0 * s;
- }
- else {
- // For k == -1.0:
- ss = 0.0;
- s = 0.0;
- d = 0.0;
- }
- // Random vector of maximum length 1
- final double v1, /* v2, */v12;
- { // Temporary values - candidate
- double tv1, tv2, tv12;
- do {
- tv1 = 2.0 * random.nextDouble() - 1.0;
- tv2 = 2.0 * random.nextDouble() - 1.0;
- tv12 = tv1 * tv1 + tv2 * tv2;
- }
- while(tv12 > 1.0);
- v1 = tv1;
- /* v2 = tv2; */
- v12 = tv12;
- }
-
- // double b = 0.0, c = 0.0;
- // double si = 0.0, q0 = 0.0;
- final double b, c, si, q0;
-
- // Simpler accept cases & parameter computation
- {
- final double t = v1 * Math.sqrt(-2.0 * Math.log(v12) / v12);
- final double x = s + 0.5 * t;
- final double gds = x * x;
- if(t >= 0.0) {
- return (gds / theta); // Immediate acceptance
- }
-
- // Random uniform
- final double un = random.nextDouble();
- // Squeeze acceptance
- if(d * un <= t * t * t) {
- return (gds / theta);
- }
-
- if(k != -1.0) { // Step 4. Set-up for hat case
- final double r = 1.0 / k;
- q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r;
- if(k > 3.686) {
- if(k > 13.022) {
- b = 1.77;
- si = 0.75;
- c = 0.1515 / s;
- }
- else {
- b = 1.654 + 0.0076 * ss;
- si = 1.68 / s + 0.275;
- c = 0.062 / s + 0.024;
- }
- }
- else {
- b = 0.463 + s - 0.178 * ss;
- si = 1.235;
- c = 0.195 / s - 0.079 + 0.016 * s;
- }
- }
- else {
- // For k == -1.0:
- b = 0.0;
- c = 0.0;
- si = 0.0;
- q0 = 0.0;
- }
- // Compute v and q
- if(x > 0.0) {
- final double v = t / (s + s);
- final double q;
- if(Math.abs(v) > 0.25) {
- q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1.0 + v);
- }
- else {
- q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
- }
- // Quotient acceptance:
- if(Math.log(1.0 - un) <= q) {
- return (gds / theta);
- }
- }
- }
-
- // Double exponential deviate t
- while(true) {
- double e, u, sign_u, t;
- // Retry until t is sufficiently large
- do {
- e = -Math.log(random.nextDouble());
- u = random.nextDouble();
- u = u + u - 1.0;
- sign_u = (u > 0) ? 1.0 : -1.0;
- t = b + (e * si) * sign_u;
- }
- while(t <= -0.71874483771719);
-
- // New v(t) and q(t)
- final double v = t / (s + s);
- final double q;
- if(Math.abs(v) > 0.25) {
- q = q0 - s * t + 0.25 * t * t + (ss + ss) * Math.log(1.0 + v);
- }
- else {
- q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
- }
- if(q <= 0.0) {
- continue; // retry
- }
- // Compute w(t)
- final double w;
- if(q > 0.5) {
- w = Math.exp(q) - 1.0;
- }
- else {
- w = ((((((e7 * q + e6) * q + e5) * q + e4) * q + e3) * q + e2) * q + e1) * q;
- }
- // Hat acceptance
- if(c * u * sign_u <= w * Math.exp(e - 0.5 * t * t)) {
- final double x = s + 0.5 * t;
- return (x * x / theta);
- }
- }
- }
- }
-
- /**
- * Simple toString explaining the distribution parameters.
- *
- * Used in producing a model description.
- */
- @Override
- public String toString() {
- return "Gamma Distribution (k=" + k + ", theta=" + theta + ")";
- }
-
- /**
- * @return the value of k
- */
- public double getK() {
- return k;
- }
-
- /**
- * @return the standard deviation
- */
- public double getTheta() {
- return theta;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java
deleted file mode 100644
index 24f06f32..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/NormalDistribution.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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.math.MathUtil;
-
-/**
- * Simple generator for a Gaussian = Normal Distribution
- *
- * @author Erich Schubert
- */
-public final class NormalDistribution implements Distribution {
- /**
- * Mean value for the generator
- */
- private double mean;
-
- /**
- * Standard deviation
- */
- private double stddev;
-
- /**
- * The random generator.
- */
- private Random random;
-
- /**
- * Constructor for Gaussian generator
- *
- * @param mean Mean
- * @param stddev Standard Deviation
- * @param random Random generator
- */
- public NormalDistribution(double mean, double stddev, Random random) {
- this.mean = mean;
- this.stddev = stddev;
- this.random = random;
- }
-
- /**
- * Standardized Gaussian PDF
- *
- * @param x query value
- * @return probability density
- */
- // TODO: make a math.distributions package with various PDF, CDF, Error
- // functions etc.?
- private static double phi(double x) {
- return Math.exp(-x * x / 2) / MathUtil.SQRTTWOPI;
- }
-
- /**
- * Gaussian distribution PDF
- *
- * @param x query value
- * @param mu mean
- * @param sigma standard distribution
- * @return probability density
- */
- public static double phi(double x, double mu, double sigma) {
- return phi((x - mu) / sigma) / sigma;
- }
-
- /**
- * Return the PDF of the generators distribution
- */
- @Override
- public double explain(double val) {
- return phi(val, mean, stddev);
- }
-
- /**
- * Generate a random value with the generators parameters
- */
- @Override
- public double generate() {
- return mean + random.nextGaussian() * stddev;
- }
-
- /**
- * Simple toString explaining the distribution parameters.
- *
- * Used in producing a model description.
- */
- @Override
- public String toString() {
- return "Normal Distribution (mean="+mean+", stddev="+stddev+")";
- }
-
- /**
- * @return the mean
- */
- public double getMean() {
- return mean;
- }
-
- /**
- * @return the standard deviation
- */
- public double getStddev() {
- return stddev;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java
deleted file mode 100644
index 0686f1a3..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/UniformDistribution.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2011
- 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;
-
-/**
- * Simple uniform distribution class
- *
- * @author Erich Schubert
- */
-public final class UniformDistribution implements Distribution {
- /**
- * Minimum
- */
- private double min;
-
- /**
- * Maximum
- */
- private double max;
-
- /**
- * Len := max - min
- */
- private double len;
-
- /**
- * The random generator.
- */
- private Random random;
-
- /**
- * Constructor for a uniform distribution on the interval [min, max[
- *
- * @param min Minimum value
- * @param max Maximum value
- * @param random Random generator
- */
- public UniformDistribution(double min, double max, Random random) {
- // 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;
- this.random = random;
- }
-
- /**
- * Return the PDF of the generators distribution
- */
- @Override
- public double explain(double val) {
- if(val < min || val >= max) {
- return 0.0;
- }
- return 1.0 / len;
- }
-
- /**
- * Generate a random value with the generators parameters
- */
- @Override
- public double generate() {
- return min + random.nextDouble() * len;
- }
-
- /**
- * Simple toString explaining the distribution parameters.
- *
- * Used in describing cluster models.
- */
- @Override
- public String toString() {
- return "Uniform Distribution (min=" + min + ", max=" + max + ")";
- }
-
- /**
- * @return the minimum value
- */
- public double getMin() {
- return min;
- }
-
- /**
- * @return the maximum value
- */
- public double getMax() {
- return max;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java
deleted file mode 100644
index 6aab20ab..00000000
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/distribution/package-info.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * <p>Data generators used by the model-based generator.</p>
- *
- */
-/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
-
-Copyright (C) 2011
-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.data.synthetic.bymodel.distribution; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
index dd0d3e44..51dcd8e8 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/package-info.java
@@ -13,7 +13,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java
index 4151409d..c311cf0b 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/package-info.java
@@ -7,7 +7,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team