diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/utilities')
258 files changed, 4412 insertions, 3827 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/Alias.java b/src/de/lmu/ifi/dbs/elki/utilities/Alias.java index 839fc406..e3360b1e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/Alias.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/Alias.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/Base64.java b/src/de/lmu/ifi/dbs/elki/utilities/Base64.java deleted file mode 100644 index c6a22f20..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/Base64.java +++ /dev/null @@ -1,122 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities; -/* - 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.lang.reflect.Constructor; -import java.lang.reflect.Method; - -/** - * Class to wrap various Base64 encoders that could be available. - * - * This is a rather ugly hack; it would maybe have been sensible to just import - * one of the publicly available (and fast) Base64 encoders. The expectation was - * that at some point, Oracle will actually include a public and fast Base64 - * encoder in Java... - * - * @author Erich Schubert - */ -public final class Base64 { - /** - * Instance of sun.misc.BASE64Encoder - */ - private static Object sunj6i; - - /** - * Encode method - */ - private static Method sunj6m; - - /** - * Instance of java.util.prefs.Base64 - */ - private static Object jup6i; - - /** - * Encode method - */ - private static Method jup6m; - - // Initialize - static { - // Try Java 6 - { - try { - Class<?> c = ClassLoader.getSystemClassLoader().loadClass("sun.misc.BASE64Encoder"); - sunj6i = c.newInstance(); - sunj6m = c.getMethod("encode", byte[].class); - } - catch(Throwable e) { - // de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e); - // Ignore. - sunj6i = null; - sunj6m = null; - } - } - // Try private class in Java6 preferences - { - try { - Class<?> c = ClassLoader.getSystemClassLoader().loadClass("java.util.prefs.Base64"); - Constructor<?> cons = c.getDeclaredConstructor(); - cons.setAccessible(true); - jup6i = cons.newInstance(); - jup6m = c.getDeclaredMethod("byteArrayToBase64", byte[].class); - jup6m.setAccessible(true); - } - catch(Throwable e) { - // de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e); - // Ignore. - jup6i = null; - jup6m = null; - } - } - if(sunj6i == null && jup6i == null) { - de.lmu.ifi.dbs.elki.logging.LoggingUtil.warning("No usable Base64 encoders detected."); - } - } - - /** - * Encode a string as Base64. - * - * @param s Bytes to encode - * @return Result string - */ - public static final String encodeBase64(byte[] s) { - if(jup6i != null && jup6m != null) { - try { - return (String) jup6m.invoke(jup6i, s); - } - catch(Exception e) { - throw new RuntimeException("java.util.prefs.Base64 is not working."); - } - } - if(sunj6i != null && sunj6m != null) { - try { - return (String) sunj6m.invoke(sunj6i, s); - } - catch(Exception e) { - throw new RuntimeException("sun.misc.BASE64Encoder is not working."); - } - } - throw new RuntimeException("No usable Base64 encoder detected."); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java index 64d5be25..9ed9097e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/BitsUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,6 +23,8 @@ package de.lmu.ifi.dbs.elki.utilities; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import gnu.trove.strategy.HashingStrategy; + import java.util.Arrays; /** @@ -61,13 +63,33 @@ public final class BitsUtil { 9765625, 48828125, 244140625, 1220703125 }; /** + * Hashing strategy to use with Trove. + */ + public static final HashingStrategy<long[]> TROVE_HASH_STRATEGY = new HashingStrategy<long[]>() { + /** + * Serial version number. + */ + private static final long serialVersionUID = 1L; + + @Override + public int computeHashCode(long[] arg0) { + return BitsUtil.hashCode(arg0); + } + + @Override + public boolean equals(long[] arg0, long[] arg1) { + return equal(arg0, arg1); + } + }; + + /** * Allocate a new long[]. * * @param bits Number of bits in storage * @return New array */ public static long[] zero(int bits) { - return new long[((bits - 1) >>> LONG_LOG2_SIZE) + 1]; + return new long[(bits > 0) ? ((bits - 1) >>> LONG_LOG2_SIZE) + 1 : 1]; } /** @@ -120,7 +142,7 @@ public final class BitsUtil { */ public static long[] copy(long[] v, int mincap) { int words = ((mincap - 1) >>> LONG_LOG2_SIZE) + 1; - if (v.length == words) { + if(v.length == words) { return Arrays.copyOf(v, v.length); } long[] ret = new long[words]; @@ -140,15 +162,15 @@ public final class BitsUtil { */ public static long[] copy(long[] v, int mincap, int shift) { int words = ((mincap - 1) >>> LONG_LOG2_SIZE) + 1; - if (v.length == words && shift == 0) { + if(v.length == words && shift == 0) { return Arrays.copyOf(v, v.length); } long[] ret = new long[words]; final int shiftWords = shift >>> LONG_LOG2_SIZE; final int shiftBits = shift & LONG_LOG2_MASK; // Simple case - multiple of word size - if (shiftBits == 0) { - for (int i = shiftWords; i < ret.length; i++) { + if(shiftBits == 0) { + for(int i = shiftWords; i < ret.length; i++) { ret[i] |= v[i - shiftWords]; } return ret; @@ -156,7 +178,7 @@ public final class BitsUtil { // Overlapping case final int unshiftBits = Long.SIZE - shiftBits; final int end = Math.min(ret.length, v.length + shiftWords) - 1; - for (int i = end; i > shiftWords; i--) { + for(int i = end; i > shiftWords; i--) { final int src = i - shiftWords; ret[i] |= (v[src] << shiftBits) | (v[src - 1] >>> unshiftBits); } @@ -214,15 +236,15 @@ public final class BitsUtil { final int last = v.length - 1; int o; // Sub word level: - for (o = 1; o < Long.SIZE; o <<= 1) { - for (int i = 0; i < last; i++) { + for(o = 1; o < Long.SIZE; o <<= 1) { + for(int i = 0; i < last; i++) { v[i] ^= (v[i] >>> o) ^ (v[i + 1] << (Long.SIZE - o)); } v[last] ^= (v[last] >>> o); } // Word level: - for (o = 1; o <= last; o <<= 1) { - for (int i = o; i <= last; i++) { + for(o = 1; o <= last; o <<= 1) { + for(int i = o; i <= last; i++) { v[i - o] ^= v[i]; } } @@ -236,8 +258,8 @@ public final class BitsUtil { * @return true when all zero */ public static boolean isZero(long[] v) { - for (int i = 0; i < v.length; i++) { - if (v[i] != 0) { + for(int i = 0; i < v.length; i++) { + if(v[i] != 0) { return false; } } @@ -262,9 +284,9 @@ public final class BitsUtil { * @param v Value * @return Number of bits set in long[] */ - public static long cardinality(long[] v) { + public static int cardinality(long[] v) { int sum = 0; - for (int i = 0; i < v.length; i++) { + for(int i = 0; i < v.length; i++) { sum += Long.bitCount(v[i]); } return sum; @@ -321,6 +343,22 @@ public final class BitsUtil { } /** + * Put o onto v inplace, i.e. v = o + * + * @param v Primary object + * @param o data to initialize to. + * @return v + */ + public static long[] setI(long[] v, long[] o) { + assert (o.length <= v.length) : "Bit set sizes do not agree."; + final int max = Math.min(v.length, o.length); + for(int i = 0; i < max; i++) { + v[i] = o[i]; + } + return v; + } + + /** * Clear bit number "off" in v. * * @param v Buffer @@ -365,7 +403,7 @@ public final class BitsUtil { */ public static boolean get(long[] v, int off) { final int wordindex = off >>> LONG_LOG2_SIZE; - return (v[wordindex] & (1L << off)) != 0; + return (wordindex < v.length) && (v[wordindex] & (1L << off)) != 0; } /** @@ -390,7 +428,7 @@ public final class BitsUtil { */ public static long[] xorI(long[] v, long[] o) { assert (o.length <= v.length) : "Bit set sizes do not agree."; - for (int i = 0; i < o.length; i++) { + for(int i = 0; i < o.length; i++) { v[i] ^= o[i]; } return v; @@ -405,23 +443,23 @@ public final class BitsUtil { * @return v */ public static long[] xorI(long[] v, long[] o, int off) { - if (off == 0) { + if(off == 0) { return xorI(v, o); } - if (off < 0) { + if(off < 0) { throw new UnsupportedOperationException("Negative shifts are not supported."); } // Break shift into integers to shift and bits to shift final int shiftWords = off >>> LONG_LOG2_SIZE; final int shiftBits = off & LONG_LOG2_MASK; - if (shiftWords >= v.length) { + if(shiftWords >= v.length) { return v; } // Simple case - multiple of word size - if (shiftBits == 0) { + if(shiftBits == 0) { final int end = Math.min(v.length, o.length + shiftWords); - for (int i = shiftWords; i < end; i++) { + for(int i = shiftWords; i < end; i++) { v[i] ^= o[i - shiftWords]; } return v; @@ -429,7 +467,7 @@ public final class BitsUtil { // Overlapping case final int unshiftBits = Long.SIZE - shiftBits; final int end = Math.min(v.length, o.length + shiftWords) - 1; - for (int i = end; i > shiftWords; i--) { + for(int i = end; i > shiftWords; i--) { final int src = i - shiftWords; v[i] ^= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits); } @@ -447,7 +485,7 @@ public final class BitsUtil { public static long[] orI(long[] v, long[] o) { assert (o.length <= v.length) : "Bit set sizes do not agree."; final int max = Math.min(v.length, o.length); - for (int i = 0; i < max; i++) { + for(int i = 0; i < max; i++) { v[i] |= o[i]; } return v; @@ -464,23 +502,23 @@ public final class BitsUtil { * @return v */ public static long[] orI(long[] v, long[] o, int off) { - if (off == 0) { + if(off == 0) { return orI(v, o); } - if (off < 0) { + if(off < 0) { throw new UnsupportedOperationException("Negative shifts are not supported."); } // Break shift into integers to shift and bits to shift final int shiftWords = off >>> LONG_LOG2_SIZE; final int shiftBits = off & LONG_LOG2_MASK; - if (shiftWords >= v.length) { + if(shiftWords >= v.length) { return v; } // Simple case - multiple of word size - if (shiftBits == 0) { + if(shiftBits == 0) { final int end = Math.min(v.length, o.length + shiftWords); - for (int i = shiftWords; i < end; i++) { + for(int i = shiftWords; i < end; i++) { v[i] |= o[i - shiftWords]; } return v; @@ -488,7 +526,7 @@ public final class BitsUtil { // Overlapping case final int unshiftBits = Long.SIZE - shiftBits; final int end = Math.min(v.length, o.length + shiftWords) - 1; - for (int i = end; i > shiftWords; i--) { + for(int i = end; i > shiftWords; i--) { final int src = i - shiftWords; v[i] |= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits); } @@ -505,8 +543,8 @@ public final class BitsUtil { */ public static long[] andI(long[] v, long[] o) { int i = 0; - for (; i < o.length; i++) { - v[i] |= o[i]; + for(; i < o.length; i++) { + v[i] &= o[i]; } // Zero higher words Arrays.fill(v, i, v.length, 0); @@ -522,23 +560,23 @@ public final class BitsUtil { * @return v */ public static long[] andI(long[] v, long[] o, int off) { - if (off == 0) { + if(off == 0) { return andI(v, o); } - if (off < 0) { + if(off < 0) { throw new UnsupportedOperationException("Negative shifts are not supported."); } // Break shift into integers to shift and bits to shift final int shiftWords = off >>> LONG_LOG2_SIZE; final int shiftBits = off & LONG_LOG2_MASK; - if (shiftWords >= v.length) { + if(shiftWords >= v.length) { return v; } // Simple case - multiple of word size - if (shiftBits == 0) { + if(shiftBits == 0) { final int end = Math.min(v.length, o.length + shiftWords); - for (int i = shiftWords; i < end; i++) { + for(int i = shiftWords; i < end; i++) { v[i] &= o[i - shiftWords]; } // Clear bottom words @@ -549,7 +587,7 @@ public final class BitsUtil { final int unshiftBits = Long.SIZE - shiftBits; final int end = Math.min(v.length, o.length + shiftWords) - 1; Arrays.fill(v, end + 1, v.length, 0); - for (int i = end; i > shiftWords; i--) { + for(int i = end; i > shiftWords; i--) { final int src = i - shiftWords; v[i] &= (o[src] << shiftBits) | (o[src - 1] >>> unshiftBits); } @@ -560,13 +598,74 @@ public final class BitsUtil { } /** + * AND o onto v in a copy, i.e. v & o + * + * The resulting array will have the shorter length of the two. + * + * @param v Primary object + * @param o data to and + * @return Copy of v and o + */ + public static long[] andCMin(long[] v, long[] o) { + final int min = Math.min(v.length, o.length); + long[] out = new long[min]; + int i = 0; + for(; i < min; i++) { + out[i] = v[i] & o[i]; + } + return out; + } + + /** + * AND o onto v in a copy, i.e. v & o + * + * The resulting array will have the shorter length of the two. + * + * @param v Primary object + * @param o data to and + * @return Copy of v and o + */ + public static long[] andCMax(long[] v, long[] o) { + final int min, max; + if(v.length < o.length) { + min = v.length; + max = o.length; + } + else { + min = o.length; + max = v.length; + } + long[] out = new long[max]; + int i = 0; + for(; i < min; i++) { + out[i] = v[i] & o[i]; + } + return out; + } + + /** + * NOTAND o onto v inplace, i.e. v &= ~o + * + * @param v Primary object + * @param o data to and + * @return v + */ + public static long[] nandI(long[] v, long[] o) { + int i = 0; + for(; i < o.length; i++) { + v[i] &= ~o[i]; + } + return v; + } + + /** * Invert v inplace. * * @param v Object to invert * @return v */ public static long[] invertI(long[] v) { - for (int i = 0; i < v.length; i++) { + for(int i = 0; i < v.length; i++) { v[i] = ~v[i]; } return v; @@ -582,21 +681,21 @@ public final class BitsUtil { * @return Bitset */ public static long[] shiftRightI(long[] v, int off) { - if (off == 0) { + if(off == 0) { return v; } - if (off < 0) { + if(off < 0) { return shiftLeftI(v, -off); } // Break shift into integers to shift and bits to shift final int shiftWords = off >>> LONG_LOG2_SIZE; final int shiftBits = off & LONG_LOG2_MASK; - if (shiftWords >= v.length) { + if(shiftWords >= v.length) { return zeroI(v); } // Simple case - multiple of word size - if (shiftBits == 0) { + if(shiftBits == 0) { // Move whole words down System.arraycopy(v, shiftWords, v, 0, v.length - shiftWords); // Fill top words with zeros @@ -606,7 +705,7 @@ public final class BitsUtil { // Overlapping case final int unshiftBits = Long.SIZE - shiftBits; // Bottom-up to not overlap the operations. - for (int i = 0; i < v.length - shiftWords - 1; i++) { + for(int i = 0; i < v.length - shiftWords - 1; i++) { final int src = i + shiftWords; v[i] = (v[src + 1] << unshiftBits) | (v[src] >>> shiftBits); } @@ -627,21 +726,21 @@ public final class BitsUtil { * @return Bitset */ public static long[] shiftLeftI(long[] v, int off) { - if (off == 0) { + if(off == 0) { return v; } - if (off < 0) { + if(off < 0) { return shiftRightI(v, -off); } // Break shift into integers to shift and bits to shift final int shiftWords = off >>> LONG_LOG2_SIZE; final int shiftBits = off & LONG_LOG2_MASK; - if (shiftWords >= v.length) { + if(shiftWords >= v.length) { return zeroI(v); } // Simple case - multiple of word size - if (shiftBits == 0) { + if(shiftBits == 0) { // Move whole words up System.arraycopy(v, 0, v, shiftWords, v.length - shiftWords); // Fill the initial words with zeros @@ -651,7 +750,7 @@ public final class BitsUtil { // Overlapping case final int unshiftBits = Long.SIZE - shiftBits; // Top-Down to not overlap the operations. - for (int i = v.length - 1; i > shiftWords; i--) { + for(int i = v.length - 1; i > shiftWords; i--) { final int src = i - shiftWords; v[i] = (v[src] << shiftBits) | (v[src - 1] >>> unshiftBits); } @@ -670,10 +769,10 @@ public final class BitsUtil { * @return cycled bit set */ public static long cycleRightC(long v, int shift, int len) { - if (shift == 0) { + if(shift == 0) { return v; } - if (shift < 0) { + if(shift < 0) { return cycleLeftC(v, -shift, len); } final long ones = (1 << len) - 1; @@ -706,7 +805,7 @@ public final class BitsUtil { final int zapWords = (zap >>> LONG_LOG2_SIZE); final int zapbits = zap & LONG_LOG2_MASK; Arrays.fill(v, v.length - zapWords, v.length, 0); - if (zapbits > 0) { + if(zapbits > 0) { v[v.length - zapWords - 1] &= (LONG_ALL_BITS >>> zapbits); } return v; @@ -721,10 +820,10 @@ public final class BitsUtil { * @return cycled bit set */ public static long cycleLeftC(long v, int shift, int len) { - if (shift == 0) { + if(shift == 0) { return v; } - if (shift < 0) { + if(shift < 0) { return cycleRightC(v, -shift, len); } final long ones = (1 << len) - 1; @@ -753,25 +852,30 @@ public final class BitsUtil { * @return String representation */ public static String toString(long[] v) { + if(v == null) { + return "null"; + } final int mag = magnitude(v); - if (v.length == 0 || mag == 0) { + if(mag == 0) { return "0"; } - final int words = ((mag - 1) >>> LONG_LOG2_SIZE) + 1; char[] digits = new char[mag]; - int pos = mag - 1; - for (int w = 0; w < words; w++) { + + outer: for(int w = 0; w < v.length; w++) { long f = 1L; - for (int i = 0; i < Long.SIZE; i++) { + for(int i = 0; i < Long.SIZE; i++) { digits[pos] = ((v[w] & f) == 0) ? '0' : '1'; - pos--; f <<= 1; - if (pos < 0) { - break; + --pos; + if(pos < 0) { + break outer; } } } + for(; pos >= 0; --pos) { + digits[pos] = '0'; + } return new String(digits); } @@ -783,25 +887,30 @@ public final class BitsUtil { * @return String representation */ public static String toString(long[] v, int minw) { + if(v == null) { + return "null"; + } final int mag = Math.max(magnitude(v), minw); - if (v.length == 0 || mag == 0) { + if(mag == 0) { return "0"; } - final int words = ((mag - 1) >>> LONG_LOG2_SIZE) + 1; char[] digits = new char[mag]; - int pos = mag - 1; - for (int w = 0; w < words; w++) { + + outer: for(int w = 0; w < v.length; w++) { long f = 1L; - for (int i = 0; i < Long.SIZE; i++) { + for(int i = 0; i < Long.SIZE; i++) { digits[pos] = ((v[w] & f) == 0) ? '0' : '1'; - pos--; f <<= 1; - if (pos < 0) { - break; + --pos; + if(pos < 0) { + break outer; } } } + for(; pos >= 0; --pos) { + digits[pos] = '0'; + } return new String(digits); } @@ -813,36 +922,140 @@ public final class BitsUtil { */ public static String toString(long v) { final int mag = magnitude(v); - if (mag == 0) { + if(mag == 0) { return "0"; } char[] digits = new char[mag]; - int pos = mag - 1; long f = 1L; - for (int i = 0; i < Long.SIZE; i++) { + for(int pos = mag - 1; pos >= 0; --pos, f <<= 1) { digits[pos] = ((v & f) == 0) ? '0' : '1'; - pos--; - f <<= 1; - if (pos < 0) { - break; + } + return new String(digits); + } + + /** + * Convert bitset to a string consisting of "0" and "1", in low-endian order. + * + * @param v Value to process + * @return String representation + */ + public static String toStringLow(long[] v) { + if(v == null) { + return "null"; + } + final int mag = magnitude(v); + if(mag == 0) { + return "0"; + } + char[] digits = new char[mag]; + int pos = 0; + + outer: for(int w = 0; w < v.length; w++) { + long f = 1L; + for(int i = 0; i < Long.SIZE; i++) { + digits[pos] = ((v[w] & f) == 0) ? '0' : '1'; + f <<= 1; + ++pos; + if(pos >= mag) { + break outer; + } } } + for(; pos < mag; ++pos) { + digits[pos] = '0'; + } + return new String(digits); + } + + /** + * Convert bitset to a string consisting of "0" and "1", in low-endian order. + * + * @param v Value to process + * @param minw Minimum width + * @return String representation + */ + public static String toStringLow(long[] v, int minw) { + if(v == null) { + return "null"; + } + final int mag = Math.max(magnitude(v), minw); + if(mag == 0) { + return "0"; + } + char[] digits = new char[mag]; + int pos = 0; + + outer: for(int w = 0; w < v.length; w++) { + long f = 1L; + for(int i = 0; i < Long.SIZE; i++) { + digits[pos] = ((v[w] & f) == 0) ? '0' : '1'; + f <<= 1; + ++pos; + if(pos >= mag) { + break outer; + } + } + } + for(; pos < mag; ++pos) { + digits[pos] = '0'; + } + return new String(digits); + } + + /** + * Convert bitset to a string consisting of "0" and "1", in low-endian order. + * + * @param v Value to process + * @return String representation + */ + public static String toStringLow(long v) { + final int mag = magnitude(v); + if(mag == 0) { + return "0"; + } + char[] digits = new char[mag]; + + long f = 1L; + for(int pos = 0; pos < mag; ++pos, f <<= 1) { + digits[pos] = ((v & f) == 0) ? '0' : '1'; + } return new String(digits); } /** + * Convert the bitset into a decimal representation, e.g. <tt>0, 3, 5</tt> + * + * @param v Value + * @param sep Value separator + * @param offset Counting offset (usually, 0 or 1) + * @return String representation + */ + public static String toString(long[] v, String sep, int offset) { + int p = nextSetBit(v, 0); + if(p < 0) { + return ""; + } + StringBuilder buf = new StringBuilder(); + buf.append(p + offset); + for(p = nextSetBit(v, p + 1); p >= 0; p = nextSetBit(v, p + 1)) { + buf.append(sep).append(p + offset); + } + return buf.toString(); + } + + /** * Find the number of trailing zeros. * * @param v Bitset * @return Position of first set bit, -1 if no set bit was found. */ public static int numberOfTrailingZerosSigned(long[] v) { - for (int p = 0;; p++) { - if (p == v.length) { + for(int p = 0;; p++) { + if(p == v.length) { return -1; } - if (v[p] != 0) { + if(v[p] != 0) { return Long.numberOfTrailingZeros(v[p]) + p * Long.SIZE; } } @@ -855,11 +1068,11 @@ public final class BitsUtil { * @return Position of first set bit, v.length * 64 if no set bit was found. */ public static int numberOfTrailingZeros(long[] v) { - for (int p = 0;; p++) { - if (p == v.length) { + for(int p = 0;; p++) { + if(p == v.length) { return p * Long.SIZE; } - if (v[p] != 0) { + if(v[p] != 0) { return Long.numberOfTrailingZeros(v[p]) + p * Long.SIZE; } } @@ -909,11 +1122,11 @@ public final class BitsUtil { * @return Position of first set bit, -1 if no set bit was found. */ public static int numberOfLeadingZerosSigned(long[] v) { - for (int p = 0, ip = v.length - 1;; p++, ip--) { - if (p == v.length) { + for(int p = 0, ip = v.length - 1;; p++, ip--) { + if(p == v.length) { return -1; } - if (v[ip] != 0) { + if(v[ip] != 0) { return Long.numberOfLeadingZeros(v[ip]) + p * Long.SIZE; } } @@ -926,11 +1139,11 @@ public final class BitsUtil { * @return Position of first set bit, v.length * 64 if no set bit was found. */ public static int numberOfLeadingZeros(long[] v) { - for (int p = 0, ip = v.length - 1;; p++, ip--) { - if (p == v.length) { + for(int p = 0, ip = v.length - 1;; p++, ip--) { + if(p == v.length) { return p * Long.SIZE; } - if (v[ip] != 0) { + if(v[ip] != 0) { return Long.numberOfLeadingZeros(v[ip]) + p * Long.SIZE; } } @@ -946,7 +1159,7 @@ public final class BitsUtil { * @return Position of first set bit, -1 if no set bit was found. */ public static int numberOfLeadingZerosSigned(long v) { - if (v == 0) { + if(v == 0) { return -1; } return Long.numberOfLeadingZeros(v); @@ -962,7 +1175,7 @@ public final class BitsUtil { * @return Position of first set bit, -1 if no set bit was found. */ public static int numberOfLeadingZerosSigned(int v) { - if (v == 0) { + if(v == 0) { return -1; } return Integer.numberOfLeadingZeros(v); @@ -999,22 +1212,40 @@ public final class BitsUtil { * @param start Start position (inclusive) * @return Position of previous set bit, or -1. */ + public static int previousSetBit(long v, int start) { + if(start == -1 || start >= Long.SIZE) { + return -1; + } + long cur = v & (LONG_ALL_BITS >>> start); + if(cur == 0) { + return -1; + } + return Long.SIZE - 1 - Long.numberOfLeadingZeros(cur); + } + + /** + * Find the previous set bit. + * + * @param v Values to process + * @param start Start position (inclusive) + * @return Position of previous set bit, or -1. + */ public static int previousSetBit(long[] v, int start) { - if (start == -1) { + if(start == -1) { return -1; } int wordindex = start >>> LONG_LOG2_SIZE; - if (wordindex >= v.length) { + if(wordindex >= v.length) { return magnitude(v) - 1; } // Initial word final int off = Long.SIZE - 1 - (start & LONG_LOG2_MASK); long cur = v[wordindex] & (LONG_ALL_BITS >>> off); - for (;;) { - if (cur != 0) { + for(;;) { + if(cur != 0) { return (wordindex + 1) * Long.SIZE - 1 - Long.numberOfLeadingZeros(cur); } - if (wordindex == 0) { + if(wordindex == 0) { return -1; } wordindex--; @@ -1029,22 +1260,40 @@ public final class BitsUtil { * @param start Start position (inclusive) * @return Position of previous clear bit, or -1. */ + public static int previousClearBit(long v, int start) { + if(start < 0 || start >= Long.SIZE) { + return -1; + } + long cur = ~v & (LONG_ALL_BITS >>> start); + if(cur == 0) { + return -1; + } + return Long.SIZE - 1 - Long.numberOfTrailingZeros(cur); + } + + /** + * Find the previous clear bit. + * + * @param v Values to process + * @param start Start position (inclusive) + * @return Position of previous clear bit, or -1. + */ public static int previousClearBit(long[] v, int start) { - if (start == -1) { + if(start == -1) { return -1; } int wordindex = start >>> LONG_LOG2_SIZE; - if (wordindex >= v.length) { + if(wordindex >= v.length) { return magnitude(v); } final int off = Long.SIZE + 1 - (start & LONG_LOG2_MASK); // Initial word long cur = ~v[wordindex] & (LONG_ALL_BITS >>> off); - for (;;) { - if (cur != 0) { + for(;;) { + if(cur != 0) { return (wordindex + 1) * Long.SIZE - 1 - Long.numberOfTrailingZeros(cur); } - if (wordindex == 0) { + if(wordindex == 0) { return -1; } wordindex--; @@ -1059,20 +1308,38 @@ public final class BitsUtil { * @param start Start position (inclusive) * @return Position of next set bit, or -1. */ + public static int nextSetBit(long v, int start) { + if(start >= Long.SIZE) { + return -1; + } + long cur = v & (LONG_ALL_BITS << start); + if(cur == 0) { + return -1; + } + return Long.numberOfTrailingZeros(cur); + } + + /** + * Find the next set bit. + * + * @param v Value to process + * @param start Start position (inclusive) + * @return Position of next set bit, or -1. + */ public static int nextSetBit(long[] v, int start) { int wordindex = start >>> LONG_LOG2_SIZE; - if (wordindex >= v.length) { + if(wordindex >= v.length) { return -1; } // Initial word long cur = v[wordindex] & (LONG_ALL_BITS << start); - for (;;) { - if (cur != 0) { + for(;;) { + if(cur != 0) { return (wordindex * Long.SIZE) + Long.numberOfTrailingZeros(cur); } wordindex++; - if (wordindex == v.length) { + if(wordindex == v.length) { return -1; } cur = v[wordindex]; @@ -1086,16 +1353,34 @@ public final class BitsUtil { * @param start Start position (inclusive) * @return Position of next clear bit, or -1. */ + public static int nextClearBit(long v, int start) { + if(start >= Long.SIZE) { + return -1; + } + long cur = ~v & (LONG_ALL_BITS << start); + if(cur == 0) { + return -1; + } + return Long.numberOfTrailingZeros(cur); + } + + /** + * Find the next clear bit. + * + * @param v Value to process + * @param start Start position (inclusive) + * @return Position of next clear bit, or -1. + */ public static int nextClearBit(long[] v, int start) { int wordindex = start >>> LONG_LOG2_SIZE; - if (wordindex >= v.length) { + if(wordindex >= v.length) { return -1; } // Initial word long cur = ~v[wordindex] & (LONG_ALL_BITS << start); - for (; wordindex < v.length;) { - if (cur != 0) { + for(; wordindex < v.length;) { + if(cur != 0) { return (wordindex * Long.SIZE) + Long.numberOfTrailingZeros(cur); } wordindex++; @@ -1136,6 +1421,132 @@ public final class BitsUtil { } /** + * Test whether two Bitsets intersect. + * + * @param x First bitset + * @param y Second bitset + * @return {@code true} when the bitsets intersect. + */ + public static boolean intersect(long x, long y) { + return (x & y) != 0L; + } + + /** + * Test whether two Bitsets intersect. + * + * @param x First bitset + * @param y Second bitset + * @return {@code true} when the bitsets intersect. + */ + public static boolean intersect(long[] x, long[] y) { + final int min = (x.length < y.length) ? x.length : y.length; + for(int i = 0; i < min; i++) { + if((x[i] & y[i]) != 0L) { + return true; + } + } + return false; + } + + /** + * Compute the intersection size of two Bitsets. + * + * @param x First bitset + * @param y Second bitset + * @return Intersection size + */ + public static int intersectionSize(long x, long y) { + return Long.bitCount(x & y); + } + + /** + * Compute the intersection size of two Bitsets. + * + * @param x First bitset + * @param y Second bitset + * @return Intersection size + */ + public static int intersectionSize(long[] x, long[] y) { + final int lx = x.length, ly = y.length; + final int min = (lx < ly) ? lx : ly; + int res = 0; + for(int i = 0; i < min; i++) { + res += Long.bitCount(x[i] & y[i]); + } + return res; + } + + /** + * Compute the union size of two Bitsets. + * + * @param x First bitset + * @param y Second bitset + * @return Union size + */ + public static int unionSize(long x, long y) { + return Long.bitCount(x | y); + } + + /** + * Compute the union size of two Bitsets. + * + * @param x First bitset + * @param y Second bitset + * @return Union size + */ + public static int unionSize(long[] x, long[] y) { + final int lx = x.length, ly = y.length; + final int min = (lx < ly) ? lx : ly; + int i = 0, res = 0; + for(; i < min; i++) { + res += Long.bitCount(x[i] | y[i]); + } + for(; i < lx; i++) { + res += Long.bitCount(x[i]); + } + for(; i < ly; i++) { + res += Long.bitCount(y[i]); + } + return res; + } + + /** + * Compute the Hamming distance (Size of symmetric difference), i.e. + * {@code cardinality(a ^ b)}. + * + * @param b1 First vector + * @param b2 Second vector + * @return Cardinality of symmetric difference + */ + public static int hammingDistance(long b1, long b2) { + return Long.bitCount(b1 ^ b2); + } + + /** + * Compute the Hamming distance (Size of symmetric difference), i.e. + * {@code cardinality(a ^ b)}. + * + * @param x First vector + * @param y Second vector + * @return Cardinality of symmetric difference + */ + public static int hammingDistance(long[] x, long[] y) { + final int lx = x.length, ly = y.length; + final int min = (lx < ly) ? lx : ly; + int i = 0, h = 0; + for(; i < min; i++) { + h += Long.bitCount(x[i] ^ y[i]); + } + for(; i < lx; i++) { + h += Long.bitCount(x[i]); + } + for(; i < ly; i++) { + h += Long.bitCount(y[i]); + } + return h; + } + + /** * Capacity of the vector v. * * @param v Vector v @@ -1146,6 +1557,36 @@ public final class BitsUtil { } /** + * Test two bitsets for equality + * + * @param x First bitset + * @param y Second bitset + * @return {@code true} when the bitsets are equal + */ + public static boolean equal(long[] x, long[] y) { + if(x == null || y == null) { + return (x == null) && (y == null); + } + int p = Math.min(x.length, y.length) - 1; + for(int i = x.length - 1; i > p; i--) { + if(x[i] != 0L) { + return false; + } + } + for(int i = y.length - 1; i > p; i--) { + if(y[i] != 0L) { + return false; + } + } + for(; p >= 0; p--) { + if(x[p] != y[p]) { + return false; + } + } + return true; + } + + /** * Compare two bitsets. * * @param x First bitset @@ -1153,31 +1594,40 @@ public final class BitsUtil { * @return Comparison result */ public static int compare(long[] x, long[] y) { + if(x == null) { + return (y == null) ? 0 : -1; + } + if(y == null) { + return +1; + } int p = Math.min(x.length, y.length) - 1; - for (int i = x.length - 1; i > p; i--) { - if (x[i] != 0) { + for(int i = x.length - 1; i > p; i--) { + if(x[i] != 0) { return +1; } } - for (int i = y.length - 1; i > p; i--) { - if (y[i] != 0) { + for(int i = y.length - 1; i > p; i--) { + if(y[i] != 0) { return -1; } } - for (; p >= 0; p--) { + for(; p >= 0; p--) { final long xp = x[p]; final long yp = y[p]; - if (xp != yp) { - if (xp < 0) { - if (yp < 0) { + if(xp != yp) { + if(xp < 0) { + if(yp < 0) { return (yp < xp) ? -1 : ((yp == xp) ? 0 : 1); - } else { + } + else { return +1; } - } else { - if (yp < 0) { + } + else { + if(yp < 0) { return -1; - } else { + } + else { return (xp < yp) ? -1 : ((xp == yp) ? 0 : 1); } } @@ -1186,25 +1636,63 @@ public final class BitsUtil { return 0; } + /** + * Compute a hash code for the given bitset. + * + * @param x Bitset bitset + * @return Hash code + */ + public static int hashCode(long x) { + // We use almost the same hash code function as Java BitSet. + // Optimized for speed only, not protected against collision attacks + // If you need that, consider using murmur hashing with custom seeds. + long hash = 0x76543210L ^ x; + return (int) ((hash >> 32) ^ hash); + } + + /** + * Compute a hash code for the given bitset. + * + * @param x Bitset bitset + * @return Hash code + */ + public static int hashCode(long[] x) { + // We use almost the same hash code function as Java BitSet. + // Optimized for speed only, not protected against collision attacks + // If you need that, consider using murmur hashing with custom seeds. + long hash = 0x76543210L; + for(int i = 0; i < x.length;) { + hash ^= x[i] * ++i; + } + return (int) ((hash >> 32) ^ hash); + } + + /** + * Compute <code>m * pow(2., n)</code> using bit operations. + * + * @param m Mantissa + * @param n Exponent + * @return Double value + */ public static double lpow2(long m, int n) { - if (m == 0) { + if(m == 0) { return 0.0; } - if (m == Long.MIN_VALUE) { + if(m == Long.MIN_VALUE) { return lpow2(Long.MIN_VALUE >> 1, n + 1); } - if (m < 0) { + if(m < 0) { return -lpow2(-m, n); } - assert(m >= 0); + assert (m >= 0); int bitLength = magnitude(m); int shift = bitLength - 53; long exp = 1023L + 52 + n + shift; // Use long to avoid overflow. - if (exp >= 0x7FF) { + if(exp >= 0x7FF) { return Double.POSITIVE_INFINITY; } - if (exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52) - if (exp <= -54) { + if(exp <= 0) { // Degenerated number (subnormal, assume 0 for bit 52) + if(exp <= -54) { return 0.0; } return lpow2(m, n + 54) / 18014398509481984L; // 2^54 Exact. @@ -1212,7 +1700,7 @@ public final class BitsUtil { // Normal number. long bits = (shift > 0) ? (m >> shift) + ((m >> (shift - 1)) & 1) : // Rounding. m << -shift; - if (((bits >> 52) != 1) && (++exp >= 0x7FF)) { + if(((bits >> 52) != 1) && (++exp >= 0x7FF)) { return Double.POSITIVE_INFINITY; } bits &= 0x000fffffffffffffL; // Clears MSB (bit 52) @@ -1229,17 +1717,17 @@ public final class BitsUtil { * @return Double value. */ public static double lpow10(long m, int n) { - if (m == 0) { + if(m == 0) { return 0.0; } - if (m == Long.MIN_VALUE) { + if(m == Long.MIN_VALUE) { return lpow10(Long.MIN_VALUE / 10, n + 1); } - if (m < 0) { + if(m < 0) { return -lpow10(-m, n); } - if (n >= 0) { // Positive power. - if (n > 308) { + if(n >= 0) { // Positive power. + if(n > 308) { return Double.POSITIVE_INFINITY; } // Works with 4 x 32 bits registers (x3:x2:x1:x0) @@ -1248,14 +1736,14 @@ public final class BitsUtil { long x2 = m & LONG_32_BITS; // 32 bits. long x3 = m >>> 32; // 32 bits. int pow2 = 0; - while (n != 0) { + while(n != 0) { int i = (n >= POW5_INT.length) ? POW5_INT.length - 1 : n; int coef = POW5_INT[i]; // 31 bits max. - if (((int) x0) != 0) { + if(((int) x0) != 0) { x0 *= coef; // 63 bits max. } - if (((int) x1) != 0) { + if(((int) x1) != 0) { x1 *= coef; // 63 bits max. } x2 *= coef; // 63 bits max. @@ -1276,7 +1764,7 @@ public final class BitsUtil { // Normalizes (x3 should be 32 bits max). long carry = x3 >>> 32; - if (carry != 0) { // Shift. + if(carry != 0) { // Shift. x0 = x1; x1 = x2; x2 = x3 & LONG_32_BITS; @@ -1286,14 +1774,15 @@ public final class BitsUtil { } // Merges registers to a 63 bits mantissa. - assert(x3 >= 0); + assert (x3 >= 0); int shift = 31 - magnitude(x3); // -1..30 pow2 -= shift; long mantissa = (shift < 0) ? (x3 << 31) | (x2 >>> 1) : // x3 is 32 bits. (((x3 << 32) | x2) << shift) | (x1 >>> (32 - shift)); return lpow2(mantissa, pow2); - } else { // n < 0 - if (n < -324 - 20) { + } + else { // n < 0 + if(n < -324 - 20) { return 0.; } @@ -1301,9 +1790,9 @@ public final class BitsUtil { long x1 = m; // 63 bits. long x0 = 0; // 63 bits. int pow2 = 0; - while (true) { + while(true) { // Normalizes x1:x0 - assert(x1 >= 0); + assert (x1 >= 0); int shift = 63 - magnitude(x1); x1 <<= shift; x1 |= x0 >>> (63 - shift); @@ -1311,7 +1800,7 @@ public final class BitsUtil { pow2 -= shift; // Checks if division has to be performed. - if (n == 0) { + if(n == 0) { break; // Done. } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java index a60bf15f..f1d7304e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ClassGenericsUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,6 +34,7 @@ import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; @@ -106,17 +107,22 @@ public final class ClassGenericsUtil { try { try { instance = type.cast(loader.loadClass(className).newInstance()); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // try package of type instance = type.cast(loader.loadClass(type.getPackage().getName() + "." + className).newInstance()); } - } catch (InstantiationException e) { + } + catch(InstantiationException e) { throw new UnableToComplyException(e); - } catch (IllegalAccessException e) { + } + catch(IllegalAccessException e) { throw new UnableToComplyException(e); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { throw new UnableToComplyException(e); - } catch (ClassCastException e) { + } + catch(ClassCastException e) { throw new UnableToComplyException(e); } return instance; @@ -152,17 +158,22 @@ public final class ClassGenericsUtil { try { try { instance = ((Class<T>) type).cast(loader.loadClass(className).newInstance()); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // try package of type instance = ((Class<T>) type).cast(loader.loadClass(type.getPackage().getName() + "." + className).newInstance()); } - } catch (InstantiationException e) { + } + catch(InstantiationException e) { throw new UnableToComplyException(e); - } catch (IllegalAccessException e) { + } + catch(IllegalAccessException e) { throw new UnableToComplyException(e); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { throw new UnableToComplyException(e); - } catch (ClassCastException e) { + } + catch(ClassCastException e) { throw new UnableToComplyException(e); } return instance; @@ -183,13 +194,13 @@ public final class ClassGenericsUtil { */ public static <C> Method getParameterizationFactoryMethod(Class<C> c, Class<?> ret) throws NoSuchMethodException { Method m = c.getMethod(FACTORY_METHOD_NAME, Parameterization.class); - if (m == null) { + if(m == null) { throw new NoSuchMethodException("No parameterization method found."); } - if (!ret.isAssignableFrom(m.getReturnType())) { + if(!ret.isAssignableFrom(m.getReturnType())) { throw new NoSuchMethodException("Return type doesn't match: " + m.getReturnType().getName() + ", expected: " + ret.getName()); } - if (!java.lang.reflect.Modifier.isStatic(m.getModifiers())) { + if(!java.lang.reflect.Modifier.isStatic(m.getModifiers())) { throw new NoSuchMethodException("Factory method is not static."); } return m; @@ -202,11 +213,12 @@ public final class ClassGenericsUtil { * @return Parameterizer or null. */ public static Parameterizer getParameterizer(Class<?> c) { - for (Class<?> inner : c.getDeclaredClasses()) { - if (Parameterizer.class.isAssignableFrom(inner)) { + for(Class<?> inner : c.getDeclaredClasses()) { + if(Parameterizer.class.isAssignableFrom(inner)) { try { return inner.asSubclass(Parameterizer.class).newInstance(); - } catch (Exception e) { + } + catch(Exception e) { LOG.warning("Non-usable Parameterizer in class: " + c.getName()); } } @@ -229,14 +241,14 @@ public final class ClassGenericsUtil { * @throws Exception when other instantiation errors occurred */ public static <C> C tryInstantiate(Class<C> r, Class<?> c, Parameterization config) throws InvocationTargetException, NoSuchMethodException, Exception { - if (c == null) { + if(c == null) { // TODO: better class? AbortException maybe? throw new UnsupportedOperationException("Trying to instantiate 'null' class!"); } // Try a V3 parameterization class Parameterizer par = getParameterizer(c); // TODO: API good? - if (par instanceof AbstractParameterizer) { + if(par instanceof AbstractParameterizer) { final Object instance = ((AbstractParameterizer) par).make(config); return r.cast(instance); } @@ -245,7 +257,8 @@ public final class ClassGenericsUtil { final Method factory = getParameterizationFactoryMethod(c, r); final Object instance = factory.invoke(null, config); return r.cast(instance); - } catch (NoSuchMethodException e) { + } + catch(NoSuchMethodException e) { // continue. } // Try a regular "parameterization" constructor @@ -253,7 +266,8 @@ public final class ClassGenericsUtil { final Constructor<?> constructor = c.getConstructor(Parameterization.class); final Object instance = constructor.newInstance(config); return r.cast(instance); - } catch (NoSuchMethodException e) { + } + catch(NoSuchMethodException e) { // continue } // Try a default constructor. @@ -275,8 +289,18 @@ public final class ClassGenericsUtil { @SuppressWarnings("unchecked") public static <C> C parameterizeOrAbort(Class<?> c, Parameterization config) { try { - return tryInstantiate((Class<C>) c, c, config); - } catch (Exception e) { + C ret = tryInstantiate((Class<C>) c, c, config); + if(ret == null) { + throw new AbortException("Could not instantiate class. Check parameters."); + } + return ret; + } + catch(Exception e) { + if (config.hasErrors()) { + for (ParameterException err : config.getErrors()) { + LOG.warning(err.toString()); + } + } throw new AbortException("Instantiation failed", e); } } @@ -324,7 +348,7 @@ public final class ClassGenericsUtil { @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T> ArrayList<T>[] newArrayOfEmptyArrayList(int len) { ArrayList[] result = new ArrayList[len]; - for (int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { result[i] = new ArrayList<>(); } return result; @@ -343,7 +367,7 @@ public final class ClassGenericsUtil { @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T> HashSet<T>[] newArrayOfEmptyHashSet(int len) { HashSet[] result = new HashSet[len]; - for (int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { result[i] = new HashSet<>(); } return result; @@ -398,8 +422,8 @@ public final class ClassGenericsUtil { */ @SuppressWarnings("unchecked") public static <BASE, FROM extends BASE, TO extends BASE> Class<TO> uglyCrossCast(Class<FROM> cls, Class<BASE> base) { - if (!base.isAssignableFrom(cls)) { - if (cls == null) { + if(!base.isAssignableFrom(cls)) { + if(cls == null) { throw new ClassCastException("Attempted to use 'null' as class."); } throw new ClassCastException(cls.getName() + " is not a superclass of " + base); @@ -424,7 +448,8 @@ public final class ClassGenericsUtil { public static <B, T extends B> T castWithGenericsOrNull(Class<B> base, Object obj) { try { return (T) base.cast(obj); - } catch (ClassCastException e) { + } + catch(ClassCastException e) { return null; } } @@ -445,7 +470,8 @@ public final class ClassGenericsUtil { try { Object n = obj.getClass().getConstructor().newInstance(); return (T) n; - } catch (NullPointerException e) { + } + catch(NullPointerException e) { throw new IllegalArgumentException("Null pointer exception in newInstance()", e); } } @@ -473,7 +499,7 @@ public final class ClassGenericsUtil { */ @SuppressWarnings("unchecked") public static <T> T[] newArray(Class<? extends T> k, int size) { - if (k.isPrimitive()) { + if(k.isPrimitive()) { throw new IllegalArgumentException("Argument cannot be primitive: " + k); } Object a = java.lang.reflect.Array.newInstance(k, size); @@ -505,13 +531,17 @@ public final class ClassGenericsUtil { C copy = newInstance(coll); copy.addAll(coll); return copy; - } catch (InstantiationException e) { + } + catch(InstantiationException e) { throw new RuntimeException(e); - } catch (IllegalAccessException e) { + } + catch(IllegalAccessException e) { throw new RuntimeException(e); - } catch (InvocationTargetException e) { + } + catch(InvocationTargetException e) { throw new RuntimeException(e); - } catch (NoSuchMethodException e) { + } + catch(NoSuchMethodException e) { throw new RuntimeException(e); } } @@ -525,15 +555,15 @@ public final class ClassGenericsUtil { * @return new array containing the collection elements */ public static <T> T[] collectionToArray(Collection<T> c, T[] a) { - if (a.length < c.size()) { + if(a.length < c.size()) { a = newArray(a, c.size()); } int i = 0; - for (T x : c) { + for(T x : c) { a[i] = x; i++; } - if (i < a.length) { + if(i < a.length) { a[i] = null; } return a; diff --git a/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java index baa90829..110b5bad 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/DatabaseUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,44 +23,32 @@ package de.lmu.ifi.dbs.elki.utilities; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Pattern; import de.lmu.ifi.dbs.elki.data.ClassLabel; -import de.lmu.ifi.dbs.elki.data.FeatureVector; import de.lmu.ifi.dbs.elki.data.LabelList; -import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException; import de.lmu.ifi.dbs.elki.data.type.TypeUtil; import de.lmu.ifi.dbs.elki.database.Database; -import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.ids.DBIDs; +import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery; +import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery; +import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery; +import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery; import de.lmu.ifi.dbs.elki.database.relation.ConvertToStringView; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; +import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; +import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor; /** * Class with Database-related utility functions such as centroid computation, * covariances etc. * * @author Erich Schubert - * - * @apiviz.landmark - * - * @apiviz.has RelationObjectIterator - * @apiviz.has CollectionFromRelation */ public final class DatabaseUtil { /** @@ -69,124 +57,6 @@ public final class DatabaseUtil { private DatabaseUtil() { // Do not instantiate! } - - /** - * Get the dimensionality of a relation. - * - * @param relation Relation - * @return Dimensionality - * - * @deprecated Use {@link RelationUtil#dimensionality(Relation)} instead! - */ - @Deprecated - public static <V extends FeatureVector<?>> int dimensionality(Relation<V> relation) { - return RelationUtil.dimensionality(relation); - } - - /** - * Determines the variances in each dimension of the specified objects stored - * in the given database. - * - * @param database the database storing the objects - * @param ids the ids of the objects - * @param centroid the centroid or reference vector of the ids - * @return the variances in each dimension of the specified objects - */ - public static double[] variances(Relation<? extends NumberVector<?>> database, NumberVector<?> centroid, DBIDs ids) { - final int size = ids.size(); - double[] variances = new double[centroid.getDimensionality()]; - - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - NumberVector<?> o = database.get(iter); - for (int d = 0; d < centroid.getDimensionality(); d++) { - final double diff = o.doubleValue(d) - centroid.doubleValue(d); - variances[d ] += diff * diff / size; - } - } - return variances; - } - - /** - * Determines the minimum and maximum values in each dimension of all objects - * stored in the given database. - * - * @param <NV> vector type - * @param relation the database storing the objects - * @return Minimum and Maximum vector for the hyperrectangle - */ - public static <NV extends NumberVector<?>> Pair<NV, NV> computeMinMax(Relation<NV> relation) { - int dim = RelationUtil.dimensionality(relation); - double[] mins = new double[dim]; - double[] maxs = new double[dim]; - for (int i = 0; i < dim; i++) { - mins[i] = Double.MAX_VALUE; - maxs[i] = -Double.MAX_VALUE; - } - for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { - final NV o = relation.get(iditer); - for (int d = 0; d < dim; d++) { - final double v = o.doubleValue(d); - mins[d] = Math.min(mins[d], v); - maxs[d] = Math.max(maxs[d], v); - } - } - NumberVector.Factory<NV, ?> factory = RelationUtil.getNumberVectorFactory(relation); - NV min = factory.newNumberVector(mins); - NV max = factory.newNumberVector(maxs); - return new Pair<>(min, max); - } - - /** - * Returns the median of a data set in the given dimension by using a sampling - * method. - * - * @param relation Relation to process - * @param ids DBIDs to process - * @param dimension Dimensionality - * @param numberOfSamples Number of samples to draw - * @return Median value - */ - public static <V extends NumberVector<?>> double quickMedian(Relation<V> relation, ArrayDBIDs ids, int dimension, int numberOfSamples) { - final int everyNthItem = (int) Math.max(1, Math.floor(ids.size() / (double) numberOfSamples)); - final double[] vals = new double[numberOfSamples]; - for (int i = 0; i < numberOfSamples; i++) { - final DBID id = ids.get(i * everyNthItem); - vals[i] = relation.get(id).doubleValue(dimension); - } - Arrays.sort(vals); - if (vals.length % 2 == 1) { - return vals[((vals.length + 1) >> 1) - 1]; - } else { - final double v1 = vals[vals.length >> 1]; - final double v2 = vals[(vals.length >> 1) - 1]; - return (v1 + v2) / 2.0; - } - } - - /** - * Returns the median of a data set in the given dimension. - * - * @param relation Relation to process - * @param ids DBIDs to process - * @param dimension Dimensionality - * @return Median value - */ - public static <V extends NumberVector<?>> double exactMedian(Relation<V> relation, DBIDs ids, int dimension) { - final double[] vals = new double[ids.size()]; - int i = 0; - for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) { - vals[i] = relation.get(iter).doubleValue(dimension); - i++; - } - Arrays.sort(vals); - if (vals.length % 2 == 1) { - return vals[((vals.length + 1) >> 1) - 1]; - } else { - final double v1 = vals[vals.length >> 1]; - final double v2 = vals[(vals.length >> 1) - 1]; - return (v1 + v2) / 2.0; - } - } /** * Guess a potentially label-like representation, preferring class labels. @@ -197,26 +67,29 @@ public final class DatabaseUtil { public static Relation<String> guessLabelRepresentation(Database database) throws NoSupportedDataTypeException { try { Relation<? extends ClassLabel> classrep = database.getRelation(TypeUtil.CLASSLABEL); - if (classrep != null) { + if(classrep != null) { return new ConvertToStringView(classrep); } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } try { Relation<? extends LabelList> labelsrep = database.getRelation(TypeUtil.LABELLIST); - if (labelsrep != null) { + if(labelsrep != null) { return new ConvertToStringView(labelsrep); } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } try { Relation<String> stringrep = database.getRelation(TypeUtil.STRING); - if (stringrep != null) { + if(stringrep != null) { return stringrep; } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } throw new NoSupportedDataTypeException("No label-like representation was found."); @@ -231,26 +104,29 @@ public final class DatabaseUtil { public static Relation<String> guessObjectLabelRepresentation(Database database) throws NoSupportedDataTypeException { try { Relation<? extends LabelList> labelsrep = database.getRelation(TypeUtil.LABELLIST); - if (labelsrep != null) { + if(labelsrep != null) { return new ConvertToStringView(labelsrep); } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } try { Relation<String> stringrep = database.getRelation(TypeUtil.STRING); - if (stringrep != null) { + if(stringrep != null) { return stringrep; } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } try { Relation<? extends ClassLabel> classrep = database.getRelation(TypeUtil.CLASSLABEL); - if (classrep != null) { + if(classrep != null) { return new ConvertToStringView(classrep); } - } catch (NoSupportedDataTypeException e) { + } + catch(NoSupportedDataTypeException e) { // retry. } throw new NoSupportedDataTypeException("No label-like representation was found."); @@ -265,7 +141,7 @@ public final class DatabaseUtil { */ public static SortedSet<ClassLabel> getClassLabels(Relation<? extends ClassLabel> database) { SortedSet<ClassLabel> labels = new TreeSet<>(); - for (DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) { + for(DBIDIter it = database.iterDBIDs(); it.valid(); it.advance()) { labels.add(database.get(it)); } return labels; @@ -284,83 +160,6 @@ public final class DatabaseUtil { } /** - * Do a cheap guess at the databases object class. - * - * @param <O> Restriction type - * @param database Database - * @return Class of first object in the Database. - */ - @SuppressWarnings("unchecked") - public static <O> Class<? extends O> guessObjectClass(Relation<O> database) { - return (Class<? extends O>) database.get(database.iterDBIDs()).getClass(); - } - - /** - * Do a full inspection of the database to find the base object class. - * - * Note: this can be an abstract class or interface! - * - * TODO: Implement a full search for shared superclasses. But since currently - * the databases will always use only once class, this is not yet implemented. - * - * @param <O> Restriction type - * @param database Database - * @return Superclass of all objects in the database - */ - public static <O> Class<?> getBaseObjectClassExpensive(Relation<O> database) { - List<Class<?>> candidates = new ArrayList<>(); - DBIDIter iditer = database.iterDBIDs(); - // empty database?! - if (!iditer.valid()) { - return null; - } - // put first class into result set. - candidates.add(database.get(iditer).getClass()); - iditer.advance(); - // other objects - for (; iditer.valid(); iditer.advance()) { - Class<?> newcls = database.get(iditer).getClass(); - // validate all candidates - Iterator<Class<?>> ci = candidates.iterator(); - while (ci.hasNext()) { - Class<?> cand = ci.next(); - if (cand.isAssignableFrom(newcls)) { - continue; - } - // TODO: resolve conflicts by finding all superclasses! - // Does this code here work? - for (Class<?> interf : cand.getInterfaces()) { - candidates.add(interf); - } - candidates.add(cand.getSuperclass()); - ci.remove(); - } - } - // if we have any candidates left ... - if (candidates.size() > 0) { - // remove subclasses - Iterator<Class<?>> ci = candidates.iterator(); - while (ci.hasNext()) { - Class<?> cand = ci.next(); - for (Class<?> oc : candidates) { - if (!oc.equals(cand) && cand.isAssignableFrom(oc)) { - ci.remove(); - break; - } - } - } - assert (candidates.size() > 0); - try { - return candidates.get(0); - } catch (ClassCastException e) { - // ignore, and retry with next - } - } - // no resulting class. - return null; - } - - /** * Find object by matching their labels. * * @param database Database to search in @@ -369,12 +168,12 @@ public final class DatabaseUtil { */ public static ArrayModifiableDBIDs getObjectsByLabelMatch(Database database, Pattern name_pattern) { Relation<String> relation = guessLabelRepresentation(database); - if (name_pattern == null) { + if(name_pattern == null) { return DBIDUtil.newArray(); } ArrayModifiableDBIDs ret = DBIDUtil.newArray(); - for (DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { - if (name_pattern.matcher(relation.get(iditer)).find()) { + for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) { + if(name_pattern.matcher(relation.get(iditer)).find()) { ret.add(iditer); } } @@ -382,104 +181,45 @@ public final class DatabaseUtil { } /** - * An ugly vector type cast unavoidable in some situations due to Generics. + * Get (or create) a precomputed kNN query for the database. * - * @param <V> Base vector type - * @param <T> Derived vector type (is actually V, too) * @param database Database - * @return Database - */ - @SuppressWarnings("unchecked") - public static <V extends NumberVector<?>, T extends NumberVector<?>> Relation<V> relationUglyVectorCast(Relation<T> database) { - return (Relation<V>) database; - } - - /** - * Iterator class that retrieves the given objects from the database. - * - * @author Erich Schubert + * @param relation Relation + * @param dq Distance query + * @param k required number of neighbors + * @return KNNQuery for the given relation, that is precomputed. */ - public static class RelationObjectIterator<O> implements Iterator<O> { - /** - * The real iterator. - */ - final DBIDIter iter; - - /** - * The database we use. - */ - final Relation<? extends O> database; - - /** - * Full Constructor. - * - * @param iter Original iterator. - * @param database Database - */ - public RelationObjectIterator(DBIDIter iter, Relation<? extends O> database) { - super(); - this.iter = iter; - this.database = database; - } - - /** - * Simplified constructor. - * - * @param database Database - */ - public RelationObjectIterator(Relation<? extends O> database) { - super(); - this.database = database; - this.iter = database.iterDBIDs(); - } - - @Override - public boolean hasNext() { - return iter.valid(); - } - - @Override - public O next() { - O ret = database.get(iter); - iter.advance(); - return ret; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); + public static <O> KNNQuery<O> precomputedKNNQuery(Database database, Relation<O> relation, DistanceQuery<O> dq, int k) { + // "HEAVY" flag for knn query since it is used more than once + KNNQuery<O> knnq = database.getKNNQuery(dq, k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE); + // No optimized kNN query - use a preprocessor! + if(knnq instanceof PreprocessorKNNQuery) { + return knnq; } + MaterializeKNNPreprocessor<O> preproc = new MaterializeKNNPreprocessor<>(relation, dq.getDistanceFunction(), k); + preproc.initialize(); + return preproc.getKNNQuery(dq, k); } /** - * Collection view on a database that retrieves the objects when needed. + * Get (or create) a precomputed kNN query for the database. * - * @author Erich Schubert - */ - public static class CollectionFromRelation<O> extends AbstractCollection<O> implements Collection<O> { - /** - * The database we query. - */ - Relation<? extends O> db; - - /** - * Constructor. - * - * @param db Database - */ - public CollectionFromRelation(Relation<? extends O> db) { - super(); - this.db = db; - } - - @Override - public Iterator<O> iterator() { - return new DatabaseUtil.RelationObjectIterator<>(db); - } - - @Override - public int size() { - return db.size(); - } + * @param database Database + * @param relation Relation + * @param distf Distance function + * @param k required number of neighbors + * @return KNNQuery for the given relation, that is precomputed. + */ + public static <O> KNNQuery<O> precomputedKNNQuery(Database database, Relation<O> relation, DistanceFunction<? super O> distf, int k) { + DistanceQuery<O> dq = database.getDistanceQuery(relation, distf); + // "HEAVY" flag for knn query since it is used more than once + KNNQuery<O> knnq = database.getKNNQuery(dq, k, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE); + // No optimized kNN query - use a preprocessor! + if(knnq instanceof PreprocessorKNNQuery) { + return knnq; + } + MaterializeKNNPreprocessor<O> preproc = new MaterializeKNNPreprocessor<>(relation, dq.getDistanceFunction(), k); + preproc.initialize(); + return preproc.getKNNQuery(dq, k); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java b/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java index d42b2834..ce40e988 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ELKIServiceLoader.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,6 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities; */ import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; @@ -50,7 +51,7 @@ public class ELKIServiceLoader implements Iterator<Class<?>> { /** * Prefix for the ELKI functionality discovery. */ - public static final String PREFIX = "META-INF/elki/"; + public static final String PREFIX = "META-INF" + File.separator + "elki" + File.separator; /** * Comment character @@ -112,19 +113,20 @@ public class ELKIServiceLoader implements Iterator<Class<?>> { try { String fullName = PREFIX + parent.getName(); configfiles = cl.getResources(fullName); - } catch (IOException x) { + } + catch(IOException x) { throw new AbortException("Could not load service configuration files.", x); } } @Override public boolean hasNext() { - if (nextclass != null) { + if(nextclass != null) { return true; } // Find next iterator - while ((curiter == null) || !curiter.hasNext()) { - if (!configfiles.hasMoreElements()) { + while((curiter == null) || !curiter.hasNext()) { + if(!configfiles.hasMoreElements()) { return false; } curiter = parseFile(configfiles.nextElement()); @@ -137,52 +139,55 @@ public class ELKIServiceLoader implements Iterator<Class<?>> { ArrayList<Class<?>> classes = new ArrayList<>(); try { BufferedReader r = new BufferedReader(new InputStreamReader(nextElement.openStream(), "utf-8")); - while (parseLine(r.readLine(), classes, nextElement)) { + while(parseLine(r.readLine(), classes, nextElement)) { // Continue } - } catch (IOException x) { + } + catch(IOException x) { throw new AbortException("Error reading configuration file", x); } return classes.iterator(); } private boolean parseLine(String line, ArrayList<Class<?>> classes, URL nextElement) { - if (line == null) { + if(line == null) { return false; } // Ignore comments, trim whitespace { int begin = 0; int end = line.indexOf(COMMENT_CHAR); - if (end < 0) { + if(end < 0) { end = line.length(); } - while (begin < end && line.charAt(begin) == ' ') { + while(begin < end && line.charAt(begin) == ' ') { begin++; } - while (end - 1 > begin && line.charAt(end - 1) == ' ') { + while(end - 1 > begin && line.charAt(end - 1) == ' ') { end--; } - if (begin > 0 || end < line.length()) { + if(begin > 0 || end < line.length()) { line = line.substring(begin, end); } } - if (line.length() <= 0) { + if(line.length() <= 0) { return true; // Empty/comment lines are okay, continue } // Try to load the class try { Class<?> cls = cl.loadClass(line); // Should not happen. Check anyway. - if (cls == null) { + if(cls == null) { return true; } - if (parent.isAssignableFrom(cls)) { + if(parent.isAssignableFrom(cls)) { classes.add(cls); - } else { + } + else { LOG.warning("Class " + line + " does not implement " + parent + " but listed in service file " + nextElement); } - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { LOG.warning("Class not found: " + line + "; listed in service file " + nextElement, e); } return true; diff --git a/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java index 5c3c78b5..63f842c4 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/FileUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -68,11 +68,11 @@ public final class FileUtil { * <code>null</code> */ public static String getFilenameExtension(String name) { - if (name == null) { + if(name == null) { return null; } int index = name.lastIndexOf('.'); - if (index >= name.length() - 1) { + if(index >= name.length() - 1) { return null; } return name.substring(name.lastIndexOf('.') + 1).toLowerCase(); @@ -89,11 +89,12 @@ public final class FileUtil { public static InputStream openSystemFile(String filename) throws FileNotFoundException { try { return new FileInputStream(filename); - } catch (FileNotFoundException e) { + } + catch(FileNotFoundException e) { // try with classloader String resname = filename.replace(File.separatorChar, '/'); InputStream result = ClassLoader.getSystemResourceAsStream(resname); - if (result == null) { + if(result == null) { throw e; } return result; @@ -111,25 +112,24 @@ public final class FileUtil { */ public static InputStream tryGzipInput(InputStream in) throws IOException { // try autodetecting gzip compression. - if (!in.markSupported()) { + if(!in.markSupported()) { PushbackInputStream pb = new PushbackInputStream(in, 16); in = pb; // read a magic from the file header byte[] magic = { 0, 0 }; pb.read(magic); pb.unread(magic); - if (magic[0] == 31 && magic[1] == -117) { - in = new GZIPInputStream(pb); - } - } else { - in.mark(16); - if (in.read() == 31 && in.read() == -117) { - in.reset(); - in = new GZIPInputStream(in); - } else { - // just rewind the stream - in.reset(); + if(magic[0] == 31 && magic[1] == -117) { + return new GZIPInputStream(pb); } + return in; + } + // Mark is supported. + in.mark(16); + boolean isgzip = (in.read() == 31 && in.read() == -117); + in.reset(); // Rewind + if(isgzip) { + in = new GZIPInputStream(in); } return in; } @@ -144,24 +144,24 @@ public final class FileUtil { public static File locateFile(String name, String basedir) { // Try exact match first. File f = new File(name); - if (f.exists()) { + if(f.exists()) { return f; } // Try with base directory - if (basedir != null) { + if(basedir != null) { f = new File(basedir, name); // logger.warning("Trying: "+f.getAbsolutePath()); - if (f.exists()) { + if(f.exists()) { return f; } } // try stripping whitespace { String name2 = name.trim(); - if (!name.equals(name2)) { + if(!name.equals(name2)) { // logger.warning("Trying without whitespace."); f = locateFile(name2, basedir); - if (f != null) { + if(f != null) { return f; } } @@ -169,27 +169,27 @@ public final class FileUtil { // try substituting path separators { String name2 = name.replace('/', File.separatorChar); - if (!name.equals(name2)) { + if(!name.equals(name2)) { // logger.warning("Trying with replaced separators."); f = locateFile(name2, basedir); - if (f != null) { + if(f != null) { return f; } } name2 = name.replace('\\', File.separatorChar); - if (!name.equals(name2)) { + if(!name.equals(name2)) { // logger.warning("Trying with replaced separators."); f = locateFile(name2, basedir); - if (f != null) { + if(f != null) { return f; } } } // try stripping extra characters, such as quotes. - if (name.length() > 2 && name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') { + if(name.length() > 2 && name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') { // logger.warning("Trying without quotes."); f = locateFile(name.substring(1, name.length() - 1), basedir); - if (f != null) { + if(f != null) { return f; } } @@ -207,7 +207,7 @@ public final class FileUtil { public static String slurp(InputStream is) throws IOException { StringBuilder buf = new StringBuilder(); final byte[] b = new byte[4096]; - for (int n; (n = is.read(b)) != -1;) { + for(int n; (n = is.read(b)) != -1;) { buf.append(new String(b, 0, n)); } is.close(); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java index 4601cce9..2599a3a5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/FormatUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.Formatter; +import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -56,6 +57,11 @@ public final class FormatUtil { public static final NumberFormat NF2 = NumberFormat.getInstance(Locale.US); /** + * Number Formatter (3 digits) for output purposes. + */ + public static final NumberFormat NF3 = NumberFormat.getInstance(Locale.US); + + /** * Number Formatter (4 digits) for output purposes. */ public static final NumberFormat NF4 = NumberFormat.getInstance(Locale.US); @@ -80,6 +86,9 @@ public final class FormatUtil { NF2.setMinimumFractionDigits(2); NF2.setMaximumFractionDigits(2); NF2.setGroupingUsed(false); + NF3.setMinimumFractionDigits(3); + NF3.setMaximumFractionDigits(3); + NF3.setGroupingUsed(false); NF4.setMinimumFractionDigits(4); NF4.setMaximumFractionDigits(4); NF4.setGroupingUsed(false); @@ -122,39 +131,34 @@ public final class FormatUtil { private static final int[] TIME_UNIT_DIGITS = new int[] { 3, 2, 2, 2, 2 }; /** - * Formats the double d with the specified fraction digits. + * Initialize a number format with ELKI standard options (US locale, no + * grouping). * - * @param d the double array to be formatted - * @param digits the number of fraction digits - * @return a String representing the double d - */ - public static String format(final double d, int digits) { + * @param digits Number of digits to use + * @return Number format + */ + public static NumberFormat makeNumberFormat(int digits) { + // Prefer predefined number formats where applicable. + // TODO: cache others, too? + switch(digits){ + case 0: + return NF0; + case 2: + return NF2; + case 3: + return NF3; + case 4: + return NF4; + case 6: + return NF6; + case 8: + return NF8; + } final NumberFormat nf = NumberFormat.getInstance(Locale.US); nf.setMaximumFractionDigits(digits); nf.setMinimumFractionDigits(digits); nf.setGroupingUsed(false); - return nf.format(d); - } - - /** - * Formats the double d with the specified number format. - * - * @param d the double array to be formatted - * @param nf the number format to be used for formatting - * @return a String representing the double d - */ - public static String format(final double d, NumberFormat nf) { - return nf.format(d); - } - - /** - * Formats the double d with 2 fraction digits. - * - * @param d the double to be formatted - * @return a String representing the double d - */ - public static String format(final double d) { - return format(d, 2); + return nf; } /** @@ -166,50 +170,37 @@ public final class FormatUtil { * @return a String representing the double array d */ public static String format(double[] d, String sep) { - StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < d.length; i++) { - if(i > 0) { - buffer.append(sep).append(d[i]); - } - else { - buffer.append(d[i]); - } + if(d.length == 0) { + return ""; } - return buffer.toString(); + return formatTo(new StringBuilder(), d, sep).toString(); } /** - * Formats the double array d with the specified separator and the specified - * fraction digits. + * Formats the double array d with the specified number format. * * @param d the double array to be formatted - * @param sep the separator between the single values of the double array, - * e.g. ',' - * @param digits the number of fraction digits + * @param nf the number format to be used for formatting * @return a String representing the double array d */ - public static String format(double[] d, String sep, int digits) { - StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < d.length; i++) { - if(i < d.length - 1) { - buffer.append(format(d[i], digits)).append(sep); - } - else { - buffer.append(format(d[i], digits)); - } - } - return buffer.toString(); + public static String format(double[] d, NumberFormat nf) { + return format(d, " ", nf); } /** * Formats the double array d with the specified number format. * * @param d the double array to be formatted + * @param sep the separator between the single values of the double array, + * e.g. ',' * @param nf the number format to be used for formatting * @return a String representing the double array d */ - public static String format(double[] d, NumberFormat nf) { - return format(d, " ", nf); + public static String format(double[] d, String sep, NumberFormat nf) { + if(d.length == 0) { + return ""; + } + return formatTo(new StringBuilder(), d, sep, nf).toString(); } /** @@ -218,42 +209,49 @@ public final class FormatUtil { * @param d the double array to be formatted * @param sep the separator between the single values of the double array, * e.g. ',' - * @param nf the number format to be used for formatting * @return a String representing the double array d */ - public static String format(double[] d, String sep, NumberFormat nf) { - StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < d.length; i++) { - if(i < d.length - 1) { - buffer.append(format(d[i], nf)).append(sep); - } - else { - buffer.append(format(d[i], nf)); - } + public static StringBuilder formatTo(StringBuilder a, double[] d, String sep) { + if(d.length == 0) { + return a; } - return buffer.toString(); + a.append(d[0]); + for(int i = 1; i < d.length; i++) { + a.append(sep); + a.append(d[i]); + } + return a; } /** - * Formats the double array d with ',' as separator and 2 fraction digits. + * Formats the double array d with the specified number format. * * @param d the double array to be formatted + * @param sep the separator between the single values of the double array, + * e.g. ',' + * @param nf the number format to be used for formatting * @return a String representing the double array d */ - public static String format(double[] d) { - return format(d, ", ", 2); + public static StringBuilder formatTo(StringBuilder a, double[] d, String sep, NumberFormat nf) { + if(d.length == 0) { + return a; + } + a.append(nf.format(d[0])); + for(int i = 1; i < d.length; i++) { + a.append(sep); + a.append(nf.format(d[i])); + } + return a; } /** - * Formats the double array d with ', ' as separator and with the specified - * fraction digits. + * Formats the double array d with ', ' as separator and 2 fraction digits. * * @param d the double array to be formatted - * @param digits the number of fraction digits * @return a String representing the double array d */ - public static String format(double[] d, int digits) { - return format(d, ", ", digits); + public static String format(double[] d) { + return formatTo(new StringBuilder(), d, ", ").toString(); } /** @@ -263,11 +261,7 @@ public final class FormatUtil { * @return a String representing the double array d */ public static String format(double[][] d) { - StringBuilder buffer = new StringBuilder(); - for(double[] array : d) { - buffer.append(format(array, ", ", 2)).append('\n'); - } - return buffer.toString(); + return format(d, "\n", ", ", NF2); } /** @@ -277,110 +271,40 @@ public final class FormatUtil { * @param d the double array to be formatted * @param sep1 the first separator of the outer array * @param sep2 the second separator of the inner array - * @param digits the number of fraction digits + * @param nf the number format to use * @return a String representing the double array d */ - public static String format(double[][] d, String sep1, String sep2, int digits) { - StringBuilder buffer = new StringBuilder(); - - for(int i = 0; i < d.length; i++) { - if(i < d.length - 1) { - buffer.append(format(d[i], sep2, digits)).append(sep1); - } - else { - buffer.append(format(d[i], sep2, digits)); - } + public static String format(double[][] d, String sep1, String sep2, NumberFormat nf) { + if(d.length == 0) { + return ""; } - - return buffer.toString(); - } - - /** - * Formats the Double array f with the specified separator and the specified - * fraction digits. - * - * @param f the Double array to be formatted - * @param sep the separator between the single values of the Double array, - * e.g. ',' - * @param digits the number of fraction digits - * @return a String representing the Double array f - */ - public static String format(Double[] f, String sep, int digits) { StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < f.length; i++) { - if(i < f.length - 1) { - buffer.append(format(f[i].doubleValue(), digits)).append(sep); - } - else { - buffer.append(format(f[i].doubleValue(), digits)); - } + formatTo(buffer, d[0], sep2, nf); + for(int i = 1; i < d.length; i++) { + buffer.append(sep1); + formatTo(buffer, d[i], sep2, nf); } return buffer.toString(); } /** - * Formats the Double array f with ',' as separator and 2 fraction digits. - * - * @param f the Double array to be formatted - * @return a String representing the Double array f - */ - public static String format(Double[] f) { - return format(f, ", ", 2); - } - - /** - * Formats the Double array f with the specified separator and the specified - * fraction digits. + * Formats the double array d with the specified number format. * - * @param f the Double array to be formatted - * @param sep the separator between the single values of the Double array, + * @param d the double array to be formatted + * @param sep the separator between the single values of the double array, * e.g. ',' - * @param nf the number format - * @return a String representing the Double array f + * @param nf the number format to be used for formatting + * @return a String representing the double array d */ - public static String format(Double[] f, String sep, NumberFormat nf) { - StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < f.length; i++) { - if(i < f.length - 1) { - buffer.append(format(f[i].doubleValue(), nf)).append(sep); - } - else { - buffer.append(format(f[i].doubleValue(), nf)); - } + public static String format(float[] d, String sep, NumberFormat nf) { + if(d.length == 0) { + return ""; } - return buffer.toString(); - } - - /** - * Formats the Double array f with ',' as separator and 2 fraction digits. - * - * @param f the Double array to be formatted - * @param nf the Number format - * @return a String representing the Double array f - */ - public static String format(Double[] f, NumberFormat nf) { - return format(f, ", ", nf); - } - - /** - * Formats the float array f with the specified separator and the specified - * fraction digits. - * - * @param f the float array to be formatted - * @param sep the separator between the single values of the float array, e.g. - * ',' - * @param digits the number of fraction digits - * @return a String representing the float array f - */ - public static String format(float[] f, String sep, int digits) { StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < f.length; i++) { - if(i < f.length - 1) { - buffer.append(format(f[i], digits)).append(sep); - } - else { - buffer.append(format(f[i], digits)); - } + buffer.append(nf.format((double) d[0])); + for(int i = 1; i < d.length; i++) { + buffer.append(sep); + buffer.append(nf.format((double) d[i])); } return buffer.toString(); } @@ -392,7 +316,7 @@ public final class FormatUtil { * @return a String representing the float array f */ public static String format(float[] f) { - return format(f, ", ", 2); + return format(f, ", ", NF2); } /** @@ -404,14 +328,14 @@ public final class FormatUtil { * @return a String representing the int array a */ public static String format(int[] a, String sep) { + if(a.length == 0) { + return ""; + } StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < a.length; i++) { - if(i < a.length - 1) { - buffer.append(a[i]).append(sep); - } - else { - buffer.append(a[i]); - } + buffer.append(a[0]); + for(int i = 1; i < a.length; i++) { + buffer.append(sep); + buffer.append(a[i]); } return buffer.toString(); } @@ -427,51 +351,20 @@ public final class FormatUtil { } /** - * Formats the Integer array a for printing purposes. - * - * @param a the Integer array to be formatted - * @param sep the separator between the single values of the float array, e.g. - * ',' - * @return a String representing the Integer array a - */ - public static String format(Integer[] a, String sep) { - StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < a.length; i++) { - if(i < a.length - 1) { - buffer.append(a[i]).append(sep); - } - else { - buffer.append(a[i]); - } - } - return buffer.toString(); - } - - /** - * Formats the Integer array a for printing purposes. - * - * @param a the Integer array to be formatted - * @return a String representing the Integer array a - */ - public static String format(Integer[] a) { - return format(a, ", "); - } - - /** * Formats the long array a for printing purposes. * * @param a the long array to be formatted * @return a String representing the long array a */ public static String format(long[] a) { + if(a.length == 0) { + return ""; + } StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < a.length; i++) { - if(i < a.length - 1) { - buffer.append(a[i]).append(", "); - } - else { - buffer.append(a[i]); - } + buffer.append(a[0]); + for(int i = 1; i < a.length; i++) { + buffer.append(", "); + buffer.append(a[i]); } return buffer.toString(); } @@ -483,14 +376,14 @@ public final class FormatUtil { * @return a String representing the byte array a */ public static String format(byte[] a) { + if(a.length == 0) { + return ""; + } StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < a.length; i++) { - if(i < a.length - 1) { - buffer.append(a[i]).append(", "); - } - else { - buffer.append(a[i]); - } + buffer.append(a[0]); + for(int i = 1; i < a.length; i++) { + buffer.append(", "); + buffer.append(a[i]); } return buffer.toString(); } @@ -504,14 +397,14 @@ public final class FormatUtil { * @return a String representing the boolean array b */ public static String format(boolean[] b, final String sep) { + if(b.length == 0) { + return ""; + } StringBuilder buffer = new StringBuilder(); - for(int i = 0; i < b.length; i++) { - if(i < b.length - 1) { - buffer.append(format(b[i])).append(sep); - } - else { - buffer.append(format(b[i])); - } + buffer.append(format(b[0])); + for(int i = 1; i < b.length; i++) { + buffer.append(sep); + buffer.append(format(b[i])); } return buffer.toString(); } @@ -523,10 +416,7 @@ public final class FormatUtil { * @return a String representing of the boolean b */ public static String format(final boolean b) { - if(b) { - return "1"; - } - return "0"; + return b ? "1" : "0"; } /** @@ -539,19 +429,11 @@ public final class FormatUtil { */ public static String format(BitSet bitSet, int dim, String sep) { StringBuilder msg = new StringBuilder(); - - for(int d = 0; d < dim; d++) { - if(d > 0) { - msg.append(sep); - } - if(bitSet.get(d)) { - msg.append('1'); - } - else { - msg.append('0'); - } + msg.append(bitSet.get(0) ? '1' : '0'); + for(int d = 1; d < dim; d++) { + msg.append(sep); + msg.append(bitSet.get(d) ? '1' : '0'); } - return msg.toString(); } @@ -583,13 +465,11 @@ public final class FormatUtil { return d.iterator().next(); } StringBuilder buffer = new StringBuilder(); - boolean first = true; - for(String str : d) { - if(!first) { - buffer.append(sep); - } - buffer.append(str); - first = false; + Iterator<String> it = d.iterator(); + buffer.append(it.next()); + while(it.hasNext()) { + buffer.append(sep); + buffer.append(it.next()); } return buffer.toString(); } @@ -745,7 +625,11 @@ public final class FormatUtil { * given NumberFormat */ public static String format(Vector m, NumberFormat nf) { - return "[" + FormatUtil.format(m.getArrayRef(), nf) + "]"; + StringBuilder buf = new StringBuilder(); + buf.append('['); + formatTo(buf, m.getArrayRef(), ", ", nf); + buf.append(']'); + return buf.toString(); } /** @@ -754,7 +638,7 @@ public final class FormatUtil { * @return String representation of this Vector */ public static String format(Vector m) { - return format(m, FormatUtil.NF); + return format(m.getArrayRef()); } /** @@ -1025,6 +909,18 @@ public final class FormatUtil { /** * Preallocated exceptions. */ + private static final NumberFormatException EMPTY_STRING = new NumberFormatException("Parser called on an empty string.") { + private static final long serialVersionUID = 1L; + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + }; + + /** + * Preallocated exceptions. + */ private static final NumberFormatException EXPONENT_OVERFLOW = new NumberFormatException("Precision overflow for double exponent.") { private static final long serialVersionUID = 1L; @@ -1111,6 +1007,9 @@ public final class FormatUtil { * @return Double value */ public static double parseDouble(final CharSequence str, final int start, final int end) { + if(start >= end) { + throw EMPTY_STRING; + } // Current position and character. int pos = start; char cur = str.charAt(pos); @@ -1165,7 +1064,7 @@ public final class FormatUtil { // Reads exponent. int exp = 0; - if((pos < end) && ((cur == 'E') || (cur == 'e'))) { + if((pos + 1 < end) && ((cur == 'E') || (cur == 'e'))) { cur = str.charAt(++pos); final boolean isNegativeExp = (cur == '-'); if((isNegativeExp || (cur == '+')) && (++pos < end)) { @@ -1211,6 +1110,122 @@ public final class FormatUtil { } /** + * Parse a double from a character sequence. + * + * In contrast to Javas {@link Double#parseDouble}, this will <em>not</em> + * create an object and thus is expected to put less load on the garbage + * collector. It will accept some more spellings of NaN and infinity, thus + * removing the need for checking for these independently. + * + * @param str String + * @param start Begin + * @param end End + * @return Double value + */ + public static double parseDouble(final byte[] str, final int start, final int end) { + if(start >= end) { + throw EMPTY_STRING; + } + // Current position and character. + int pos = start; + byte cur = str[pos]; + + // Match for NaN spellings + if(matchNaN(str, cur, pos, end)) { + return Double.NaN; + } + // Match sign + boolean isNegative = (cur == '-'); + // Carefully consume the - character, update c and i: + if((isNegative || (cur == '+')) && (++pos < end)) { + cur = str[pos]; + } + if(matchInf(str, cur, pos, end)) { + return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } + + // Begin parsing real numbers! + if(((cur < '0') || (cur > '9')) && (cur != '.')) { + throw NOT_A_NUMBER; + } + + // Parse digits into a long, remember offset of decimal point. + long decimal = 0; + int decimalPoint = -1; + while(true) { + final int digit = cur - '0'; + if((digit >= 0) && (digit <= 9)) { + final long tmp = (decimal << 3) + (decimal << 1) + digit; + if((decimal > MAX_LONG_OVERFLOW) || (tmp < decimal)) { + throw PRECISION_OVERFLOW; + } + decimal = tmp; + } + else if((cur == '.') && (decimalPoint < 0)) { + decimalPoint = pos; + } + else { // No more digits, or a second dot. + break; + } + if(++pos < end) { + cur = str[pos]; + } + else { + break; + } + } + // We need the offset from the back for adjusting the exponent: + // Note that we need the current value of i! + decimalPoint = (decimalPoint >= 0) ? pos - decimalPoint - 1 : 0; + + // Reads exponent. + int exp = 0; + if((pos + 1 < end) && ((cur == 'E') || (cur == 'e'))) { + cur = str[++pos]; + final boolean isNegativeExp = (cur == '-'); + if((isNegativeExp || (cur == '+')) && (++pos < end)) { + cur = str[pos]; + } + if((cur < '0') || (cur > '9')) { // At least one digit required. + throw INVALID_EXPONENT; + } + while(true) { + final int digit = cur - '0'; + if((digit >= 0) && (digit < 10)) { + final int tmp = (exp << 3) + (exp << 1) + digit; + // Actually, double can only handle Double.MAX_EXPONENT? How about + // subnormal? + if((exp > MAX_INT_OVERFLOW) || (tmp < exp)) { + throw EXPONENT_OVERFLOW; + } + exp = tmp; + } + else { + break; + } + if(++pos < end) { + cur = str[pos]; + } + else { + break; + } + } + if(isNegativeExp) { + exp = -exp; + } + } + // Adjust exponent by the offset of the dot in our long. + if(decimalPoint >= 0) { + exp = exp - decimalPoint; + } + if(pos != end) { + throw TRAILING_CHARACTERS; + } + + return BitsUtil.lpow10(isNegative ? -decimal : decimal, exp); + } + + /** * Match "NaN" in a number of different capitalizations. * * @param str String to match @@ -1243,6 +1258,38 @@ public final class FormatUtil { } /** + * Match "NaN" in a number of different capitalizations. + * + * @param str String to match + * @param firstchar First character + * @param start Interval begin + * @param end Interval end + * @return {@code true} when NaN was recognized. + */ + private static boolean matchNaN(byte[] str, byte firstchar, int start, int end) { + final int len = end - start; + if(len < 2 || len > 3) { + return false; + } + if(firstchar != 'N' && firstchar != 'n') { + return false; + } + final byte c1 = str[start + 1]; + if(c1 != 'a' && c1 != 'A') { + return false; + } + // Accept just "NA", too: + if(len == 2) { + return true; + } + final byte c2 = str[start + 2]; + if(c2 != 'N' && c2 != 'n') { + return false; + } + return true; + } + + /** * Maximum long that we can process without overflowing. */ private static final long MAX_LONG_OVERFLOW = Long.MAX_VALUE / 10; @@ -1297,6 +1344,40 @@ public final class FormatUtil { } /** + * Match "inf", "infinity" in a number of different capitalizations. + * + * @param str String to match + * @param firstchar First character + * @param start Interval begin + * @param end Interval end + * @return {@code true} when infinity was recognized. + */ + private static boolean matchInf(byte[] str, byte firstchar, int start, int end) { + final int len = end - start; + // The wonders of unicode. This is more than one byte on UTF-8 + if(len == 1 && firstchar == '∞') { + return true; + } + if(len != 3 && len != INFINITY_LENGTH) { + return false; + } + // Test beginning: "inf" + if(firstchar != 'I' && firstchar != 'i') { + return false; + } + for(int i = 1, j = INFINITY_LENGTH + 1; i < INFINITY_LENGTH; i++, j++) { + final byte c = str[start + i]; + if(c != INFINITY_PATTERN[i] && c != INFINITY_PATTERN[j]) { + return false; + } + if(i == 2 && len == 3) { + return true; + } + } + return true; + } + + /** * Parse a long integer from a character sequence. * * @param str String @@ -1348,4 +1429,143 @@ public final class FormatUtil { return isNegative ? -decimal : decimal; } + + /** + * Format a boolean value as string "true" or "false". + * + * @param b Boolean to Format + * @param buf Buffer to append to + * @return Same buffer + */ + public static StringBuilder format(boolean b, StringBuilder buf) { + return buf.append(b ? "true" : "false"); + } + + /** + * Format a boolean value as string "1" or "0". + * + * @param b Boolean to Format + * @param buf Buffer to append to + * @return Same buffer + */ + public static StringBuilder formatBit(boolean b, StringBuilder buf) { + return buf.append(b ? '1' : '0'); + } + + /** + * Format an integer value as decimal. + * + * @param i Integer value to format. + * @param buf Buffer to append to + * @return Same buffer + */ + public static StringBuilder format(int i, StringBuilder buf) { + // Int seems to be well optimized + return buf.append(i); + } + + /** + * Format a long value as decimal. + * + * @param i Long value to format. + * @param buf Buffer to append to + * @return Same buffer + */ + public static StringBuilder format(long i, StringBuilder buf) { + // Long seems to be well optimized + return buf.append(i); + } + + /** + * Buffer for zero padding. + */ + private static final char[] ZEROPADDING = new char[] { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' }; + + /** + * Buffer for whitespace padding. + */ + private static final char[] SPACEPADDING = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; + + /** + * Append zeros to a buffer. + * + * @param buf Buffer to append to + * @param zeros Number of zeros to append. + * @return Buffer + */ + public static StringBuilder appendZeros(StringBuilder buf, int zeros) { + for(int i = zeros; i > 0; i -= ZEROPADDING.length) { + buf.append(ZEROPADDING, 0, i < ZEROPADDING.length ? i : ZEROPADDING.length); + } + return buf; + } + + /** + * Append whitespace to a buffer. + * + * @param buf Buffer to append to + * @param spaces Number of spaces to append. + * @return Buffer + */ + public static StringBuilder appendSpace(StringBuilder buf, int spaces) { + for(int i = spaces; i > 0; i -= SPACEPADDING.length) { + buf.append(SPACEPADDING, 0, i < SPACEPADDING.length ? i : SPACEPADDING.length); + } + return buf; + } + + /** + * Compute the number of characters needed to represent the integer x. + * + * Reimplementation of {@link Long#stringSize}, but public and without loop. + * + * @param x Integer value + * @return Number of digits needed + */ + public static int stringSize(int x) { + if(x < 0) { + // Avoid overflow on extreme negative + return (x == Integer.MIN_VALUE) ? 11 : stringSize(-x) + 1; + } + // This is almost a binary search - 10 cases is not a power of two, and we + // assume that the smaller values are more frequent. + return // + (x < 10000) ? // 1-4 vs. 5-10 + /**/(x < 100) ? // 1-2 vs. 3-4 + /* */((x < 10) ? 1 : 2) : // + /* */((x < 1000) ? 3 : 4) : // + /**/(x < 1000000) ? // 5-6 vs. 7-10 + /* */((x < 100000) ? 5 : 6) : // 5-6 + /* */(x < 100000000) ? // 7-8 vs. 9-10 + /* */((x < 10000000) ? 7 : 8) : // 7-8 + /* */((x < 1000000000) ? 9 : 10) // 9-10 + ; + } + + /** + * Compute the number of characters needed to represent the integer x. + * + * Reimplementation of {@link Long#stringSize}, but public and without loop. + * + * @param x Integer value + * @return Number of digits needed + */ + public static int stringSize(long x) { + if(x < 0) { + // Avoid overflow on extreme negative + return (x == Long.MIN_VALUE) ? 20 : stringSize(-x) + 1; + } + // This is almost a binary search. + return (x <= Integer.MAX_VALUE) ? stringSize((int) x) : // + (x < 10000000000000L) ? // 10-13 vs. 14-19 + /**/(x < 100000000000L) ? // 10-11 vs. 12-13 + /* */((x < 10000000000L) ? 10 : 11) : // + /* */((x < 1000000000000L) ? 12 : 13) : // + /**/(x < 1000000000000000L) ? // 14-15 vs. 16-19 + /* */((x < 100000000000000L) ? 14 : 15) : // 14-15 + /* */(x < 100000000000000000L) ? // 16-17 vs. 18-19 + /* */((x < 10000000000000000L) ? 16 : 17) : // 16-17 + /* */((x < 1000000000000000000L) ? 18 : 19) // 18-19 + ; + } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java b/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java index fa17e04f..82d7703c 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/HandlerList.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java index 29745335..856e5d3d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/InspectionUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,6 +30,7 @@ import java.io.IOException; import java.lang.reflect.Modifier; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -55,7 +56,7 @@ public class InspectionUtil { /** * Class loader */ - private static final ClassLoader CLASSLOADER = ClassLoader.getSystemClassLoader(); + private static final URLClassLoader CLASSLOADER = (URLClassLoader) ClassLoader.getSystemClassLoader(); /** * Default package ignores. @@ -83,28 +84,10 @@ public class InspectionUtil { }; /** - * If we have a non-static classpath, we do more extensive scanning for user - * extensions. - */ - public static final boolean NONSTATIC_CLASSPATH; - - /** * Factory class postfix. */ public static final String FACTORY_POSTFIX = "$Factory"; - // Check for non-jar entries in classpath. - static { - String[] classpath = System.getProperty("java.class.path").split(System.getProperty("path.separator")); - boolean hasnonstatic = false; - for (String path : classpath) { - if (!path.endsWith(".jar")) { - hasnonstatic = true; - } - } - NONSTATIC_CLASSPATH = hasnonstatic; - } - /** * Weak hash map for class lookups */ @@ -123,12 +106,12 @@ public class InspectionUtil { * @return Found implementations */ public static List<Class<?>> cachedFindAllImplementations(Class<?> c) { - if (c == null) { + if(c == null) { return Collections.emptyList(); } List<Class<?>> res = CLASS_CACHE.get(c); - if (res == null) { - res = findAllImplementations(c, false); + if(res == null) { + res = findAllImplementations(c, false, true); CLASS_CACHE.put(c, res); } return res; @@ -141,42 +124,61 @@ public class InspectionUtil { * * @param c Class restriction * @param everything include interfaces, abstract and private classes + * @param parameterizable only return classes instantiable by the + * parameterizable API * @return List of found classes. */ - public static List<Class<?>> findAllImplementations(Class<?> c, boolean everything) { - ArrayList<Class<?>> list = new ArrayList<>(); + public static List<Class<?>> findAllImplementations(Class<?> c, boolean everything, boolean parameterizable) { + // For removing duplicates: + THashSet<Class<?>> dupes = new THashSet<>(); + ArrayList<Class<?>> known = new ArrayList<>(); // Add all from service files (i.e. jars) { Iterator<Class<?>> iter = new ELKIServiceLoader(c); - while (iter.hasNext()) { - list.add(iter.next()); + while(iter.hasNext()) { + known.add(iter.next()); } + dupes.addAll(known); + } + // Build cache on first use: + if(MASTER_CACHE == null) { + MASTER_CACHE = slowScan(); } - if (!InspectionUtil.NONSTATIC_CLASSPATH) { - if (list.size() == 0) { - LOG.warning("No implementations for " + c.getName() + " were found using index files."); + Iterator<Class<?>> iter = MASTER_CACHE.iterator(); + while(iter.hasNext()) { + Class<?> cls = iter.next(); + if(dupes.contains(cls)) { + continue; } - } else { - // Duplicate checking - THashSet<Class<?>> dupes = new THashSet<>(list); - // Build cache on first use: - if (MASTER_CACHE == null) { - MASTER_CACHE = slowScan(); + // skip abstract / private classes. + if(!everything && (Modifier.isInterface(cls.getModifiers()) || Modifier.isAbstract(cls.getModifiers()) || Modifier.isPrivate(cls.getModifiers()))) { + continue; } - Iterator<Class<?>> iter = MASTER_CACHE.iterator(); - while (iter.hasNext()) { - Class<?> cls = iter.next(); - // skip abstract / private classes. - if (!everything && (Modifier.isInterface(cls.getModifiers()) || Modifier.isAbstract(cls.getModifiers()) || Modifier.isPrivate(cls.getModifiers()))) { - continue; + if(!c.isAssignableFrom(cls)) { + continue; + } + if(parameterizable) { + boolean instantiable = false; + try { + instantiable = cls.getConstructor() != null; } - if (c.isAssignableFrom(cls) && !dupes.contains(cls)) { - list.add(cls); - dupes.add(cls); + catch(Exception | Error e) { + // ignore + } + try { + instantiable = instantiable || ClassGenericsUtil.getParameterizer(cls) != null; + } + catch(Exception | Error e) { + // ignore + } + if(!instantiable) { + continue; } } + known.add(cls); + dupes.add(cls); } - return list; + return known; } /** @@ -192,33 +194,37 @@ public class InspectionUtil { // Try exact class factory first. try { return (Class<? extends C>) CLASSLOADER.loadClass(value + FACTORY_POSTFIX); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // Ignore, retry } try { return (Class<? extends C>) CLASSLOADER.loadClass(value); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // Ignore, retry } final String completedName = restrictionClass.getPackage().getName() + "." + value; // Try factory for guessed name next try { return (Class<? extends C>) CLASSLOADER.loadClass(completedName + FACTORY_POSTFIX); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // Ignore, retry } // Last try: guessed name prefix only try { return (Class<? extends C>) CLASSLOADER.loadClass(completedName); - } catch (ClassNotFoundException e) { + } + catch(ClassNotFoundException e) { // Ignore, retry } // Try aliases: - for (Class<?> c : InspectionUtil.cachedFindAllImplementations(restrictionClass)) { - if (c.isAnnotationPresent(Alias.class)) { + for(Class<?> c : InspectionUtil.cachedFindAllImplementations(restrictionClass)) { + if(c.isAnnotationPresent(Alias.class)) { Alias aliases = c.getAnnotation(Alias.class); - for (String alias : aliases.value()) { - if (alias.equalsIgnoreCase(value) || alias.equalsIgnoreCase(completedName)) { + for(String alias : aliases.value()) { + if(alias.equalsIgnoreCase(value) || alias.equalsIgnoreCase(completedName)) { return (Class<? extends C>) c; } } @@ -234,43 +240,51 @@ public class InspectionUtil { */ private static List<Class<?>> slowScan() { ArrayList<Class<?>> res = new ArrayList<>(); + Enumeration<URL> cps; try { - Enumeration<URL> cps = CLASSLOADER.getResources(""); - while (cps.hasMoreElements()) { - URL u = cps.nextElement(); - // Scan file sources only. - if ("file".equals(u.getProtocol())) { - File path; + cps = CLASSLOADER.getResources(""); + } + catch(IOException e) { + de.lmu.ifi.dbs.elki.logging.LoggingUtil.exception(e); + return res; + } + while(cps.hasMoreElements()) { + URL u = cps.nextElement(); + // Scan file sources only. + if("file".equals(u.getProtocol())) { + File path; + try { + path = new File(u.toURI()); + } + catch(URISyntaxException e) { + LOG.exception("Error in classpath: " + u, e); + continue; + } + Iterator<String> it = new DirClassIterator(path, DEFAULT_IGNORES); + while(it.hasNext()) { + String classname = it.next(); try { - path = new File(u.toURI()); - } catch (URISyntaxException e) { - LOG.exception("Error in classpath: " + u, e); - continue; - } - Iterator<String> it = new DirClassIterator(path, DEFAULT_IGNORES); - while (it.hasNext()) { - String classname = it.next(); - try { - Class<?> cls = CLASSLOADER.loadClass(classname); - // skip classes where we can't get a full name. - if (cls.getCanonicalName() == null) { - continue; - } - res.add(cls); - } catch (ClassNotFoundException e) { - continue; - } catch (NoClassDefFoundError e) { - continue; - } catch (Exception e) { - continue; - } catch (Error e) { + Class<?> cls = CLASSLOADER.loadClass(classname); + // skip classes where we can't get a full name. + if(cls.getCanonicalName() == null) { continue; } + res.add(cls); + } + catch(ClassNotFoundException e) { + continue; + } + catch(NoClassDefFoundError e) { + continue; + } + catch(Exception e) { + continue; + } + catch(Error e) { + continue; } } } - } catch (IOException e) { - LOG.exception(e); } Collections.sort(res, new ClassSorter()); return res; @@ -306,7 +320,7 @@ public class InspectionUtil { public DirClassIterator(File path, String[] ignorepackages) { this.ignorepackages = ignorepackages; this.prefix = path.getAbsolutePath(); - if (prefix.charAt(prefix.length() - 1) != File.separatorChar) { + if(prefix.charAt(prefix.length() - 1) != File.separatorChar) { prefix = prefix + File.separatorChar; } @@ -315,7 +329,7 @@ public class InspectionUtil { @Override public boolean hasNext() { - if (files.size() == 0) { + if(files.size() == 0) { findNext(); } return (files.size() > 0); @@ -325,19 +339,19 @@ public class InspectionUtil { * Find the next entry, since we need to skip some directories. */ private void findNext() { - while (folders.size() > 0) { + while(folders.size() > 0) { Pair<File, String> pair = folders.remove(folders.size() - 1); // recurse into directories - if (pair.first.isDirectory()) { - nextfile: for (String localname : pair.first.list()) { + if(pair.first.isDirectory()) { + nextfile: for(String localname : pair.first.list()) { // Ignore unix-hidden files/dirs - if (localname.charAt(0) == '.') { + if(localname.charAt(0) == '.') { continue; } // Classes - if (localname.endsWith(CLASS_EXT)) { - if (localname.indexOf('$') >= 0) { - if (!localname.endsWith(FACTORY_FILE_EXT)) { + if(localname.endsWith(CLASS_EXT)) { + if(localname.indexOf('$') >= 0) { + if(!localname.endsWith(FACTORY_FILE_EXT)) { continue; } } @@ -346,10 +360,10 @@ public class InspectionUtil { } // Recurse into directories File newf = new File(pair.first, localname); - if (newf.isDirectory()) { + if(newf.isDirectory()) { String newpref = pair.second + localname + '.'; - for (String ignore : ignorepackages) { - if (ignore.equals(newpref)) { + for(String ignore : ignorepackages) { + if(ignore.equals(newpref)) { continue nextfile; } } @@ -362,10 +376,10 @@ public class InspectionUtil { @Override public String next() { - if (files.size() == 0) { + if(files.size() == 0) { findNext(); } - if (files.size() > 0) { + if(files.size() > 0) { return files.remove(files.size() - 1); } return null; @@ -389,14 +403,14 @@ public class InspectionUtil { public int compare(Class<?> o1, Class<?> o2) { Package p1 = o1.getPackage(); Package p2 = o2.getPackage(); - if (p1 == null) { + if(p1 == null) { return -1; } - if (p2 == null) { + if(p2 == null) { return 1; } int pkgcmp = p1.getName().compareTo(p2.getName()); - if (pkgcmp != 0) { + if(pkgcmp != 0) { return pkgcmp; } return o1.getCanonicalName().compareTo(o2.getCanonicalName()); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java b/src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java deleted file mode 100644 index 229afe5f..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/RandomFactory.java +++ /dev/null @@ -1,103 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities; - -/* - 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; - -/** - * RandomFactory is responsible for creating {@link Random} generator objects. - * It does not provide individual random numbers, but will create a random - * generator; either using a fixed seed or random seeded (default). - * - * TODO: allow global fixing of seed, to make whole experiments reproducible, - * without having to set every single seed. - * - * @author Erich Schubert - * - * @apiviz.has Random - */ -public class RandomFactory { - /** - * Global default factory - */ - public static RandomFactory DEFAULT = new RandomFactory(null); - - /** - * Seed - */ - private Long seed = null; - - /** - * Factory method: Get a random factory for the given seed. - * - * @param seed Seed - * @return Instance - */ - public static RandomFactory get(Long seed) { - if(seed == null) { - return DEFAULT; - } - else { - return new RandomFactory(seed); - } - } - - /** - * Constructor. - * - * @param seed Random seed - */ - public RandomFactory(Long seed) { - super(); - this.seed = seed; - } - - /** - * Get a random generator. - * - * @return Random generator - */ - public Random getRandom() { - if(seed != null) { - return new Random(seed.longValue()); - } - else { - return new Random(); - } - } - - /** - * Get a <em>non-threadsafe</em> random generator. - * - * @return Random generator - */ - public Random getSingleThreadedRandom() { - if(seed != null) { - return new UnsafeRandom(seed.longValue()); - } - else { - return new UnsafeRandom(); - } - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/UnsafeRandom.java b/src/de/lmu/ifi/dbs/elki/utilities/UnsafeRandom.java deleted file mode 100644 index 898b685a..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/UnsafeRandom.java +++ /dev/null @@ -1,81 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities; - -/* - 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; - -/** - * Drop-in replacement for {@link java.util.Random}, but not using atomic long - * seeds. This implementation is <em>no longer thread-safe</em> (but faster)! - * - * @author Erich Schubert - */ -public class UnsafeRandom extends Random { - /** - * Serial version number. - */ - private static final long serialVersionUID = 1L; - - // These are the same constants as in {@link java.util.Random} - // since we want to leave the random sequence unchanged. - private static final long multiplier = 0x5DEECE66DL, addend = 0xBL, - mask = (1L << 48) - 1; - - /** - * The random seed. We can't use super.seed. - */ - private long seed; - - /** - * Constructor called only by localRandom.initialValue. - */ - public UnsafeRandom() { - super(); - } - - /** - * Constructor. - * - * @param seed Random generator seed. - */ - public UnsafeRandom(long seed) { - this.seed = (seed ^ multiplier) & mask; - } - - /** - * Throws {@code UnsupportedOperationException}. Setting seeds in this - * generator is not supported. - * - * @throws UnsupportedOperationException always - */ - @Override - public void setSeed(long seed) { - this.seed = (seed ^ multiplier) & mask; - } - - @Override - protected int next(int bits) { - seed = (seed * multiplier + addend) & mask; - return (int) (seed >>> (48 - bits)); - } -} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/Util.java b/src/de/lmu/ifi/dbs/elki/utilities/Util.java index ffac6573..252cdcf1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/Util.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/Util.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java index d0a2cd20..89cbdc1e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/QuickSelect.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java index 2c5eeed1..c1b7a280 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java index da831471..b8123e2d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayDBIDsAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java index f03d39e9..2e8496c6 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ArrayLikeUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -63,7 +63,7 @@ public final class ArrayLikeUtil { /** * Use a number vector in the array API. */ - public static final NumberVectorAdapter<?> NUMBERVECTORADAPTER = new NumberVectorAdapter<Double>(); + public static final NumberVectorAdapter NUMBERVECTORADAPTER = new NumberVectorAdapter(); /** * Adapter for matrixes, reinterpreted as flat arrays. @@ -152,9 +152,8 @@ public final class ArrayLikeUtil { * @param prototype Prototype value, for type inference * @return Instance */ - @SuppressWarnings("unchecked") - public static <N extends Number> NumberVectorAdapter<N> numberVectorAdapter(NumberVector<N> prototype) { - return (NumberVectorAdapter<N>) NUMBERVECTORADAPTER; + public static NumberVectorAdapter numberVectorAdapter(NumberVector prototype) { + return NUMBERVECTORADAPTER; } /** @@ -236,7 +235,7 @@ public final class ArrayLikeUtil { * @param obj Object to convert * @return primitive double array */ - public static <N extends Number> double[] toPrimitiveDoubleArray(NumberVector<N> obj) { + public static double[] toPrimitiveDoubleArray(NumberVector obj) { return toPrimitiveDoubleArray(obj, numberVectorAdapter(obj)); } @@ -274,7 +273,7 @@ public final class ArrayLikeUtil { * @param obj Object to convert * @return primitive float array */ - public static <N extends Number> float[] toPrimitiveFloatArray(NumberVector<N> obj) { + public static float[] toPrimitiveFloatArray(NumberVector obj) { return toPrimitiveFloatArray(obj, numberVectorAdapter(obj)); } @@ -309,7 +308,7 @@ public final class ArrayLikeUtil { * @param obj Object to convert * @return primitive double array */ - public static <N extends Number> int[] toPrimitiveIntegerArray(NumberVector<N> obj) { + public static int[] toPrimitiveIntegerArray(NumberVector obj) { return toPrimitiveIntegerArray(obj, numberVectorAdapter(obj)); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java index 0e31a61a..462cd763 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/DoubleArrayAdapter.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java index 3af14982..aeeeafea 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ExtendedArray.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java index deb5aafc..d353812a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FeatureVectorAdapter.java @@ -6,7 +6,7 @@ import de.lmu.ifi.dbs.elki.data.FeatureVector; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java index 18fbae5d..175a672d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FlatMatrixAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java index 831dc929..0ef25d78 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/FloatArrayAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java index dfde46b7..99a3dd80 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/IdentityArrayAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java index 729dfab8..ab947111 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/ListArrayAdapter.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java index 5ebbcb0d..d4911f95 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberArrayAdapter.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java index a2606347..d1ccd560 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberListArrayAdapter.java @@ -6,7 +6,7 @@ import java.util.List; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java index 5e674026..b4f1cca1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/NumberVectorAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,10 +31,8 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; * Use the static instance from {@link ArrayLikeUtil}! * * @author Erich Schubert - * - * @param <N> Number type */ -public class NumberVectorAdapter<N extends Number> implements NumberArrayAdapter<N, NumberVector<N>> { +public class NumberVectorAdapter implements NumberArrayAdapter<Number, NumberVector> { /** * Constructor. * @@ -45,43 +43,43 @@ public class NumberVectorAdapter<N extends Number> implements NumberArrayAdapter } @Override - public int size(NumberVector<N> array) { + public int size(NumberVector array) { return array.getDimensionality(); } @Override @Deprecated - public N get(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public Number get(NumberVector array, int off) throws IndexOutOfBoundsException { return array.getValue(off + 1); } @Override - public double getDouble(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public double getDouble(NumberVector array, int off) throws IndexOutOfBoundsException { return array.doubleValue(off); } @Override - public float getFloat(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public float getFloat(NumberVector array, int off) throws IndexOutOfBoundsException { return array.floatValue(off); } @Override - public int getInteger(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public int getInteger(NumberVector array, int off) throws IndexOutOfBoundsException { return array.intValue(off); } @Override - public short getShort(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public short getShort(NumberVector array, int off) throws IndexOutOfBoundsException { return array.shortValue(off); } @Override - public long getLong(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public long getLong(NumberVector array, int off) throws IndexOutOfBoundsException { return array.longValue(off); } @Override - public byte getByte(NumberVector<N> array, int off) throws IndexOutOfBoundsException { + public byte getByte(NumberVector array, int off) throws IndexOutOfBoundsException { return array.byteValue(off); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java index 941c6245..abf88cbc 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SingleSubsetArrayAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java index 746647cc..f6b54c9e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetArrayAdapter.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java index c394f9b7..9e46a94a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/SubsetNumberArrayAdapter.java @@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java index a52ff15e..e72d23d1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/TDoubleListAdapter.java @@ -6,7 +6,7 @@ import gnu.trove.list.TDoubleList; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java index 0bb979e9..6d28888d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/VectorAdapter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java index 33058cf4..489d0316 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arraylike/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java new file mode 100644 index 00000000..851fed11 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/DoubleIntegerArrayQuickSort.java @@ -0,0 +1,218 @@ +package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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/>. + */ + +/** + * Class to sort a double and an integer DBID array, using a quicksort with a + * best of 5 heuristic. + * + * @author Erich Schubert + */ +public class DoubleIntegerArrayQuickSort { + /** + * Threshold for using insertion sort. + */ + private static final int INSERTION_THRESHOLD = 22; + + /** + * Sort the full array using the given comparator. + * + * @param keys Keys for sorting + * @param values Values for sorting + * @param len Length to sort. + */ + public static void sort(double[] keys, int[] values, int len) { + sort(keys, values, 0, len); + } + + /** + * Sort the array using the given comparator. + * + * @param keys Keys for sorting + * @param values Values for sorting + * @param start First index + * @param end Last index (exclusive) + */ + public static void sort(double[] keys, int[] values, int start, int end) { + quickSort(keys, values, start, end); + } + + /** + * Actual recursive sort function. + * + * @param keys Keys for sorting + * @param vals Values for sorting + * @param start First index + * @param end Last index (exclusive!) + */ + private static void quickSort(double[] keys, int[] vals, final int start, final int end) { + final int len = end - start; + if(len < INSERTION_THRESHOLD) { + insertionSort(keys, vals, start, end); + return; + } + final int last = end - 1; + + // Choose pivots by looking at five candidates. + final int seventh = (len >> 3) + (len >> 6) + 1; + final int m3 = (start + end) >> 1; // middle + final int m2 = m3 - seventh; + final int m1 = m2 - seventh; + final int m4 = m3 + seventh; + final int m5 = m4 + seventh; + + // Mixture of insertion and merge sort: + sort5(keys, vals, m1, m2, m3, m4, m5); + + // Move pivot to the front. + double pivotkey = keys[m3]; + int pivotval = vals[m3]; + keys[m3] = keys[start]; + vals[m3] = vals[start]; + + // The interval to pivotize + int left = start + 1; // Without pivot + int right = last; // inclusive + + // This is the classic QuickSort loop: + while(true) { + // Move duplicates to right partition, i.e. < here, <= below. + while(left <= right && keys[left] < pivotkey) { + left++; + } + while(left <= right && pivotkey <= keys[right]) { + right--; + } + if(right <= left) { + break; + } + swap(keys, vals, left, right); + left++; + right--; + } + // right now points to the last element smaller than the pivot. + // Move pivot back into the appropriate place + keys[start] = keys[right]; + vals[start] = vals[right]; + keys[right] = pivotkey; + vals[right] = pivotval; + + // Recursion when more than one element only: + if(start + 1 < right) { + quickSort(keys, vals, start, right); + } + int rstart = right + 1; + // Avoid recursing on duplicates of the pivot: + while(rstart < last && keys[rstart] <= keys[right]) { + rstart++; + } + // Recurse when _more_ than 1 element only + if(rstart < last) { + quickSort(keys, vals, rstart, end); + } + } + + /** + * An explicit sort, for the five pivot candidates. + * + * Note that this <em>must</em> only be used with + * {@code m1 < m2 < m3 < m4 < m5}. + * + * @param keys Keys + * @param vals Values + * @param m1 Pivot candidate position + * @param m2 Pivot candidate position + * @param m3 Pivot candidate position + * @param m4 Pivot candidate position + * @param m5 Pivot candidate position + */ + private static void sort5(double[] keys, int[] vals, final int m1, final int m2, final int m3, final int m4, final int m5) { + if(keys[m1] > keys[m2]) { + swap(keys, vals, m1, m2); + } + if(keys[m3] > keys[m4]) { + swap(keys, vals, m3, m4); + } + // Merge 1+2 and 3+4 + if(keys[m2] > keys[m4]) { + swap(keys, vals, m2, m4); + } + if(keys[m1] > keys[m3]) { + swap(keys, vals, m1, m3); + } + if(keys[m2] > keys[m3]) { + swap(keys, vals, m2, m3); + } + // Insertion sort m5: + if(keys[m4] > keys[m5]) { + swap(keys, vals, m4, m5); + if(keys[m3] > keys[m4]) { + swap(keys, vals, m3, m4); + if(keys[m2] > keys[m3]) { + swap(keys, vals, m2, m3); + if(keys[m1] > keys[m1]) { + swap(keys, vals, m1, m2); + } + } + } + } + } + + /** + * Sort via insertion sort. + * + * @param keys Keys + * @param vals Values + * @param start Interval start + * @param end Interval end + */ + private static void insertionSort(double[] keys, int[] vals, final int start, final int end) { + // Classic insertion sort. + for(int i = start + 1; i < end; i++) { + for(int j = i; j > start; j--) { + if(keys[j] >= keys[j - 1]) { + break; + } + swap(keys, vals, j, j - 1); + } + } + } + + /** + * Swap two entries. + * + * @param keys Keys + * @param vals Values + * @param j First index + * @param i Second index + */ + private static void swap(double[] keys, int[] vals, int j, int i) { + double td = keys[j]; + keys[j] = keys[i]; + keys[i] = td; + int ti = vals[j]; + vals[j] = vals[i]; + vals[i] = ti; + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java index eaf47738..b91d79b1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerArrayQuickSort.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -34,15 +34,17 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; * Vladimir Yaroslavskiy * </p> * - * and differs mostly in that we sort different kinds of arrays, - * and allow the use of comparators - useful in particular when - * the array references external objects. + * and differs mostly in that we sort different kinds of arrays, and allow the + * use of comparators - useful in particular when the array references external + * objects. * * @author Erich Schubert * * @apiviz.uses IntegerComparator */ -@Reference(authors = "Vladimir Yaroslavskiy", title = "Dual-Pivot Quicksort", booktitle = "http://iaroslavski.narod.ru/quicksort/", url = "http://iaroslavski.narod.ru/quicksort/") +@Reference(authors = "Vladimir Yaroslavskiy", // +title = "Dual-Pivot Quicksort", booktitle = "http://iaroslavski.narod.ru/quicksort/", // +url = "http://iaroslavski.narod.ru/quicksort/") public class IntegerArrayQuickSort { /** * Threshold for using insertion sort. Value taken from Javas QuickSort, @@ -69,7 +71,7 @@ public class IntegerArrayQuickSort { * @param comp Comparator */ public static void sort(int[] data, int start, int end, IntegerComparator comp) { - quickSort(data, start, end - 1, comp); + quickSort(data, start, end, comp); } /** @@ -77,24 +79,14 @@ public class IntegerArrayQuickSort { * * @param data Data to sort * @param start First index - * @param end Last index (inclusive!) + * @param end Last index (exclusive!) * @param comp Comparator */ private static void quickSort(int[] data, final int start, final int end, IntegerComparator comp) { final int len = end - start; - if (len < INSERTION_THRESHOLD) { - // Classic insertion sort. - for (int i = start + 1; i <= end; i++) { - for (int j = i; j > start; j--) { - if (comp.compare(data[j], data[j - 1]) < 0) { - final int tmp = data[j - 1]; - data[j - 1] = data[j]; - data[j] = tmp; - } else { - break; - } - } - } + final int last = end - 1; + if(len < INSERTION_THRESHOLD) { + insertionSort(data, start, end, comp); return; } @@ -108,51 +100,7 @@ public class IntegerArrayQuickSort { // Explicit (and optimal) sorting network for 5 elements // See Knuth for details. - if (comp.compare(data[m1], data[m2]) > 0) { - final int tmp = data[m2]; - data[m2] = data[m1]; - data[m1] = tmp; - } - if (comp.compare(data[m1], data[m3]) > 0) { - final int tmp = data[m3]; - data[m3] = data[m1]; - data[m1] = tmp; - } - if (comp.compare(data[m2], data[m3]) > 0) { - final int tmp = data[m3]; - data[m3] = data[m2]; - data[m2] = tmp; - } - if (comp.compare(data[m4], data[m5]) > 0) { - final int tmp = data[m5]; - data[m5] = data[m4]; - data[m4] = tmp; - } - if (comp.compare(data[m1], data[m4]) > 0) { - final int tmp = data[m4]; - data[m4] = data[m1]; - data[m1] = tmp; - } - if (comp.compare(data[m3], data[m4]) > 0) { - final int tmp = data[m4]; - data[m4] = data[m3]; - data[m3] = tmp; - } - if (comp.compare(data[m2], data[m5]) > 0) { - final int tmp = data[m5]; - data[m5] = data[m2]; - data[m2] = tmp; - } - if (comp.compare(data[m2], data[m3]) > 0) { - final int tmp = data[m3]; - data[m3] = data[m2]; - data[m2] = tmp; - } - if (comp.compare(data[m4], data[m5]) > 0) { - final int tmp = data[m5]; - data[m5] = data[m4]; - data[m4] = tmp; - } + sort5(data, m1, m2, m3, m4, m5, comp); // Choose the 2 and 4th as pivots, as we want to get three parts // Copy to variables v1 and v3, replace them with the start and end @@ -160,35 +108,38 @@ public class IntegerArrayQuickSort { final int lpivot = data[m2]; final int rpivot = data[m4]; data[m2] = data[start]; - data[m4] = data[end]; + data[m4] = data[last]; // A tie is when the two chosen pivots are the same final boolean tied = comp.compare(lpivot, rpivot) == 0; // Insertion points for pivot areas. int left = start + 1; - int right = end - 1; + int right = last - 1; // Note: we merged the ties and no ties cases. // This likely is marginally slower, but not at a macro level // And you never know with hotspot. - for (int k = left; k <= right; k++) { + for(int k = left; k <= right; k++) { final int tmp = data[k]; final int c = comp.compare(tmp, lpivot); - if (c == 0) { + if(c == 0) { continue; - } else if (c < 0) { + } + else if(c < 0) { // Traditional quicksort data[k] = data[left]; data[left] = tmp; left++; - } else if (tied || comp.compare(tmp, rpivot) > 0) { + } + else if(tied || comp.compare(tmp, rpivot) > 0) { // Now look at the right. First skip correct entries there, too - while (true) { + while(true) { final int tmp2 = data[right]; - if (comp.compare(tmp2, rpivot) > 0 && k < right) { + if(comp.compare(tmp2, rpivot) > 0 && k < right) { right--; - } else { + } + else { break; } } @@ -197,7 +148,7 @@ public class IntegerArrayQuickSort { data[right] = tmp; right--; // Test the element we just inserted: left or center? - if (comp.compare(data[k], lpivot) < 0) { + if(comp.compare(data[k], lpivot) < 0) { final int tmp2 = data[k]; data[k] = data[left]; data[left] = tmp2; @@ -209,17 +160,105 @@ public class IntegerArrayQuickSort { // Remember: we must not modify v1 and v3 above. data[start] = data[left - 1]; data[left - 1] = lpivot; - data[end] = data[right + 1]; + data[last] = data[right + 1]; data[right + 1] = rpivot; // v1 and v3 are now safe to modify again. Perform recursion: - quickSort(data, start, left - 2, comp); + quickSort(data, start, left - 1, comp); // Handle the middle part - if necessary: - if (!tied) { + if(!tied) { // TODO: the original publication had a special tie handling here. // It shouldn't affect correctness, but probably improves situations // with a lot of tied elements. - quickSort(data, left, right, comp); + quickSort(data, left, right + 1, comp); } quickSort(data, right + 2, end, comp); } + + /** + * Insertion sort, for short arrays. + * + * @param data Data to sort + * @param start First index + * @param end Last index (exclusive!) + * @param comp Comparator + */ + private static void insertionSort(int[] data, final int start, final int end, IntegerComparator comp) { + // Classic insertion sort. + for(int i = start + 1; i < end; i++) { + final int cur = data[i]; + int j = i - 1; + while(j >= start) { + final int pre = data[j]; + if(comp.compare(cur, pre) >= 0) { + break; + } + data[j + 1] = pre; + --j; + } + data[j + 1] = cur; + } + } + + /** + * An explicit sort, for the five pivot candidates. + * + * Note that this <em>must</em> only be used with + * {@code m1 < m2 < m3 < m4 < m5}. + * + * @param data Data + * @param m1 Pivot candidate position + * @param m2 Pivot candidate position + * @param m3 Pivot candidate position + * @param m4 Pivot candidate position + * @param m5 Pivot candidate position + * @param comp Comparator + */ + private static void sort5(int[] data, int m1, int m2, int m3, int m4, int m5, IntegerComparator comp) { + // Sort m1, m2 + if(comp.compare(data[m1], data[m2]) > 0) { + final int tmp = data[m2]; + data[m2] = data[m1]; + data[m1] = tmp; + } + // Sort m3, m4 + if(comp.compare(data[m3], data[m4]) > 0) { + final int tmp = data[m4]; + data[m4] = data[m3]; + data[m3] = tmp; + } + // Merge 1+2 and 3+4 + if(comp.compare(data[m2], data[m4]) > 0) { + final int tmp = data[m4]; + data[m4] = data[m2]; + data[m2] = tmp; + } + if(comp.compare(data[m1], data[m3]) > 0) { + final int tmp = data[m3]; + data[m3] = data[m1]; + data[m1] = tmp; + } + if(comp.compare(data[m2], data[m3]) > 0) { + final int tmp = data[m3]; + data[m3] = data[m2]; + data[m2] = tmp; + } + // Insertion sort m5: + final int tmp = data[m5]; + if(comp.compare(data[m4], tmp) > 0) { + data[m5] = data[m4]; + data[m4] = tmp; + if(comp.compare(data[m3], tmp) > 0) { + data[m4] = data[m3]; + data[m3] = tmp; + if(comp.compare(data[m2], tmp) > 0) { + data[m3] = data[m2]; + data[m2] = tmp; + if(comp.compare(data[m1], tmp) > 0) { + data[m2] = data[m1]; + data[m1] = tmp; + } + } + } + } + } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java index 0ccd47db..47b0ccfd 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/IntegerComparator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,13 +24,13 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.arrays; */ /** - * Interface for comparing two integers. + * Interface for comparing two Integer. * * @author Erich Schubert */ public interface IntegerComparator { /** - * Compare two integers. + * Compare two Integer. * * @param x First int * @param y Second int diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java index 874a6d44..921de083 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/arrays/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java new file mode 100644 index 00000000..ab149c39 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/Unique.java @@ -0,0 +1,132 @@ +package de.lmu.ifi.dbs.elki.utilities.datastructures.hash; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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 gnu.trove.impl.hash.TObjectHash; + +import java.util.Arrays; + +/** + * This hash set is designed to keep only a unique copy of each object (hence + * its name). For this, the method {@link #addOrGet} is the key API, which + * allows retrieving existing values. + * + * @author Erich Schubert + * + * @param <E> + */ +public class Unique<E> extends TObjectHash<E> { + /** + * Serial version number. + */ + static final long serialVersionUID = 1L; + + /** + * Constructor with default size and load factors. + */ + public Unique() { + super(); + } + + /** + * Constructor with desired initial size. + * + * @param initialCapacity desired initial size. + */ + public Unique(int initialCapacity) { + super(initialCapacity); + } + + /** + * Constructor with desired initial size, and with the specified load factor. + * + * @param initialCapacity desired initial size + * @param loadFactor load factor + */ + public Unique(int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); + } + + /** + * Inserts a value into the set, unless it is already present. + * + * This function returns the existing value, if present. + * + * @param obj Object to insert or retrieve + * @return Existing object if already present, or the new object. + */ + @SuppressWarnings("unchecked") + public E addOrGet(E obj) { + int index = insertKey(obj); + + if(index < 0) { + obj = (E) _set[-index - 1]; + } + + postInsertHook(consumeFreeSlot); + return obj; + } + + /** + * Removes an existing object from the set. + * + * @param obj Object to remove + * @return true if the object was found and removed. + */ + public boolean remove(Object obj) { + int index = index(obj); + if(index >= 0) { + removeAt(index); + return true; + } + return false; + } + + @Override + public void clear() { + super.clear(); + + Arrays.fill(_set, 0, _set.length, FREE); + } + + @SuppressWarnings("unchecked") + @Override + protected void rehash(int newCapacity) { + final int oldCapacity = _set.length, oldSize = size(); + // Replace data storage: + Object oldSet[] = _set; + _set = new Object[newCapacity]; + Arrays.fill(_set, FREE); + + // Reinsert all objects: + for(int i = oldCapacity; i-- > 0;) { + E o = (E) oldSet[i]; + if(o != FREE && o != REMOVED) { + insertKey(o); + } + } + // Last check: size before and after should be the same + reportPotentialConcurrentMod(size(), oldSize); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java new file mode 100644 index 00000000..03746389 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hash/package-info.java @@ -0,0 +1,30 @@ +/** + * Hashing based data structures. + * + * Note: much of the desired functionality is provided by the very good GNU Trove library. + * + * This package will only contain slight extensions or variations, not provided by Trove already. + */ +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.utilities.datastructures.hash;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java index d6937b4d..1433bd4e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -233,8 +233,9 @@ public class ComparableMaxHeap<K extends Comparable<? super K>> implements Objec } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @SuppressWarnings("unchecked") diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java index 167c6bc7..76104644 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparableMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -233,8 +233,9 @@ public class ComparableMinHeap<K extends Comparable<? super K>> implements Objec } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @SuppressWarnings("unchecked") diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java index e5887c73..516177fd 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -242,8 +242,9 @@ public class ComparatorMaxHeap<K> implements ObjectHeap<K> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @SuppressWarnings("unchecked") diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java index 215a78b6..11518553 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ComparatorMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -242,8 +242,9 @@ public class ComparatorMinHeap<K> implements ObjectHeap<K> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @SuppressWarnings("unchecked") diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java index c82f2a4a..d32a07a9 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java index 5d8d31f7..6899e327 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java index e903c23d..1a9f8dbe 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -249,8 +249,9 @@ public class DoubleIntegerMaxHeap implements DoubleIntegerHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java index 0e4e2204..11237841 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleIntegerMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -249,8 +249,9 @@ public class DoubleIntegerMinHeap implements DoubleIntegerHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java index b93adafa..1b02d3c7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java index b7508a61..7caa7cd4 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -249,8 +249,9 @@ public class DoubleLongMaxHeap implements DoubleLongHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java index 9fbe0300..1e1a5956 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleLongMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -249,8 +249,9 @@ public class DoubleLongMinHeap implements DoubleLongHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java index 2c74b34b..78743779 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -226,8 +226,9 @@ public class DoubleMaxHeap implements DoubleHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java index afc50296..1c6954b7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -226,8 +226,9 @@ public class DoubleMinHeap implements DoubleHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java index 7323cd8d..ad964c08 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java index 939c4d7e..3999c218 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -251,8 +251,9 @@ public class DoubleObjectMaxHeap<V> implements DoubleObjectHeap<V> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java index 01b8e58d..18713455 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoubleObjectMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -251,8 +251,9 @@ public class DoubleObjectMinHeap<V> implements DoubleObjectHeap<V> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java index 82453885..d940cd21 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/DoublePriorityObject.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 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.utilities.datastructures.heap; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; /** * Object for a priority queue with integer priority. Can be used in the @@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; * * @param <O> Stored object type. */ -public class DoublePriorityObject<O> implements PairInterface<Double, O>, Comparable<DoublePriorityObject<?>> { +public class DoublePriorityObject<O> implements Comparable<DoublePriorityObject<?>> { /** * Priority. */ @@ -79,17 +78,6 @@ public class DoublePriorityObject<O> implements PairInterface<Double, O>, Compar } @Override - @Deprecated - public Double getFirst() { - return Double.valueOf(priority); - } - - @Override - public O getSecond() { - return object; - } - - @Override public int hashCode() { return ((object == null) ? 0 : object.hashCode()); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java index 2c278110..dad6f1d7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/Heap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -442,8 +442,9 @@ public class Heap<E> { } @Override - public void advance() { + public UnorderedIter advance() { pos++; + return this; } /** diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java index 77e5f3e5..80d8882b 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java index 4f3b1495..b3fc51ca 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -226,8 +226,9 @@ public class IntegerMaxHeap implements IntegerHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java index b02e04db..6632d005 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -226,8 +226,9 @@ public class IntegerMinHeap implements IntegerHeap { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java index e4f577af..f4c7043f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java index 036a9520..5a4bd70f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMaxHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -251,8 +251,9 @@ public class IntegerObjectMaxHeap<V> implements IntegerObjectHeap<V> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java index cc816a0e..b6fc9a74 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerObjectMinHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -251,8 +251,9 @@ public class IntegerObjectMinHeap<V> implements IntegerObjectHeap<V> { } @Override - public void advance() { + public de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter advance() { pos++; + return this; } @Override diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java index f007b9fc..11f8c7d5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/IntegerPriorityObject.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 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.utilities.datastructures.heap; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; /** * Object for a priority queue with integer priority. Can be used in the @@ -35,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.PairInterface; * * @param <O> Stored object type. */ -public class IntegerPriorityObject<O> implements PairInterface<Integer, O>, Comparable<IntegerPriorityObject<?>> { +public class IntegerPriorityObject<O> implements Comparable<IntegerPriorityObject<?>> { /** * Priority. */ @@ -79,17 +78,6 @@ public class IntegerPriorityObject<O> implements PairInterface<Integer, O>, Comp } @Override - @Deprecated - public Integer getFirst() { - return Integer.valueOf(priority); - } - - @Override - public O getSecond() { - return object; - } - - @Override public int hashCode() { return ((object == null) ? 0 : object.hashCode()); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java index 2b03740e..3aa1dd7f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/ObjectHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2012 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java index 32f57999..14e708c5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java index 3905030f..4c8c6ddb 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TiedTopBoundedUpdatableHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java index 9adda9f3..29880fd7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java index 4a591d4c..d80f209f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/TopBoundedUpdatableHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java index a585d94d..f3c42e90 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/UpdatableHeap.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.heap; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java index 83be37f4..7062650e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java index c77a9329..f8bd27a8 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/HashMapHierarchy.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -353,8 +353,9 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<O> advance() { pos++; + return this; } @SuppressWarnings("unchecked") @@ -380,8 +381,9 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<O> advance() { pos++; + return this; } @SuppressWarnings("unchecked") @@ -425,7 +427,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<O> advance() { if (subiter == null) { // Not yet descended assert (childiter.valid()); subiter = iterDescendants(childiter.get()); @@ -433,11 +435,12 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { subiter.advance(); } if (subiter.valid()) { - return; + return this; } // Proceed to next child. childiter.advance(); subiter = null; + return this; } @Override @@ -485,7 +488,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<O> advance() { if (subiter == null) { // Not yet descended assert (parentiter.valid()); subiter = iterAncestors(parentiter.get()); @@ -493,11 +496,12 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { subiter.advance(); } if (subiter.valid()) { - return; + return this; } // Proceed to next child. parentiter.advance(); subiter = null; + return this; } @Override @@ -544,12 +548,13 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<O> advance() { if (iter.hasNext()) { cur = iter.next(); } else { cur = null; } + return this; } @Override @@ -568,7 +573,7 @@ public class HashMapHierarchy<O> implements ModifiableHierarchy<O> { } @Override - public void advance() { + public Iter<Object> advance() { throw new UnsupportedOperationException("Empty iterators must not be advanced."); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java index fec9c7b4..7d751dc1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/Hierarchy.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -113,5 +113,8 @@ public interface Hierarchy<O> { * @return Current object */ O get(); + + @Override + Iter<O> advance(); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java index 06001d6b..0b1b0534 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/ModifiableHierarchy.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.hierarchy; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java index 965b15fc..4ea54ef2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/hierarchy/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java index 165c2c8b..d3d3f006 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -74,12 +74,12 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi @SuppressWarnings("unchecked") void materialize() { // already materialized? - if (cachefill <= 0) { + if(cachefill <= 0) { return; } // Compute minimum and maximum double min = Double.MAX_VALUE, max = Double.MIN_VALUE; - for (int i = 0; i < cachefill; i++) { + for(int i = 0; i < cachefill; i++) { min = Math.min(min, cacheposs[i]); max = Math.max(max, cacheposs[i]); } @@ -93,14 +93,14 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi this.binsize = (max - min) / this.destsize; // initialize array this.data = new Object[this.destsize << 1]; - for (int i = 0; i < this.destsize; i++) { + for(int i = 0; i < this.destsize; i++) { this.data[i] = makeObject(); } size = destsize; // re-insert data we have final int end = cachefill; cachefill = -1; // So reinsert works! - for (int i = 0; i < end; i++) { + for(int i = 0; i < end; i++) { putData(cacheposs[i], (T) cachevals[i]); } // delete cache, signal that we're initialized @@ -125,21 +125,24 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi @Override public void putData(double coord, T value) { // Store in cache - if (cachefill >= 0) { - if (cachefill < cacheposs.length) { + if(cachefill >= 0) { + if(cachefill < cacheposs.length) { cacheposs[cachefill] = coord; cachevals[cachefill] = cloneForCache(value); ++cachefill; return; } } - if (coord == Double.NEGATIVE_INFINITY) { + if(coord == Double.NEGATIVE_INFINITY) { aggregateSpecial(value, 0); - } else if (coord == Double.POSITIVE_INFINITY) { + } + else if(coord == Double.POSITIVE_INFINITY) { aggregateSpecial(value, 1); - } else if (Double.isNaN(coord)) { + } + else if(Double.isNaN(coord)) { aggregateSpecial(value, 2); - } else { + } + else { // super class will handle histogram resizing / shifting T exist = get(coord); data[getBinNr(coord)] = aggregate(exist, value); @@ -167,17 +170,19 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi private void testResample(double coord) { final int bin = getBinNr(coord); final int sizereq, off; - if (bin < 0) { + if(bin < 0) { sizereq = size - bin; off = -bin; - } else if (bin >= data.length) { + } + else if(bin >= data.length) { sizereq = bin + 1; off = 0; - } else { + } + else { // Within the designated size - nothing to do. return; } - if (sizereq < data.length) { + if(sizereq < data.length) { // Accomodate by shifting. Let super do the job in {@link #get} return; } @@ -186,31 +191,33 @@ public abstract class AbstractObjDynamicHistogram<T> extends AbstractObjStaticHi assert (levels > 0) : "No resampling required?!?"; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); - for (; inp < size; inp += step, oup++) { + for(; inp < size; inp += step, oup++) { assert (oup < inp + step && oup < data.length); data[oup] = downsample(data, Math.max(0, inp), Math.min(size, inp + step), step); } // Clean upwards - for (; oup < data.length; oup++) { + for(; oup < data.length; oup++) { data[oup] = null; } } - if (off >= step) { + if(off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); - for (; inp > -step; inp -= step, oup--) { + for(; inp > -step; inp -= step, oup--) { assert (oup >= inp && oup >= 0); data[oup] = downsample(data, Math.max(0, inp), Math.min(size, inp + step), step); } - for (; oup >= 0; oup--) { + for(; oup >= 0; oup--) { data[oup] = makeObject(); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java index 4a1649af..cbfb29c0 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractObjStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java index 3363e61e..798e1d80 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/AbstractStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -193,8 +193,9 @@ public abstract class AbstractStaticHistogram implements Histogram { } @Override - public void advance() { + public Iter advance() { bin++; + return this; } @Override @@ -203,18 +204,21 @@ public abstract class AbstractStaticHistogram implements Histogram { } @Override - public void advance(int count) { + public Iter advance(int count) { bin += count; + return this; } @Override - public void retract() { + public Iter retract() { bin--; + return this; } @Override - public void seek(int off) { + public Iter seek(int off) { bin = off; + return this; } } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java index 86b53d03..192abceb 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleArrayStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java index 84f97dfe..1c0f5f33 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -162,10 +162,12 @@ public class DoubleDynamicHistogram extends DoubleStaticHistogram { assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp < size; inp += step, oup++) { @@ -177,9 +179,9 @@ public class DoubleDynamicHistogram extends DoubleStaticHistogram { data[oup] = 0; } } - if (off > 0) { + if(off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp > -step; inp -= step, oup--) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java index e4a24c95..1d8ae54d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java index 5a634cf2..7475e00c 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/DoubleStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java index 9829eaf8..1d816e2d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -162,10 +162,12 @@ public class FloatDynamicHistogram extends FloatStaticHistogram { assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp < size; inp += step, oup++) { @@ -177,9 +179,9 @@ public class FloatDynamicHistogram extends FloatStaticHistogram { data[oup] = 0; } } - if (off > 0) { + if(off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp > -step; inp -= step, oup--) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java index 7f034152..a7cb7153 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java index 063bd80a..c42c0bec 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/FloatStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java index 8c8d9a87..7e94d522 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/Histogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java index ff9a82aa..784fe86b 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntArrayStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java index b131af7d..f241b036 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -162,10 +162,12 @@ public class IntDynamicHistogram extends IntStaticHistogram { assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp < size; inp += step, oup++) { @@ -177,9 +179,9 @@ public class IntDynamicHistogram extends IntStaticHistogram { data[oup] = 0; } } - if (off > 0) { + if (off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp > -step; inp -= step, oup--) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java index 9bfae100..94cf6b34 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java index 84b55cd1..96f57399 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/IntStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java index e3580792..8447d3ba 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongArrayStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java index 93c4eee5..d1f8d8fd 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -162,10 +162,12 @@ public class LongDynamicHistogram extends LongStaticHistogram { assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp < size; inp += step, oup++) { @@ -177,9 +179,9 @@ public class LongDynamicHistogram extends LongStaticHistogram { data[oup] = 0; } } - if (off > 0) { + if(off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp > -step; inp -= step, oup--) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java index 16577c38..c55f7705 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java index b270908d..6d8b8cf7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/LongStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java index 0f1ea0a3..7b9c648c 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/MeanVarianceStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java index bad4eec1..9546efee 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ObjHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java index a49810ee..4a6a3de7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortDynamicHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -162,10 +162,12 @@ public class ShortDynamicHistogram extends ShortStaticHistogram { assert (levels > 0) : "No resampling required?!? sizereq=" + sizereq + " destsize=" + destsize + " array=" + data.length; final int step = 1 << levels; + // We want to map [i ... i+step[ -> (i+off)/step + // Fix point: i = (i+off)/step; i*(step-1)=off; i=off/(step-1) final int fixpoint = off / (step - 1); { // Start positions for in-place bottom-up downsampling. - int oup = fixpoint; + int oup = (fixpoint >= 0) ? fixpoint : 0; int inp = (oup << levels) - off; assert (-step < inp && inp <= oup && oup < inp + step) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp < size; inp += step, oup++) { @@ -177,9 +179,9 @@ public class ShortDynamicHistogram extends ShortStaticHistogram { data[oup] = 0; } } - if (off > 0) { + if(off >= step) { // Start positions for in-place downsampling top-down: - int oup = fixpoint - 1; + int oup = (fixpoint - 1 < size) ? fixpoint - 1 : size - 1; int inp = (oup << levels) - off; assert (oup > inp) : (inp + " -> " + oup + " s=" + step + " o=" + off + " l=" + levels); for (; inp > -step; inp -= step, oup--) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java index 0b83bc4c..4e65e3a7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java index 2819d966..375e5945 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/ShortStaticHistogram.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.histogram; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java index cee1836b..702bd0a5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/histogram/package-info.java @@ -13,7 +13,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java index 7b2a96ad..fe3c54f0 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,29 +31,36 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator; * @apiviz.excludeSubtypes */ public interface ArrayIter extends Iter { - /** - * Get current iterator offset. - * - * @return Iterator position - */ - public int getOffset(); + @Override + ArrayIter advance(); /** * Moves the iterator forward or backward by the given offset. * * @param count offset to move forward or backwards + * @return Iterator */ - public void advance(int count); + ArrayIter advance(int count); /** * Moves the iterator backward to the previous entry. + * + * @return Iterator */ - public void retract(); + ArrayIter retract(); /** * Moves the iterator to the given position * * @param off Seek offset + * @return Iterator + */ + ArrayIter seek(int off); + + /** + * Get current iterator offset. + * + * @return Iterator position */ - public void seek(int off); + int getOffset(); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java index 820217ec..68cd0448 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/ArrayListIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -60,12 +60,13 @@ public class ArrayListIter<O> implements ArrayIter { @Override public boolean valid() { - return pos < data.size(); + return pos < data.size() && pos >= 0; } @Override - public void advance() { + public ArrayIter advance() { pos++; + return this; } @Override @@ -74,18 +75,21 @@ public class ArrayListIter<O> implements ArrayIter { } @Override - public void advance(int count) { + public ArrayIter advance(int count) { pos += count; + return this; } @Override - public void retract() { + public ArrayIter retract() { pos--; + return this; } @Override - public void seek(int off) { + public ArrayIter seek(int off) { pos = off; + return this; } /** diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java index 3d111f14..b6ff34ad 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/Iter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -62,10 +62,12 @@ public interface Iter { * * @return a <code>boolean</code> value, whether the position is valid. */ - public boolean valid(); + boolean valid(); /** * Moves the iterator forward to the next entry. + * + * @return The iterator itself. */ - public void advance(); + Iter advance(); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java index 14e5443d..76be972f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/MIter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.datastructures.iterator; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java index d241fcc4..17dc7e44 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/iterator/package-info.java @@ -19,7 +19,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java index a0d894a9..db324217 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java index 3ce24e4e..e63ca693 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Description.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java index a1d649d4..336dd4db 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/DocumentationUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java index 8d2768e2..c9f13e64 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Reference.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -36,7 +36,7 @@ import java.lang.annotation.Target; */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) +@Target( { ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PACKAGE }) public @interface Reference { /** * Publication title. diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java index 0cb205df..e4f6bc68 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Restricted.java @@ -10,7 +10,7 @@ import java.lang.annotation.Target; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java index c77ca875..0c832526 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/Title.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.documentation; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java index d6f9ac3c..dd7ced9d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/documentation/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java index 47c46d46..b8e67e76 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVoting.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,14 +23,12 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; - /** * Interface for ensemble voting rules * * @author Erich Schubert */ -public interface EnsembleVoting extends Parameterizable { +public interface EnsembleVoting { /** * Combine scores function. Note: it is assumed that the scores are * comparable. diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java index 2e082761..bc511b1a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingInverseMultiplicative.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java index e179999d..67fbade9 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMax.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,8 +30,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; */ public class EnsembleVotingMax implements EnsembleVoting { /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + * Constructor. */ public EnsembleVotingMax() { // empty diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java index 19643782..08b3fada 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMean.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,8 +30,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; */ public class EnsembleVotingMean implements EnsembleVoting { /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + * Constructor. */ public EnsembleVotingMean() { // Empty. diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java index 85e7f6c8..8d3f5ff2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMedian.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java index b4baa4ab..9b7b754d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMin.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,8 +31,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; */ public class EnsembleVotingMin implements EnsembleVoting { /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + * Constructor. */ public EnsembleVotingMin() { // empty diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java index 3d99b8aa..bb941b5a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/EnsembleVotingMultiplicative.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.ensemble; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java index 76ee4ab8..552607dd 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/ensemble/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java index ab6430f4..5271a9d3 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/APIViolationException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java index 21179a62..9fda136a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/AbortException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java index cdaa6220..1214afeb 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ExceptionMessages.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team @@ -40,12 +40,6 @@ public interface ExceptionMessages { public static final String DATABASE_EMPTY = "database empty: must contain elements";
/**
- * Message when a new label was discovered in a database, that did not exist
- * before.
- */
- public static final String INCONSISTENT_STATE_NEW_LABEL = "inconsistent state of database - found new label";
-
- /**
* Message when an empty clustering is encountered.
*/
public static final String CLUSTERING_EMPTY = "Clustering doesn't contain any cluster.";
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java index 343a5b38..ecd644f0 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/NotImplementedException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java index 266ad0bb..1014e37c 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/ObjectNotFoundException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java index ecb80950..2d90d58f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/UnableToComplyException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.exceptions; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java index b55fd8ee..a156d821 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/exceptions/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java new file mode 100644 index 00000000..20225ded --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteArrayUtil.java @@ -0,0 +1,889 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.MappedByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CharsetEncoder; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import de.lmu.ifi.dbs.elki.logging.LoggingUtil; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; + +/** + * Class with various utilities for manipulating byte arrays. + * + * If you find a reusable copy of this in the Java API, please tell me. Using a + * {@link java.io.ByteArrayOutputStream} and {@link java.io.DataInputStream} + * doesn't seem appropriate. + * + * C.f. {@link java.io.DataOutputStream} and + * {@link java.io.ByteArrayOutputStream} + * + * @author Erich Schubert + * + * @apiviz.landmark + * + * @apiviz.composedOf ByteSerializer + * @apiviz.composedOf ShortSerializer + * @apiviz.composedOf IntegerSerializer + * @apiviz.composedOf LongSerializer + * @apiviz.composedOf FloatSerializer + * @apiviz.composedOf DoubleSerializer + * @apiviz.composedOf StringSerializer + * @apiviz.composedOf VarintSerializer + */ +public final class ByteArrayUtil { + /** + * Fake constructor. + */ + private ByteArrayUtil() { + // Do not instantiate + } + + /** + * Size of a byte in bytes. + */ + public static final int SIZE_BYTE = 1; + + /** + * Size of a short in bytes. + */ + public static final int SIZE_SHORT = 2; + + /** + * Size of an integer in bytes. + */ + public static final int SIZE_INT = 4; + + /** + * Size of a long in bytes. + */ + public static final int SIZE_LONG = 8; + + /** + * Size of a float in bytes. + */ + public static final int SIZE_FLOAT = 4; + + /** + * Size of a double in bytes. + */ + public static final int SIZE_DOUBLE = 8; + + /** + * Write a short to the byte array at the given offset. + * + * @param array Array to write to + * @param offset Offset to write to + * @param v data + * @return number of bytes written + */ + public static int writeShort(byte[] array, int offset, int v) { + array[offset + 0] = (byte) (v >>> 8); + array[offset + 1] = (byte) (v >>> 0); + return SIZE_SHORT; + } + + /** + * Write an integer to the byte array at the given offset. + * + * @param array Array to write to + * @param offset Offset to write to + * @param v data + * @return number of bytes written + */ + public static int writeInt(byte[] array, int offset, int v) { + array[offset + 0] = (byte) (v >>> 24); + array[offset + 1] = (byte) (v >>> 16); + array[offset + 2] = (byte) (v >>> 8); + array[offset + 3] = (byte) (v >>> 0); + return SIZE_INT; + } + + /** + * Write a long to the byte array at the given offset. + * + * @param array Array to write to + * @param offset Offset to write to + * @param v data + * @return number of bytes written + */ + public static int writeLong(byte[] array, int offset, long v) { + array[offset + 0] = (byte) (v >>> 56); + array[offset + 1] = (byte) (v >>> 48); + array[offset + 2] = (byte) (v >>> 40); + array[offset + 3] = (byte) (v >>> 32); + array[offset + 4] = (byte) (v >>> 24); + array[offset + 5] = (byte) (v >>> 16); + array[offset + 6] = (byte) (v >>> 8); + array[offset + 7] = (byte) (v >>> 0); + return SIZE_LONG; + } + + /** + * Write a float to the byte array at the given offset. + * + * @param array Array to write to + * @param offset Offset to write to + * @param v data + * @return number of bytes written + */ + public static int writeFloat(byte[] array, int offset, float v) { + return writeInt(array, offset, Float.floatToIntBits(v)); + } + + /** + * Write a double to the byte array at the given offset. + * + * @param array Array to write to + * @param offset Offset to write to + * @param v data + * @return number of bytes written + */ + public static int writeDouble(byte[] array, int offset, double v) { + return writeLong(array, offset, Double.doubleToLongBits(v)); + } + + /** + * Read a short from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return (signed) short + */ + public static short readShort(byte[] array, int offset) { + // First make integers to resolve signed vs. unsigned issues. + int b0 = array[offset + 0] & 0xFF; + int b1 = array[offset + 1] & 0xFF; + return (short) ((b0 << 8) + (b1 << 0)); + } + + /** + * Read an unsigned short from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return short + */ + public static int readUnsignedShort(byte[] array, int offset) { + // First make integers to resolve signed vs. unsigned issues. + int b0 = array[offset + 0] & 0xFF; + int b1 = array[offset + 1] & 0xFF; + return ((b0 << 8) + (b1 << 0)); + } + + /** + * Read an integer from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return data + */ + public static int readInt(byte[] array, int offset) { + // First make integers to resolve signed vs. unsigned issues. + int b0 = array[offset + 0] & 0xFF; + int b1 = array[offset + 1] & 0xFF; + int b2 = array[offset + 2] & 0xFF; + int b3 = array[offset + 3] & 0xFF; + return ((b0 << 24) + (b1 << 16) + (b2 << 8) + (b3 << 0)); + } + + /** + * Read a long from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return data + */ + public static long readLong(byte[] array, int offset) { + // First make integers to resolve signed vs. unsigned issues. + long b0 = array[offset + 0]; + long b1 = array[offset + 1] & 0xFF; + long b2 = array[offset + 2] & 0xFF; + long b3 = array[offset + 3] & 0xFF; + long b4 = array[offset + 4] & 0xFF; + int b5 = array[offset + 5] & 0xFF; + int b6 = array[offset + 6] & 0xFF; + int b7 = array[offset + 7] & 0xFF; + return ((b0 << 56) + (b1 << 48) + (b2 << 40) + (b3 << 32) + (b4 << 24) + (b5 << 16) + (b6 << 8) + (b7 << 0)); + } + + /** + * Read a float from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return data + */ + public static float readFloat(byte[] array, int offset) { + return Float.intBitsToFloat(readInt(array, offset)); + } + + /** + * Read a double from the byte array at the given offset. + * + * @param array Array to read from + * @param offset Offset to read at + * @return data + */ + public static double readDouble(byte[] array, int offset) { + return Double.longBitsToDouble(readLong(array, offset)); + } + + /** + * Serializer for byte objects. + * + * @author Erich Schubert + */ + public static final class ByteSerializer implements FixedSizeByteBufferSerializer<Byte> { + /** + * Constructor. Protected: use static instance! + */ + private ByteSerializer() { + super(); + } + + @Deprecated + @Override + public Byte fromByteBuffer(ByteBuffer buffer) { + return buffer.get(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Byte obj) { + buffer.put(obj); + } + + @Deprecated + @Override + public int getByteSize(Byte object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_BYTE; + } + } + + /** + * Serializer for short objects. + * + * @author Erich Schubert + */ + public static final class ShortSerializer implements FixedSizeByteBufferSerializer<Short> { + /** + * Constructor. Protected: use static instance! + */ + private ShortSerializer() { + super(); + } + + @Deprecated + @Override + public Short fromByteBuffer(ByteBuffer buffer) { + return buffer.getShort(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Short obj) { + buffer.putShort(obj); + } + + @Deprecated + @Override + public int getByteSize(Short object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_SHORT; + } + } + + /** + * Serializer for integer objects. + * + * @author Erich Schubert + */ + public static final class IntegerSerializer implements FixedSizeByteBufferSerializer<Integer> { + /** + * Constructor. Protected: use static instance! + */ + private IntegerSerializer() { + super(); + } + + @Deprecated + @Override + public Integer fromByteBuffer(ByteBuffer buffer) { + return buffer.getInt(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Integer obj) { + buffer.putInt(obj); + } + + @Deprecated + @Override + public int getByteSize(Integer object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_INT; + } + } + + /** + * Serializer for long objects. + * + * @author Erich Schubert + */ + public static final class LongSerializer implements FixedSizeByteBufferSerializer<Long> { + /** + * Constructor. Protected: use static instance! + */ + private LongSerializer() { + super(); + } + + @Deprecated + @Override + public Long fromByteBuffer(ByteBuffer buffer) { + return buffer.getLong(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Long obj) { + buffer.putLong(obj); + } + + @Deprecated + @Override + public int getByteSize(Long object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_LONG; + } + } + + /** + * Serializer for float objects. + * + * @author Erich Schubert + */ + public static final class FloatSerializer implements FixedSizeByteBufferSerializer<Float> { + /** + * Constructor. Protected: use static instance! + */ + private FloatSerializer() { + super(); + } + + @Deprecated + @Override + public Float fromByteBuffer(ByteBuffer buffer) { + return buffer.getFloat(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Float obj) { + buffer.putFloat(obj); + } + + @Deprecated + @Override + public int getByteSize(Float object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_FLOAT; + } + } + + /** + * Serializer for double objects. + * + * @author Erich Schubert + */ + public static final class DoubleSerializer implements FixedSizeByteBufferSerializer<Double> { + /** + * Constructor. Protected: use static instance! + */ + private DoubleSerializer() { + super(); + } + + @Deprecated + @Override + public Double fromByteBuffer(ByteBuffer buffer) { + return buffer.getDouble(); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Double obj) { + buffer.putDouble(obj); + } + + @Deprecated + @Override + public int getByteSize(Double object) { + return getFixedByteSize(); + } + + @Override + public int getFixedByteSize() { + return SIZE_DOUBLE; + } + } + + /** + * Serializer for String objects. + * + * @author Erich Schubert + */ + public static final class StringSerializer implements ByteBufferSerializer<String> { + /** + * Character set to use. + */ + Charset charset = Charset.forName("UTF-8"); + + /** + * Encoder. + */ + CharsetEncoder encoder = charset.newEncoder(); + + /** + * Decoder. + */ + CharsetDecoder decoder = charset.newDecoder(); + + /** + * Constructor. Protected: use static instance! + */ + private StringSerializer() { + super(); + } + + @Override + public String fromByteBuffer(ByteBuffer buffer) { + int len = readUnsignedVarint(buffer); + // Create and limit a view + ByteBuffer subbuffer = buffer.slice(); + subbuffer.limit(len); + CharBuffer res; + try { + res = decoder.decode(subbuffer); + } catch (CharacterCodingException e) { + throw new AbortException("String not representable as UTF-8.", e); + } + // TODO: assert that the decoding did not yet advance the buffer! + buffer.position(buffer.position() + len); + return res.toString(); + } + + @Override + public void toByteBuffer(ByteBuffer buffer, String obj) { + ByteBuffer data; + try { + data = encoder.encode(CharBuffer.wrap(obj)); + } catch (CharacterCodingException e) { + throw new AbortException("String not representable as UTF-8.", e); + } + writeUnsignedVarint(buffer, data.remaining()); + buffer.put(data); + } + + @Override + public int getByteSize(String object) { + try { + final int len = encoder.encode(CharBuffer.wrap(object)).remaining(); + return getUnsignedVarintSize(len) + len; + } catch (CharacterCodingException e) { + throw new AbortException("String not representable as UTF-8.", e); + } + } + } + + /** + * Serializer for Integer objects using a variable size encoding. + * + * @author Erich Schubert + */ + public static final class VarintSerializer implements ByteBufferSerializer<Integer> { + /** + * Constructor. Protected: use static instance! + */ + private VarintSerializer() { + super(); + } + + @Deprecated + @Override + public Integer fromByteBuffer(ByteBuffer buffer) { + return readSignedVarint(buffer); + } + + @Deprecated + @Override + public void toByteBuffer(ByteBuffer buffer, Integer obj) { + writeSignedVarint(buffer, obj); + } + + @Deprecated + @Override + public int getByteSize(Integer object) { + return getSignedVarintSize(object); + } + } + + /** + * Static instance. + */ + public static final ByteSerializer BYTE_SERIALIZER = new ByteSerializer(); + + /** + * Static instance. + */ + public static final ShortSerializer SHORT_SERIALIZER = new ShortSerializer(); + + /** + * Static instance. + */ + public static final IntegerSerializer INT_SERIALIZER = new IntegerSerializer(); + + /** + * Static instance. + */ + public static final LongSerializer LONG_SERIALIZER = new LongSerializer(); + + /** + * Static instance. + */ + public static final FloatSerializer FLOAT_SERIALIZER = new FloatSerializer(); + + /** + * Static instance. + */ + public static final DoubleSerializer DOUBLE_SERIALIZER = new DoubleSerializer(); + + /** + * Static instance. + */ + public static final StringSerializer STRING_SERIALIZER = new StringSerializer(); + + /** + * Static instance. + */ + public static final VarintSerializer VARINT_SERIALIZER = new VarintSerializer(); + + /** + * Write an signed integer using a variable-length encoding. + * + * The sign bit is moved to bit 0. + * + * Data is always written in 7-bit little-endian, where the 8th bit is the + * continuation flag. + * + * @param buffer Buffer to write to + * @param val number to write + */ + public static void writeSignedVarint(ByteBuffer buffer, int val) { + // Move sign to lowest bit + writeUnsignedVarint(buffer, (val << 1) ^ (val >> 31)); + } + + /** + * Write a signed long using a variable-length encoding. + * + * The sign bit is moved to bit 0. + * + * Data is always written in 7-bit little-endian, where the 8th bit is the + * continuation flag. + * + * @param buffer Buffer to write to + * @param val number to write + */ + public static void writeSignedVarintLong(ByteBuffer buffer, long val) { + // Move sign to lowest bit + writeUnsignedVarintLong(buffer, (val << 1) ^ (val >> 63)); + } + + /** + * Write an unsigned integer using a variable-length encoding. + * + * Data is always written in 7-bit little-endian, where the 8th bit is the + * continuation flag. + * + * @param buffer Buffer to write to + * @param val number to write + */ + public static void writeUnsignedVarint(ByteBuffer buffer, int val) { + // Extra bytes have the high bit set + while ((val & 0x7F) != val) { + buffer.put((byte) ((val & 0x7F) | 0x80)); + val >>>= 7; + } + // Last byte doesn't have high bit set + buffer.put((byte) (val & 0x7F)); + } + + /** + * Write an unsigned long using a variable-length encoding. + * + * Data is always written in 7-bit little-endian, where the 8th bit is the + * continuation flag. + * + * Note that for integers, this will result in the same encoding as + * {@link #writeUnsignedVarint} + * + * @param buffer Buffer to write to + * @param val number to write + */ + public static void writeUnsignedVarintLong(ByteBuffer buffer, long val) { + // Extra bytes have the high bit set + while ((val & 0x7F) != val) { + buffer.put((byte) ((val & 0x7F) | 0x80)); + val >>>= 7; + } + // Last byte doesn't have high bit set + buffer.put((byte) (val & 0x7F)); + } + + /** + * Write a string to the buffer. + * + * See {@link StringSerializer} for details. + * + * @param buffer Buffer to write to + * @param s String to write + */ + public static void writeString(ByteBuffer buffer, String s) { + if (s == null) { + s = ""; // Which will be written as Varint 0 = single byte 0. + } + ByteArrayUtil.STRING_SERIALIZER.toByteBuffer(buffer, s); + } + + /** + * Compute the size of the varint encoding for this signed integer. + * + * @param val integer to write + * @return Encoding size of this integer + */ + public static int getSignedVarintSize(int val) { + // Move sign to lowest bit + return getUnsignedVarintSize((val << 1) ^ (val >> 31)); + } + + /** + * Compute the size of the varint encoding for this unsigned integer. + * + * @param obj integer to write + * @return Encoding size of this integer + */ + public static int getUnsignedVarintSize(int obj) { + int bytes = 1; + // Extra bytes have the high bit set + while ((obj & 0x7F) != obj) { + bytes++; + obj >>>= 7; + } + return bytes; + } + + /** + * Compute the size of the varint encoding for this signed integer. + * + * @param val integer to write + * @return Encoding size of this integer + */ + public static int getSignedVarintLongSize(long val) { + // Move sign to lowest bit + return getUnsignedVarintLongSize((val << 1) ^ (val >> 31)); + } + + /** + * Compute the size of the varint encoding for this unsigned integer. + * + * @param obj integer to write + * @return Encoding size of this integer + */ + public static int getUnsignedVarintLongSize(long obj) { + int bytes = 1; + // Extra bytes have the high bit set + while ((obj & 0x7F) != obj) { + bytes++; + obj >>>= 7; + } + return bytes; + } + + /** + * Compute the size of the string after encoding. + * + * @param s String to encode + * @return Byte size + */ + public static int getStringSize(String s) { + return STRING_SERIALIZER.getByteSize(s); + } + + /** + * Read a signed integer. + * + * @param buffer Buffer to read from + * @return Integer value + */ + public static int readSignedVarint(ByteBuffer buffer) { + final int raw = readUnsignedVarint(buffer); + return (raw >>> 1) ^ -(raw & 1); + } + + /** + * Read an unsigned integer. + * + * @param buffer Buffer to read from + * @return Integer value + */ + public static int readUnsignedVarint(ByteBuffer buffer) { + int val = 0; + int bits = 0; + while (true) { + final int data = buffer.get(); + val |= (data & 0x7F) << bits; + if ((data & 0x80) == 0) { + return val; + } + bits += 7; + if (bits > 35) { + throw new AbortException("Variable length quantity is too long for expected integer."); + } + } + } + + /** + * Read a signed long. + * + * @param buffer Buffer to read from + * @return long value + */ + public static long readSignedVarintLong(ByteBuffer buffer) { + final long raw = readUnsignedVarintLong(buffer); + return (raw >>> 1) ^ -(raw & 1); + } + + /** + * Read an unsigned long. + * + * @param buffer Buffer to read from + * @return long value + */ + public static long readUnsignedVarintLong(ByteBuffer buffer) { + long val = 0; + int bits = 0; + while (true) { + final int data = buffer.get(); + val |= (data & 0x7F) << bits; + if ((data & 0x80) == 0) { + return val; + } + bits += 7; + if (bits > 63) { + throw new AbortException("Variable length quantity is too long for expected integer."); + } + } + } + + /** + * Read a string from the buffer. + * + * Note: this is not 100% symmetric to writeString, as a {@code null} value + * and the empty string are encoded the same way. + * + * @param buffer Buffer to read from. + * @return Deserialized string + */ + public static String readString(ByteBuffer buffer) { + return STRING_SERIALIZER.fromByteBuffer(buffer); + } + + /** + * Unmap a byte buffer. + * + * @param map Byte buffer to unmap. + */ + public static void unmapByteBuffer(final MappedByteBuffer map) { + if (map == null) { + return; + } + map.force(); + // This is an ugly hack, but all that Java currently offers. + // See also: http://bugs.sun.com/view_bug.do?bug_id=4724038 + AccessController.doPrivileged(new PrivilegedAction<Object>() { + @Override + public Object run() { + try { + Method getCleanerMethod = map.getClass().getMethod("cleaner", new Class[0]); + if (getCleanerMethod == null) { + return null; + } + + getCleanerMethod.setAccessible(true); + Object cleaner = getCleanerMethod.invoke(map, new Object[0]); + Method cleanMethod = cleaner.getClass().getMethod("clean"); + if (cleanMethod == null) { + return null; + } + cleanMethod.invoke(cleaner); + } catch (Exception e) { + LoggingUtil.exception(e); + } + return null; + } + }); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java new file mode 100644 index 00000000..57cd352d --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferInputStream.java @@ -0,0 +1,67 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.io.InputStream; +import java.nio.ByteBuffer; + +/** + * Wrap an existing ByteBuffer as InputStream. + * + * @author Erich Schubert + * + * @apiviz.has ByteBuffer + */ +public class ByteBufferInputStream extends InputStream { + /** + * The actual buffer we're using. + */ + final ByteBuffer buffer; + + /** + * Constructor. + * + * @param buffer ByteBuffer to wrap. + */ + public ByteBufferInputStream(ByteBuffer buffer) { + super(); + this.buffer = buffer; + } + + @Override + public int read() { + if(buffer.hasRemaining()) { + return -1; + } + // Note: is this and 0xFF needed? + return (buffer.get() & 0xFF); + } + + @Override + public int read(byte[] b, int off, int len) { + final int maxread = Math.min(len, buffer.remaining()); + buffer.get(b, off, maxread); + return maxread == 0 ? -1 : maxread; + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferOutputStream.java index fde1f3a9..d589a782 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairInterface.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferOutputStream.java @@ -1,10 +1,10 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; +package de.lmu.ifi.dbs.elki.utilities.io; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,31 +23,39 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.io.OutputStream; +import java.nio.ByteBuffer; /** - * Pair interface. - * - * Note: this currently is <em>empty by design</em>. You should always decide - * explicitly whether to use boxing pairs {@link Pair} or primitive pairs such - * as {@link IntIntPair} + * Wrap an existing ByteBuffer as OutputStream. * * @author Erich Schubert * - * @param FIRST first type - * @param SECOND second type + * @apiviz.has ByteBuffer */ -public interface PairInterface<FIRST, SECOND> { +public class ByteBufferOutputStream extends OutputStream { /** - * Get the first object - note: this may cause autoboxing, use pair.first for native pairs! - * - * @return First object + * The actual buffer we're using. */ - public FIRST getFirst(); - + final ByteBuffer buffer; + /** - * Get the second object - note: this may cause autoboxing, use pair.second for native pairs! + * Constructor. * - * @return Second object + * @param buffer ByteBuffer to wrap. */ - public SECOND getSecond(); + public ByteBufferOutputStream(ByteBuffer buffer) { + super(); + this.buffer = buffer; + } + + @Override + public void write(int b) { + buffer.put((byte) b); + } + + @Override + public void write(byte[] b, int off, int len) { + buffer.put(b, off, len); + } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java new file mode 100644 index 00000000..c20e999b --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/ByteBufferSerializer.java @@ -0,0 +1,72 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.io.IOException; +import java.nio.ByteBuffer; + +/** + * Class to convert from and to byte arrays (in index structures). + * + * @author Erich Schubert + * + * @apiviz.has ByteBuffer - - oneway «serializes to/from» + * @apiviz.excludeSubtypes + * + * @param <T> Object type processed + */ +public interface ByteBufferSerializer<T> { + /** + * Deserialize an object from a byte buffer (e.g. disk) + * + * @param buffer Data array to process + * @return Deserialized object + * @throws IOException on IO errors + * @throws UnsupportedOperationException When functionality not implemented or + * available + */ + T fromByteBuffer(ByteBuffer buffer) throws IOException, UnsupportedOperationException; + + /** + * Serialize the object to a byte array (e.g. disk) + * + * @param buffer Buffer to serialize to + * @param object Object to serialize + * @throws IOException on IO errors + * @throws UnsupportedOperationException When functionality not implemented or + * available + */ + void toByteBuffer(ByteBuffer buffer, T object) throws IOException, UnsupportedOperationException; + + /** + * Get the size of the object in bytes. + * + * @param object Object to serialize + * @return maximum size in serialized form + * @throws IOException on IO errors + * @throws UnsupportedOperationException When functionality not implemented or + * available + */ + int getByteSize(T object) throws IOException, UnsupportedOperationException; +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java new file mode 100644 index 00000000..b46c5ac8 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/FixedSizeByteBufferSerializer.java @@ -0,0 +1,41 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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/>. + */ + +/** + * Serializers with a fixed length serialization. + * + * @author Erich Schubert + * @apiviz.excludeSubtypes + * + * @param <T> Type + */ +public interface FixedSizeByteBufferSerializer<T> extends ByteBufferSerializer<T> { + /** + * Get the fixed size needed by this serializer. + * + * @return Size + */ + public int getFixedByteSize(); +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java b/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java new file mode 100644 index 00000000..115a5df6 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/LineReader.java @@ -0,0 +1,122 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Fast class to read a file, line per line. + * + * Lines must be split using Unix newlines <code>\n</code>, linefeeds + * <code>\r</code> are ignored. + * + * This is a rather minimal implementation, which supposedly pays off in + * performance. In particular, this class allows recycling the buffer, which + * will yield less object allocations and thus less garbage collection. + * + * Usage example: + * + * <pre> + * StringBuilder buf = new StringBuilder(); + * LineReader reader = new LineReader(inputStream); + * // Clear buffer, and append next line. + * while(reader.readLine(buf.delete(0, buf.length()))) { + * // process string in buffer. + * } + * </pre> + * + * @author Erich Schubert + */ +public class LineReader implements AutoCloseable { + /** Buffer size to use */ + final static int BUFFER_SIZE = 4096; + + /** Input stream to read from */ + Reader in; + + /** Character buffer */ + char[] buffer = new char[BUFFER_SIZE]; + + /** Current position, and length of buffer */ + int pos = 0, end = 0; + + /** + * Constructor + * + * @param in Stream + */ + public LineReader(InputStream in) { + this(new InputStreamReader(in)); + } + + /** + * Constructor + * + * @param in Reader + */ + public LineReader(Reader in) { + this.in = in; + } + + /** + * Read a line into the given buffer. + * + * @param buf Buffer. + * @return {@code true} if some characters have been read. + */ + public boolean readLine(Appendable buf) throws IOException { + boolean success = false; + while(true) { + // Process buffer: + while(pos < end) { + success = true; + final char c = buffer[pos++]; + if(c == '\n') { + return success; + } + if(c == '\r') { + continue; + } + buf.append(c); + } + // Refill buffer: + assert (pos >= end) : "Buffer wasn't empty when refilling!"; + end = in.read(buffer, 0, buffer.length); + pos = 0; + if(end < 0) { // End of stream. + return success; + } + } + } + + @Override + public void close() throws IOException { + if(in != null) { + in.close(); + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java b/src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java new file mode 100644 index 00000000..497c1a2b --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/Tokenizer.java @@ -0,0 +1,278 @@ +package de.lmu.ifi.dbs.elki.utilities.io; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.regex.Matcher; +import java.util.regex.Pattern; + +import de.lmu.ifi.dbs.elki.logging.Logging; +import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter; + +/** + * String tokenizer. + * + * @author Erich Schubert + */ +public class Tokenizer implements Iter { + /** + * Class logger. + */ + private static final Logging LOG = Logging.getLogger(Tokenizer.class); + + /** + * Quote characters + */ + public static final String QUOTE_CHAR = "\"'"; + + /** + * Stores the quotation character + */ + private char[] quoteChars = QUOTE_CHAR.toCharArray(); + + /** + * Constructor. + * + * @param colSep Column separator pattern. + * @param quoteChars Quotation character. + */ + public Tokenizer(Pattern colSep, String quoteChars) { + super(); + this.matcher = colSep.matcher("Dummy text"); + this.quoteChars = quoteChars != null ? quoteChars.toCharArray() : new char[0]; + } + + /** + * Regular expression match helper. + */ + private Matcher matcher; + + /** + * Data currently processed. + */ + private CharSequence input; + + /** + * Substring to process. + */ + private int send; + + /** + * Current positions of result and iterator. + */ + private int start, end, index; + + /** + * Whether the current token is a quoted string. + */ + private boolean quoted; + + /** + * Initialize parser with a new string. + * + * @param input New string to parse. + * @param begin Begin + * @param end End + */ + public void initialize(CharSequence input, int begin, int end) { + this.input = input; + this.send = end; + this.matcher.reset(input).region(begin, end); + this.index = begin; + advance(); + } + + @Override + public boolean valid() { + return start < send; + } + + @Override + public Tokenizer advance() { + char inquote = isQuote(index); + while(matcher.find()) { + // Quoted code path vs. regular code path + if(inquote != 0) { + // Matching closing quote found? + if(matcher.start() > index + 1 && input.charAt(matcher.start() - 1) == inquote) { + this.start = index + 1; + this.end = matcher.start() - 1; + this.index = matcher.end(); + this.quoted = true; + return this; + } + continue; + } + else { + this.start = index; + this.end = matcher.start(); + this.index = matcher.end(); + this.quoted = false; + return this; + } + } + // Add tail after last separator. + this.start = index; + this.end = send; + this.index = end + 1; + this.quoted = false; + if(inquote != 0) { + final int last = send - 1; + if(input.charAt(last) == inquote) { + ++this.start; + --this.end; + this.quoted = true; + } + else { + LOG.warning("Invalid quoted line in input: no closing quote found in: " + input); + } + } + return this; + } + + /** + * Get the current part as substring + * + * @return Current value as substring. + */ + public String getSubstring() { + // TODO: detect Java <6 and make sure we only return the substring? + // With java 7, String.substring will arraycopy the characters. + return input.subSequence(start, end).toString(); + } + + /** + * Get the current part as substring + * + * @return Current value as substring. + */ + public String getStrippedSubstring() { + // TODO: detect Java <6 and make sure we only return the substring? + // With java 7, String.substring will arraycopy the characters. + int sstart = start, send = end; + while(sstart < send) { + char c = input.charAt(sstart); + if(c != ' ' || c != '\n' || c != '\r' || c != '\t') { + break; + } + ++sstart; + } + while(--send >= sstart) { + char c = input.charAt(send); + if(c != ' ' || c != '\n' || c != '\r' || c != '\t') { + break; + } + } + ++send; + return (sstart < send) ? input.subSequence(sstart, send).toString() : ""; + } + + /** + * Get current value as double. + * + * @return double value + * @throws NumberFormatException when current value cannot be parsed as double + * value. + */ + public double getDouble() throws NumberFormatException { + return FormatUtil.parseDouble(input, start, end); + } + + /** + * Get current value as long. + * + * @return double value + * @throws NumberFormatException when current value cannot be parsed as long + * value. + */ + public long getLongBase10() throws NumberFormatException { + return FormatUtil.parseLongBase10(input, start, end); + } + + /** + * Test for empty tokens; usually at end of line. + * + * @return Empty + */ + public boolean isEmpty() { + return end <= start; + } + + /** + * Detect quote characters. + * + * TODO: support more than one quote character, make sure opening and closing + * quotes match then. + * + * @param index Position + * @return {@code 1} when a quote character, {@code 0} otherwise. + */ + private char isQuote(int index) { + if(index >= input.length()) { + return 0; + } + char c = input.charAt(index); + for(int i = 0; i < quoteChars.length; i++) { + if(c == quoteChars[i]) { + return c; + } + } + return 0; + } + + /** + * Test if the current string was quoted. + * + * @return {@code true} when quoted. + */ + public boolean isQuoted() { + return quoted; + } + + /** + * Get start of token. + * + * @return Start + */ + public int getStart() { + return start; + } + + /** + * Get end of token. + * + * @return End + */ + public int getEnd() { + return end; + } + + /** + * Perform cleanup. + */ + public void cleanup() { + input = null; + matcher.reset(""); + } +} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java new file mode 100644 index 00000000..3518e7b7 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/io/package-info.java @@ -0,0 +1,29 @@ +/** + * Utility classes for input/output. + * + * @author Erich Schubert + */ + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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.utilities.io;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java index 6aa22964..0fa9b240 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/AbstractParameterizer.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java index 1cff200a..aa77c364 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/InternalParameterizationErrors.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java index 53d992ff..e0266028 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/NoParameterValueException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java index 60e51a98..60afb2b1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionID.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -42,10 +42,7 @@ public final class OptionID { private String description; /** - * Provides a new OptionID of the given name and description. - * <p/> - * All OptionIDs are unique w.r.t. their name. An OptionID provides - * additionally a description of the option. + * Constructor. * * @param name the name of the option * @param description the description of the option diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java index ea28aa42..32d7a84d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/OptionUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,10 +31,10 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; import de.lmu.ifi.dbs.elki.utilities.documentation.DocumentationUtil; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackedParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedParameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; /** * Utility functions related to Option handling. @@ -123,11 +123,11 @@ public final class OptionUtil { * @param indent Indentation string * @param options List of options */ - public static void formatForConsole(StringBuilder buf, int width, String indent, Collection<Pair<Object, Parameter<?>>> options) { - for(Pair<Object, Parameter<?>> pair : options) { - String currentOption = pair.getSecond().getName(); - String syntax = pair.getSecond().getSyntax(); - String longDescription = pair.getSecond().getFullDescription(); + public static void formatForConsole(StringBuilder buf, int width, String indent, Collection<TrackedParameter> options) { + for(TrackedParameter pair : options) { + String currentOption = pair.getParameter().getName(); + String syntax = pair.getParameter().getSyntax(); + String longDescription = pair.getParameter().getFullDescription(); buf.append(SerializedParameterization.OPTION_PREFIX); buf.append(currentOption); @@ -196,7 +196,7 @@ public final class OptionUtil { TrackParameters track = new TrackParameters(config); @SuppressWarnings("unused") Object p = ClassGenericsUtil.tryInstantiate(Object.class, pcls, track); - Collection<Pair<Object, Parameter<?>>> options = track.getAllParameters(); + Collection<TrackedParameter> options = track.getAllParameters(); if(options.size() > 0) { OptionUtil.formatForConsole(buf, width, indent, options); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java index 326335fd..0c9d5421 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/ParameterException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java deleted file mode 100644 index ead565b1..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizable.java +++ /dev/null @@ -1,100 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.optionhandling; - -/* - 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/>. - */ - -/** - * Interface to define the required methods for command line interaction. - * - * <b>Important note:</b> - * - * <p> - * Although <em>this cannot be specified in a Java interface</em>, any class - * implementing this interface <em>must</em> also have a constructor that takes - * a single - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization} - * as option, which is used to set the class parameters. - * </p> - * - * <p> - * Alternatively, a constructor with no options is also allowed. - * </p> - * - * <p> - * This means, each class implementing Parameterizable - * <em>must have a constructor that either is</em> <blockquote> - * - * <pre> - * {@code - * public Class(Parameterizable config) { ... } - * } - * </pre> - * - * </blockquote> or <blockquote> - * - * <pre> - * {@code - * public Class() { ... } - * } - * </pre> - * - * </blockquote> - * </p> - * - * <p> - * Constructors <em>MUST</em> not do expensive operations or allocations, since - * they will also be called just to determine and validate parameters. - * </p> - * - * <p> - * For <em>documentation</em>, the classes should also be annotated with - * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Title} - * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Description} and - * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Reference} (where - * possible). - * </p> - * - * <p> - * Please check the <em>package documentation</em> for full information on this - * interface. - * </p> - * - * <p> - * The application - * {@link de.lmu.ifi.dbs.elki.application.internal.CheckParameterizables} can be - * used to check this class contracts. - * </p> - * - * @author Erich Schubert - * - * @apiviz.exclude - * @apiviz.excludeSubtypes - * @apiviz.has de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter - * oneway - n - * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization - * .Parameterization oneway - */ -public interface Parameterizable { - // Empty marker interface - the \@Description / \@Title / \@Reference and - // constructor requirements cannot be specified in Java! -} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java index 7e3a848c..b7017206 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/Parameterizer.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java index 31af6d87..8d22b113 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnspecifiedParameterException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java index d5dbd4b2..6bd13429 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/UnusedParameterException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java index eeb6a9e7..3f34efb7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/WrongParameterValueException.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -54,7 +54,7 @@ public class WrongParameterValueException extends ParameterException { * @param cause the cause */ public WrongParameterValueException(Parameter<?> parameter, String read, Throwable cause) { - this("Wrong value of parameter \"" + parameter.getName() + "\".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + cause.getMessage(), cause); + this("Wrong value of parameter \"" + parameter.getName() + "\".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + formatCause(cause), cause); } /** @@ -66,7 +66,7 @@ public class WrongParameterValueException extends ParameterException { * @param cause the cause */ public WrongParameterValueException(Parameter<?> parameter, String read, String reason, Throwable cause) { - this("Wrong value of parameter " + parameter.getName() + ".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + reason + "\n" + cause.getMessage(), cause); + this("Wrong value of parameter " + parameter.getName() + ".\n" + "Read: " + read + ".\n" + "Expected: " + parameter.getFullDescription() + "\n" + reason + "\n" + formatCause(cause), cause); } /** @@ -98,4 +98,21 @@ public class WrongParameterValueException extends ParameterException { public WrongParameterValueException(String message, Throwable e) { super(message, e); } + + /** + * Format the error cause. + * + * @param cause Error cause. + * @return String representation + */ + private static String formatCause(Throwable cause) { + if(cause == null) { + return ""; + } + String message = cause.getMessage(); + if(message != null) { + return message; + } + return cause.toString(); + } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java index fc4a673e..edd6166e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java index a87af1a8..dfa9ffae 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AllOrNoneMustBeSetGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java index ea1caed9..6464ed13 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/CommonConstraints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,6 +29,9 @@ import java.util.List; * Class storing a number of very common constraints. * * @author Erich Schubert + * + * @apiviz.landmark + * @apiviz.composedOf ParameterConstraint */ public final class CommonConstraints { /** diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java index 586b4257..56ecd0b6 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualSizeGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java index 1ab35cc1..3dda08b6 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java index 7c35045e..997e7295 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalListSizeConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -71,7 +71,7 @@ public class GlobalListSizeConstraint implements GlobalParameterConstraint { return; } - if(list.getListSize() != length.getValue().intValue()) { + if(list.getListSize() != length.intValue()) { throw new WrongParameterValueException("Global Parameter Constraint Error." + "\nThe size of the list parameter \"" + list.getName() + "\" must be " + length.getValue() + ", current size is " + list.getListSize() + ". The value is defined by the integer parameter " + length.getName() + ".\n"); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java index 5e38b2b7..e249e0ef 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalParameterConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java index 01c99d42..9afd0a56 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GlobalVectorListElementSizeConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,8 +23,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.List; - +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; @@ -74,8 +73,8 @@ public class GlobalVectorListElementSizeConstraint implements GlobalParameterCon return; } - for(List<Double> vec : vector.getValue()) { - if(vec.size() != size.getValue().intValue()) { + for(Vector vec : vector.getValue()) { + if(vec.getDimensionality() != size.intValue()) { throw new WrongParameterValueException("Global Parameter Constraint Error.\n" + "The vectors of vector list parameter " + vector.getName() + " have not the required dimension of " + size.getValue() + " given by integer parameter " + size.getName() + "."); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java index 33c73fb8..8ec817e9 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java index d05235c1..ba3d63e9 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/GreaterEqualConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java deleted file mode 100644 index 00c2f5ad..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java +++ /dev/null @@ -1,217 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; - -/* - 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 de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException; - -/** - * Represents an interval parameter constraint testing if a given value lies - * within the specified interval. The value of the number parameter ( - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter} - * ) tested has to be greater than (or equal to, if specified) than the - * specified low constraint value and less than (or equal to, if specified) than - * the specified high constraint value. - * - * @author Steffi Wanka - * - * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter - * - * @deprecated Use two constraints instead. - */ -@Deprecated -public class IntervalConstraint implements ParameterConstraint<Number> { - /** - * Available interval boundary types types: - * {@link IntervalConstraint.IntervalBoundary#OPEN} denotes an open interval, - * i.e. less than (or greater than) comparison - * {@link IntervalConstraint.IntervalBoundary#CLOSE} denotes a closed - * interval, i.e. an equal to or less than (or equal to or greater than) - * comparison - * - * @apiviz.exclude - */ - public enum IntervalBoundary { - /** - * Open interval boundary - */ - OPEN, - /** - * Closed interval boundary - */ - CLOSE - } - - /** - * The low constraint value (left interval boundary). - */ - private final Number lowConstraintValue; - - /** - * The interval boundary for the low constraint value. - * - * @see IntervalBoundary - */ - private final IntervalBoundary lowBoundary; - - /** - * The high constraint value (right interval boundary). - */ - private final Number highConstraintValue; - - /** - * The interval boundary for the high constraint value. - * - * @see IntervalBoundary - */ - private final IntervalBoundary highBoundary; - - /** - * Creates an IntervalConstraint parameter constraint. - * <p/> - * That is, the value of the number parameter given has to be greater than (or - * equal to, if specified) than the specified low constraint value and less - * than (or equal to, if specified) than the specified high constraint value. - * - * @param lowConstraintValue the low constraint value (left interval boundary) - * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary}) - * @param highConstraintValue the high constraint value (right interval - * boundary) - * @param highBoundary the interval boundary for the high constraint value - * (see {@link IntervalBoundary}) - */ - public IntervalConstraint(Number lowConstraintValue, IntervalBoundary lowBoundary, Number highConstraintValue, IntervalBoundary highBoundary) { - if(lowConstraintValue.doubleValue() >= highConstraintValue.doubleValue()) { - throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!"); - } - - this.lowConstraintValue = lowConstraintValue; - this.lowBoundary = lowBoundary; - this.highConstraintValue = highConstraintValue; - this.highBoundary = highBoundary; - } - - /** - * Creates an IntervalConstraint parameter constraint. - * <p/> - * That is, the value of the number parameter given has to be greater than (or - * equal to, if specified) than the specified low constraint value and less - * than (or equal to, if specified) than the specified high constraint value. - * - * @param lowConstraintValue the low constraint value (left interval boundary) - * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary}) - * @param highConstraintValue the high constraint value (right interval - * boundary) - * @param highBoundary the interval boundary for the high constraint value - * (see {@link IntervalBoundary}) - */ - public IntervalConstraint(int lowConstraintValue, IntervalBoundary lowBoundary, int highConstraintValue, IntervalBoundary highBoundary) { - if(lowConstraintValue >= highConstraintValue) { - throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!"); - } - - this.lowConstraintValue = Integer.valueOf(lowConstraintValue); - this.lowBoundary = lowBoundary; - this.highConstraintValue = Integer.valueOf(highConstraintValue); - this.highBoundary = highBoundary; - } - - /** - * Creates an IntervalConstraint parameter constraint. - * <p/> - * That is, the value of the number parameter given has to be greater than (or - * equal to, if specified) than the specified low constraint value and less - * than (or equal to, if specified) than the specified high constraint value. - * - * @param lowConstraintValue the low constraint value (left interval boundary) - * @param lowBoundary the interval boundary for the low constraint value (see {@link IntervalBoundary}) - * @param highConstraintValue the high constraint value (right interval - * boundary) - * @param highBoundary the interval boundary for the high constraint value - * (see {@link IntervalBoundary}) - */ - public IntervalConstraint(double lowConstraintValue, IntervalBoundary lowBoundary, double highConstraintValue, IntervalBoundary highBoundary) { - if(lowConstraintValue >= highConstraintValue) { - throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!"); - } - - this.lowConstraintValue = Double.valueOf(lowConstraintValue); - this.lowBoundary = lowBoundary; - this.highConstraintValue = Double.valueOf(highConstraintValue); - this.highBoundary = highBoundary; - } - - /** - * Checks if the number value given by the number parameter is greater equal - * than the constraint value. If not, a parameter exception is thrown. - * - */ - @Override - public void test(Number t) throws ParameterException { - // lower value - if(lowBoundary.equals(IntervalBoundary.CLOSE)) { - if(t.doubleValue() < lowConstraintValue.doubleValue()) { - throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n"); - } - } - else if(lowBoundary.equals(IntervalBoundary.OPEN)) { - if(t.doubleValue() <= lowConstraintValue.doubleValue()) { - throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n"); - } - } - - // higher value - if(highBoundary.equals(IntervalBoundary.CLOSE)) { - if(t.doubleValue() > highConstraintValue.doubleValue()) { - throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n"); - } - } - else if(highBoundary.equals(IntervalBoundary.OPEN)) { - if(t.doubleValue() >= highConstraintValue.doubleValue()) { - throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n"); - } - } - } - - @Override - public String getDescription(String parameterName) { - String description = parameterName + " in "; - if(lowBoundary.equals(IntervalBoundary.CLOSE)) { - description += "["; - } - else if(lowBoundary.equals(IntervalBoundary.OPEN)) { - description += "("; - } - - description += lowConstraintValue.toString() + ", " + highConstraintValue; - - if(highBoundary.equals(IntervalBoundary.CLOSE)) { - description += "]"; - } - if(highBoundary.equals(IntervalBoundary.OPEN)) { - description += ")"; - } - return description; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java index 5c4d0635..e4273272 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java index d81c821b..ce84412a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java index 9fa0ee99..aae6012e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessEqualGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java index 989f6e29..cbc29edf 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/LessGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java index 918c59f5..a561b884 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListEachConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java index 1ff23f80..533db703 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListParameterNoDuplicateValueConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java index 95b5214b..b23ae76d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java index 7036ecef..c6d9d93f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/NoDuplicateValueGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java index e7802685..fd708d47 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OneMustBeSetGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java index bdd55572..0a22096f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/OnlyOneIsAllowedToBeSetGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java index 2847260a..fa600907 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java index ab77240a..87db36dc 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java index ff42a21f..98dd588e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java index e05ca2fa..371bd643 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java index d2106865..8f2dc2e5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/package-info.java @@ -246,14 +246,12 @@ * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Title} * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Description} and * {@link de.lmu.ifi.dbs.elki.utilities.documentation.Reference} (where possible).</p> - * - * @apiviz.excludeSubtypes de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable */ /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java index 75a5be86..6b804777 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/AbstractParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java index 97cdb51f..9d8c171b 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ChainedParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java index 02802593..b43fed45 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java index b870b57b..3cb309f5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java index 9f765963..8e6e10c8 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/MergedParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java index 01c46583..32ab5bdb 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/Parameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java index b3e3f214..7eb3cf45 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java index 5a20bd9e..a9ccda98 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackParameters.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -32,11 +32,9 @@ import java.util.Map; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; import de.lmu.ifi.dbs.elki.utilities.optionhandling.InternalParameterizationErrors; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GlobalParameterConstraint; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; /** * Utility wrapper to track parameters for a configuration session. @@ -54,7 +52,7 @@ public class TrackParameters implements Parameterization { /** * Tracking storage */ - List<Pair<Object, Parameter<?>>> options = new ArrayList<>(); + List<TrackedParameter> options = new ArrayList<>(); /** * Tree information: parent links @@ -70,7 +68,7 @@ public class TrackParameters implements Parameterization { /** * Current parent for nested parameterization */ - Object cur = null; + Object owner = null; /** * Constructor. @@ -83,18 +81,30 @@ public class TrackParameters implements Parameterization { } /** + * Constructor. + * + * @param inner Inner parameterization to wrap. + * @param owner Class/instance owning the parameter + */ + public TrackParameters(Parameterization inner, Object owner) { + super(); + this.inner = inner; + this.owner = owner; + } + + /** * Internal constructor, for nested tracking. * * @param inner Inner parameterization - * @param option Option + * @param owner Object owning the current parameters * @param options List of options * @param parents Parent map * @param children Child map */ - private TrackParameters(Parameterization inner, Object option, List<Pair<Object, Parameter<?>>> options, Map<Object, Object> parents, Map<Object, List<Object>> children) { + private TrackParameters(Parameterization inner, Object owner, List<TrackedParameter> options, Map<Object, Object> parents, Map<Object, List<Object>> children) { super(); - this.inner = inner.descend(option); - this.cur = option; + this.inner = inner.descend(owner); + this.owner = owner; this.options = options; this.parents = parents; this.children = children; @@ -113,7 +123,7 @@ public class TrackParameters implements Parameterization { @Override public boolean grab(Parameter<?> opt) { registerChild(opt); - options.add(new Pair<Object, Parameter<?>>(cur, opt)); + options.add(new TrackedParameter(owner, opt)); return inner.grab(opt); } @@ -130,7 +140,7 @@ public class TrackParameters implements Parameterization { @Override public boolean setValueForOption(Parameter<?> opt) throws ParameterException { registerChild(opt); - options.add(new Pair<Object, Parameter<?>>(cur, opt)); + options.add(new TrackedParameter(owner, opt)); return inner.setValueForOption(opt); } @@ -139,33 +149,19 @@ public class TrackParameters implements Parameterization { * * @return Parameters seen */ - public Collection<Pair<Object, Parameter<?>>> getAllParameters() { + public Collection<TrackedParameter> getAllParameters() { return options; } - /** - * Get the tracked parameters that were actually set. - * - * @return Parameters given - */ - public Collection<Pair<OptionID, Object>> getGivenParameters() { - ArrayList<Pair<OptionID, Object>> ret = new ArrayList<>(); - for(Pair<Object, Parameter<?>> pair : options) { - if(pair.second.isDefined() && pair.second.getGivenValue() != null) { - ret.add(new Pair<>(pair.second.getOptionID(), pair.second.getGivenValue())); - } - } - return ret; - } - @Override public boolean checkConstraint(GlobalParameterConstraint constraint) { return inner.checkConstraint(constraint); } /** - * {@inheritDoc} Track parameters using a shared options list with parent - * tracker. + * {@inheritDoc} + * + * Track parameters using a shared options list with parent tracker. */ @Override public Parameterization descend(Object option) { @@ -174,14 +170,14 @@ public class TrackParameters implements Parameterization { } private void registerChild(Object opt) { - if(opt == cur) { + if(opt == owner) { LoggingUtil.exception("Options shouldn't have themselves as parents!", new Throwable()); } - parents.put(opt, cur); - List<Object> c = children.get(cur); + parents.put(opt, owner); + List<Object> c = children.get(owner); if(c == null) { c = new ArrayList<>(); - children.put(cur, c); + children.put(owner, c); } if(!c.contains(opt)) { c.add(opt); @@ -204,7 +200,7 @@ public class TrackParameters implements Parameterization { return ClassGenericsUtil.tryInstantiate(r, c, this); } catch(Exception e) { - reportError(new InternalParameterizationErrors("Error instantiating internal class: "+c.getName(), e)); + reportError(new InternalParameterizationErrors("Error instantiating internal class: " + c.getName(), e)); return null; } } @@ -215,7 +211,7 @@ public class TrackParameters implements Parameterization { return ClassGenericsUtil.tryInstantiate(c, c, this); } catch(Exception e) { - reportError(new InternalParameterizationErrors("Error instantiating internal class: "+c.getName(), e)); + reportError(new InternalParameterizationErrors("Error instantiating internal class: " + c.getName(), e)); return null; } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java new file mode 100644 index 00000000..01969302 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/TrackedParameter.java @@ -0,0 +1,71 @@ +package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2014 + 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 de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; + +/** + * Class containing an object, and the associated value. + * + * @author Erich Schubert + */ +public class TrackedParameter { + /** + * Option ID + */ + private Object owner; + + /** + * Parameter value + */ + private Parameter<?> parameter; + + /** + * Constructor. + * + * @param owner Object owning the parameter value + * @param parameter Parameter + */ + public TrackedParameter(Object owner, Parameter<?> parameter) { + this.owner = owner; + this.parameter = parameter; + } + + /** + * Get the owner object. + * + * @return Parameter owner + */ + public Object getOwner() { + return owner; + } + + /** + * Get the parameter observed. + * + * @return Parameter + */ + public Parameter<?> getParameter() { + return parameter; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java index 2a05a766..dfdbe7ac 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java index ce9c89b4..d330d343 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/package-info.java @@ -8,7 +8,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java index cdad8583..05e82152 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/AbstractParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -131,10 +131,12 @@ public abstract class AbstractParameter<THIS extends AbstractParameter<THIS, T>, this(optionID, false); } + @SuppressWarnings("unchecked") @Override - public void setDefaultValue(T defaultValue) { + public THIS setDefaultValue(T defaultValue) { this.defaultValue = defaultValue; this.optionalParameter = true; + return (THIS) this; } @Override @@ -142,7 +144,6 @@ public abstract class AbstractParameter<THIS extends AbstractParameter<THIS, T>, return !(defaultValue == null); } - // TODO: can we do this more elegantly? @Override public void useDefaultValue() { setValueInternal(defaultValue); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java index 1cea7fac..bd41e139 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java index 42288738..02545582 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ClassParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,6 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; import java.lang.reflect.InvocationTargetException; import java.util.List; +import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; @@ -51,6 +52,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz // TODO: turn restrictionClass into a constraint? public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Class<? extends C>> { /** + * The class logger. + */ + private static final Logging LOG = Logging.getLogger(ClassParameter.class); + + /** * The restriction class for this class parameter. */ protected Class<C> restrictionClass; @@ -176,7 +182,27 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas @Override public String getValuesDescription() { if(restrictionClass != null && restrictionClass != Object.class) { - return restrictionString(); + StringBuilder info = new StringBuilder(); + if(restrictionClass.isInterface()) { + info.append("Implementing "); + } + else { + info.append("Extending "); + } + info.append(restrictionClass.getName()); + info.append(FormatUtil.NEWLINE); + + List<Class<?>> known = getKnownImplementations(); + if(!known.isEmpty()) { + info.append("Known classes (default package " + restrictionClass.getPackage().getName() + "):"); + info.append(FormatUtil.NEWLINE); + for(Class<?> c : known) { + info.append("->").append(FormatUtil.NONBREAKING_SPACE); + info.append(canonicalClassName(c, getRestrictionClass())); + info.append(FormatUtil.NEWLINE); + } + } + return info.toString(); } return ""; } @@ -214,6 +240,9 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas throw new WrongParameterValueException(this, getValue().getCanonicalName(), "Error instantiating class - no usable public constructor."); } catch(Exception e) { + if(LOG.isVerbose()) { + LOG.exception("Class initialization failed.", e); + } throw new WrongParameterValueException(this, getValue().getCanonicalName(), "Error instantiating class.", e); } return instance; @@ -243,37 +272,6 @@ public class ClassParameter<C> extends AbstractParameter<ClassParameter<C>, Clas } /** - * Provides a description string listing all classes for the given superclass - * or interface as specified in the properties. - * - * @return a description string listing all classes for the given superclass - * or interface as specified in the properties - */ - public String restrictionString() { - StringBuilder info = new StringBuilder(); - if(restrictionClass.isInterface()) { - info.append("Implementing "); - } - else { - info.append("Extending "); - } - info.append(restrictionClass.getName()); - info.append(FormatUtil.NEWLINE); - - List<Class<?>> known = getKnownImplementations(); - if(!known.isEmpty()) { - info.append("Known classes (default package " + restrictionClass.getPackage().getName() + "):"); - info.append(FormatUtil.NEWLINE); - for(Class<?> c : known) { - info.append("->" + FormatUtil.NONBREAKING_SPACE); - info.append(canonicalClassName(c, getRestrictionClass())); - info.append(FormatUtil.NEWLINE); - } - } - return info.toString(); - } - - /** * Get the "simple" form of a class name. * * @param c Class diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java deleted file mode 100644 index eda54082..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DistanceParameter.java +++ /dev/null @@ -1,149 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; - -/* - 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 de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction; -import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException; - -/** - * Parameter class for a parameter specifying a double value. - * - * @author Steffi Wanka - * @author Erich Schubert - * - * @param <D> Distance type - */ -public class DistanceParameter<D extends Distance<D>> extends AbstractParameter<DistanceParameter<D>, D> { - /** - * Distance type - */ - D dist; - - /** - * Constructs a double parameter with the given optionID and default value. - * - * @param optionID the unique optionID - * @param dist distance factory - * @param defaultValue the default value for this double parameter - */ - public DistanceParameter(OptionID optionID, D dist, D defaultValue) { - super(optionID, defaultValue); - this.dist = dist; - } - - /** - * Constructs a double parameter with the given optionID and default value. - * - * @param optionID the unique optionID - * @param dist distance factory - * @param defaultValue the default value for this double parameter - */ - public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist, D defaultValue) { - super(optionID, defaultValue); - this.dist = (dist != null) ? dist.getDistanceFactory() : null; - } - - /** - * Constructs a double parameter with the given optionID and optional flag. - * - * @param optionID the unique id of this parameter - * @param dist distance factory - * @param optional specifies whether this parameter is an optional parameter - */ - public DistanceParameter(OptionID optionID, D dist, boolean optional) { - super(optionID, optional); - this.dist = dist; - } - - /** - * Constructs a double parameter with the given optionID and optional flag. - * - * @param optionID the unique id of this parameter - * @param dist distance factory - * @param optional specifies whether this parameter is an optional parameter - */ - public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist, boolean optional) { - super(optionID, optional); - this.dist = (dist != null) ? dist.getDistanceFactory() : null; - } - - /** - * Constructs a double parameter with the given optionID. - * - * @param optionID the unique id of this parameter - * @param dist distance factory - */ - public DistanceParameter(OptionID optionID, D dist) { - super(optionID); - this.dist = dist; - } - - /** - * Constructs a double parameter with the given optionID. - * - * @param optionID the unique id of this parameter - * @param dist distance factory - */ - public DistanceParameter(OptionID optionID, DistanceFunction<?, D> dist) { - super(optionID); - this.dist = (dist != null) ? dist.getDistanceFactory() : null; - } - - @Override - public String getValueAsString() { - return getValue().toString(); - } - - @SuppressWarnings("unchecked") - @Override - protected D parseValue(Object obj) throws WrongParameterValueException { - if (dist == null) { - throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, but the distance was not set!"); - } - if (obj == null) { - throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, but a null value was given!"); - } - if(dist.nullDistance().getClass().isAssignableFrom(obj.getClass())) { - return (D) dist.nullDistance().getClass().cast(obj); - } - try { - return dist.parseString(obj.toString()); - } - catch(IllegalArgumentException e) { - throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a distance value, read: " + obj + "!\n"); - } - } - - /** - * Returns a string representation of the parameter's type. - * - * @return "<distance>" - */ - @Override - public String getSyntax() { - return "<distance>"; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java index 84f97734..b5c651c2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; +import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException; @@ -59,7 +60,7 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub @Override public String getValueAsString() { - return FormatUtil.format(getValue().toArray(new Double[getValue().size()]), LIST_SEP, FormatUtil.NF); + return FormatUtil.format(ArrayLikeUtil.toPrimitiveDoubleArray(getValue()), LIST_SEP); } @SuppressWarnings("unchecked") @@ -68,15 +69,16 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub try { List<?> l = List.class.cast(obj); // do extra validation: - for (Object o : l) { - if (!(o instanceof Double)) { + for(Object o : l) { + if(!(o instanceof Double)) { throw new WrongParameterValueException("Wrong parameter format for parameter \"" + getName() + "\". Given list contains objects of different type!"); } } // TODO: can we use reflection to get extra checks? // TODO: Should we copy the list? - return (List<Double>)l; - } catch (ClassCastException e) { + return (List<Double>) l; + } + catch(ClassCastException e) { // continue with others } if(obj instanceof String) { @@ -87,6 +89,11 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub } return doubleValue; } + if(obj instanceof Double) { + ArrayList<Double> doubleValue = new ArrayList<>(1); + doubleValue.add((Double) obj); + return doubleValue; + } throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of Double values!"); } @@ -97,11 +104,10 @@ public class DoubleListParameter extends ListParameter<DoubleListParameter, Doub * parameter */ // Unused? - /*public void setDefaultValue(double allListDefaultValue) { - for(int i = 0; i < defaultValue.size(); i++) { - defaultValue.set(i, allListDefaultValue); - } - }*/ + /* + * public void setDefaultValue(double allListDefaultValue) { for(int i = 0; i + * < defaultValue.size(); i++) { defaultValue.set(i, allListDefaultValue); } } + */ /** * Returns a string representation of the parameter's type. diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java index efa64370..109d3204 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/DoubleParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java index 22d7dd54..ed86b542 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,6 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; import java.util.ArrayList;
import java.util.Collection;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
@@ -111,16 +112,17 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara @Override
protected E parseValue(Object obj) throws ParameterException {
- if (obj == null) {
+ if(obj == null) {
throw new UnspecifiedParameterException(this);
}
- if (enumClass.isInstance(obj)) {
+ if(enumClass.isInstance(obj)) {
return enumClass.cast(obj);
}
- if (obj instanceof String) {
+ if(obj instanceof String) {
try {
return Enum.valueOf(enumClass, (String) obj);
- } catch (IllegalArgumentException ex) {
+ }
+ catch(IllegalArgumentException ex) {
throw new WrongParameterValueException("Enum parameter " + getName() + " is invalid (must be one of [" + joinEnumNames(", ") + "].");
}
}
@@ -133,6 +135,26 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara }
/**
+ * This class sometimes provides a list of value descriptions.
+ *
+ * @see de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.AbstractParameter#hasValuesDescription()
+ */
+ @Override
+ public boolean hasValuesDescription() {
+ return true;
+ }
+
+ @Override
+ public String getValuesDescription() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("One of:").append(FormatUtil.NEWLINE);
+ for(String s : getPossibleValues()) {
+ buf.append("->").append(FormatUtil.NONBREAKING_SPACE).append(s).append(FormatUtil.NEWLINE);
+ }
+ return buf.toString();
+ }
+
+ /**
* Get a list of possible values for this enum parameter.
*
* @return list of strings representing possible enum values.
@@ -141,7 +163,7 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara // Convert to string array
final E[] enums = enumClass.getEnumConstants();
ArrayList<String> values = new ArrayList<>(enums.length);
- for (E t : enums) {
+ for(E t : enums) {
values.add(t.name());
}
return values;
@@ -157,8 +179,8 @@ public class EnumParameter<E extends Enum<E>> extends AbstractParameter<EnumPara private String joinEnumNames(String separator) {
E[] enumTypes = enumClass.getEnumConstants();
StringBuilder sb = new StringBuilder();
- for (int i = 0; i < enumTypes.length; ++i) {
- if (i > 0) {
+ for(int i = 0; i < enumTypes.length; ++i) {
+ if(i > 0) {
sb.append(separator);
}
sb.append(enumTypes[i].name());
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java index 9e115dc7..f4301fd7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java index 3e9fdc7d..2d2cd43a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/FileParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java index f9e1a1f1..8c2e35e2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Flag.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java index cc8327b4..036aaff0 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java index 3d867770..68c1ff2e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/IntParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java index df520daa..b10a2779 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -49,9 +49,9 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte public static final String LIST_SEP = ","; /** - * A pattern defining a ":". + * A pattern defining a ":" or ";". */ - public static final Pattern VECTOR_SPLIT = Pattern.compile(":"); + public static final Pattern VECTOR_SPLIT = Pattern.compile("[:;]"); /** * Vector separator character - ":" @@ -93,7 +93,7 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte * @return the size of this list parameter. */ public int getListSize() { - if (getValue() == null && isOptional()) { + if(getValue() == null && isOptional()) { return 0; } @@ -106,15 +106,15 @@ public abstract class ListParameter<THIS extends ListParameter<THIS, T>, T> exte */ // TODO: keep? remove? protected String asString() { - if (getValue() == null) { + if(getValue() == null) { return ""; } StringBuilder buffer = new StringBuilder(); buffer.append('['); - for (int i = 0; i < getValue().size(); i++) { + for(int i = 0; i < getValue().size(); i++) { buffer.append(getValue().get(i).toString()); - if (i != getValue().size() - 1) { + if(i != getValue().size() - 1) { buffer.append(','); } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java index 5ab6b487..67995a5d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/LongParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java index fabdce53..8c7381fd 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/NumberParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java index ada6239a..96e6a80e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java index 4166d0a2..34b0ed3e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/ObjectParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java index ffacb6d1..8ff5199c 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/Parameter.java @@ -9,7 +9,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstra This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -49,8 +49,9 @@ public interface Parameter<T> { * Sets the default value of this parameter. * * @param defaultValue default value of this parameter + * @return the parameter itself, for chaining */ - public abstract void setDefaultValue(T defaultValue); + public abstract Parameter<T> setDefaultValue(T defaultValue); /** * Checks if this parameter has a default value. diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java index e3cb4bcf..2e8121ba 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/PatternParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java index bf5e0cb0..40fa6d53 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/RandomParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.RandomFactory; +import de.lmu.ifi.dbs.elki.math.random.RandomFactory; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException; diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java index dc2a2a32..9dd6ea26 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/StringParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java index 43fa0797..51578fb5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/VectorListParameter.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,10 +23,13 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import gnu.trove.list.array.TDoubleArrayList; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException; @@ -39,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.ParameterConstra * @author Steffi Wanka * @author Erich Schubert */ -public class VectorListParameter extends ListParameter<VectorListParameter, List<Double>> { +public class VectorListParameter extends ListParameter<VectorListParameter, Vector> { /** * Constructs a vector list parameter with the given name and description. * @@ -47,7 +50,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List * @param constraint Constraint * @param defaultValue Default value */ - public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint, List<List<Double>> defaultValue) { + public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint, List<Vector> defaultValue) { super(optionID, defaultValue); addConstraint(constraint); } @@ -59,7 +62,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List * @param constraint Constraint * @param optional Optional flag */ - public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint, boolean optional) { + public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint, boolean optional) { super(optionID, optional); addConstraint(constraint); } @@ -70,7 +73,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List * @param optionID Option ID * @param constraint Constraint */ - public VectorListParameter(OptionID optionID, ParameterConstraint<List<List<Double>>> constraint) { + public VectorListParameter(OptionID optionID, ParameterConstraint<List<Vector>> constraint) { super(optionID); addConstraint(constraint); } @@ -83,8 +86,8 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List */ // Indiscernible from optionID, constraints /* - * public VectorListParameter(OptionID optionID, List<List<Double>> - * defaultValue) { super(optionID, defaultValue); } + * public VectorListParameter(OptionID optionID, List<Vector> defaultValue) { + * super(optionID, defaultValue); } */ /** @@ -109,17 +112,10 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List @Override public String getValueAsString() { StringBuilder buf = new StringBuilder(); - List<List<Double>> val = getValue(); - Iterator<List<Double>> valiter = val.iterator(); + List<Vector> val = getValue(); + Iterator<Vector> valiter = val.iterator(); while(valiter.hasNext()) { - List<Double> vec = valiter.next(); - Iterator<Double> veciter = vec.iterator(); - while(veciter.hasNext()) { - buf.append(veciter.next().toString()); - if(veciter.hasNext()) { - buf.append(LIST_SEP); - } - } + buf.append(FormatUtil.format(valiter.next().getArrayRef(), LIST_SEP)); // Append separation character if(valiter.hasNext()) { buf.append(VECTOR_SEP); @@ -130,7 +126,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List @SuppressWarnings("unchecked") @Override - protected List<List<Double>> parseValue(Object obj) throws ParameterException { + protected List<Vector> parseValue(Object obj) throws ParameterException { try { List<?> l = List.class.cast(obj); // do extra validation: @@ -144,7 +140,7 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List } // TODO: can we use reflection to get extra checks? // TODO: Should we copy the list and vectors? - return (List<List<Double>>) l; + return (List<Vector>) l; } catch(ClassCastException e) { // continue with other attempts. @@ -154,11 +150,12 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List if(vectors.length == 0) { throw new WrongParameterValueException("Wrong parameter format! Given list of vectors for parameter \"" + getName() + "\" is empty!"); } - ArrayList<List<Double>> vecs = new ArrayList<>(); + ArrayList<Vector> vecs = new ArrayList<>(); + TDoubleArrayList vectorCoord = new TDoubleArrayList(); for(String vector : vectors) { + vectorCoord.clear(); String[] coordinates = SPLIT.split(vector); - ArrayList<Double> vectorCoord = new ArrayList<>(); for(String coordinate : coordinates) { try { vectorCoord.add(FormatUtil.parseDouble(coordinate)); @@ -167,11 +164,11 @@ public class VectorListParameter extends ListParameter<VectorListParameter, List throw new WrongParameterValueException("Wrong parameter format! Coordinates of vector \"" + vector + "\" are not valid!"); } } - vecs.add(vectorCoord); + vecs.add(new Vector(vectorCoord.toArray())); } return vecs; } - throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of Double values!"); + throw new WrongParameterValueException("Wrong parameter format! Parameter \"" + getName() + "\" requires a list of double values!"); } /** diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java index 75d7c5a1..272cb8f2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/package-info.java @@ -12,7 +12,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/package-info.java index 1e110d8e..45447362 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/package-info.java @@ -8,12 +8,11 @@ * <ul> * <li>Basic and low-level:<ul> * <li>{@link de.lmu.ifi.dbs.elki.utilities.Util}: Miscellaneous utility functions.</li> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.PairUtil}: for Pair Comparators.</li> * <li>{@link de.lmu.ifi.dbs.elki.logging.LoggingUtil}: simple logging access.</li> * <li>{@link de.lmu.ifi.dbs.elki.math.MathUtil}: Mathematics utility functions.</li> * <li>{@link de.lmu.ifi.dbs.elki.data.VectorUtil}: Vector and Matrix functions.</li> * <li>{@link de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil}: Spatial MBR computations (intersection, union etc.).</li> - * <li>{@link de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil}: byte array processing (low-level IO via byte arrays).</li> + * <li>{@link de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil}: byte array processing (low-level IO via byte arrays).</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.FileUtil}: File and file name utility functions.</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil}: Generic classes (instantiation, arrays of arrays, sets that require safe but unchecked casts).</li> * </ul></li> @@ -23,7 +22,6 @@ * <li>{@link de.lmu.ifi.dbs.elki.database.ids.DBIDUtil}: Database ID DBID handling.</li> * <li>{@link de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil}: Data storage layer (like Maps).</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.DatabaseUtil}: database utility functions (centroid etc.).</li> - * <li>{@link de.lmu.ifi.dbs.elki.distance.DistanceUtil}: distance functions related (min, max for {@link de.lmu.ifi.dbs.elki.distance.distancevalue.Distance}s).</li> * <li>{@link de.lmu.ifi.dbs.elki.result.ResultUtil}: result processing functions (e.g. extracting sub-results).</li> * </ul></li> * <li>Output-related:<ul> @@ -34,7 +32,6 @@ * <li>{@link de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil}: Visualizer handling.</li> * </ul></li> * <li>Specialized:<ul> - * <li>{@link de.lmu.ifi.dbs.elki.data.images.ImageUtil}: image handling.</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionUtil}: Managing parameter settings</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.InspectionUtil}: class and classpath inspection.</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.documentation.DocumentationUtil}: documentation extraction from annotations.</li> @@ -46,7 +43,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java deleted file mode 100644 index 036eaea2..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CPair.java +++ /dev/null @@ -1,96 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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 de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; - -/** - * Pair with canonical comparison function derived from the components comparable interfaces. - * - * @author Erich Schubert - * - * @param <FIRST> first type - * @param <SECOND> second type - */ -public class CPair<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> extends Pair<FIRST, SECOND> implements Comparable<CPair<FIRST,SECOND>> { - /** - * Initialize pair - * - * @param first first parameter - * @param second second parameter - */ - public CPair(FIRST first, SECOND second) { - super(first, second); - } - - /** - * Generic derived compare function. - * - * @param other Object to compare to - * @return comparison result - */ - @Override - public int compareTo(CPair<FIRST, SECOND> other) { - // try comparing by first - if(this.first != null) { - if(other.first == null) { - return -1; - } - int delta1 = this.first.compareTo(other.first); - if(delta1 != 0) { - return delta1; - } - } - else if(other.first != null) { - return +1; - } - // try comparing by second - if(this.second != null) { - if(other.second == null) { - return -1; - } - int delta2 = this.second.compareTo(other.second); - if(delta2 != 0) { - return delta2; - } - } - else if(other.second != null) { - return +1; - } - return 0; - } - - /** - * Array constructor for generics - * - * @param <F> First type - * @param <S> Second type - * @param size Size of array to be constructed - * @return New array of requested size - */ - public static final <F extends Comparable<? super F>, S extends Comparable<? super S>> CPair<F, S>[] newArray(int size) { - Class<CPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(CPair.class); - return ClassGenericsUtil.newArrayOfNull(size, paircls); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java deleted file mode 100644 index 88ed35eb..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/CTriple.java +++ /dev/null @@ -1,104 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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/>. - */ - -/** - * Triple with canonical comparison function. - * - * @author Erich Schubert - * - * @param <FIRST> first type - * @param <SECOND> second type - * @param <THIRD> second type - */ -public final class CTriple<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>, THIRD extends Comparable<? super THIRD>> extends Triple<FIRST, SECOND, THIRD> implements Comparable<CTriple<FIRST, SECOND, THIRD>> { - /** - * Constructor with fields - * - * @param first Value of first component - * @param second Value of second component - * @param third Value of third component - */ - public CTriple(FIRST first, SECOND second, THIRD third) { - super(first, second, third); - } - - /** - * Canonical toString operator - */ - @Override - public String toString() { - return "Triple(" + first.toString() + ", " + second.toString() + ", " + third.toString() + ")"; - } - - /** - * Generic derived compare function. - * - * @param other Object to compare to - * @return comparison result - */ - @Override - public int compareTo(CTriple<FIRST, SECOND, THIRD> other) { - // try comparing by first - if(this.first != null) { - if(other.first == null) { - return -1; - } - int delta1 = this.first.compareTo(other.first); - if(delta1 != 0) { - return delta1; - } - } - else if(other.first != null) { - return +1; - } - // try comparing by second - if(this.second != null) { - if(other.second == null) { - return -1; - } - int delta2 = this.second.compareTo(other.second); - if(delta2 != 0) { - return delta2; - } - } - else if(other.second != null) { - return +1; - } - // try comparing by third - if(this.third != null) { - if(other.third == null) { - return -1; - } - int delta3 = this.third.compareTo(other.third); - if(delta3 != 0) { - return delta3; - } - } - else if(other.third != null) { - return +1; - } - return 0; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java index 092d6635..bc17fff3 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleDoublePair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,14 +28,11 @@ import java.util.Comparator; /** * Pair storing two doubles. * - * Since double is a native type, this can't be done via the {@link CPair} - * generic. - * * @author Erich Schubert * * @apiviz.has Comparator */ -public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInterface<Double, Double> { +public class DoubleDoublePair implements Comparable<DoubleDoublePair> { /** * first value */ @@ -134,15 +131,6 @@ public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInter } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Double getFirst() { - return Double.valueOf(first); - } - - /** * Set first value * * @param first new value @@ -152,15 +140,6 @@ public class DoubleDoublePair implements Comparable<DoubleDoublePair>, PairInter } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Double getSecond() { - return Double.valueOf(second); - } - - /** * Set second value * * @param second new value diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java index be18c712..731d5cf6 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleIntPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,14 +28,11 @@ import java.util.Comparator; /** * Pair storing an integer and a double. * - * Since double and int are native types, this can't be done via the - * {@link CPair} generic. - * * @author Erich Schubert * * @apiviz.has Comparator */ -public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<Double, Integer> { +public class DoubleIntPair implements Comparable<DoubleIntPair> { /** * first value */ @@ -122,15 +119,6 @@ public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<D } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Double getFirst() { - return Double.valueOf(first); - } - - /** * Set first value * * @param first new value @@ -140,15 +128,6 @@ public class DoubleIntPair implements Comparable<DoubleIntPair>, PairInterface<D } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Integer getSecond() { - return Integer.valueOf(second); - } - - /** * Set second value * * @param second new value diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java index 678d4532..945f58aa 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/DoubleObjPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,7 +31,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; * * @param <O> Object type */ -public class DoubleObjPair<O> implements PairInterface<Double, O>, Comparable<DoubleObjPair<O>> { +public class DoubleObjPair<O> implements Comparable<DoubleObjPair<O>> { /** * Double value */ @@ -53,20 +53,6 @@ public class DoubleObjPair<O> implements PairInterface<Double, O>, Comparable<Do this.second = second; } - /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public Double getFirst() { - return Double.valueOf(first); - } - - @Override - public O getSecond() { - return second; - } - @Override public int compareTo(DoubleObjPair<O> o) { return Double.compare(first, o.first); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java deleted file mode 100644 index 4d2f707c..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/FCPair.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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 de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; - -/** - * Pair that can <em>only</em> be compared by it's first component. - * - * @author Erich Schubert - * - * @param <FIRST> first type (comparable) - * @param <SECOND> second type - */ -public class FCPair<FIRST extends Comparable<? super FIRST>, SECOND> extends Pair<FIRST, SECOND> implements Comparable<FCPair<FIRST, SECOND>> { - /** - * Initialize pair - * - * @param first first parameter - * @param second second parameter - */ - public FCPair(FIRST first, SECOND second) { - super(first, second); - } - - /** - * Generic derived compare function. - * - * @param other Object to compare to - * @return comparison result - */ - @Override - public int compareTo(FCPair<FIRST, SECOND> other) { - // try comparing by first - if(this.first != null) { - if(other.first == null) { - return -1; - } - int delta1 = this.first.compareTo(other.first); - if(delta1 != 0) { - return delta1; - } - } - else if(other.first != null) { - return +1; - } - return 0; - } - - /** - * Array constructor for generics - * - * @param <F> First type - * @param <S> Second type - * @param size Size of array to be constructed - * @return New array of requested size - */ - public static final <F extends Comparable<? super F>, S> FCPair<F, S>[] newArray(int size) { - Class<FCPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(FCPair.class); - return ClassGenericsUtil.newArrayOfNull(size, paircls); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java index bfcf5971..805cf6dc 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntDoublePair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,14 +28,11 @@ import java.util.Comparator; /** * Pair storing an integer and a double. * - * Since double and int are native types, this can't be done via the - * {@link CPair} generic. - * * @author Erich Schubert * * @apiviz.has Comparator */ -public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<Integer, Double> { +public class IntDoublePair implements Comparable<IntDoublePair> { /** * first value */ @@ -122,15 +119,6 @@ public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<I } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Integer getFirst() { - return Integer.valueOf(first); - } - - /** * Set first value * * @param first new value @@ -140,15 +128,6 @@ public class IntDoublePair implements Comparable<IntDoublePair>, PairInterface<I } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Double getSecond() { - return Double.valueOf(second); - } - - /** * Set second value * * @param second new value diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java index 5d3210a4..bf4f810f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/IntIntPair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -28,13 +28,11 @@ import java.util.Comparator; /** * Pair storing two integers. * - * Since int is a native type, this can't be done via the {@link CPair} generic. - * * @author Erich Schubert * * @apiviz.has Comparator */ -public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer, Integer> { +public class IntIntPair implements Comparable<IntIntPair> { /** * first value */ @@ -119,15 +117,6 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Integer getFirst() { - return Integer.valueOf(first); - } - - /** * Set first value * * @param first new value @@ -137,15 +126,6 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer } /** - * @deprecated use pair.first to avoid boxing! - */ - @Override - @Deprecated - public final Integer getSecond() { - return Integer.valueOf(second); - } - - /** * Set second value * * @param second new value @@ -153,14 +133,14 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer public final void setSecond(int second) { this.second = second; } - + @Override public String toString() { return "(" + first + ", " + second + ")"; } /** - * Comparator to compare by second component only + * Comparator to compare by second component only */ public static final Comparator<IntIntPair> BYFIRST_COMPARATOR = new Comparator<IntIntPair>() { @Override @@ -168,9 +148,9 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer return o1.first - o2.first; } }; - + /** - * Comparator to compare by second component only + * Comparator to compare by second component only */ public static final Comparator<IntIntPair> BYSECOND_COMPARATOR = new Comparator<IntIntPair>() { @Override @@ -178,7 +158,7 @@ public class IntIntPair implements Comparable<IntIntPair>, PairInterface<Integer return o1.second - o2.second; } }; - + /** * Comparator to compare by swapped components */ diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java index ca8db67d..c423cdd8 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Pair.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,17 +26,21 @@ package de.lmu.ifi.dbs.elki.utilities.pairs; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; /** - * Generic SimplePair<FIRST,SECOND> class. + * Simple class wrapping two objects. * - * Does not implement any "special" interfaces such as Comparable, use - * {@link CPair} if you want comparable pairs. + * <b>Do not use this for primitive types such as {@code Integer} and + * {@code Double} - avoid the memory waste and garbage collection overhead!</b> + * + * Does not implement any "special" interfaces such as Comparable. If you need + * more complicated pairs, please use <em>domain specific</em> code, with more + * meaningful field names and comparators. * * @author Erich Schubert * * @param <FIRST> first type * @param <SECOND> second type */ -public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> { +public class Pair<FIRST, SECOND> { /** * First value in pair */ @@ -71,7 +75,6 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> { * * @return first element in pair */ - @Override public final FIRST getFirst() { return first; } @@ -90,7 +93,6 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> { * * @return second element in pair */ - @Override public final SECOND getSecond() { return second; } @@ -145,8 +147,9 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> { if(other.first != null) { return false; } - } else { - if (!this.first.equals(other.first)) { + } + else { + if(!this.first.equals(other.first)) { return false; } } @@ -154,8 +157,9 @@ public class Pair<FIRST, SECOND> implements PairInterface<FIRST, SECOND> { if(other.second != null) { return false; } - } else { - if (!this.second.equals(other.second)) { + } + else { + if(!this.second.equals(other.second)) { return false; } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java deleted file mode 100644 index 387d4f79..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/PairUtil.java +++ /dev/null @@ -1,478 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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.Comparator; - -/** - * Utility functions for (boxed) Pair classes. - * - * @author Erich Schubert - * - * @apiviz.uses Pair - * @apiviz.has CompareNatural - * @apiviz.has CompareNaturalFirst - * @apiviz.has CompareNaturalSecond - * @apiviz.has CompareNaturalSwapped - * @apiviz.has Compare - * @apiviz.has CompareByFirst - * @apiviz.has CompareBySecond - * @apiviz.has CompareSwapped - */ -public final class PairUtil { - /** - * Return a comparator for this pair, given that both components are already - * comparable. (So it could have been a CPair) - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @return Comparator - */ - public static <FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparator() { - return new CompareNatural<>(); - } - - /** - * Return a derived comparator given a comparator for each component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @param c1 First comparator - * @param c2 Second comparator - * @return Comparator - */ - public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparator(Comparator<? super FIRST> c1, Comparator<? super SECOND> c2) { - return new Compare<>(c1, c2); - } - - /** - * Return a comparator by first component for this pair, given that the first - * component is already comparable. (So it could have been a FCPair) - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @return Comparator - */ - public static <FIRST extends Comparable<? super FIRST>, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorFirst() { - return new CompareNaturalFirst<>(); - } - - /** - * Return a derived comparator by first component given a comparator for this - * component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @param c1 Comparator for first - * @return Comparator - */ - public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorFirst(Comparator<? super FIRST> c1) { - return new CompareByFirst<>(c1); - } - - /** - * Return a comparator by first component for this pair, given that the first - * component is already comparable. (So it could have been a FCPair) - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @return Comparator - */ - public static <FIRST, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSecond() { - return new CompareNaturalSecond<>(); - } - - /** - * Return a derived comparator by first component given a comparator for this - * component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @param c2 Comparator for second - * @return Comparator - */ - public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSecond(Comparator<? super SECOND> c2) { - return new CompareBySecond<>(c2); - } - - /** - * Return a component-swapped comparator for this pair, given that both - * components are already comparable. (So it could have been a CPair) - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @return Comparator - */ - public static <FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSwapped() { - return new CompareNaturalSwapped<>(); - } - - /** - * Return a derived component-swapped comparator given a comparator for each - * component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - * @param c1 First comparator - * @param c2 Second comparator - * @return Comparator - */ - public static <FIRST, SECOND> Comparator<Pair<? extends FIRST, ? extends SECOND>> comparatorSwapped(Comparator<? super FIRST> c1, Comparator<? super SECOND> c2) { - return new CompareSwapped<>(c1, c2); - } - - /** - * Class to do a "natural order" comparison on this class. - * - * @param <FIRST> First type - * @param <SECOND> Second type - */ - public static final class CompareNatural<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * Compare by first, then by second. - * - * @param o1 First object - * @param o2 Second object - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - // try comparing by first - if(o1.first != null) { - if(o2.first == null) { - return -1; - } - int delta1 = o1.first.compareTo(o2.first); - if(delta1 != 0) { - return delta1; - } - } - else if(o2.first != null) { - return +1; - } - // try comparing by second - if(o1.second != null) { - if(o2.second == null) { - return -1; - } - int delta2 = o1.second.compareTo(o2.second); - if(delta2 != 0) { - return delta2; - } - } - else if(o2.second != null) { - return +1; - } - return 0; - } - - } - - /** - * Class to do a natural comparison on this class' first component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - */ - public static final class CompareNaturalFirst<FIRST extends Comparable<? super FIRST>, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * Compare by first component natural ordering - * - * @param o1 First object - * @param o2 Second object - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - // try comparing by first - if(o1.first != null) { - if(o2.first == null) { - return -1; - } - int delta1 = o1.first.compareTo(o2.first); - if(delta1 != 0) { - return delta1; - } - } - else if(o2.first != null) { - return +1; - } - return 0; - } - - } - - /** - * Class to do a natural comparison on this class' second component. - * - * @param <FIRST> First type - * @param <SECOND> Second type - */ - public static final class CompareNaturalSecond<FIRST, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * Compare by second components natural ordering - * - * @param o1 First object - * @param o2 Second object - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - // try comparing by second - if(o1.second != null) { - if(o2.second == null) { - return -1; - } - int delta2 = o1.second.compareTo(o2.second); - if(delta2 != 0) { - return delta2; - } - } - else if(o2.second != null) { - return +1; - } - return 0; - } - - } - - /** - * Class to do a canonical swapped comparison on this class. - * - * @param <FIRST> First type - * @param <SECOND> Second type - */ - public static final class CompareNaturalSwapped<FIRST extends Comparable<? super FIRST>, SECOND extends Comparable<? super SECOND>> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * Compare by second component, using the ComparableSwapped interface. - * - * @param o1 First object - * @param o2 Second object - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - // try comparing by second - if(o1.second != null) { - if(o2.second == null) { - return -1; - } - int delta2 = o1.second.compareTo(o2.second); - if(delta2 != 0) { - return delta2; - } - } - else if(o2.second != null) { - return +1; - } - // try comparing by first - if(o1.first != null) { - if(o2.first == null) { - return -1; - } - int delta1 = o1.first.compareTo(o2.first); - if(delta1 != 0) { - return delta1; - } - } - else if(o2.first != null) { - return +1; - } - return 0; - } - - } - - /** - * Compare two SimplePairs based on two comparators - * - * @param <FIRST> first type - * @param <SECOND> second type - */ - public static class Compare<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * A comparator for type FIRST. - */ - private Comparator<? super FIRST> fcomparator; - - /** - * A comparator for type FIRST. - */ - private Comparator<? super SECOND> scomparator; - - /** - * Provides a comparator for an {@link Pair} based on the given Comparator - * for type <code>P</code>. - * - * @param fcomparator Comparator for the first component - * @param scomparator Comparator for the second component - */ - public Compare(Comparator<? super FIRST> fcomparator, Comparator<? super SECOND> scomparator) { - this.fcomparator = fcomparator; - this.scomparator = scomparator; - } - - /** - * Two Objects of type {@link Pair} are compared based on the comparison of - * their property using the comparators {@link #fcomparator}, then - * {@link #scomparator}. - * - * @param o1 First object - * @param o2 Second object - * @return comparison result - * @see java.util.Comparator#compare - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - int delta1 = fcomparator.compare(o1.getFirst(), o2.getFirst()); - if(delta1 != 0) { - return delta1; - } - return scomparator.compare(o1.getSecond(), o2.getSecond()); - } - } - - /** - * Compare two SimplePairs based on a comparator for the first component. - * - * @param <FIRST> first type - * @param <SECOND> second type - */ - public static class CompareByFirst<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * A comparator for type P. - */ - private Comparator<? super FIRST> comparator; - - /** - * Provides a comparator for an {@link Pair} based on the given Comparator - * for type <code>P</code>. - * - * @param comparator a Comparator for type <code>P</code> to base the - * comparison of an {@link Pair} on - */ - public CompareByFirst(Comparator<? super FIRST> comparator) { - this.comparator = comparator; - } - - /** - * To Objects of type {@link Pair} are compared based on the comparison of - * their property using the current {@link #comparator}. - * - * @param o1 First object - * @param o2 Second object - * @return comparison result - * @see java.util.Comparator#compare - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - return comparator.compare(o1.getFirst(), o2.getFirst()); - } - } - - /** - * Compare two SimplePairs based on a comparator for the second component. - * - * @param <FIRST> first type - * @param <SECOND> second type - */ - public static class CompareBySecond<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * A comparator for type P. - */ - private Comparator<? super SECOND> comparator; - - /** - * Provides a comparator for an {@link Pair} based on the given Comparator - * for type <code>P</code>. - * - * @param comparator a Comparator for type <code>P</code> to base the - * comparison of an {@link Pair} on - */ - public CompareBySecond(Comparator<? super SECOND> comparator) { - this.comparator = comparator; - } - - /** - * To Objects of type {@link Pair} are compared based on the comparison of - * their property using the current {@link #comparator}. - * - * @param o1 First object - * @param o2 Second object - * @return comparison result - * @see java.util.Comparator#compare - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - return comparator.compare(o1.getSecond(), o2.getSecond()); - } - } - - /** - * Compare two SimplePairs based on two comparators, but by second component - * first. - * - * @param <FIRST> first type - * @param <SECOND> second type - */ - public static class CompareSwapped<FIRST, SECOND> implements Comparator<Pair<? extends FIRST, ? extends SECOND>> { - /** - * A comparator for type FIRST. - */ - private Comparator<? super FIRST> fcomparator; - - /** - * A comparator for type FIRST. - */ - private Comparator<? super SECOND> scomparator; - - /** - * Provides a comparator for an {@link Pair} based on the given Comparator - * for type <code>P</code>. - * - * @param fcomparator Comparator for the first component - * @param scomparator Comparator for the second component - */ - public CompareSwapped(Comparator<? super FIRST> fcomparator, Comparator<? super SECOND> scomparator) { - this.fcomparator = fcomparator; - this.scomparator = scomparator; - } - - /** - * Two Objects of type {@link Pair} are compared based on the comparison of - * their property using the given comparators {@link #scomparator}, then - * {@link #fcomparator}. - * - * @param o1 First object - * @param o2 Second object - * @return comparison result - * @see java.util.Comparator#compare - */ - @Override - public int compare(Pair<? extends FIRST, ? extends SECOND> o1, Pair<? extends FIRST, ? extends SECOND> o2) { - int delta2 = scomparator.compare(o1.getSecond(), o2.getSecond()); - if(delta2 != 0) { - return delta2; - } - return fcomparator.compare(o1.getFirst(), o2.getFirst()); - } - } - -} diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java deleted file mode 100644 index 90d7f738..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/SCPair.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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 de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; - -/** - * Pair that can <em>only</em> be compared by it's second component. - * - * @author Erich Schubert - * - * @param <FIRST> first type (comparable) - * @param <SECOND> second type - */ -public class SCPair<FIRST, SECOND extends Comparable<? super SECOND>> extends Pair<FIRST, SECOND> implements Comparable<SCPair<FIRST, SECOND>> { - /** - * Initialize pair - * - * @param first first parameter - * @param second second parameter - */ - public SCPair(FIRST first, SECOND second) { - super(first, second); - } - - /** - * Generic derived compare function. - * - * @param other Object to compare to - * @return comparison result - */ - @Override - public int compareTo(SCPair<FIRST, SECOND> other) { - // try comparing by first - if(this.second != null) { - if(other.second == null) { - return -1; - } - int delta1 = this.second.compareTo(other.second); - if(delta1 != 0) { - return delta1; - } - } - else if(other.second != null) { - return +1; - } - return 0; - } - - /** - * Array constructor for generics - * - * @param <F> First type - * @param <S> Second type - * @param size Size of array to be constructed - * @return New array of requested size - */ - public static final <F, S extends Comparable<? super S>> SCPair<F, S>[] newArray(int size) { - Class<SCPair<F,S>> paircls = ClassGenericsUtil.uglyCastIntoSubclass(SCPair.class); - return ClassGenericsUtil.newArrayOfNull(size, paircls); - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java deleted file mode 100644 index 4cac1e9c..00000000 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/Triple.java +++ /dev/null @@ -1,215 +0,0 @@ -package de.lmu.ifi.dbs.elki.utilities.pairs; - -/* - 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 de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; - -/** - * Triple without comparison. - * - * See also {@link CTriple} - * - * @author Erich Schubert - * - * @param <FIRST> first type - * @param <SECOND> second type - * @param <THIRD> second type - */ -public class Triple<FIRST, SECOND, THIRD> { - /** - * First value - */ - public FIRST first; - - /** - * Second value - */ - public SECOND second; - - /** - * Third value - */ - public THIRD third; - - /** - * Constructor with fields - * - * @param first Value of first component - * @param second Value of second component - * @param third Value of third component - */ - public Triple(FIRST first, SECOND second, THIRD third) { - this.first = first; - this.second = second; - this.third = third; - } - - /** - * Canonical toString operator - */ - @Override - public String toString() { - return "Triple(" + (first != null ? first.toString() : "null") + ", " + (second != null ? second.toString() : "null") + ", " + (third != null ? third.toString() : "null") + ")"; - } - - /** - * Getter for first - * - * @return first element in triple - */ - public final FIRST getFirst() { - return first; - } - - /** - * Setter for first - * - * @param first new value for first element - */ - public final void setFirst(FIRST first) { - this.first = first; - } - - /** - * Getter for second element in triple - * - * @return second element in triple - */ - public final SECOND getSecond() { - return second; - } - - /** - * Setter for second - * - * @param second new value for second element - */ - public final void setSecond(SECOND second) { - this.second = second; - } - - /** - * Getter for third - * - * @return third element in triple - */ - public final THIRD getThird() { - return third; - } - - /** - * Setter for third - * - * @param third new value for third element - */ - public final void setThird(THIRD third) { - this.third = third; - } - - /** - * Array constructor for generics - * @param <F> First type - * @param <S> Second type - * @param <T> Third type - * - * @param size Size of array to be constructed. - * @return new array of the requested size. - */ - public static final <F, S, T> Triple<F, S, T>[] newArray(int size) { - Class<Triple<F,S,T>> tripcls = ClassGenericsUtil.uglyCastIntoSubclass(Triple.class); - return ClassGenericsUtil.newArrayOfNull(size, tripcls); - } - - /** - * Canonical equals function - * - * @param obj Object to compare to - */ - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if(obj == null) { - return false; - } - if(!(obj instanceof Triple)) { - return false; - } - Triple<FIRST, SECOND, THIRD> other = (Triple<FIRST, SECOND, THIRD>) obj; - if(this.first == null) { - if(other.getFirst() != null) { - return false; - } - } - else { - if(other.getFirst() == null) { - return false; - } - if(!this.first.equals(other.getFirst())) { - return false; - } - } - if(this.second == null) { - if(other.getSecond() != null) { - return false; - } - } - else { - if(other.getSecond() == null) { - return false; - } - if(!this.second.equals(other.getSecond())) { - return false; - } - } - if(this.third == null) { - if(other.getThird() != null) { - return false; - } - } - else { - if(other.getThird() == null) { - return false; - } - if(!this.third.equals(other.getThird())) { - return false; - } - } - return true; - } - - /** - * Canonical derived hash function - */ - @Override - public int hashCode() { - // primitive hash function mixing the three integer hash values. - // this number does supposedly not have any factors in common with 2^32 - final long prime = 2654435761L; - long result = 1; - result = prime * result + ((first == null) ? 0 : first.hashCode()); - result = prime * result + ((second == null) ? 0 : second.hashCode()); - result = prime * result + ((third == null) ? 0 : third.hashCode()); - return (int) result; - } -}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java index 6a4e9501..b1d1fb90 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/pairs/package-info.java @@ -1,20 +1,7 @@ /** - * <p>Pairs and triples utility classes.</p> - * <p>Pairs and triples are frequently used classes and reimplemented too often.</p> - * - * <ul> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.Pair Pair} is the generic <em>non-comparable</em> pair (you can use external comparators!).</li> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.FCPair FCPair} is the generic pair comparable in the <em>first</em> component only.</li> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.CPair CPair} is the pair comparable in <em>both</em> components.</li> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.SCPair SCPair} is the generic pair comparable in the <em>second</em> component only.</li> - * </ul> - * - * <p>Due to limitations in object subclassing, {@link de.lmu.ifi.dbs.elki.utilities.pairs.CPair CPair} cannot be - * a subclass of {@link de.lmu.ifi.dbs.elki.utilities.pairs.FCPair FCPair}, since a class cannot implement - * the Comparable interface twice.</p> - * - * <p>Also primitive types cannot be used in Generics, resulting in the following classes for primitive types:</p> + * <p>Pairs utility classes.</p> * + * A number of commonly needed primitive pairs are the following: * <ul> * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair IntIntPair} storing two <code>int</code> values</li> * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair DoubleIntPair} storing one <code>double</code> and one <code>int</code> value.</li> @@ -22,37 +9,34 @@ * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair DoubleDoublePair} storing two <code>double</code> values</li> * </ul> * - * <p>Triples can be used via:</p> + * Why no more {@code Pair<A,B>}? * <ul> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.Triple Triple} is the generic non-comparable triple.</li> - * <li>{@link de.lmu.ifi.dbs.elki.utilities.pairs.CTriple CTriple} is the triple comparable in <em>all</em> components.</li> - * </ul> - * - * <p>If you need a triple comparable in just particular components, either define a comparator for sorting - * or subclass Triple appropriately.</p> + * <li>Because such pairs are expensive in Java when using primitive types.</li> + * <li>Because domain-specific code can often be optimized better by the HotSpot VM.</li> + * </ul> * * @apiviz.exclude java.lang. */ /* -This file is part of ELKI: -Environment for Developing KDD-Applications Supported by Index-Structures + 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 + Copyright (C) 2014 + 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 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. + 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/>. -*/ + 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.utilities.pairs;
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java index d8544cd4..35cf11f2 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/AxisBasedReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,13 +29,12 @@ import java.util.Collection; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; -import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; 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.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.pairs.Pair; /** * Strategy to pick reference points by placing them on the axis ends. @@ -44,21 +43,10 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; * surrounding cube. * * @author Erich Schubert - * - * @param <V> Vector type */ -public class AxisBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> { - /** - * Parameter to specify the extra scaling of the space, to allow - * out-of-data-space reference points. - * <p> - * Key: {@code -axisref.scale} - * </p> - */ - public static final OptionID SPACE_SCALE_ID = new OptionID("axisref.scale", "Scale the data space extension by the given factor."); - +public class AxisBasedReferencePoints implements ReferencePointsHeuristic { /** - * Holds the value of {@link #SPACE_SCALE_ID}. + * Scaling factor. */ protected double spacescale; @@ -73,33 +61,29 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe } @Override - public <T extends V> Collection<V> getReferencePoints(Relation<T> db) { - Relation<V> database = DatabaseUtil.relationUglyVectorCast(db); - Pair<V, V> minmax = DatabaseUtil.computeMinMax(database); - NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database); - + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { + double[][] minmax = RelationUtil.computeMinMax(db); int dim = RelationUtil.dimensionality(db); // Compute mean and extend from minmax. - double[] mean = new double[dim]; - double[] delta = new double[dim]; + double[] mean = minmax[0], delta = minmax[1]; for(int d = 0; d < dim; d++) { - mean[d] = (minmax.first.doubleValue(d) + minmax.second.doubleValue(d)) * .5; - delta[d] = spacescale * (minmax.second.doubleValue(d) - mean[d]); + delta[d] -= mean[d]; + mean[d] -= delta[d] * .5; } - ArrayList<V> result = new ArrayList<>(2 + dim); + ArrayList<Vector> result = new ArrayList<>(2 + dim); double[] vec = new double[dim]; // Use min and max for(int d = 0; d < dim; d++) { vec[d] = mean[d] - delta[d]; } - result.add(factory.newNumberVector(vec)); + result.add(new Vector(vec)); for(int d = 0; d < dim; d++) { vec[d] = mean[d] + delta[d]; } - result.add(factory.newNumberVector(vec)); + result.add(new Vector(vec)); // Plus axis end points: for(int i = 0; i < dim; i++) { @@ -111,7 +95,7 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe vec[d] = mean[d] + delta[d]; } } - result.add(factory.newNumberVector(vec)); + result.add(new Vector(vec)); } return result; @@ -124,7 +108,16 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { + /** + * Parameter to specify the extra scaling of the space, to allow + * out-of-data-space reference points. + * <p> + * Key: {@code -axisref.scale} + * </p> + */ + public static final OptionID SPACE_SCALE_ID = new OptionID("axisref.scale", "Scale the data space extension by the given factor."); + /** * Holds the value of {@link #SPACE_SCALE_ID}. */ @@ -133,16 +126,16 @@ public class AxisBasedReferencePoints<V extends NumberVector<?>> implements Refe @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - DoubleParameter spacescaleP = new DoubleParameter(SPACE_SCALE_ID, 1.0); - spacescaleP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE); + DoubleParameter spacescaleP = new DoubleParameter(SPACE_SCALE_ID, 1.0)// + .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE); if(config.grab(spacescaleP)) { spacescale = spacescaleP.getValue(); } } @Override - protected AxisBasedReferencePoints<V> makeInstance() { - return new AxisBasedReferencePoints<>(spacescale); + protected AxisBasedReferencePoints makeInstance() { + return new AxisBasedReferencePoints(spacescale); } } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java index b92d0575..644dccba 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/FullDatabaseReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -27,16 +27,14 @@ import java.util.Collection; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; /** * Strategy to use the complete database as reference points. * * @author Erich Schubert - * - * @param <O> Object type. */ -public class FullDatabaseReferencePoints<O extends NumberVector<?>> implements ReferencePointsHeuristic<O> { +public class FullDatabaseReferencePoints implements ReferencePointsHeuristic { /** * Constructor, Parameterizable style. */ @@ -45,7 +43,7 @@ public class FullDatabaseReferencePoints<O extends NumberVector<?>> implements R } @Override - public <T extends O> Collection<O> getReferencePoints(Relation<T> db) { - return new DatabaseUtil.CollectionFromRelation<O>(db); + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { + return new RelationUtil.CollectionFromRelation<>(db); } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java index 007efe6f..5ebee64b 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/GridBasedReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,50 +29,35 @@ import java.util.Collection; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; +import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.math.MathUtil; -import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; 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.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; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; /** * Grid-based strategy to pick reference points. * * @author Erich Schubert - * - * @param <V> Object type */ -public class GridBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> { - // TODO: add "grid sampling" option. - - /** - * Parameter to specify the grid resolution. - * <p> - * Key: {@code -grid.size} - * </p> - */ - public static final OptionID GRID_ID = new OptionID("grid.size", "The number of partitions in each dimension. Points will be placed on the edges of the grid, except for a grid size of 0, where only the mean is generated as reference point."); - +public class GridBasedReferencePoints implements ReferencePointsHeuristic { /** - * Parameter to specify the extra scaling of the space, to allow - * out-of-data-space reference points. - * <p> - * Key: {@code -grid.oversize} - * </p> + * Class logger. */ - public static final OptionID GRID_SCALE_ID = new OptionID("grid.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space."); + private static final Logging LOG = Logging.getLogger(GridBasedReferencePoints.class); /** - * Holds the value of {@link #GRID_ID}. + * Holds the grid resolution. */ protected int gridres; /** - * Holds the value of {@link #GRID_SCALE_ID}. + * Holds the grid scale. */ protected double gridscale; @@ -89,46 +74,47 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe } @Override - public <T extends V> Collection<V> getReferencePoints(Relation<T> db) { - Relation<V> database = DatabaseUtil.relationUglyVectorCast(db); - Pair<V, V> minmax = DatabaseUtil.computeMinMax(database); - NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database); - - int dim = RelationUtil.dimensionality(db); + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { + double[][] minmax = RelationUtil.computeMinMax(db); + final int dim = minmax[0].length; // Compute mean from minmax. double[] mean = new double[dim]; for(int d = 0; d < dim; d++) { - mean[d] = (minmax.first.doubleValue(d) + minmax.second.doubleValue(d)) * .5; + mean[d] = (minmax[0][d] + minmax[1][d]) * .5; } - int gridpoints = Math.max(1, MathUtil.ipowi(gridres + 1, dim)); - ArrayList<V> result = new ArrayList<>(gridpoints); + if(gridres <= 0) { + LOG.warning("Grid of resolution " + gridres + " will have a single point only."); + ArrayList<Vector> result = new ArrayList<>(1); + result.add(new Vector(mean)); + return result; + } + final int grids = gridres + 1; + final int gridpoints = MathUtil.ipowi(grids, dim); + if(gridpoints < 0) { + throw new AbortException("Grids with more than 2^31 are not supported, or meaningful."); + } + if(gridpoints < 0 || gridpoints > db.size()) { + LOG.warning("Grid has " + gridpoints + " points, but you only have " + db.size() + " observations."); + } + ArrayList<Vector> result = new ArrayList<>(gridpoints); double[] delta = new double[dim]; - if(gridres > 0) { - double halfgrid = gridres / 2.0; - for(int d = 0; d < dim; d++) { - delta[d] = (minmax.second.doubleValue(d) - minmax.first.doubleValue(d)) / gridres; - } + for(int d = 0; d < dim; d++) { + delta[d] = (minmax[1][d] - minmax[0][d]) / gridres; + } - double[] vec = new double[dim]; - for(int i = 0; i < gridpoints; i++) { - int acc = i; - for(int d = 0; d < dim; d++) { - int coord = acc % (gridres + 1); - acc = acc / (gridres + 1); - vec[d] = mean[d] + (coord - halfgrid) * delta[d] * gridscale; - } - V newp = factory.newNumberVector(vec); - // logger.debug("New reference point: " + FormatUtil.format(vec)); - result.add(newp); + double halfgrid = gridres * .5; + for(int i = 0; i < gridpoints; i++) { + double[] vec = new double[dim]; // Will be returned! + int acc = i; + for(int d = 0; d < dim; d++) { + int coord = acc % grids; + acc /= grids; + vec[d] = mean[d] + (coord - halfgrid) * delta[d] * gridscale; } + result.add(new Vector(vec)); } - else { - result.add(factory.newNumberVector(mean)); - // logger.debug("New reference point: " + FormatUtil.format(mean)); - } - return result; } @@ -139,7 +125,26 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { + // TODO: add "grid sampling" option. + + /** + * Parameter to specify the grid resolution. + * <p> + * Key: {@code -grid.size} + * </p> + */ + public static final OptionID GRID_ID = new OptionID("grid.size", "The number of partitions in each dimension. Points will be placed on the edges of the grid, except for a grid size of 0, where only the mean is generated as reference point."); + + /** + * Parameter to specify the extra scaling of the space, to allow + * out-of-data-space reference points. + * <p> + * Key: {@code -grid.oversize} + * </p> + */ + public static final OptionID GRID_SCALE_ID = new OptionID("grid.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space."); + /** * Holds the value of {@link #GRID_ID}. */ @@ -167,8 +172,8 @@ public class GridBasedReferencePoints<V extends NumberVector<?>> implements Refe } @Override - protected GridBasedReferencePoints<V> makeInstance() { - return new GridBasedReferencePoints<>(gridres, gridscale); + protected GridBasedReferencePoints makeInstance() { + return new GridBasedReferencePoints(gridres, gridscale); } } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java index 9d866ecc..58d1c886 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomGeneratedReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,86 +29,70 @@ import java.util.Collection; import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; -import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; +import de.lmu.ifi.dbs.elki.math.random.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.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; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.RandomParameter; /** * Reference points generated randomly within the used data space. * * @author Erich Schubert - * - * @param <V> Object type */ -// TODO: Erich: use reproducible random -public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> { - /** - * Parameter to specify the number of requested reference points. - * <p> - * Key: {@code -generate.n} - * </p> - */ - public static final OptionID N_ID = new OptionID("generate.n", "The number of reference points to be generated."); - +public class RandomGeneratedReferencePoints implements ReferencePointsHeuristic { /** - * Parameter for additional scaling of the space, to allow out-of-space - * reference points. - * <p> - * Key: {@code -generate.scale} - * </p> + * Holds the sample size. */ - public static final OptionID SCALE_ID = new OptionID("generate.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space."); + protected int samplesize; /** - * Holds the value of {@link #N_ID}. + * Holds the scaling factor. */ - protected int samplesize; + protected double scale = 1.0; /** - * Holds the value of {@link #SCALE_ID}. + * Random generator. */ - protected double scale = 1.0; + protected RandomFactory rnd; /** * Constructor. * * @param samplesize Size of desired sample set * @param scale Scaling factor + * @param rnd Random generator */ - public RandomGeneratedReferencePoints(int samplesize, double scale) { + public RandomGeneratedReferencePoints(int samplesize, double scale, RandomFactory rnd) { super(); this.samplesize = samplesize; this.scale = scale; + this.rnd = rnd; } @Override - public <T extends V> Collection<V> getReferencePoints(Relation<T> db) { - Relation<V> database = DatabaseUtil.relationUglyVectorCast(db); - Pair<V, V> minmax = DatabaseUtil.computeMinMax(database); - NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database); - + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { + double[][] minmax = RelationUtil.computeMinMax(db); int dim = RelationUtil.dimensionality(db); - // Compute mean from minmax. - double[] mean = new double[dim]; - double[] delta = new double[dim]; + // Compute mean and extend from minmax. + double[] mean = minmax[0], delta = minmax[1]; for(int d = 0; d < dim; d++) { - mean[d] = (minmax.first.doubleValue(d + 1) + minmax.second.doubleValue(d + 1)) * .5; - delta[d] = (minmax.second.doubleValue(d + 1) - minmax.first.doubleValue(d + 1)); + delta[d] -= mean[d]; + mean[d] -= delta[d] * .5; } - ArrayList<V> result = new ArrayList<>(samplesize); + ArrayList<Vector> result = new ArrayList<>(samplesize); double[] vec = new double[dim]; for(int i = 0; i < samplesize; i++) { for(int d = 0; d < dim; d++) { vec[d] = mean[d] + (Math.random() - 0.5) * scale * delta[d]; } - V newp = factory.newNumberVector(vec); + Vector newp = new Vector(vec); // logger.debug("New reference point: " + FormatUtil.format(vec)); result.add(newp); } @@ -123,7 +107,32 @@ public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implement * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { + /** + * Parameter to specify the number of requested reference points. + * <p> + * Key: {@code -generate.n} + * </p> + */ + public static final OptionID N_ID = new OptionID("generate.n", "The number of reference points to be generated."); + + /** + * Parameter for additional scaling of the space, to allow out-of-space + * reference points. + * <p> + * Key: {@code -generate.scale} + * </p> + */ + public static final OptionID SCALE_ID = new OptionID("generate.scale", "Scale the grid by the given factor. This can be used to obtain reference points outside the used data space."); + + /** + * Parameter to specify the sample size. + * <p> + * Key: {@code -generate.random} + * </p> + */ + public static final OptionID RANDOM_ID = new OptionID("generate.random", "Random generator seed."); + /** * Holds the value of {@link #N_ID}. */ @@ -134,26 +143,36 @@ public class RandomGeneratedReferencePoints<V extends NumberVector<?>> implement */ protected double scale = 1.0; + /** + * Random generator. + */ + protected RandomFactory rnd; + @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - IntParameter samplesizeP = new IntParameter(N_ID); - samplesizeP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT); + IntParameter samplesizeP = new IntParameter(N_ID) // + .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT); if(config.grab(samplesizeP)) { samplesize = samplesizeP.getValue(); } - DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0); - scaleP.addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE); + DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0) // + .addConstraint(CommonConstraints.GREATER_THAN_ZERO_DOUBLE); if(config.grab(scaleP)) { scale = scaleP.getValue(); } + + RandomParameter randomP = new RandomParameter(RANDOM_ID); + if(config.grab(randomP)) { + rnd = randomP.getValue(); + } } @Override - protected RandomGeneratedReferencePoints<V> makeInstance() { - return new RandomGeneratedReferencePoints<>(samplesize, scale); + protected RandomGeneratedReferencePoints makeInstance() { + return new RandomGeneratedReferencePoints(samplesize, scale, rnd); } } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java index ea80d9d9..472d36d3 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/RandomSampleReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,112 +25,62 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import de.lmu.ifi.dbs.elki.data.NumberVector; -import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DBIDs; import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; +import de.lmu.ifi.dbs.elki.math.random.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.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; /** * Random-Sampling strategy for picking reference points. * * @author Erich Schubert - * - * @param <V> Vector type */ -public class RandomSampleReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> { - // TODO: use reproducible Random - - /** - * Parameter to specify the sample size. - * <p> - * Key: {@code -sample.n} - * </p> - */ - public static final OptionID N_ID = new OptionID("sample.n", "The number of samples to draw."); - +public class RandomSampleReferencePoints implements ReferencePointsHeuristic { /** - * Constant used in choosing optimal table sizes. + * Sample size. */ - private static final double LOG4 = Math.log(4); + protected int samplesize; /** - * Holds the value of {@link #N_ID}. + * Random generator. */ - private int samplesize; + protected RandomFactory rnd; /** * Constructor. * * @param samplesize Sampling size */ - public RandomSampleReferencePoints(int samplesize) { + public RandomSampleReferencePoints(int samplesize, RandomFactory rnd) { super(); this.samplesize = samplesize; + this.rnd = rnd; } @Override - public <T extends V> Collection<V> getReferencePoints(Relation<T> db) { + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { if(samplesize >= db.size()) { - LoggingUtil.warning("Sample size is larger than database size!"); - - ArrayList<V> selection = new ArrayList<>(db.size()); - for(DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) { - selection.add(db.get(iditer)); - } - return selection; + LoggingUtil.warning("Requested sample size is larger than database size!"); + return new RelationUtil.CollectionFromRelation<>(db); } - ArrayList<V> result = new ArrayList<>(samplesize); - int dbsize = db.size(); + ArrayList<NumberVector> result = new ArrayList<>(samplesize); + DBIDs sample = DBIDUtil.randomSample(db.getDBIDs(), samplesize, rnd); - // Guess the memory requirements of a hashmap. - // The values are based on Python code, and might need modification for - // Java! - // If the hashmap is likely to become too big, lazy-shuffle a list instead. - int setsize = 21; - if(samplesize > 5) { - setsize += 2 << (int) Math.ceil(Math.log(samplesize * 3) / LOG4); - } - // logger.debug("Setsize: "+setsize); - ArrayDBIDs ids = DBIDUtil.ensureArray(db.getDBIDs()); - boolean fastrandomaccess = false; - if(ArrayList.class.isAssignableFrom(ids.getClass())) { - fastrandomaccess = true; - } - if(samplesize <= setsize || !fastrandomaccess) { - // use pool approach - // if getIDs() is an array list, we don't need to copy it again. - ArrayModifiableDBIDs pool = ((ArrayModifiableDBIDs.class.isAssignableFrom(ids.getClass())) ? (ArrayModifiableDBIDs) ids : DBIDUtil.newArray(ids)); - for(int i = 0; i < samplesize; i++) { - int j = (int) Math.floor(Math.random() * (dbsize - i)); - result.add(db.get(pool.get(j))); - pool.set(j, pool.get(dbsize - i - 1)); - } - ids = null; // dirty! - } - else { - HashSet<Integer> selected = new HashSet<>(); - for(int i = 0; i < samplesize; i++) { - int j = (int) Math.floor(Math.random() * dbsize); - // Redraw from pool. - while(selected.contains(j)) { - j = (int) Math.floor(Math.random() * dbsize); - } - selected.add(j); - result.add(db.get(ids.get(j))); - } + for(DBIDIter it = sample.iter(); it.valid(); it.advance()) { + result.add(db.get(it)); } - assert (result.size() == samplesize); return result; } @@ -141,25 +91,50 @@ public class RandomSampleReferencePoints<V extends NumberVector<?>> implements R * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { + /** + * Parameter to specify the sample size. + * <p> + * Key: {@code -sample.n} + * </p> + */ + public static final OptionID N_ID = new OptionID("sample.n", "The number of samples to draw."); + /** - * Holds the value of {@link #N_ID}. + * Parameter to specify the sample size. + * <p> + * Key: {@code -sample.random} + * </p> + */ + public static final OptionID RANDOM_ID = new OptionID("sample.random", "Random generator seed."); + + /** + * Sample size. */ protected int samplesize; + /** + * Random generator. + */ + protected RandomFactory rnd; + @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); - IntParameter samplesizeP = new IntParameter(N_ID); - samplesizeP.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT); + IntParameter samplesizeP = new IntParameter(N_ID)// + .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT); if(config.grab(samplesizeP)) { samplesize = samplesizeP.intValue(); } + RandomParameter randomP = new RandomParameter(RANDOM_ID); + if(config.grab(randomP)) { + rnd = randomP.getValue(); + } } @Override - protected RandomSampleReferencePoints<V> makeInstance() { - return new RandomSampleReferencePoints<>(samplesize); + protected RandomSampleReferencePoints makeInstance() { + return new RandomSampleReferencePoints(samplesize, rnd); } } }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java index 672b5240..a20fdfd6 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/ReferencePointsHeuristic.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,22 +25,20 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; import java.util.Collection; +import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; /** * Simple Interface for an heuristic to pick reference points. * * @author Erich Schubert - * - * @param <O> Object type */ -public interface ReferencePointsHeuristic<O> extends Parameterizable { +public interface ReferencePointsHeuristic { /** * Get the reference points for the given database. * * @param db Database * @return Collection of reference points. */ - public <T extends O> Collection<O> getReferencePoints(Relation<T> db); + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db); }
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java index 74cdf92b..b8de4338 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/StarBasedReferencePoints.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.referencepoints; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -30,7 +30,7 @@ import de.lmu.ifi.dbs.elki.data.NumberVector; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.relation.Relation; import de.lmu.ifi.dbs.elki.database.relation.RelationUtil; -import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector; 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.CommonConstraints; @@ -42,34 +42,15 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag; * Star-based strategy to pick reference points. * * @author Erich Schubert - * - * @param <V> Object type */ -public class StarBasedReferencePoints<V extends NumberVector<?>> implements ReferencePointsHeuristic<V> { - /** - * Parameter to specify the grid resolution. - * <p> - * Key: {@code -star.nocenter} - * </p> - */ - public static final OptionID NOCENTER_ID = new OptionID("star.nocenter", "Do not use the center as extra reference point."); - +public class StarBasedReferencePoints implements ReferencePointsHeuristic { /** - * Parameter to specify the extra scaling of the space, to allow - * out-of-data-space reference points. - * <p> - * Key: {@code -star.scale} - * </p> - */ - public static final OptionID SCALE_ID = new OptionID("star.scale", "Scale the reference points by the given factor. This can be used to obtain reference points outside the used data space."); - - /** - * Holds the value of {@link #NOCENTER_ID}. + * Exclude the center vector. */ protected boolean nocenter; /** - * Holds the value of {@link #SCALE_ID}. + * Scaling factor. */ protected double scale; @@ -86,10 +67,7 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe } @Override - public <T extends V> Collection<V> getReferencePoints(Relation<T> db) { - Relation<V> database = DatabaseUtil.relationUglyVectorCast(db); - NumberVector.Factory<V, ?> factory = RelationUtil.getNumberVectorFactory(database); - + public Collection<? extends NumberVector> getReferencePoints(Relation<? extends NumberVector> db) { int dim = RelationUtil.dimensionality(db); // Compute minimum, maximum and centroid @@ -101,10 +79,10 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe min[d] = Double.MAX_VALUE; max[d] = -Double.MAX_VALUE; } - for(DBIDIter iditer = database.iterDBIDs(); iditer.valid(); iditer.advance()) { - V obj = database.get(iditer); + for(DBIDIter iditer = db.iterDBIDs(); iditer.valid(); iditer.advance()) { + NumberVector obj = db.get(iditer); for(int d = 0; d < dim; d++) { - double val = obj.doubleValue(d + 1); + double val = obj.doubleValue(d); centroid[d] += val; min[d] = Math.min(min[d], val); max[d] = Math.max(max[d], val); @@ -112,27 +90,23 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe } // finish centroid, scale min, max for(int d = 0; d < dim; d++) { - centroid[d] = centroid[d] / database.size(); + centroid[d] = centroid[d] / db.size(); min[d] = (min[d] - centroid[d]) * scale + centroid[d]; max[d] = (max[d] - centroid[d]) * scale + centroid[d]; } - ArrayList<V> result = new ArrayList<>(2 * dim + 1); + ArrayList<Vector> result = new ArrayList<>(2 * dim + 1); if(!nocenter) { - result.add(factory.newNumberVector(centroid)); + result.add(new Vector(centroid)); } // Plus axis end points through centroid - double[] vec = new double[dim]; for(int i = 0; i < dim; i++) { - for(int d = 0; d < dim; d++) { - if(d != i) { - vec[d] = centroid[d]; - } - } + double[] vec = centroid.clone(); vec[i] = min[i]; - result.add(factory.newNumberVector(vec)); + result.add(new Vector(vec)); + vec = centroid.clone(); vec[i] = max[i]; - result.add(factory.newNumberVector(vec)); + result.add(new Vector(vec)); } return result; @@ -145,7 +119,24 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe * * @apiviz.exclude */ - public static class Parameterizer<V extends NumberVector<?>> extends AbstractParameterizer { + public static class Parameterizer extends AbstractParameterizer { + /** + * Parameter to specify the grid resolution. + * <p> + * Key: {@code -star.nocenter} + * </p> + */ + public static final OptionID NOCENTER_ID = new OptionID("star.nocenter", "Do not use the center as extra reference point."); + + /** + * Parameter to specify the extra scaling of the space, to allow + * out-of-data-space reference points. + * <p> + * Key: {@code -star.scale} + * </p> + */ + public static final OptionID SCALE_ID = new OptionID("star.scale", "Scale the reference points by the given factor. This can be used to obtain reference points outside the used data space."); + /** * Holds the value of {@link #NOCENTER_ID}. */ @@ -164,16 +155,16 @@ public class StarBasedReferencePoints<V extends NumberVector<?>> implements Refe nocenter = nocenterF.getValue(); } - DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0); - scaleP.addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE); + DoubleParameter scaleP = new DoubleParameter(SCALE_ID, 1.0) // + .addConstraint(CommonConstraints.GREATER_EQUAL_ZERO_DOUBLE); if(config.grab(scaleP)) { scale = scaleP.getValue(); } } @Override - protected StarBasedReferencePoints<V> makeInstance() { - return new StarBasedReferencePoints<>(nocenter, scale); + protected StarBasedReferencePoints makeInstance() { + return new StarBasedReferencePoints(nocenter, scale); } } } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java index 6268d5d2..1fa77206 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/referencepoints/package-info.java @@ -7,7 +7,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java index 068e1230..3fa42408 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ClipScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java index daff7275..998b3c52 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/GammaScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java index 7f24431d..6820f3c1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/IdentityScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java index ef28c434..01721c34 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/LinearScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java index 8e497dd9..0a18ca00 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/MinusLogScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java index c738aa9a..9aedddc9 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/ScalingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,8 +23,6 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; - /** * Interface for scaling functions used e.g. by outlier evaluation such as * Histograms and visualization. @@ -39,7 +37,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; * * @author Erich Schubert */ -public interface ScalingFunction extends Parameterizable { +public interface ScalingFunction { /** * Transform a given value using the scaling function. * diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java index 27d12db4..633fad16 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/StaticScalingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java index 202d1044..9f00d9ab 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/COPOutlierScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; import java.util.Arrays; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.statistics.distribution.Distribution; import de.lmu.ifi.dbs.elki.math.statistics.distribution.estimator.meta.BestFitEstimator; import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta; @@ -117,11 +117,11 @@ public class COPOutlierScaling implements OutlierScalingFunction { public void prepare(OutlierResult or) { double[] s; { - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); s = new double[scores.size()]; int i = 0; for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance(), i++) { - s[i] = scores.get(id); + s[i] = scores.doubleValue(id); } } Arrays.sort(s); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java index 5e55c2e0..4d7d4d9f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/HeDESNormalizationOutlierScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; @@ -63,9 +63,9 @@ public class HeDESNormalizationOutlierScaling implements OutlierScalingFunction MeanVariance mv = new MeanVariance(); DoubleMinMax minmax = new DoubleMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isNaN(val) && !Double.isInfinite(val)) { mv.put(val); minmax.put(val); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java index effbcfe0..0ba85d79 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogGammaScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.math.statistics.distribution.GammaDistribution; @@ -68,9 +68,9 @@ public class MinusLogGammaScaling extends OutlierGammaScaling { meta = or.getOutlierMeta(); // Determine Minimum and Maximum. DoubleMinMax mm = new DoubleMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double score = scores.get(id); + double score = scores.doubleValue(id); if(!Double.isNaN(score) && !Double.isInfinite(score)) { mm.put(score); } @@ -80,7 +80,7 @@ public class MinusLogGammaScaling extends OutlierGammaScaling { // with the prescaling, do Gamma Scaling. MeanVariance mv = new MeanVariance(); for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double score = scores.get(id); + double score = scores.doubleValue(id); score = preScale(score); if(!Double.isNaN(score) && !Double.isInfinite(score)) { mv.put(score); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java index d30fbac7..1b5c7023 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MinusLogStandardDeviationScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.Mean; import de.lmu.ifi.dbs.elki.math.MeanVariance; @@ -69,9 +69,9 @@ public class MinusLogStandardDeviationScaling extends StandardDeviationScaling { public void prepare(OutlierResult or) { if(fixedmean == null) { MeanVariance mv = new MeanVariance(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = -Math.log(scores.get(id)); + double val = -Math.log(scores.doubleValue(id)); if(!Double.isNaN(val) && !Double.isInfinite(val)) { mv.put(val); } @@ -82,9 +82,9 @@ public class MinusLogStandardDeviationScaling extends StandardDeviationScaling { else { mean = fixedmean; Mean sqsum = new Mean(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = -Math.log(scores.get(id)); + double val = -Math.log(scores.doubleValue(id)); if(!Double.isNaN(val) && !Double.isInfinite(val)) { sqsum.put((val - mean) * (val - mean)); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java index 9c5ad920..5c1d8f5f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MixtureModelOutlierScalingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.MeanVariance; @@ -122,9 +122,9 @@ public class MixtureModelOutlierScalingFunction implements OutlierScalingFunctio public void prepare(OutlierResult or) { // Initial parameters - are these defaults sounds? MeanVariance mv = new MeanVariance(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isNaN(val) && !Double.isInfinite(val)) { mv.put(val); } @@ -151,7 +151,7 @@ public class MixtureModelOutlierScalingFunction implements OutlierScalingFunctio // Weighted deviation from previous mean double sqsum = 0.0; for (int i = 0; i < ids.size(); i++) { - double val = or.getScores().get(ids.get(i)); + double val = or.getScores().doubleValue(ids.get(i)); // E-Step double ti = calcPosterior(val, curAlpha, curMu, curSigma, curLambda); // M-Step diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java index d5cd3f40..718ca3be 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/MultiplicativeInverseScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; @@ -41,11 +41,13 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; * * @author Erich Schubert */ -@Reference(authors="H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", title="Interpreting and Unifying Outlier Scores", booktitle="Proc. 11th SIAM International Conference on Data Mining (SDM), Mesa, AZ, 2011", url="http://siam.omnibooksonline.com/2011datamining/data/papers/018.pdf") +@Reference(authors="H.-P. Kriegel, P. Kröger, E. Schubert, A. Zimek", // +title="Interpreting and Unifying Outlier Scores", // +booktitle="Proc. 11th SIAM International Conference on Data Mining (SDM), Mesa, AZ, 2011", // +url="http://siam.omnibooksonline.com/2011datamining/data/papers/018.pdf") public class MultiplicativeInverseScaling implements OutlierScalingFunction { /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + * Constructor. */ public MultiplicativeInverseScaling() { super(); @@ -70,9 +72,9 @@ public class MultiplicativeInverseScaling implements OutlierScalingFunction { @Override public void prepare(OutlierResult or) { double max = Double.MIN_VALUE; - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for(DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); double inv = Math.abs(1.0 / val); if(!Double.isInfinite(inv) && !Double.isNaN(inv)) { max = Math.max(max, inv); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java index 7da0c933..b8c4e23a 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierGammaScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.math.statistics.distribution.GammaDistribution; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; @@ -102,9 +102,9 @@ public class OutlierGammaScaling implements OutlierScalingFunction { public void prepare(OutlierResult or) { meta = or.getOutlierMeta(); MeanVariance mv = new MeanVariance(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double score = scores.get(id); + double score = scores.doubleValue(id); score = preScale(score); if (!Double.isNaN(score) && !Double.isInfinite(score)) { mv.put(score); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java index dfae1068..710ddc91 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierLinearScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; import java.util.ArrayList; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; @@ -149,9 +149,9 @@ public class OutlierLinearScaling implements OutlierScalingFunction { MeanVariance mv = new MeanVariance(); DoubleMinMax mm = (max == null) ? new DoubleMinMax() : null; boolean skippedzeros = false; - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (nozeros && val == 0.0) { skippedzeros = true; continue; @@ -175,9 +175,9 @@ public class OutlierLinearScaling implements OutlierScalingFunction { if (min == null || max == null) { boolean skippedzeros = false; DoubleMinMax mm = new DoubleMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (nozeros && val == 0.0) { skippedzeros = true; continue; diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java index f0e04913..932ee691 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierMinusLogScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; @@ -34,7 +34,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; * Scaling function to invert values by computing -1 * Math.log(x) * * Useful for example for scaling - * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.ABOD}, but see + * {@link de.lmu.ifi.dbs.elki.algorithm.outlier.anglebased.ABOD}, but see * {@link MinusLogStandardDeviationScaling} and {@link MinusLogGammaScaling} for * more advanced scalings for this algorithm. * @@ -53,8 +53,7 @@ public class OutlierMinusLogScaling implements OutlierScalingFunction { double mlogmax; /** - * Constructor, adhering to - * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable} + * Constructor. */ public OutlierMinusLogScaling() { super(); @@ -79,9 +78,9 @@ public class OutlierMinusLogScaling implements OutlierScalingFunction { @Override public void prepare(OutlierResult or) { DoubleMinMax mm = new DoubleMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isNaN(val) && !Double.isInfinite(val)) { mm.put(val); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java index 9de05e78..ac2533c1 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierScalingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java index 302602d4..2f318ea4 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/OutlierSqrtScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.DoubleMinMax; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.NumberArrayAdapter; @@ -83,9 +83,9 @@ public class OutlierSqrtScaling implements OutlierScalingFunction { public void prepare(OutlierResult or) { if (pmin == null || pmax == null) { DoubleMinMax mm = new DoubleMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isInfinite(val)) { mm.put(val); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java index 505f2002..4f8fec79 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/RankingPseudoOutlierScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -26,7 +26,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; import java.util.Arrays; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.result.outlier.InvertedOutlierScoreMeta; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayLikeUtil; @@ -54,14 +54,14 @@ public class RankingPseudoOutlierScaling implements OutlierScalingFunction { @Override public void prepare(OutlierResult or) { // collect all outlier scores - Relation<Double> oscores = or.getScores(); + DoubleRelation oscores = or.getScores(); scores = new double[oscores.size()]; int pos = 0; if(or.getOutlierMeta() instanceof InvertedOutlierScoreMeta) { inverted = true; } for(DBIDIter iditer = oscores.iterDBIDs(); iditer.valid(); iditer.advance()) { - scores[pos] = oscores.get(iditer); + scores[pos] = oscores.doubleValue(iditer); pos++; } if(pos != oscores.size()) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java index 34911169..0887933f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SigmoidOutlierScalingFunction.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -29,7 +29,7 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs; import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.math.MeanVariance; import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult; @@ -63,9 +63,9 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { public void prepare(OutlierResult or) { // Initial parameters - are these defaults sounds? MeanVariance mv = new MeanVariance(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); mv.put(val); } double a = 1.0; @@ -81,7 +81,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { // E-Step it.seek(0); for (int i = 0; i < ids.size(); i++, it.advance()) { - double val = or.getScores().get(it); + double val = or.getScores().doubleValue(it); double targ = a * val + b; if (targ > 0) { if (!t.get(i)) { @@ -196,7 +196,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { * @param scores Scores * @return new values for A and B. */ - private final double[] MStepLevenbergMarquardt(double a, double b, ArrayDBIDs ids, BitSet t, Relation<Double> scores) { + private final double[] MStepLevenbergMarquardt(double a, double b, ArrayDBIDs ids, BitSet t, DoubleRelation scores) { final int prior1 = t.cardinality(); final int prior0 = ids.size() - prior1; DBIDArrayIter iter = ids.iter(); @@ -216,7 +216,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { double fval = 0.0; iter.seek(0); for (int i = 0; i < ids.size(); i++, iter.advance()) { - final double val = scores.get(iter); + final double val = scores.doubleValue(iter); final double fApB = val * a + b; final double ti = t.get(i) ? hiTarget : loTarget; if (fApB >= 0) { @@ -235,7 +235,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { double g2 = 0.0; iter.seek(0); for (int i = 0; i < ids.size(); i++, iter.advance()) { - final double val = scores.get(iter); + final double val = scores.doubleValue(iter); final double fApB = val * a + b; final double p; final double q; @@ -270,7 +270,7 @@ public class SigmoidOutlierScalingFunction implements OutlierScalingFunction { double newf = 0.0; iter.seek(0); for (int i = 0; i < ids.size(); i++, iter.advance()) { - final double val = scores.get(iter); + final double val = scores.doubleValue(iter); final double fApB = val * newA + newB; final double ti = t.get(i) ? hiTarget : loTarget; if (fApB >= 0) { diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java index 2110570e..ad631bb7 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/SqrtStandardDeviationScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.Mean; import de.lmu.ifi.dbs.elki.math.MeanVarianceMinMax; @@ -99,9 +99,9 @@ public class SqrtStandardDeviationScaling implements OutlierScalingFunction { public void prepare(OutlierResult or) { if (pmean == null) { MeanVarianceMinMax mv = new MeanVarianceMinMax(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); val = (val <= min) ? 0 : Math.sqrt(val - min); mv.put(val); } @@ -112,10 +112,10 @@ public class SqrtStandardDeviationScaling implements OutlierScalingFunction { mean = pmean; double sqsum = 0; int cnt = 0; - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); double mm = Double.POSITIVE_INFINITY; for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); mm = Math.min(mm, val); val = (val <= min) ? 0 : Math.sqrt(val - min); sqsum += (val - mean) * (val - mean); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java index b0040571..c9486b9d 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/StandardDeviationScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -24,7 +24,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; */ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; -import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation; import de.lmu.ifi.dbs.elki.math.MathUtil; import de.lmu.ifi.dbs.elki.math.Mean; import de.lmu.ifi.dbs.elki.math.MeanVariance; @@ -109,9 +109,9 @@ public class StandardDeviationScaling implements OutlierScalingFunction { public void prepare(OutlierResult or) { if (fixedmean == null) { MeanVariance mv = new MeanVariance(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isNaN(val) && !Double.isInfinite(val)) { mv.put(val); } @@ -124,9 +124,9 @@ public class StandardDeviationScaling implements OutlierScalingFunction { } else { mean = fixedmean; Mean sqsum = new Mean(); - Relation<Double> scores = or.getScores(); + DoubleRelation scores = or.getScores(); for (DBIDIter id = scores.iterDBIDs(); id.valid(); id.advance()) { - double val = scores.get(id); + double val = scores.doubleValue(id); if (!Double.isNaN(val) && !Double.isInfinite(val)) { sqsum.put((val - mean) * (val - mean)); } diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java index 71a495a6..f00a18b3 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/TopKOutlierScaling.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.scaling.outlier; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -102,7 +102,7 @@ public class TopKOutlierScaling implements OutlierScalingFunction { } DBIDIter order = or.getOrdering().iter(or.getOrdering().getDBIDs()).iter(); for(int i = 0; i < k && order.valid(); i++, order.advance()) { - cutoff = or.getScores().get(order); + cutoff = or.getScores().doubleValue(order); } max = or.getOutlierMeta().getActualMaximum(); ground = or.getOutlierMeta().getTheoreticalBaseline(); diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java index a34aac08..80c9c2d5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/outlier/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java index 633aa65a..e88a2df5 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/scaling/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java index 44116dfe..e8b5145e 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/DOMCloner.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java index a68631d5..7a90361f 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/HTMLUtil.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java index c1decfe1..8586bc66 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeIterator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java index 1fb39663..eea27828 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/XMLNodeListIterator.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.utilities.xml; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java b/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java index 8f6d8a04..651c5aac 100644 --- a/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/utilities/xml/package-info.java @@ -6,7 +6,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2013 +Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |