All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.meliorbis.numerics.generic.impl.AbstractBlockedArray Maven / Gradle / Ivy

Go to download

A library for working with large multi-dimensional arrays and the functions they represent

There is a newer version: 1.2
Show newest version
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> 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_));
	}
	
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy