Java tutorial
/******************************************************************************************************* * * msi.gama.util.matrix.GamaObjectMatrix.java, in plugin msi.gama.core, * is part of the source code of the GAMA modeling and simulation platform (v. 1.8) * * (c) 2007-2018 UMI 209 UMMISCO IRD/SU & Partners * * Visit https://github.com/gama-platform/gama for license information and contacts. * ********************************************************************************************************/ package msi.gama.util.matrix; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.ArrayUtils; import com.google.common.collect.ImmutableList; import msi.gama.common.util.RandomUtils; import msi.gama.metamodel.shape.ILocation; import msi.gama.metamodel.topology.grid.GamaSpatialMatrix; import msi.gama.runtime.GAMA; import msi.gama.runtime.GAMA.InScope; import msi.gama.runtime.IScope; import msi.gama.runtime.exceptions.GamaRuntimeException; import msi.gama.util.GamaListFactory; import msi.gama.util.IContainer; import msi.gama.util.IList; import msi.gaml.operators.fastmaths.CmnFastMath; import msi.gaml.types.GamaMatrixType; import msi.gaml.types.GamaType; import msi.gaml.types.IType; import msi.gaml.types.Types; import one.util.streamex.StreamEx; public class GamaObjectMatrix extends GamaMatrix<Object> { static public GamaObjectMatrix from(final int c, final int r, final IMatrix<?> m) { if (m instanceof GamaFloatMatrix) { return new GamaObjectMatrix(c, r, ((GamaFloatMatrix) m).getMatrix()); } if (m instanceof GamaObjectMatrix) { return new GamaObjectMatrix(c, r, ((GamaObjectMatrix) m).getMatrix(), m.getGamlType().getContentType()); } if (m instanceof GamaIntMatrix) { return new GamaObjectMatrix(c, r, ((GamaIntMatrix) m).matrix); } if (m instanceof GamaSpatialMatrix) { return new GamaObjectMatrix(c, r, ((GamaSpatialMatrix) m).getMatrix(), m.getGamlType().getContentType()); } return null; } /** The matrix. */ private Object[] matrix; public GamaObjectMatrix(final ILocation p, final IType<?> contentsType) { this((int) p.getX(), (int) p.getY(), contentsType); } public GamaObjectMatrix(final int cols, final int rows, final IType<?> contentsType) { super(cols, rows, contentsType); setMatrix(new Object[cols * rows]); } public GamaObjectMatrix(final int cols, final int rows, final double[] objects) { this(cols, rows, Types.FLOAT); final int n = CmnFastMath.min(objects.length, rows * cols); for (int i = 0; i < n; i++) { matrix[i] = objects[i]; } // java.lang.System.arraycopy(objects, 0, getMatrix(), 0, // FastMath.min(objects.length, rows * cols)); } public GamaObjectMatrix(final int cols, final int rows, final int[] objects) { this(cols, rows, Types.INT); final int n = CmnFastMath.min(objects.length, rows * cols); for (int i = 0; i < n; i++) { matrix[i] = objects[i]; } } public GamaObjectMatrix(final int cols, final int rows, final Object[] objects, final IType<?> contentsType) { this(cols, rows, contentsType); java.lang.System.arraycopy(objects, 0, getMatrix(), 0, CmnFastMath.min(objects.length, rows * cols)); } public GamaObjectMatrix(final IScope scope, final IList<?> objects, final ILocation preferredSize, final IType<?> contentsType) { super(scope, objects, preferredSize, contentsType); setMatrix(new Object[numRows * numCols]); final boolean requiresCasting = GamaType.requiresCasting(contentsType, objects.getGamlType().getContentType()); if (preferredSize != null) { for (int i = 0, stop = CmnFastMath.min(getMatrix().length, objects.size()); i < stop; i++) { getMatrix()[i] = requiresCasting ? contentsType.cast(scope, objects.get(i), null, false) : objects.get(i); } } else if (isFlat(objects)) { for (int i = 0, stop = objects.size(); i < stop; i++) { getMatrix()[i] = contentsType.cast(scope, objects.get(i), null, false); } } else { for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { set(scope, j, i, ((List<?>) objects.get(j)).get(i)); } } } } // public GamaObjectMatrix(final IScope scope, final Object[] mat) { // super(1, mat.length); // setMatrix(mat); // } @Override public void _clear() { Arrays.fill(getMatrix(), null); } @Override public boolean _contains(final IScope scope, final Object o) { for (int i = 0; i < getMatrix().length; i++) { if (getMatrix()[i].equals(o)) { return true; } } return false; } @Override public Object _first(final IScope scope) { if (getMatrix().length == 0) { return null; } return getMatrix()[0]; } @Override public Object _last(final IScope scope) { if (getMatrix().length == 0) { return null; } return getMatrix()[getMatrix().length - 1]; } @Override public Integer _length(final IScope scope) { return getMatrix().length; } /** * Take two matrices (with the same number of columns) and create a big * matrix putting the second matrix on the right side of the first matrix * * @param two * matrix to concatenate * @return the matrix concatenated */ // @Override // @operator(value = IKeyword.APPEND_VERTICALLY, content_type = // ITypeProvider.CONTENT_TYPE_AT_INDEX + 1, category={IOperatorCategory.MATRIX}) public IMatrix<?> _opAppendVertically(final IScope scope, final IMatrix<?> b) { final GamaObjectMatrix a = this; final Object[] ma = a.getMatrix(); final Object[] mb = ((GamaObjectMatrix) b).getMatrix(); final Object[] mab = ArrayUtils.addAll(ma, mb); final IType<?> newContentsType = GamaType.findCommonType(getGamlType().getContentType(), b.getGamlType().getContentType()); final IMatrix<?> fl = new GamaObjectMatrix(a.getCols(scope), a.getRows(scope) + b.getRows(scope), mab, newContentsType); // throw GamaRuntimeException.error("ATTENTION : Matrix additions not // implemented. Returns nil for the moment"); return fl; } /** * Take two matrices (with the same number of rows) and create a big matrix * putting the second matrix on the right side of the first matrix * * @param two * matrix to concatenate * @return the matrix concatenated */ // @Override // @operator(value = IKeyword.APPEND_HORYZONTALLY, content_type = // ITypeProvider.CONTENT_TYPE_AT_INDEX + 1, category={IOperatorCategory.MATRIX}) public GamaObjectMatrix _opAppendHorizontally(final IScope scope, final IMatrix<?> b) { // GamaObjectMatrix a = this; final GamaObjectMatrix aprime = _reverse(scope); // DEBUG.LOG("aprime = " + aprime); final GamaObjectMatrix bprime = GamaObjectMatrix.from(b.getCols(scope), b.getRows(scope), b) ._reverse(scope); // DEBUG.LOG("bprime = " + bprime); final GamaObjectMatrix c = (GamaObjectMatrix) aprime.opAppendVertically(scope, bprime); // DEBUG.LOG("c = " + c); final GamaObjectMatrix cprime = c._reverse(scope); // DEBUG.LOG("cprime = " + cprime); return cprime; } // @Override // public Double _max(final IScope scope) { // Double max = -Double.MAX_VALUE; // for ( int i = 0; i < matrix.length; i++ ) { // Object o = matrix[i]; // if ( o instanceof Number && ((Number) o).doubleValue() > max ) { // max = Double.valueOf(((Number) o).doubleValue()); // } // } // return max; // } // // @Override // public Double _min(final IScope scope) { // Double min = Double.MAX_VALUE; // for ( int i = 0; i < matrix.length; i++ ) { // Object o = matrix[i]; // if ( o instanceof Number && ((Number) o).doubleValue() < min ) { // min = Double.valueOf(((Number) o).doubleValue()); // } // } // return min; // } // // @Override // public Double _product(final IScope scope) { // Double result = 1.0; // for ( int i = 0, n = matrix.length; i < n; i++ ) { // Object d = matrix[i]; // if ( d instanceof Number ) { // result *= ((Number) d).doubleValue(); // } // } // return result; // } // // @Override // public Double _sum(final IScope scope) { // Double result = 0.0; // for ( int i = 0, n = matrix.length; i < n; i++ ) { // Object d = matrix[i]; // if ( d instanceof Number ) { // result += ((Number) d).doubleValue(); // } // } // return result; // } // @Override public boolean _isEmpty(final IScope scope) { for (int i = 0; i < getMatrix().length; i++) { if (getMatrix()[i] != null) { return false; } } return true; } @Override protected IList<Object> _listValue(final IScope scope, final IType contentsType, final boolean cast) { return cast ? GamaListFactory.create(scope, contentsType, getMatrix()) : GamaListFactory.createWithoutCasting(contentsType, getMatrix()); } @Override protected IMatrix<Object> _matrixValue(final IScope scope, final ILocation preferredSize, final IType type, final boolean copy) { return GamaMatrixType.from(scope, this, type, preferredSize, copy); } @Override public GamaObjectMatrix _reverse(final IScope scope) throws GamaRuntimeException { final GamaObjectMatrix result = new GamaObjectMatrix(numRows, numCols, getGamlType().getContentType()); for (int i = 0; i < numCols; i++) { for (int j = 0; j < numRows; j++) { result.set(scope, j, i, get(scope, i, j)); } } return result; } @Override public GamaObjectMatrix copy(final IScope scope, final ILocation size, final boolean copy) { if (size == null) { if (copy) { return new GamaObjectMatrix(numCols, numRows, Arrays.copyOf(matrix, matrix.length), getGamlType().getContentType()); } else { return this; } } return new GamaObjectMatrix((int) size.getX(), (int) size.getX(), Arrays.copyOf(matrix, matrix.length), getGamlType().getContentType()); } @Override public boolean equals(final Object m) { if (this == m) { return true; } if (!(m instanceof GamaObjectMatrix)) { return false; } final GamaObjectMatrix mat = (GamaObjectMatrix) m; return Arrays.equals(this.getMatrix(), mat.getMatrix()); } @Override public int hashCode() { return super.hashCode(); } @Override public void _putAll(final IScope scope, final Object o) { fillWith(scope, getGamlType().getContentType().cast(scope, o, null, false)); } public void fillWith(final IScope scope, final Object o) { // We copy the element with which to fill the matrix if it is a // (possibly) complex value // WARNING TODO WHY ??? // if ( o instanceof IValue ) { // IValue v = (IValue) o; // for ( int i = 0; i < matrix.length; i++ ) { // matrix[i] = v.copy(scope); // } // } else { Arrays.fill(getMatrix(), o); // } } @Override public Object get(final IScope scope, final int col, final int row) { if (col >= numCols || col < 0 || row >= numRows || row < 0) { return null; } return getMatrix()[row * numCols + col]; } @Override public void set(final IScope scope, final int col, final int row, final Object obj) { if (col >= numCols || col < 0 || row >= numRows || row < 0) { return; } getMatrix()[row * numCols + col] = GamaType.toType(scope, obj, getGamlType().getContentType(), false); } @Override public Object remove(final IScope scope, final int col, final int row) { if (col >= numCols || col < 0 || row >= numRows || row < 0) { return null; } final Object o = getMatrix()[row * numCols + col]; getMatrix()[row * numCols + col] = null; return o; } @Override public boolean _removeFirst(final IScope scope, final Object o) { for (int i = 0; i < getMatrix().length; i++) { if (getMatrix()[i].equals(o)) { getMatrix()[i] = null; return true; } } return false; } @Override public boolean _removeAll(final IScope scope, final IContainer<?, Object> list) throws GamaRuntimeException { boolean removed = false; for (int i = 0; i < getMatrix().length; i++) { if (list.contains(scope, getMatrix()[i])) { // VERIFY NULL SCOPE getMatrix()[i] = null; removed = true; } } // TODO Make a test to verify the return return removed; } @Override public void shuffleWith(final RandomUtils randomAgent) { setMatrix(randomAgent.shuffle(getMatrix())); } @Override public String toString() { final StringBuilder sb = new StringBuilder(numRows * numCols * 5); sb.append('['); GAMA.run(new InScope.Void() { @Override public void process(final IScope scope) { for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { sb.append(get(scope, col, row)); if (col < numCols - 1) { sb.append(','); } } if (row < numRows - 1) { sb.append(';'); } } } }); sb.append(']'); return sb.toString(); } /** * Method iterator() * * @see msi.gama.util.matrix.GamaMatrix#iterator() */ @Override public java.lang.Iterable<Object> iterable(final IScope scope) { return ImmutableList.copyOf(getMatrix()); } public Object[] getMatrix() { return matrix; } protected void setMatrix(final Object[] matrix) { this.matrix = matrix; } /** * Method getNthElement() * * @see msi.gama.util.matrix.GamaMatrix#getNthElement(java.lang.Integer) */ @Override protected Object getNthElement(final Integer index) { if (index == null) { return null; } if (index > getMatrix().length) { return null; } return getMatrix()[index]; } @Override public StreamEx<Object> stream(final IScope scope) { return StreamEx.of(matrix); } }