summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
new file mode 100644
index 00000000..626e8abb
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
@@ -0,0 +1,148 @@
+package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
+/*
+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/>.
+*/
+
+/**
+ * Holds the lower and upper hull for some values.
+ *
+ * @author Elke Achtert
+ */
+public class ConvexHull {
+ /**
+ * The lower hull.
+ */
+ private int[] lowerHull;
+
+ /**
+ * The upper hull.
+ */
+ private int[] upperHull;
+
+ /**
+ * Number of points in lower hull.
+ */
+ private int l;
+
+ /**
+ * Number of points in upper hull.
+ */
+ private int u;
+
+ /**
+ * Creates a new convex hull for the specified distances.
+ *
+ * @param x the x-values of the points for which the lower and upper hull
+ * should be computed
+ * @param y the y-values of the points for which the lower and upper hull
+ * should be computed
+ */
+ public ConvexHull(double[] x, double[] y) {
+ if(x.length != y.length) {
+ throw new IllegalArgumentException("x and y have different lengths!");
+ }
+
+ lowerHull = new int[x.length];
+ upperHull = new int[x.length];
+ determineLowerAndUpperHull(x, y);
+ }
+
+ /**
+ * Returns the lower hull.
+ *
+ * @return the lower hull
+ */
+ public int[] getLowerHull() {
+ return lowerHull;
+ }
+
+ /**
+ * Returns the upper hull.
+ *
+ * @return the upper hull
+ */
+ public int[] getUpperHull() {
+ return upperHull;
+ }
+
+ /**
+ * Returns the number of points in lower hull
+ *
+ * @return the number of points in lower hull
+ */
+ public int getNumberOfPointsInLowerHull() {
+ return l;
+ }
+
+ /**
+ * Returns the number of points in upper hull
+ *
+ * @return the number of points in upper hull
+ */
+ public int getNumberOfPointsInUpperHull() {
+ return u;
+ }
+
+ /**
+ * Computes the lower and upper hull of the specified distances.
+ *
+ * @param x the x-values of the points for which the lower and upper hull
+ * should be computed
+ * @param y the y-values of the points for which the lower and upper hull
+ * should be computed
+ */
+ private void determineLowerAndUpperHull(double[] x, double[] y) {
+ StringBuffer msg = new StringBuffer();
+ // first point is always in lowerHull and upperHull
+ lowerHull[0] = 0;
+ l = 1;
+ upperHull[0] = 0;
+ u = 1;
+
+ // Determine the convex hulls (using point stack)
+ for(int i = 1; i < x.length; i++) {
+ // lower hull
+ lowerHull[l] = i;
+ while(l >= 2 && (y[lowerHull[l]] - y[lowerHull[l - 1]]) / (x[lowerHull[l]] - x[lowerHull[l - 1]]) <= (y[lowerHull[l - 1]] - y[lowerHull[l - 2]]) / (x[lowerHull[l - 1]] - x[lowerHull[l - 2]])) {
+ // right curved
+ lowerHull[l - 1] = lowerHull[l];
+ this.l--;
+ }
+ this.l++;
+
+ // upper hull
+ upperHull[u] = i;
+ while(u >= 2 && (y[upperHull[u]] - y[upperHull[u - 1]]) / (x[upperHull[u]] - x[upperHull[u - 1]]) >= (y[upperHull[u - 1]] - y[upperHull[u - 2]]) / (x[upperHull[u - 1]] - x[upperHull[u - 2]])) {
+ // left curved
+ upperHull[u - 1] = upperHull[u];
+ u--;
+ }
+ u++;
+ }
+
+ msg.append("lower and upper hull\n");
+ for(int i = 0; i < i; i++) {
+ msg.append(" uhull ").append(i).append("=").append(upperHull[i]).append(" y=").append(y[upperHull[i]]).append("\n");
+ msg.append(" lhull ").append(i).append("=").append(lowerHull[i]).append(" y=").append(y[lowerHull[i]]).append("\n");
+ }
+ }
+} \ No newline at end of file