/*
* RapidMiner
*
* Copyright (C) 2001-2008 by Rapid-I and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapid-i.com
*
* 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 com.rapidminer.tools.container;
/**
* This class represents a multidimensional array whose
* dimensions have to be specified during construction. The
* multidimensional array is modeled by an underlying single
* dimension array.
*
* @author Tobias Malbrecht
* @version $Id: MultidimensionalArraySet.java,v 1.1 2008/06/13 13:39:43 tobiasmalbrecht Exp $
*
* @param <E> the class of the array elements
*/
public class MultidimensionalArraySet<E> {
/** The underlying single dimension array. */
private E[] array;
/**
* The dimensions of the multidimensional array.
*/
private int[] dimensions;
/**
* The number of combinations that is possible with specifying
* the last following attributes. These are used for computing
* the single array index from multidimensional indices.
*/
private int[] combinations;
/**
* The constructor.
*
* @param dimensions int array which contains the size of each dimension
*/
@SuppressWarnings("unchecked")
public MultidimensionalArraySet(int[] dimensions) {
this.dimensions = dimensions;
int splits = dimensions.length;
int numberOfCombinations = 1;
combinations = new int[splits];
for (int i = splits - 1; i > 0; i--) {
numberOfCombinations *= dimensions[i];
combinations[i - 1] = numberOfCombinations;
}
numberOfCombinations *= dimensions[0];
combinations[splits - 1] = 1;
array = (E[]) new Object[numberOfCombinations];
}
/**
* Returns the array element at the specified single dimension
* array position.
*
* @param index the index
* @return an element
*/
public E get(int index) {
return array[index];
}
/**
* Returns the array element at the position specified by the
* given indices.
*
* @param indices the indices
* @return an element
*/
public E get(int[] indices) {
return array[getIndex(indices)];
}
/**
* Sets the array element at the specified single dimension
* array position.
*
* @param index the index
* @param e an element
*/
public void set(int index, E e) {
array[index] = e;
}
/**
* Sets the array element at the position specified by the given
* indices
*
* @param indices the indices
* @param e an element
*/
public void set(int[] indices, E e) {
array[getIndex(indices)] = e;
}
/**
* Computes the single dimension array index from the given
* multidimensional indices.
*
* @param indices the indices
* @return the corresponding index
*/
public int getIndex(int[] indices) {
return sumProduct(indices, combinations);
}
/**
* Computs the multidimensional indices corresponding to a single
* dimension array index.
*
* @param index the index
* @return the corresponding indices
*/
public int[] getIndices(int index) {
int[] indices = new int[combinations.length];
int r = index;
for (int i = 0; i < indices.length; i++) {
indices[i] = r / combinations[i];
r = r % combinations[i];
}
return indices;
}
/**
* Returns the number of elements this array can hold.
*
* @return size
*/
public int size() {
return array.length;
}
/**
* Returns an int array holding the dimensions of the
* multidimensional array.
*
* @return dimensions
*/
public int[] getDimensions() {
return dimensions;
}
/**
* Calculates the sum product of two int arrays. Used for the calculation
* of a single dimension array index from multidimensional indices.
*/
private int sumProduct(int[] firstIndices, int[] secondIndices) {
int firstLength = firstIndices.length;
int secondLength = secondIndices.length;
int length = secondLength > firstLength ? firstLength : secondLength;
int product = 0;
for (int i = 0; i < length; i++) {
product += firstIndices[i] * secondIndices[i];
}
return product;
}
}