com.meliorbis.numerics.generic.impl.AbstractBlockedArray Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Numerics Show documentation
Show all versions of Numerics Show documentation
A library for working with large multi-dimensional arrays and the functions they represent
package com.meliorbis.numerics.generic.impl;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import com.meliorbis.numerics.generic.MultiDimensionalArray;
import com.meliorbis.numerics.generic.MultiDimensionalArrayException;
import com.meliorbis.numerics.generic.SettableIndexedIterator;
import com.meliorbis.numerics.generic.SettableIterator;
import com.meliorbis.numerics.generic.SubSpaceSplitIterator;
import com.meliorbis.numerics.index.SubIndex;
import com.meliorbis.numerics.index.impl.Index;
import com.meliorbis.numerics.threading.Executor;
/**
* This implementation of {@link MultiDimensionalArray} effectively holds the
* data in a one dimensional array. Because that array might be rather large,
* making allocation difficult and costly, the array is split into fixed size
* blocks.
*
* @author Tobias Grasl
*
* @param The underlying type
*/
public abstract class AbstractBlockedArray> extends AbstractArray {
protected final BlockedArrayData _data;
protected SubIndex _subIndex;
public AbstractBlockedArray(Executor executor_, int[] dimensions_) {
super(executor_, dimensions_);
_data = createData(dimensions_);
}
abstract protected BlockedArrayData createData(int[] dimensions_);
abstract protected BlockedArrayData createDataFromValues(T[] data_);
protected AbstractBlockedArray(BlockedArrayData data_, Executor executor_) {
super(data_.getLogicalIndex(), executor_);
_data = data_;
}
protected AbstractBlockedArray(final T[] data_, Executor executor_) {
// Create a one dimensional array, as long as data
super(executor_, new int[]{data_.length});
_data = createDataFromValues(data_);
}
public AbstractBlockedArray(BlockedArrayData data_, SubIndex subIndex_, Executor executor_) {
super(subIndex_, executor_);
_data = data_;
_subIndex = subIndex_;
}
/*
* (non-Javadoc)
*
* @see
* com.meliorbis.numerics.generic.IMultiDimensionalArray#subArrayAt(int[])
*/
@Override
public R at(int... atPosition_) {
return createSub(_data, _index.subIndexAt(atPosition_));
}
protected abstract R createSub(
BlockedArrayData _data, SubIndex dimensionCounter_);
public interface ElementGetter {
Object get(Object[] block_, int index_);
}
@Override
public SettableIndexedIterator iterator() {
if (_subIndex != null) {
return _data.iteratorAcross(_subIndex);
}
return _data.iterator();
}
@Override
public SubSpaceSplitIterator iteratorAcross(int[] dimensions_)
{
if(dimensions_ == null || dimensions_.length == 0)
{
throw new IllegalArgumentException("Dimensions for iteration must be specified!");
}
if (_subIndex != null) {
return _data.iteratorAcross(
(Index.SubIndex) _subIndex, dimensions_);
}
return _data.iteratorAcross(dimensions_);
}
@Override
public List extends SettableIterator> parallelIterators(int[] dimensions_)
{
if (_subIndex != null) {
return _data.parallelIterators(_subIndex, dimensions_);
}
return _data.parallelIterators(dimensions_);
}
@Override
public SubSpaceSplitIterator iteratorAt(int... index_) {
return iteratorAtArray(index_);
}
public SubSpaceSplitIterator iteratorAtArray(int[] index_)
{
if (_subIndex != null)
{
return _data.iteratorAt(_subIndex,index_);
}
return _data.iteratorAt(index_);
}
/**
* Provides an iterator over the provided range of linear indexes
*
* @param from_ The linear index at which to start (inclusive)
* @param to_ The linear index to which to run (exclusive)
*
* @return An iterator over the requested range
*/
public SettableIndexedIterator rangeIterator(int from_, int to_){
if(_subIndex != null)
{
return _data.rangeIterator(_subIndex, from_, to_);
}
return _data.rangeIterator(from_, to_);
}
@Override
final public R transpose(int dimA_, int dimB_)
throws MultiDimensionalArrayException {
if (_subIndex != null) {
return createSub(_data,
(SubIndex) _subIndex.transpose(dimA_, dimB_));
}
return createSub(_data, (SubIndex) _index.transpose(dimA_, dimB_));
}
@Override
final public R arrangeDimensions(int[] order_) throws MultiDimensionalArrayException
{
if(_subIndex != null)
{
throw new MultiDimensionalArrayException("Can't arrange dimensions on a subarray");
}
// If not all the dimensions are specified then add the unspecified ones to the end, in their original order
if(order_.length < _index.numberOfDimensions())
{
int[] original = order_;
order_ = Arrays.copyOf(order_,_index.numberOfDimensions());
int nextEmptySpace = original.length;
int dim = 0;
while(dim < _index.numberOfDimensions() && nextEmptySpace < order_.length)
{
if(!ArrayUtils.contains(original, dim))
{
order_[nextEmptySpace++] = dim;
}
dim++;
}
}
return createSub(_data, (SubIndex) _index.reorder(order_));
}
}