From 68952f0ce0ce30180d5f6c5cf7a3c98c07d55e94 Mon Sep 17 00:00:00 2001 From: brinn <brinn> Date: Sat, 4 Feb 2012 13:55:28 +0000 Subject: [PATCH] Make MDAbstractArray an Iterable<ArrayEntry>. Add methods computeReverseIndex(), numberOfHyperRows(). Add methods getAsObject(int) and setToObject(T, int) (1D, i.e.linear index). Make computeIndex() methods public. SVN: 24341 --- .../cisd/base/mdarray/MDAbstractArray.java | 127 +++++++++++++++-- .../systemsx/cisd/base/mdarray/MDArray.java | 12 ++ .../cisd/base/mdarray/MDByteArray.java | 12 ++ .../cisd/base/mdarray/MDDoubleArray.java | 12 ++ .../cisd/base/mdarray/MDFloatArray.java | 12 ++ .../cisd/base/mdarray/MDIntArray.java | 12 ++ .../cisd/base/mdarray/MDLongArray.java | 12 ++ .../cisd/base/mdarray/MDShortArray.java | 12 ++ .../cisd/base/mdarray/MDArrayTests.java | 133 ++++++++---------- 9 files changed, 258 insertions(+), 86 deletions(-) diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java index 6986d7a4930..4c11abfe31b 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.base.mdarray; import java.io.Serializable; +import java.util.Iterator; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ClassUtils; @@ -30,9 +31,9 @@ import org.apache.commons.lang.ClassUtils; * * @author Bernd Rinn */ -public abstract class MDAbstractArray<T> implements Serializable +public abstract class MDAbstractArray<T> implements Serializable, + Iterable<MDAbstractArray<T>.ArrayEntry> { - private static final long serialVersionUID = 1L; protected final int[] dimensions; @@ -40,9 +41,46 @@ public abstract class MDAbstractArray<T> implements Serializable protected int hyperRowLength; protected int capacityHyperRows; - + protected int size; + /** + * A class to represent an entry (index and value) of a {@link MDArray}, used for iteration. + */ + public class ArrayEntry + { + private final int linearIndex; + + ArrayEntry(int linearIndex) + { + this.linearIndex = linearIndex; + } + + /** + * The multi-dimensional index of this entry. + */ + public int[] getIndex() + { + return computeReverseIndex(linearIndex); + } + + /** + * The linear index of this entry. + */ + public int getLinearIndex() + { + return linearIndex; + } + + /** + * The value of this entry. + */ + public T getValue() + { + return getAsObject(linearIndex); + } + } + protected MDAbstractArray(int[] dimensions, int arrayLength, int capacityHyperRows) { assert dimensions != null; @@ -61,8 +99,8 @@ public abstract class MDAbstractArray<T> implements Serializable + " does not match hyper-row length " + hyperRowLength + "."); } this.capacityHyperRows = - (capacityHyperRows > 0) ? capacityHyperRows : Math.max(dimensions[0], arrayLength - / hyperRowLength); + (capacityHyperRows > 0) ? capacityHyperRows : Math.max(dimensions[0], + arrayLength / hyperRowLength); this.size = dimensions[0] * hyperRowLength; } } @@ -124,6 +162,23 @@ public abstract class MDAbstractArray<T> implements Serializable { return size; } + + /** + * Returns the current number of hyper rows of of this array. + */ + public int numberOfHyperRows() + { + return numberOfHyperRows(); + } + + /** + * Return an object which has the same value as the element of the array specified by + * <var>linearIndex</var>. + * + * @param linearIndex The index in the linear array returned by {@link #getAsFlatArray()}. + * @return The value at the specified index. + */ + public abstract T getAsObject(int linearIndex); /** * Return an object which has the same value as the element of the array specified by @@ -137,6 +192,15 @@ public abstract class MDAbstractArray<T> implements Serializable */ public abstract void setToObject(T value, int... indices); + /** + * Sets the element of the array specified by <var>linearIndex</var> to the particular + * <var>value</var>. + * + * @param value The new value to set. + * @param linearIndex The index in the linear array returned by {@link #getAsFlatArray()}. + */ + public abstract void setToObject(T value, int linearIndex); + /** * Returns the array in flattened form. Changes to the returned object will change the * multi-dimensional array directly. @@ -188,7 +252,7 @@ public abstract class MDAbstractArray<T> implements Serializable /** * Computes the linear index for the multi-dimensional <var>indices</var> provided. */ - protected int computeIndex(int... indices) + public int computeIndex(int... indices) { assert indices != null; assert indices.length == dimensions.length; @@ -201,10 +265,27 @@ public abstract class MDAbstractArray<T> implements Serializable return index; } + /** + * Computes the multi-dimensional index from the <var>linearIndex</var>. + */ + public int[] computeReverseIndex(int linearIndex) + { + final int[] index = new int[dimensions.length]; + int workIndex = linearIndex; + int blockSize = size; + for (int i = 0; i < dimensions.length; ++i) + { + blockSize /= dimensions[i]; + index[i] = workIndex / blockSize; + workIndex = workIndex - index[i] * blockSize; + } + return index; + } + /** * Computes the linear index for the two-dimensional (<var>indexX, indexY</var>) provided. */ - protected int computeIndex(int indexX, int indexY) + public int computeIndex(int indexX, int indexY) { assert 2 == dimensions.length; @@ -215,7 +296,7 @@ public abstract class MDAbstractArray<T> implements Serializable * Computes the linear index for the three-dimensional (<var>indexX, indexY, indexZ</var>) * provided. */ - protected int computeIndex(int indexX, int indexY, int indexZ) + public int computeIndex(int indexX, int indexY, int indexZ) { assert 3 == dimensions.length; @@ -335,6 +416,36 @@ public abstract class MDAbstractArray<T> implements Serializable return intLength; } + // + // Iterable + // + + public Iterator<ArrayEntry> iterator() + { + return new Iterator<ArrayEntry>() + { + int linearIndex = 0; + + public boolean hasNext() + { + return linearIndex < size; + } + + public ArrayEntry next() + { + final ArrayEntry next = new ArrayEntry(linearIndex); + ++linearIndex; + return next; + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + + }; + } + // // Object // diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java index 861acd77b9d..1a4a2360b77 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java @@ -149,6 +149,18 @@ public class MDArray<T> extends MDAbstractArray<T> set(value, indices); } + @Override + public T getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(T value, int linearIndex) + { + set(value, linearIndex); + } + @Override public T[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java index b724d6fce00..4bb36ad7d58 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java @@ -179,6 +179,18 @@ public final class MDByteArray extends MDAbstractArray<Byte> set(value, indices); } + @Override + public Byte getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Byte value, int linearIndex) + { + set(value, linearIndex); + } + @Override public byte[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java index 40c60fef379..8a755f442ab 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java @@ -179,6 +179,18 @@ public final class MDDoubleArray extends MDAbstractArray<Double> set(value, indices); } + @Override + public Double getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Double value, int linearIndex) + { + set(value, linearIndex); + } + @Override public double[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java index 69e7e076d2f..4b10fb8da65 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java @@ -179,6 +179,18 @@ public final class MDFloatArray extends MDAbstractArray<Float> set(value, indices); } + @Override + public Float getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Float value, int linearIndex) + { + set(value, linearIndex); + } + @Override public float[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java index 7fea30fdd8b..76cbcd144e3 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java @@ -179,6 +179,18 @@ public final class MDIntArray extends MDAbstractArray<Integer> set(value, indices); } + @Override + public Integer getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Integer value, int linearIndex) + { + set(value, linearIndex); + } + @Override public int[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java index 085caffb57d..3b927b131fe 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java @@ -179,6 +179,18 @@ public final class MDLongArray extends MDAbstractArray<Long> set(value, indices); } + @Override + public Long getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Long value, int linearIndex) + { + set(value, linearIndex); + } + @Override public long[] getAsFlatArray() { diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java index 122213b07fb..eefb0b8459f 100644 --- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java +++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java @@ -179,6 +179,18 @@ public final class MDShortArray extends MDAbstractArray<Short> set(value, indices); } + @Override + public Short getAsObject(int linearIndex) + { + return get(linearIndex); + } + + @Override + public void setToObject(Short value, int linearIndex) + { + set(value, linearIndex); + } + @Override public short[] getAsFlatArray() { diff --git a/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java b/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java index a20b743dd87..38a91820966 100644 --- a/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java +++ b/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java @@ -34,57 +34,6 @@ import ch.systemsx.cisd.base.BuildAndEnvironmentInfo; */ public class MDArrayTests { - - static class TestMDArray extends MDAbstractArray<Void> - { - private static final long serialVersionUID = 1L; - - protected TestMDArray(int[] shape) - { - super(shape, 0, 0); - } - - @Override - public Void getAsObject(int... indices) - { - return null; - } - - @Override - public void setToObject(Void value, int... indices) - { - } - - @Override - public int size() - { - return 0; - } - - @Override - public int capacity() - { - return 0; - } - - @Override - public Object getAsFlatArray() - { - return null; - } - - @Override - public Object getCopyAsFlatArray() - { - return null; - } - - @Override - protected void adaptCapacityHyperRows() - { - } - } - @Test public void testGetLength() { @@ -93,21 +42,21 @@ public class MDArrayTests assertEquals(1, MDAbstractArray.getLength(new int[] { 1 }, 0)); assertEquals(2, MDAbstractArray.getLength(new int[] - { 1 }, 2)); + { 1 }, 2)); assertEquals(15, MDAbstractArray.getLength(new int[] { 5, 3 }, 0)); assertEquals(21, MDAbstractArray.getLength(new int[] - { 5, 3 }, 7)); + { 5, 3 }, 7)); assertEquals(15, MDAbstractArray.getLength(new int[] - { 5, 3 }, 3)); + { 5, 3 }, 3)); assertEquals(1, MDAbstractArray.getLength(new int[] { 1, 1, 1 }, 0)); assertEquals(3, MDAbstractArray.getLength(new int[] - { 1, 1, 1 }, 3)); + { 1, 1, 1 }, 3)); assertEquals(8, MDAbstractArray.getLength(new int[] { 2, 2, 2 }, 0)); assertEquals(20, MDAbstractArray.getLength(new int[] - { 2, 2, 2 }, 5)); + { 2, 2, 2 }, 5)); assertEquals(2, MDAbstractArray.getLength(new int[] { 1, 1, 2 }, 0)); assertEquals(2, MDAbstractArray.getLength(new int[] @@ -132,32 +81,40 @@ public class MDArrayTests @Test public void testComputeIndex() { - TestMDArray array; - array = new TestMDArray(new int[] + MDArray<Object> array; + array = new MDArray<Object>(Object.class, new int[] { 33 }); assertEquals(17, array.computeIndex(new int[] { 17 })); - array = new TestMDArray(new int[] + assertTrue(Arrays.toString(array.computeReverseIndex(17)), Arrays.equals(new int[] + { 17 }, array.computeReverseIndex(17))); + array = new MDArray<Object>(Object.class, new int[] { 100, 10 }); - assertEquals(10 * 42 + 17, array.computeIndex(new int[] - { 42, 17 })); - array = new TestMDArray(new int[] + assertEquals(10 * 42 + 8, array.computeIndex(new int[] + { 42, 8 })); + assertTrue(Arrays.toString(array.computeReverseIndex(10 * 42 + 8)), + Arrays.equals(new int[] + { 42, 8 }, array.computeReverseIndex(10 * 42 + 8))); + array = new MDArray<Object>(Object.class, new int[] { 2, 7, 3 }); - assertEquals(3 * 7 * 1 + 3 * 2 + 3, array.computeIndex(new int[] - { 1, 2, 3 })); + assertEquals(3 * 7 * 1 + 3 * 3 + 2, array.computeIndex(new int[] + { 1, 3, 2 })); + assertTrue(Arrays.toString(array.computeReverseIndex(3 * 7 * 1 + 3 * 3 + 2)), + Arrays.equals(new int[] + { 1, 3, 2 }, array.computeReverseIndex(3 * 7 * 1 + 3 * 3 + 2))); } @Test public void testComputeIndex2D() { - TestMDArray array; - array = new TestMDArray(new int[] + MDArray<Object> array; + array = new MDArray<Object>(Object.class, new int[] { 100, 10 }); assertEquals(array.computeIndex(new int[] { 5, 8, }), array.computeIndex(5, 8)); assertEquals(array.computeIndex(new int[] { 9, 1, }), array.computeIndex(9, 1)); - array = new TestMDArray(new int[] + array = new MDArray<Object>(Object.class, new int[] { 101, 11 }); assertEquals(array.computeIndex(new int[] { 5, 8, }), array.computeIndex(5, 8)); @@ -168,14 +125,14 @@ public class MDArrayTests @Test public void testComputeIndex3() { - TestMDArray array; - array = new TestMDArray(new int[] + MDArray<Object> array; + array = new MDArray<Object>(Object.class, new int[] { 100, 10, 17 }); assertEquals(array.computeIndex(new int[] { 5, 8, 16 }), array.computeIndex(5, 8, 16)); assertEquals(array.computeIndex(new int[] { 9, 1, 5 }), array.computeIndex(9, 1, 5)); - array = new TestMDArray(new int[] + array = new MDArray<Object>(Object.class, new int[] { 101, 11, 3 }); assertEquals(array.computeIndex(new int[] { 5, 8, 0 }), array.computeIndex(5, 8, 0)); @@ -190,11 +147,12 @@ public class MDArrayTests assertEquals(0, arr.dimensions()[0]); assertEquals(0, arr.dimensions()[1]); } - + @Test public void testChangeHyperRowCountIntArray() { - final MDIntArray arr = new MDIntArray(new int[] { 2, 2 }, 3); + final MDIntArray arr = new MDIntArray(new int[] + { 2, 2 }, 3); assertEquals(2, arr.dimensions[0]); assertEquals(2, arr.dimensions[1]); arr.set(1, 0, 0); @@ -204,7 +162,7 @@ public class MDArrayTests final MDIntArray arr2 = new MDIntArray(arr.getCopyAsFlatArray(), arr.dimensions()); assertTrue(arr2.equals(arr)); - + arr.incNumberOfHyperRows(1); assertEquals(3, arr.dimensions[0]); assertEquals(1, arr.get(0, 0)); @@ -234,11 +192,12 @@ public class MDArrayTests assertEquals(7, arr.get(3, 0)); assertEquals(8, arr.get(3, 1)); } - + @Test public void testChangeHyperRowCountIntArrayFromZero() { - final MDIntArray arr = new MDIntArray(new int[] { 0 }); + final MDIntArray arr = new MDIntArray(new int[] + { 0 }); assertEquals(0, arr.size(0)); arr.incNumberOfHyperRows(1); assertEquals(1, arr.size(0)); @@ -248,11 +207,12 @@ public class MDArrayTests arr.incNumberOfHyperRows(1); assertEquals(3, arr.size()); } - + @Test public void testChangeHyperRowCountTArray() { - final MDArray<Integer> arr = new MDArray<Integer>(Integer.class, new int[] { 2, 2 }, 3); + final MDArray<Integer> arr = new MDArray<Integer>(Integer.class, new int[] + { 2, 2 }, 3); assertEquals(2, arr.dimensions[0]); assertEquals(2, arr.dimensions[1]); arr.set(1, 0, 0); @@ -288,7 +248,24 @@ public class MDArrayTests assertEquals(7, (int) arr.get(3, 0)); assertEquals(8, (int) arr.get(3, 1)); } - + + @Test + public void testMDIntArrayIterator() + { + final int[] linArray = new int[120]; + for (int i = 0; i < linArray.length; ++i) + { + linArray[i] = i; + } + final MDIntArray array = new MDIntArray(linArray, new int[] + { 2, 3, 4, 5 }); + for (MDIntArray.ArrayEntry e : array) + { + assertEquals(e.getLinearIndex(), e.getValue().intValue()); + assertEquals(e.getLinearIndex(), array.computeIndex(e.getIndex())); + } + } + @Test public void testMDFloatArrayMatrix() { -- GitLab