diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/data/synthetic')
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 < 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 |