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) 2012 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 . */ import java.util.List; import de.lmu.ifi.dbs.elki.data.FeatureVector; import de.lmu.ifi.dbs.elki.data.NumberVector; /** * Utility class that allows plug-in use of various "array-like" types such as * lists in APIs that can take any kind of array to safe the cost of * reorganizing the objects into a real array. * * @author Erich Schubert */ public final class ArrayLikeUtil { /** * Static instance for lists */ private static final ListArrayAdapter LISTADAPTER = new ListArrayAdapter(); /** * Static instance for lists of numbers */ private static final NumberListArrayAdapter NUMBERLISTADAPTER = new NumberListArrayAdapter(); /** * Static instance */ private final static IdentityArrayAdapter IDENTITYADAPTER = new IdentityArrayAdapter(); /** * Static instance */ private static final FeatureVectorAdapter FEATUREVECTORADAPTER = new FeatureVectorAdapter(); /** * Use a number vector in the array API. */ private static final NumberVectorAdapter NUMBERVECTORADAPTER = new NumberVectorAdapter(); /** * Use a double array in the array API. */ public static final NumberArrayAdapter DOUBLEARRAYADAPTER = new DoubleArrayAdapter(); /** * Use a float array in the array API. */ public static final NumberArrayAdapter FLOATARRAYADAPTER = new FloatArrayAdapter(); /** * Use a Trove double list as array. */ public static final TDoubleListAdapter TDOUBLELISTADAPTER = new TDoubleListAdapter(); /** * Use ArrayDBIDs as array. */ public static final ArrayDBIDsAdapter ARRAYDBIDADAPTER = new ArrayDBIDsAdapter(); /** * Cast the static instance. * * @param dummy Dummy variable, for type inference * @return Static instance */ @SuppressWarnings("unchecked") public static ArrayAdapter> listAdapter(List dummy) { return (ListArrayAdapter) LISTADAPTER; } /** * Cast the static instance. * * @param dummy Dummy variable, for type inference * @return Static instance */ @SuppressWarnings("unchecked") public static NumberArrayAdapter> numberListAdapter(List dummy) { return (NumberListArrayAdapter) NUMBERLISTADAPTER; } /** * Get the static instance. * * @param dummy Dummy object for type inference * @return Static instance */ @SuppressWarnings("unchecked") public static IdentityArrayAdapter identityAdapter(T dummy) { return (IdentityArrayAdapter) IDENTITYADAPTER; } /** * Get the static instance. * * @param prototype Prototype value, for type inference * @return Instance */ @SuppressWarnings("unchecked") public static FeatureVectorAdapter featureVectorAdapter(FeatureVector prototype) { return (FeatureVectorAdapter) FEATUREVECTORADAPTER; } /** * Get the static instance. * * @param prototype Prototype value, for type inference * @return Instance */ @SuppressWarnings("unchecked") public static NumberVectorAdapter numberVectorAdapter(NumberVector prototype) { return (NumberVectorAdapter) NUMBERVECTORADAPTER; } /** * Get the adapter for double arrays. * * @return double array adapter */ public static NumberArrayAdapter doubleArrayAdapter() { return DOUBLEARRAYADAPTER; } /** * Returns the index of the maximum of the given values. If no value is bigger * than the first, the index of the first entry is returned. * * @param array type * @param array Array to inspect * @param adapter API adapter class * @return the index of the maximum in the given values * @throws IndexOutOfBoundsException if the length of the array is 0. */ public static int getIndexOfMaximum(A array, NumberArrayAdapter adapter) throws IndexOutOfBoundsException { final int size = adapter.size(array); int index = 0; double max = adapter.getDouble(array, 0); for(int i = 1; i < size; i++) { double val = adapter.getDouble(array, i); if(val > max) { max = val; index = i; } } return index; } /** * Returns the index of the maximum of the given values. If no value is bigger * than the first, the index of the first entry is returned. * * @param array Array to inspect * @return the index of the maximum in the given values * @throws IndexOutOfBoundsException if the length of the array is 0. */ public static int getIndexOfMaximum(double[] array) throws IndexOutOfBoundsException { return getIndexOfMaximum(array, DOUBLEARRAYADAPTER); } /** * Convert a numeric array-like to a double[] * * @param array Array-like * @param adapter Adapter * @return primitive double array */ public static double[] toPrimitiveDoubleArray(A array, NumberArrayAdapter adapter) { double[] ret = new double[adapter.size(array)]; for(int i = 0; i < ret.length; i++) { ret[i] = adapter.getDouble(array, i); } return ret; } /** * Convert a list of numbers to double[]. * * @param array List of numbers * @return double array */ public static double[] toPrimitiveDoubleArray(List array) { return toPrimitiveDoubleArray(array, NUMBERLISTADAPTER); } /** * Convert a number vector to double[]. * * @param obj Object to convert * @return primitive double array */ public static double[] toPrimitiveDoubleArray(NumberVector obj) { return toPrimitiveDoubleArray(obj, numberVectorAdapter(obj)); } /** * Convert a numeric array-like to a float[] * * @param array Array-like * @param adapter Adapter * @return primitive float array */ public static float[] toPrimitiveFloatArray(A array, NumberArrayAdapter adapter) { float[] ret = new float[adapter.size(array)]; for(int i = 0; i < ret.length; i++) { ret[i] = adapter.getFloat(array, i); } return ret; } /** * Convert a list of numbers to float[]. * * @param array List of numbers * @return float array */ public static float[] toPrimitiveFloatArray(List array) { return toPrimitiveFloatArray(array, NUMBERLISTADAPTER); } /** * Convert a number vector to float[]. * * @param obj Object to convert * @return primitive float array */ public static float[] toPrimitiveFloatArray(NumberVector obj) { return toPrimitiveFloatArray(obj, numberVectorAdapter(obj)); } }