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 extends T> 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 extends T> 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, F> prototype) {
return (FeatureVectorAdapter) FEATUREVECTORADAPTER;
}
/**
* Get the static instance.
*
* @param prototype Prototype value, for type inference
* @return Instance
*/
@SuppressWarnings("unchecked")
public static NumberVectorAdapter numberVectorAdapter(NumberVector, N> 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, A> 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, ? super A> 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 extends Number> 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, N> 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, ? super A> 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 extends Number> 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, N> obj) {
return toPrimitiveFloatArray(obj, numberVectorAdapter(obj));
}
}