From 9c386518a49b161c49a16ba86cdc44078346c93e Mon Sep 17 00:00:00 2001 From: brinn <brinn> Date: Mon, 15 Sep 2008 06:47:19 +0000 Subject: [PATCH] add: classes for numerical multi-dimensional arrays SVN: 8286 --- .../systemsx/cisd/common/array/MDArray.java | 199 ++++++++++++++++++ .../cisd/common/array/MDByteArray.java | 156 ++++++++++++++ .../cisd/common/array/MDDoubleArray.java | 156 ++++++++++++++ .../cisd/common/array/MDFloatArray.java | 156 ++++++++++++++ .../cisd/common/array/MDIntArray.java | 156 ++++++++++++++ .../cisd/common/array/MDLongArray.java | 156 ++++++++++++++ .../cisd/common/array/MDShortArray.java | 156 ++++++++++++++ .../cisd/common/array/MDArraytest.java | 92 ++++++++ 8 files changed, 1227 insertions(+) create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java create mode 100644 common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDArray.java new file mode 100644 index 00000000000..29eacad2110 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDArray.java @@ -0,0 +1,199 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +/** + * Base class of a multi-dimensional array. The <var>shape</var> of an array is provided separately + * to the data as a <code>int[]</code>. + * + * @author Bernd Rinn + */ +public abstract class MDArray<T> +{ + + protected final int[] shape; + + protected MDArray(int[] shape) + { + assert shape != null; + + this.shape = shape; + } + + /** + * Returns the rank of the array. + */ + public int rank() + { + return shape.length; + } + + /** + * Returns the extent of the array along its <var>dim</var>-th axis. + */ + public int size(int dim) + { + assert dim < shape.length; + + return shape[dim]; + } + + /** + * Returns a copy of the shape (dimensions) of the multi-dimensional array. + */ + public int[] shape() + { + return shape.clone(); + } + + /** + * Returns a copy of the shape (dimensions) of the multi-dimensional array as + * <code>long[]</code>. + */ + public long[] longShape() + { + final long[] shapeCopy = new long[shape.length]; + for (int i = 0; i < shapeCopy.length; ++i) + { + shapeCopy[i] = shape[i]; + } + return shapeCopy; + } + + /** + * Returns the number of elements in the array. + */ + public abstract int size(); + + /** + * Return an object which has the same value as the element of the array specified by + * <var>indices</var>. + */ + public abstract T getAsObject(int[] indices); + + /** + * Sets the element of the array specified by <var>indices</var> to the particular + * <var>value</var>. + */ + public abstract void setToObject(int[] indices, T value); + + /** + * Computes the linear index for the multi-dimensional <var>indices</var> provided. + */ + protected int computeIndex(int[] indices) + { + assert indices != null; + assert indices.length == shape.length; + + int index = indices[0]; + for (int i = 1; i < indices.length; ++i) + { + index = index * shape[i] + indices[i]; + } + return index; + } + + /** + * Converts the <var>shape</var> from <code>long[]</code> to <code>int[]</code>. + */ + public static int[] toInt(final long[] shape) + { + assert shape != null; + + final int[] result = new int[shape.length]; + for (int i = 0; i < result.length; ++i) + { + result[i] = (int) shape[i]; + if (result[i] != shape[i]) + { + throw new IllegalArgumentException("Dimension " + i + " is too large (" + shape[i] + + ")"); + } + } + return result; + } + + /** + * Converts the <var>shape</var> from <code>int[]</code> to <code>long[]</code>. + */ + public static long[] toLong(final int[] shape) + { + assert shape != null; + + final long[] result = new long[shape.length]; + for (int i = 0; i < result.length; ++i) + { + result[i] = shape[i]; + } + return result; + } + + /** + * Returns the one-dimensional length of the multi-dimensional array defined by + * <var>shape</var>. + * + * @throws IllegalArgumentException If <var>shape</var> overflow the <code>int</code> type. + */ + public static int getLength(final int[] shape) + { + assert shape != null; + + if (shape.length == 0) + { + return 0; + } + long length = shape[0]; + for (int i = 1; i < shape.length; ++i) + { + length *= shape[i]; + } + int intLength = (int) length; + if (length != intLength) + { + throw new IllegalArgumentException("Length is too large (" + length + ")"); + } + return intLength; + } + + /** + * Returns the one-dimensional length of the multi-dimensional array defined by + * <var>shape</var>. + * + * @throws IllegalArgumentException If <var>shape</var> overflow the <code>int</code> type. + */ + public static int getLength(final long[] shape) + { + assert shape != null; + + if (shape.length == 0) // NULL data space needs to be treated differently + { + return 0; + } + long length = shape[0]; + for (int i = 1; i < shape.length; ++i) + { + length *= shape[i]; + } + int intLength = (int) length; + if (length != intLength) + { + throw new IllegalArgumentException("Length is too large (" + length + ")"); + } + return intLength; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java new file mode 100644 index 00000000000..7971598145b --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>byte</code> array. + * + * @author Bernd Rinn + */ +public final class MDByteArray extends MDArray<Byte> +{ + private final byte[] flattenedArray; + + public MDByteArray(long[] dimensions) + { + this(new byte[getLength(dimensions)], dimensions, true); + } + + public MDByteArray(byte[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDByteArray(byte[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDByteArray(int[] dimensions) + { + this(new byte[getLength(dimensions)], dimensions, true); + } + + public MDByteArray(byte[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDByteArray(byte[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Byte getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Byte value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public byte[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public byte getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, byte value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDByteArray other = (MDByteArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java new file mode 100644 index 00000000000..9eb1f2ca52d --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>double</code> array. + * + * @author Bernd Rinn + */ +public final class MDDoubleArray extends MDArray<Double> +{ + private final double[] flattenedArray; + + public MDDoubleArray(long[] dimensions) + { + this(new double[getLength(dimensions)], dimensions, true); + } + + public MDDoubleArray(double[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDDoubleArray(double[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDDoubleArray(int[] dimensions) + { + this(new double[getLength(dimensions)], dimensions, true); + } + + public MDDoubleArray(double[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDDoubleArray(double[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Double getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Double value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public double[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public double getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, double value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDDoubleArray other = (MDDoubleArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java new file mode 100644 index 00000000000..b8c462e84c6 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>float</code> array. + * + * @author Bernd Rinn + */ +public final class MDFloatArray extends MDArray<Float> +{ + private final float[] flattenedArray; + + public MDFloatArray(long[] dimensions) + { + this(new float[getLength(dimensions)], dimensions, true); + } + + public MDFloatArray(float[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDFloatArray(float[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDFloatArray(int[] dimensions) + { + this(new float[getLength(dimensions)], dimensions, true); + } + + public MDFloatArray(float[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDFloatArray(float[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Float getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Float value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public float[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public float getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, float value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDFloatArray other = (MDFloatArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java new file mode 100644 index 00000000000..6b81423ee52 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>int</code> array. + * + * @author Bernd Rinn + */ +public final class MDIntArray extends MDArray<Integer> +{ + private final int[] flattenedArray; + + public MDIntArray(long[] dimensions) + { + this(new int[getLength(dimensions)], dimensions, true); + } + + public MDIntArray(int[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDIntArray(int[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDIntArray(int[] dimensions) + { + this(new int[getLength(dimensions)], dimensions, true); + } + + public MDIntArray(int[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDIntArray(int[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Integer getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Integer value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public int[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public int getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, int value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDIntArray other = (MDIntArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java new file mode 100644 index 00000000000..63252c9047a --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>long</code> array. + * + * @author Bernd Rinn + */ +public final class MDLongArray extends MDArray<Long> +{ + private final long[] flattenedArray; + + public MDLongArray(long[] dimensions) + { + this(new long[getLength(dimensions)], dimensions, true); + } + + public MDLongArray(long[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDLongArray(long[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDLongArray(int[] dimensions) + { + this(new long[getLength(dimensions)], dimensions, true); + } + + public MDLongArray(long[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDLongArray(long[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Long getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Long value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public long[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public long getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, long value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDLongArray other = (MDLongArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java new file mode 100644 index 00000000000..c3181947f41 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java @@ -0,0 +1,156 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +/** + * A multi-dimensional <code>short</code> array. + * + * @author Bernd Rinn + */ +public final class MDShortArray extends MDArray<Short> +{ + private final short[] flattenedArray; + + public MDShortArray(long[] dimensions) + { + this(new short[getLength(dimensions)], dimensions, true); + } + + public MDShortArray(short[] flattenedArray, long[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDShortArray(short[] flattenedArray, long[] dimensions, boolean checkDimensions) + { + this(flattenedArray, MDArray.toInt(dimensions), checkDimensions); + } + + public MDShortArray(int[] dimensions) + { + this(new short[getLength(dimensions)], dimensions, true); + } + + public MDShortArray(short[] flattenedArray, int[] dimensions) + { + this(flattenedArray, dimensions, true); + } + + public MDShortArray(short[] flattenedArray, int[] shape, boolean checkDimensions) + { + super(shape); + assert flattenedArray != null; + + if (checkDimensions) + { + final int expectedLength = getLength(shape); + if (flattenedArray.length != expectedLength) + { + throw new IllegalArgumentException("Actual array length " + flattenedArray.length + + " does not match expected length " + expectedLength + "."); + } + } + this.flattenedArray = flattenedArray; + } + + @Override + public int size() + { + return flattenedArray.length; + } + + @Override + public Short getAsObject(int[] indices) + { + return getValue(indices); + } + + @Override + public void setToObject(int[] indices, Short value) + { + setValue(indices, value); + } + + /** + * Returns the array in flattened form. Changes to the returned object will change the + * multi-dimensional array directly. + */ + public short[] getAsFlatArray() + { + return flattenedArray; + } + + /** + * Returns the value of array at the position defined by <var>indices</var>. + */ + public short getValue(int[] indices) + { + return flattenedArray[computeIndex(indices)]; + } + + /** + * Sets the <var>value</var> of array at the position defined by <var>indices</var>. + */ + public void setValue(int[] indices, short value) + { + flattenedArray[computeIndex(indices)] = value; + } + + // + // Object + // + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(flattenedArray); + result = prime * result + Arrays.hashCode(shape); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + MDShortArray other = (MDShortArray) obj; + if (Arrays.equals(flattenedArray, other.flattenedArray) == false) + { + return false; + } + if (Arrays.equals(shape, other.shape) == false) + { + return false; + } + return true; + } + +} diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java b/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java new file mode 100644 index 00000000000..bf4d685fec8 --- /dev/null +++ b/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.common.array; + +import java.util.Arrays; + +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.*; + +/** + * Test cases for {@link MDArray}. + * + * @author Bernd Rinn + */ +public class MDArraytest +{ + + static class TestMDArray extends MDArray<Void> + { + protected TestMDArray(int[] shape) + { + super(shape); + // TODO Auto-generated constructor stub + } + + @Override + public Void getAsObject(int[] indices) + { + return null; + } + + @Override + public void setToObject(int[] indices, Void value) + { + } + + @Override + public int size() + { + return 0; + } + } + + @Test + public void testGetLength() + { + assertEquals(0, MDArray.getLength(new int[] { 0 })); + assertEquals(1, MDArray.getLength(new int[] { 1 })); + assertEquals(15, MDArray.getLength(new int[] { 5, 3 })); + assertEquals(1, MDArray.getLength(new int[] { 1, 1, 1 })); + assertEquals(8, MDArray.getLength(new int[] { 2, 2, 2 })); + assertEquals(2, MDArray.getLength(new int[] { 1, 1, 2 })); + assertEquals(2, MDArray.getLength(new int[] { 1, 2, 1 })); + assertEquals(2, MDArray.getLength(new int[] { 2, 1, 1 })); + assertEquals(50, MDArray.getLength(new int[] { 10, 1, 5 })); + assertEquals(50, MDArray.getLength(new long[] { 10, 1, 5 })); + } + + @Test + public void testToInt() + { + assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, MDArray.toInt(new long[] { 1, 2, 3 }))); + assertTrue(Arrays.equals(new int[] { }, MDArray.toInt(new long[] { }))); + } + + @Test + public void testComputeIndex() + { + TestMDArray array; + array = new TestMDArray(new int[] { 33 }); + assertEquals(17, array.computeIndex(new int[] { 17 })); + array = new TestMDArray(new int[] { 100, 10 }); + assertEquals(10 * 42 + 17, array.computeIndex(new int[] { 42, 17 })); + array = new TestMDArray(new int[] { 2, 7, 3 }); + assertEquals(3 * 7 * 1 + 3 * 2 + 3, array.computeIndex(new int[] { 1, 2, 3 })); + } +} -- GitLab