From: Gary P. <gpa...@gm...> - 2009-08-13 06:46:13
|
The operations on a Matrix, result in a new Matrix instance. This class builds on this idea and provides an immutable matrix implementation that is an instance of Type, but is implemented using a double[][] for speed. Signed-off-by: Gary Pampara <gpa...@gm...> --- pom.xml | 6 + .../net/sourceforge/cilib/container/Matrix.java | 204 ----------- .../problem/dataset/MatrixDataSetBuilder.java | 18 +- .../mappingproblem/CurvilinearCompEvaluator.java | 6 +- .../mappingproblem/CurvilinearDistEvaluator.java | 6 +- .../problem/mappingproblem/KruskalEvaluator.java | 8 +- .../mappingproblem/LinearMappingProblem.java | 10 +- .../problem/mappingproblem/MappingEvaluator.java | 4 +- .../problem/mappingproblem/MappingProblem.java | 130 +------ .../cilib/type/types/container/Matrix.java | 376 ++++++++++++++++++++ .../java/net/sourceforge/cilib/util/Vectors.java | 13 +- .../sourceforge/cilib/container/MatrixTest.java | 197 ---------- .../cilib/type/types/container/MatrixTest.java | 249 +++++++++++++ 13 files changed, 692 insertions(+), 535 deletions(-) delete mode 100644 src/main/java/net/sourceforge/cilib/container/Matrix.java create mode 100644 src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java delete mode 100644 src/test/java/net/sourceforge/cilib/container/MatrixTest.java create mode 100644 src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java diff --git a/pom.xml b/pom.xml index 07fa70d..bf3b9f4 100644 --- a/pom.xml +++ b/pom.xml @@ -126,6 +126,11 @@ <artifactId>commons-math</artifactId> <version>1.1</version> </dependency> + <dependency> + <groupId>com.google.collections</groupId> + <artifactId>google-collections</artifactId> + <version>1.0-rc2</version> + </dependency> </dependencies> <build> <defaultGoal>package</defaultGoal> @@ -308,3 +313,4 @@ </plugins> </reporting> </project> + diff --git a/src/main/java/net/sourceforge/cilib/container/Matrix.java b/src/main/java/net/sourceforge/cilib/container/Matrix.java deleted file mode 100644 index 1119584..0000000 --- a/src/main/java/net/sourceforge/cilib/container/Matrix.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright (C) 2003 - 2009 - * Computational Intelligence Research Group (CIRG@UP) - * Department of Computer Science - * University of Pretoria - * South Africa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package net.sourceforge.cilib.container; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Vector; - -import net.sourceforge.cilib.util.Cloneable; - -/** - * Representation of a <code>Matrix</code>, with the rows and the columns represented - * as a 2D array. The 2D array has been implemented as a Object array as the needed - * data stored within the Matrix is variable. - * - * @author Gary Pampara - * @param <E> The parameterized type. - */ -@Deprecated -public class Matrix<E> implements Cloneable { - private static final long serialVersionUID = 4621194915276987567L; - - private ArrayList< ArrayList<E> > data; // This is the ArrayList of the 1st dimension - private int rows; - private int cols; - - /** - * Create a new <code>Matrix</code> object with dimensions: rows x columns. - * @param rows The number of rows the <code>Matrix</code> should contain. - * @param cols The number of columns the <code>Matrix</code> should contain. - */ - public Matrix(int rows, int cols) { - if (rows == 0 || cols == 0) { - throw new IllegalArgumentException("Cannot create a Matrix with row or column dimension < 1"); - } - - this.rows = rows; - this.cols = cols; - - data = new ArrayList< ArrayList<E> >(); - - for (int i = 0; i < rows; i++) { - ArrayList<E> tmp = new ArrayList<E>(); - - for (int j = 0; j < cols; j++) { - tmp.add(null); - } - - data.add(tmp); - } - } - - - /** - * Copy constructor. - * @param copy The instance to copy. - */ - public Matrix(Matrix<E> copy) { - rows = copy.rows; - cols = copy.cols; - - data = new ArrayList<ArrayList<E>>(); - - for (ArrayList<E> item : data) { - ArrayList<E> cloneList = new ArrayList<E>(); - - for (E j : item) - cloneList.add(j); - } - } - - - /** - * {@inheritDoc} - */ - public Matrix<E> getClone() { - return new Matrix<E>(this); - } - - /** - * Place an <code>Object</code> at a point (row, column) within the <code>Matrix</code>. - * @param row The row where the needed item is located - * @param col The column where the needed item is located - * @param object The <code>Object</code> to place the <code>Matrix</code> at prosition (row, column) - */ - public void set(int row, int col, E object) { - if ((row >= rows || col >= cols) && (row >= 0 || col >= 0)) - throw new IndexOutOfBoundsException("Cannot set item at out of bounds index"); - - ArrayList<E> tmp = data.get(row); - tmp.set(col, object); - } - - /** - * Return the current item within the grid, located at (row, column). - * @param row The row where the needed item is located - * @param col The column where the needed item is located - * @return The <code>Object</code> within the <code>Matrix</code> at position (row, column) - */ - public E get(int row, int col) { - if ((row >= rows || col >= cols) && (row >= 0 || col >= 0)) - throw new IndexOutOfBoundsException("Cannot acces element - index out of bounds"); - - return data.get(row).get(col); - } - - /** - * Get the number of columns in the <code>Matrix</code>. - * @return The number of columns in the <code>Matrix</code>. - */ - public int getColumnCount() { - return cols; - } - - /** - * Get the number of rows in the <code>Matrix</code>. - * @return The number of rows in the <code>Matrix</code>. - */ - public int getRowCount() { - return rows; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return super.hashCode(); - } - - /** - * Clear the current <code>Matrix</code> of it's internal state. - */ - public void clear() { - data = null; - data = new ArrayList< ArrayList<E> >(); - - for (int i = 0; i < rows; i++) { - ArrayList<E> tmp = new ArrayList<E>(); - - for (int j = 0; j < cols; j++) - tmp.add(null); - - data.add(tmp); - } - } - - /** - * Get a <code>Vector</code> representing the row within the <code>Matrix</code> at the given index. - * @param row The row index of the row to be returned, indexed from 0. - * @return A <code>Vector</code> representing the row within the <code>Matrix</code>. - */ - public Collection<E> getRow(int row) { - ArrayList<E> tmp = new ArrayList<E>(); - - for (int i = 0; i < cols; i++) { - tmp.add(this.get(row, i)); - } - - return tmp; - } - - /** - * Get a <code>Vector</code> representing the column within the <code>Matrix</code> at the given index. - * @param col The column index of the row to be returned, indexed from 0. - * @return A <code>Vector</code> representing the column within the <code>Matrix</code>. - */ - public Collection<E> getColumn(int col) { - Collection<E> tmp = new Vector<E>(); - - for (int i = 0; i < rows; i++) - tmp.add(this.get(i, col)); - - return tmp; - } - -} diff --git a/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java b/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java index 8b9b7f1..43d97ea 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java @@ -25,8 +25,9 @@ import java.io.EOFException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StreamTokenizer; - -import net.sourceforge.cilib.container.Matrix; +import java.util.ArrayList; +import java.util.List; +import net.sourceforge.cilib.type.types.container.Matrix; /** * TODO: This needs to implement the reading of a matrix as needed by MappingProblem. @@ -35,7 +36,7 @@ import net.sourceforge.cilib.container.Matrix; public class MatrixDataSetBuilder extends BinaryDataSetBuilder { private static final long serialVersionUID = 1141280214032774956L; - private Matrix<Double> matrix; + private Matrix matrix; private int numvectors = 0; private int m = -1; private int d = -1; @@ -57,6 +58,7 @@ public class MatrixDataSetBuilder extends BinaryDataSetBuilder { @Override public void initialise() { + Matrix.Builder matrixBuilder = null; try { InputStream is = this.getDataSet(0).getInputStream(); @@ -79,7 +81,7 @@ public class MatrixDataSetBuilder extends BinaryDataSetBuilder { if (m <= 0) throw new IllegalStateException("Need to have a positive number as the input dimensions"); - matrix = new Matrix<Double>(numvectors, m); + matrixBuilder = Matrix.builder().rows(numvectors).columns(m); if (tok.nextToken() != StreamTokenizer.TT_NUMBER) throw new IllegalStateException("Expected an integer number as the third token in the dataset"); @@ -93,6 +95,7 @@ public class MatrixDataSetBuilder extends BinaryDataSetBuilder { throw new IllegalStateException("Output dimension must be less than input dimension"); for (int i = 0; i < numvectors; i++) { + List<Double> rowVector = new ArrayList<Double>(); for (int j = 0; j < m; j++) { int tok_ret = tok.nextToken(); while (tok_ret != StreamTokenizer.TT_NUMBER) { @@ -106,20 +109,23 @@ public class MatrixDataSetBuilder extends BinaryDataSetBuilder { } } - matrix.set(i, j, tok.nval); + rowVector.add(tok.nval); } + matrixBuilder.addRow(rowVector); } } catch (Exception e) { throw new RuntimeException(e); } + + matrix = matrixBuilder.build(); } /** * Get the constructed {@see net.sourceforge.cilib.container.Matrix Matrix}. * @return The current {@code Matrix} instance. */ - public Matrix<Double> getMatrix() { + public Matrix getMatrix() { return this.matrix; } diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearCompEvaluator.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearCompEvaluator.java index dd414ef..c16d435 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearCompEvaluator.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearCompEvaluator.java @@ -21,9 +21,9 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MinimisationFitness; +import net.sourceforge.cilib.type.types.container.Matrix; /** @@ -42,14 +42,14 @@ public class CurvilinearCompEvaluator implements MappingEvaluator { * * @author jkroon */ - public Fitness evaluateMapping(Matrix<Double> dist) { + public Fitness evaluateMapping(Matrix dist) { int numvect = prob.getNumInputVectors(); double res = 0.0; for(int i = 0; i < numvect; i++) for(int j = i + 1; j < numvect; j++) { double inp = prob.getDistanceInputVect(i, j); - double tmp = inp - dist.get(i, j); + double tmp = inp - dist.valueAt(i, j); res += tmp * tmp * f(inp); } diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearDistEvaluator.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearDistEvaluator.java index 0a3bed9..e213059 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearDistEvaluator.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/CurvilinearDistEvaluator.java @@ -21,9 +21,9 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MinimisationFitness; +import net.sourceforge.cilib.type.types.container.Matrix; /** * Implements the Curvilinear Distance function for evaluating the @@ -41,14 +41,14 @@ public class CurvilinearDistEvaluator implements MappingEvaluator { * * @author jkroon */ - public Fitness evaluateMapping(Matrix<Double> d) { + public Fitness evaluateMapping(Matrix d) { int numvect = prob.getNumInputVectors(); double res = 0.0; for(int i = 0; i < numvect; i++) for(int j = i + 1; j < numvect; j++) { double inp = dist.getDistance(i, j); - double tmp = inp - d.get(i, j); + double tmp = inp - d.valueAt(i, j); res += tmp * tmp * f(inp); } diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/KruskalEvaluator.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/KruskalEvaluator.java index df5daec..676d053 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/KruskalEvaluator.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/KruskalEvaluator.java @@ -21,9 +21,9 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.MinimisationFitness; +import net.sourceforge.cilib.type.types.container.Matrix; /** * Implements the Kruskal stress function for evaluating the fitness of the MappingProblem. @@ -40,7 +40,7 @@ public class KruskalEvaluator implements MappingEvaluator { * * @author jkroon */ - public Fitness evaluateMapping(Matrix<Double> dist) { + public Fitness evaluateMapping(Matrix dist) { double above = 0.0; double below = 0.0; @@ -49,11 +49,11 @@ public class KruskalEvaluator implements MappingEvaluator { for(int i = 0; i < numvect; i++) { for(int j = i + 1; j < numvect; j++) { double inp_dist = prob.getDistanceInputVect(i, j); - double tmp = inp_dist - dist.get(i, j); + double tmp = inp_dist - dist.valueAt(i, j); above += tmp * tmp; // below += inp_dist * inp_dist; - below += dist.get(i, j) * dist.get(i, j); + below += dist.valueAt(i, j) * dist.valueAt(i, j); } } diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/LinearMappingProblem.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/LinearMappingProblem.java index 34b33bf..7ed790e 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/LinearMappingProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/LinearMappingProblem.java @@ -21,8 +21,8 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.type.DomainRegistry; +import net.sourceforge.cilib.type.types.container.Matrix; import net.sourceforge.cilib.type.types.container.Vector; /** @@ -75,7 +75,7 @@ public class LinearMappingProblem extends MappingProblem { * * @author jkroon */ - protected final void performMapping(Matrix<Double> input, Vector matrix, Matrix<Double> output) { + protected final void performMapping(Matrix input, Vector matrix, Matrix output) { int outputDimension = getOutputDim(); // D int inputDimension = getInputDim(); // M int numberOfVectors = getNumInputVectors(); // N @@ -83,11 +83,11 @@ public class LinearMappingProblem extends MappingProblem { for(int v = 0; v < numberOfVectors; v++) { int base = 0; for(int d = 0; d < outputDimension; d++) { - output.set(v, d, 0.0); +// output.set(v, d, 0.0); for(int m = 0; m < inputDimension; m++) { - double value = matrix.getReal(base+m) * input.get(v, m); + double value = matrix.getReal(base+m) * input.valueAt(v, m); //output[v][d] += matrix[base + m] * input[v][m]; - output.set(v, d, value); +// output.set(v, d, value); } base += inputDimension; } diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingEvaluator.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingEvaluator.java index c777793..3d4dae4 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingEvaluator.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingEvaluator.java @@ -21,8 +21,8 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.problem.Fitness; +import net.sourceforge.cilib.type.types.container.Matrix; /** * Class that actually evaluates a given Mapping. This is to allow using @@ -40,7 +40,7 @@ public interface MappingEvaluator { * * @author jkroon */ - public Fitness evaluateMapping(Matrix<Double> dist); + public Fitness evaluateMapping(Matrix dist); /** * Gets called when attached to a MappingProblem. This is to allow diff --git a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java index b868357..71a6f73 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java @@ -21,12 +21,12 @@ */ package net.sourceforge.cilib.problem.mappingproblem; -import net.sourceforge.cilib.container.Matrix; import net.sourceforge.cilib.problem.Fitness; import net.sourceforge.cilib.problem.OptimisationProblemAdapter; import net.sourceforge.cilib.problem.dataset.DataSetBuilder; import net.sourceforge.cilib.problem.dataset.MatrixDataSetBuilder; import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.type.types.container.Matrix; import net.sourceforge.cilib.type.types.container.Vector; import net.sourceforge.cilib.util.DistanceMeasure; import net.sourceforge.cilib.util.EuclideanDistanceMeasure; @@ -47,8 +47,8 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { private int outputDimension = -1; private int inputDimension = -1; private int numvectors = -1; - private Matrix<Double> inputs = null; - private Matrix<Double> inpDistMatrix = null; + private Matrix inputs = null; + private Matrix inpDistMatrix = null; private MappingEvaluator evaluator = null; private DistanceMeasure distanceMeasure = null; @@ -76,19 +76,23 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { protected final Fitness calculateFitness(Type solution) { Vector matrix = (Vector) solution; - Matrix<Double> distmatrix = new Matrix<Double>(numvectors, numvectors); - Matrix<Double> outputs = new Matrix<Double>(numvectors, outputDimension); + Matrix distmatrix = null; +// new Matrix<Double>(numvectors, numvectors); + Matrix outputs = null; +// new Matrix<Double>(numvectors, outputDimension); performMapping(inputs, matrix, outputs); matrix = null; + Matrix.Builder builder = Matrix.builder(); + for(int a = 0; a < numvectors; a++) { - distmatrix.set(a, a, 0.0); +// distmatrix.set(a, a, 0.0); for(int b = 0; b < a; b++) { double distance = this.distanceMeasure.distance(outputs.getRow(a), outputs.getRow(b)); - distmatrix.set(a, b, distance); - distmatrix.set(b, a, distance); +// distmatrix.set(a, b, distance); +// distmatrix.set(b, a, distance); } } @@ -112,7 +116,7 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { * * @author jkroon */ - protected abstract void performMapping(Matrix<Double> inputs, Vector distmatrix, Matrix<Double> outputs); + protected abstract void performMapping(Matrix inputs, Vector distmatrix, Matrix outputs); /** @@ -127,32 +131,6 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { /** - * Returns the DomainComponent representing this mapping. The actual - * ^ depends on the mapping scheme, so your mapping scheme will need - * to override getMatrixSize(). - * - * (-1000,1000) might not be sufficient. Atm there is no way to - * alter this other than changing it here. - * - * @return An instance of DomainComponent as explained above. - * - * @author jkroon - */ - /*public final DomainComponent getDomain() { - if(domain == null) - domain = ComponentFactory.instance().newComponent("R(-1000,1000)^" + getMatrixSize()); - - return domain; - }*/ - /*public final Domain getDomain() { - if (domain == null) { - domain = Domain.getInstance(); - } - return domain; - }*/ - - - /** * Gets the value of M, the input dimension. * * @return The current value of M. @@ -214,90 +192,22 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { public void setDataSetBuilder(DataSetBuilder dataSetBuilder) { super.setDataSetBuilder(dataSetBuilder); - MatrixDataSetBuilder matrixBuilder = (MatrixDataSetBuilder) dataSetBuilder; - inputs = matrixBuilder.getMatrix(); + MatrixDataSetBuilder matrixDataSetBuilder = (MatrixDataSetBuilder) dataSetBuilder; + inputs = matrixDataSetBuilder.getMatrix(); - inpDistMatrix = new Matrix<Double>(numvectors, numvectors); + Matrix.Builder matrixBuilder = Matrix.builder().rows(numvectors).columns(numvectors); for(int i = 0; i < numvectors; i++) { - inpDistMatrix.set(i, i, 0.0); for(int j = 0; j < i; j++) { double distance = this.distanceMeasure.distance(inputs.getRow(i), inputs.getRow(j)); - this.inpDistMatrix.set(i, j, distance); - this.inpDistMatrix.set(j, i, distance); + matrixBuilder.valueAt(i, j, distance); + matrixBuilder.valueAt(j, i, distance); } } + inpDistMatrix = matrixBuilder.build(); } - /*this.dataSetBuilder = dataSetBuilder; - - try { - InputStream is = this.dataSetBuilder.getDataSet(0).getInputStream(); - - StreamTokenizer tok = new StreamTokenizer(new InputStreamReader(is)); - - if(tok.nextToken() != StreamTokenizer.TT_NUMBER) - throw new IllegalStateException("Expected an integer number as the first token in the dataset"); - - numvectors = (int)tok.nval; - - if(numvectors <= 0) - throw new IllegalStateException("Must have a positive number of vectors in input file"); - - if(tok.nextToken() != StreamTokenizer.TT_NUMBER) - throw new IllegalStateException("Expected an integer number as the second token in the dataset"); - - M = (int)tok.nval; - - if(M <= 0) - throw new IllegalStateException("Need to have a positive number as the input dimensions"); - - inputs = new double[numvectors][M]; - - if(tok.nextToken() != StreamTokenizer.TT_NUMBER) - throw new IllegalStateException("Expected an integer number as the third token in the dataset"); - - D = (int)tok.nval; - - if(D <= 0) - throw new IllegalStateException("Need to have a positive number as the input dimensions"); - - if(!(D <= M)) - throw new IllegalStateException("Output dimension must be less than input dimension"); - - for(int i = 0; i < numvectors; i++) { - for(int m = 0; m < M; m++) { - int tok_ret = tok.nextToken(); - while(tok_ret != StreamTokenizer.TT_NUMBER) - { - switch(tok_ret) { - case StreamTokenizer.TT_EOF: - throw new EOFException(); - case StreamTokenizer.TT_WORD: - throw new IllegalStateException("Only numerical input expected (line " + tok.lineno() + ")"); - } - } - - inputs[i][m] = tok.nval; - - } - } - } - catch(Exception e) - { - throw new RuntimeException(e); - } - - inp_distmatrix = new double[numvectors][numvectors]; - for(int i = 0; i < numvectors; i++) { - inp_distmatrix[i][i] = 0.0; - for(int j = 0; j < i; j++) - inp_distmatrix[i][j] = inp_distmatrix[j][i] = - calcDistance(inputs[i], inputs[j]); - } - }*/ - /** * Retrieve the distance between the two given input vectors. * @@ -309,7 +219,7 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { * @author jkroon */ public final double getDistanceInputVect(int i1, int i2) { - return inpDistMatrix.get(i2, i1); + return inpDistMatrix.valueAt(i2, i1); } diff --git a/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java b/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java new file mode 100644 index 0000000..f42abb6 --- /dev/null +++ b/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java @@ -0,0 +1,376 @@ +/** + * Copyright (C) 2003 - 2009 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package net.sourceforge.cilib.type.types.container; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import net.sourceforge.cilib.type.types.Type; +import net.sourceforge.cilib.util.Vectors; + +/** + * Representation of a Matrix. This class is immutable with the intention that + * all opertions on a Matrix will result in a new resulting Matrix. + */ +public final class Matrix implements Type { + private static final long serialVersionUID = 7726056815026772629L; + + private final double[][] contents; + + private Matrix(int x, int y) { + Preconditions.checkArgument(x > 0, "Zero row length does not make sense."); + Preconditions.checkArgument(y > 0, "Zero column length does not make sense."); + + this.contents = new double[x][y]; + } + + /** + * Determine if the {@code Matrix} is square. In other words, if the number + * of rows and columns are the same. + * @return {@code true} if the matrix is square, {@code false} otherwise. + */ + public boolean isSquare() { + Preconditions.checkState(this.contents.length >= 1); + return (contents.length == contents[0].length) ? true : false; + } + + /** + * Obtain the current value within the matrix at the provided co-ordinates. + * @param row The row to lookup, indexed from 0. + * @param col The column to lookup, indexed from 0. + * @return The value located at the position {@code [row][col]}. + */ + public double valueAt(int row, int col) { + return this.contents[row][col]; + } + + /** + * Obtain the row vector for the given row, indexed from 0. + * @param row The row number to obtain. + * @return A {@code Vector} representing the row. + */ + public Vector getRow(int row) { + List<Double> rowList = new ArrayList<Double>(this.contents[row].length); + + for (double d : this.contents[row]) + rowList.add(d); + + return Vectors.create(rowList); + } + + /** + * Get the number of rows within the matrix. + * @return The number of rows. + */ + public int getRows() { + return this.contents.length; + } + + /** + * Get the number of columns within the matrix. + * @return The number of columns. + */ + public int getColumns() { + return this.contents[0].length; + } + + /** + * Apply the addition operation on the current matrix and the provided + * matrix. The result is a new matrix. + * @param b The matrix to add. + * @return A new {@code Matrix} representing the result of the addition. + */ + public final Matrix plus(final Matrix b) { + Preconditions.checkArgument((this.getRows() == b.getRows()) && (this.getColumns() == b.getColumns()), + "Illegal matrix dimensions for matrix addition."); + + Matrix result = new Matrix(this.getRows(), this.getColumns()); + for (int i = 0; i < getRows(); i++) { + for (int j = 0; j < getColumns(); j++) { + result.contents[i][j] = this.contents[i][j] + b.contents[i][j]; + } + } + return result; + } + + /** + * Apply the subtration operation on the current matrix and the provided + * matrix. The result is a new matrix. + * @param b The matrix to subtract. + * @return A new {@code Matrix} representing the result of the subtraction. + */ + public final Matrix minus(final Matrix b) { + Preconditions.checkArgument((this.getRows() == b.getRows()) && (this.getColumns() == b.getColumns()), + "Illegal matrix dimensions for matrix subtraction."); + + Matrix result = new Matrix(this.getRows(), this.getColumns()); + for (int i = 0; i < getRows(); i++) { + for (int j = 0; j < getColumns(); j++) { + result.contents[i][j] = this.contents[i][j] - b.contents[i][j]; + } + } + return result; + } + + /** + * Perform multiplication on the current {@code Matrix} and the provided {@code Matrix}. + * Naturally, matrix multiplication can only be performed on matricies that adhere + * to the required matrix multiplication rules. + * <p> + * The result of this operation is a new immutable matrix. + * @param b The {@code Matrix} to to multiply the current {@code Matrix} with. + * @return A new {@code Matrix} representing the result of the multiplication. + */ + public Matrix times(Matrix b) { + Preconditions.checkArgument(this.getRows() == b.getColumns(), "Illegal matrix dimensions for matrix multiplication."); + + Matrix result = new Matrix(this.getRows(), b.getColumns()); + for (int i = 0; i < result.getColumns(); i++) { + for (int j = 0; j < result.getRows(); j++) { + for (int k = 0; k < this.getRows(); k++) + result.contents[i][j] += this.contents[i][k] * b.contents[k][j]; + } + } + return result; + } + + /** + * Obtain the transposition of the current {@code Matrix} instance. + * @return A new {@code Matrix} that is the transpose of the current {@code Matrix}. + */ + public Matrix transpose() { + Matrix result = new Matrix(this.getColumns(), this.getRows()); + for (int i = 0; i < this.getRows(); i++) + for (int j = 0; j < this.getColumns(); j++) + result.contents[j][i] = this.contents[i][j]; + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public Type getClone() { + throw new UnsupportedOperationException("Cloning a Matrix is not possible."); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + final Matrix other = (Matrix) obj; + return Arrays.deepEquals(this.contents, other.contents); + } + + @Override + public int hashCode() { + int hash = 0; + + for (double[] array : this.contents) + hash += Arrays.hashCode(array); + + return hash; + } + + /** + * Obtain a builder for {@code Matrix} instances. + * @return A {@link Matrix.Builder} instance. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * A builder object to help with the construction of {@link Matrix} instances. + */ + public static final class Builder { + private int rowNumber; + private int colNumber; + private List<List<Double>> rows; + private List<DataPoint> tuples; + private boolean identity; + + private Builder() { + reset(); + } + + /** + * Define the number of rows that the built up {@code Matrix} will contain. + * @param rows The required number of rows. + * @return The current {@code Builder}. + */ + public Builder rows(int rows) { + this.rowNumber = rows; + return this; + } + + /** + * Define the number of coloumns that the built up {@code Matrix} will contain. + * @param colummns The required number of columns. + * @return The current {@code Builder}. + */ + public Builder columns(int colummns) { + this.colNumber = colummns; + return this; + } + + /** + * Add a row vector, for inclusion in the built up {@code Matrix}. + * @param columnValues The values for the columns. + * @return the current {@code Builder}. + * @throws IllegalArgumentException if the {@code columnValues} are not the same + * dimensions / length that is expected. + */ + public Builder addRow(Double... columnValues) { + Preconditions.checkArgument(columnValues.length == this.colNumber, + "Cannot add a row with a differing column length. Expected: " + this.colNumber + ", got: " + columnValues.length); + + List<Double> rowVector = Arrays.asList(columnValues); + this.rows.add(rowVector); + return this; + } + + /** + * Add a row vector, for inclusion in the built up {@code Matrix}. + * @param iterable The values for the columns. + * @return the current {@code Builder}. + * @throws IllegalArgumentException if the {@code columnValues} are not the same + * dimensions / length that is expected. + */ + public Builder addRow(Iterable<Double> iterable) { + List<Double> list = new ArrayList<Double>(); + Iterables.addAll(list, iterable); + this.rows.add(list); + return this; + } + + /** + * Define that the built up {@code Matrix} should be an identity {@code Matrix}. + * All added row vectors or position values will be discarded if the built up {@code Matrix} + * is to be an identity {@code Matrix}. + * @return The current {@code Builder}. + */ + public Builder identity() { + Preconditions.checkState(this.rowNumber == this.colNumber, "Identity on non-sqaure matrix is not allowed."); + this.identity = true; + return this; + } + + /** + * Define that at a specific value for a defined grid point within the built + * up {@code Matrix}. + * <p> + * This operation will override any values specified by a row vector addition. + * @param row The row number, indexed from 0. + * @param col The column number, indexed from 0. + * @param value The value to be set at the defined location. + * @return The curret {@code Builder}. + */ + public Builder valueAt(int row, int col, double value) { + this.tuples.add(new DataPoint(row, col, value)); + return this; + } + + /** + * Reset the builder into a clean state. + */ + private void reset() { + this.rowNumber = 0; + this.colNumber = 0; + this.rows = new ArrayList<List<Double>>(); + this.tuples = new ArrayList<DataPoint>(); + this.identity = false; + } + + /** + * Build the {@code Matrix} instance, based on the currently defined builder. + * @return A new immutable {@code Matrix} instance. + */ + public Matrix build() { + Matrix matrix = new Matrix(rowNumber, colNumber); + + if (identity) { + for (int i = 0; i < rowNumber; i++) { + for (int j = 0; j < colNumber; j++) { + matrix.contents[i][j] = (i == j) ? 1.0 : 0.0; + } + } + + return matrix; + } + + if (this.rows.size() >= 1) { + for (int i = 0; i < rowNumber; i++) { + for (int j = 0; j < colNumber; j++) { + matrix.contents[i][j] = this.rows.get(i).get(j); + } + } + } + + if (this.tuples.size() >= 0) { + for (DataPoint tuple : this.tuples) { + matrix.contents[tuple.getX()][tuple.getY()] = tuple.getValue(); + } + } + + reset(); // Reset the builder to the default state, so that it may be used again, if needed. + + return matrix; + } + } + + /** + * Class defining a [row, col, value] tuple for building up of a {@code Matrix}. + */ + private static final class DataPoint { + private int x; + private int y; + private double value; + + public DataPoint(int x, int y, double value) { + this.x = x; + this.y = y; + this.value = value; + } + + public double getValue() { + return value; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + } +} diff --git a/src/main/java/net/sourceforge/cilib/util/Vectors.java b/src/main/java/net/sourceforge/cilib/util/Vectors.java index 35679e8..36a7dab 100644 --- a/src/main/java/net/sourceforge/cilib/util/Vectors.java +++ b/src/main/java/net/sourceforge/cilib/util/Vectors.java @@ -21,6 +21,7 @@ */ package net.sourceforge.cilib.util; +import java.util.Arrays; import net.sourceforge.cilib.type.types.Numeric; import net.sourceforge.cilib.type.types.Real; import net.sourceforge.cilib.type.types.Type; @@ -83,9 +84,19 @@ public final class Vectors { * @return The created {@linkplain Vector} object, containing the provided list of items. */ public static <T extends Number> Vector create(T... result) { + return create(Arrays.asList(result)); + } + + /** + * Create a {@code Vector} from the provided {@code Iterable}. + * @param <T> The number type. + * @param iterable The iterable of data elements. + * @return A {@code Vector} of the provided objects. + */ + public static <T extends Number> Vector create(Iterable<T> iterable) { Vector vector = new Vector(); - for (T element : result) + for (T element : iterable) vector.add(new Real(element.doubleValue())); return vector; diff --git a/src/test/java/net/sourceforge/cilib/container/MatrixTest.java b/src/test/java/net/sourceforge/cilib/container/MatrixTest.java deleted file mode 100644 index d4cba40..0000000 --- a/src/test/java/net/sourceforge/cilib/container/MatrixTest.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Copyright (C) 2003 - 2009 - * Computational Intelligence Research Group (CIRG@UP) - * Department of Computer Science - * University of Pretoria - * South Africa - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package net.sourceforge.cilib.container; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.fail; - -import java.util.Collection; -import java.util.Iterator; - -import org.junit.Test; - - - -/** - * This Unit test tests all the needed operations of the Matrix class. - * - * @author Gary Pampara - */ -public class MatrixTest { - - @Test - public void testMatrixCreation() { - Matrix<Double> m = new Matrix<Double>(3, 3); - assertEquals(3, m.getColumnCount()); - assertEquals(3, m.getRowCount()); - } - - @Test(expected = IllegalArgumentException.class) - public void testMatrixExceptionCreation() { - new Matrix<Double>(0, 0); - } - - @Test - public void testDataMatrixInputOutputOperation() { - Matrix<Integer> m = new Matrix<Integer>(10, 5); - - for (int i = 0; i < m.getRowCount(); i++) { - for (int j = 0; j < m.getColumnCount(); j++) { - int tmp = i*j; - m.set(i, j, tmp); - assertSame(tmp, m.get(i, j)); - assertEquals(tmp, m.get(i, j).intValue()); - } - } - } - - @Test - public void testNullGet() { - Matrix<Integer> m = new Matrix<Integer>(5, 5); - - for (int i = 0; i < m.getRowCount(); i++) { - for (int j = 0; j < m.getColumnCount(); j++) { - assertEquals(null, m.get(i, j)); - } - } - } - - @Test - public void testOutOfBoundsSetOperation() { - Matrix<Double> m = new Matrix<Double>(2, 2); - try { - m.set(-1, 1, null); - } - catch (IndexOutOfBoundsException i1) { - try { - m.set(1, -1, null); - } - catch (IndexOutOfBoundsException i2) { - try { - m.set(0, 2, null); - } - catch (IndexOutOfBoundsException i3) { - try { - m.set(2, 0, null); - } - catch (IndexOutOfBoundsException i4) { - return; - } - } - } - } - fail("Boundary cases fail on the Matrix set operation"); - } - - @Test - public void testOutOfBoundsGetOperation() { - Matrix<Double> m = new Matrix<Double>(2, 2); - // Get operation - try { - m.get(-1, 1); - } - catch (IndexOutOfBoundsException i) { - try { - m.get(1, -1); - } - catch (IndexOutOfBoundsException i2) { - try { - m.get(0, 2); - } - catch (IndexOutOfBoundsException i3) { - try { - m.get(2, 0); - } - catch (IndexOutOfBoundsException i4) { - return; - } - } - } - } - fail("Boundary cases fail on the Matrix get operation"); - } - - @Test - public void testClearOperation() { - Matrix<Double> m = new Matrix<Double>(2, 2); - - m.set(0, 0, new Double(5.0)); - m.set(0, 1, new Double(4.0)); - m.set(1, 0, new Double(3.0)); - m.set(1, 1, new Double(2.0)); - - m.clear(); - - assertEquals(null, m.get(0, 0)); - assertEquals(null, m.get(0, 1)); - assertEquals(null, m.get(1, 0)); - assertEquals(null, m.get(1, 1)); - } - - @Test - public void testGetRow() { - Matrix<Double> m = new Matrix<Double>(2, 2); - - m.set(0, 0, new Double(5.0)); - m.set(0, 1, new Double(4.0)); - m.set(1, 0, new Double(3.0)); - m.set(1, 1, new Double(2.0)); - - Collection<Double> c1 = m.getRow(0); - Collection<Double> c2 = m.getRow(1); - - Iterator<Double> i1 = c1.iterator(); - Iterator<Double> i2 = c2.iterator(); - - for (int i = 0; i < m.getColumnCount(); i++) { - if (i1.hasNext()) assertEquals(m.get(0, i), i1.next()); - else fail(); - - if (i2.hasNext()) assertEquals(m.get(1, i), i2.next()); - else fail(); - } - } - - @Test - public void testGetColumn() { - Matrix<Double> m = new Matrix<Double>(2, 2); - - m.set(0, 0, new Double(5.0)); - m.set(0, 1, new Double(4.0)); - m.set(1, 0, new Double(3.0)); - m.set(1, 1, new Double(2.0)); - - Collection<Double> c1 = m.getColumn(0); - Collection<Double> c2 = m.getColumn(1); - - Iterator<Double> i1 = c1.iterator(); - Iterator<Double> i2 = c2.iterator(); - - for (int i = 0; i < m.getColumnCount(); i++) { - if (i1.hasNext()) assertEquals(m.get(i, 0), i1.next()); - else fail(); - if (i2.hasNext()) assertEquals(m.get(i, 1), i2.next()); - else fail(); - } - } -} diff --git a/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java b/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java new file mode 100644 index 0000000..6144707 --- /dev/null +++ b/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java @@ -0,0 +1,249 @@ +/** + * Copyright (C) 2003 - 2009 + * Computational Intelligence Research Group (CIRG@UP) + * Department of Computer Science + * University of Pretoria + * South Africa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package net.sourceforge.cilib.type.types.container; + +import net.sourceforge.cilib.util.Vectors; +import org.junit.Assert; +import org.junit.Test; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.equalTo; + +/** + * + */ +public class MatrixTest { + + @Test(expected=IllegalArgumentException.class) + public void constructionZeroRow() { + Matrix.builder().rows(0).build(); + } + + @Test(expected=IllegalArgumentException.class) + public void constructionZeroColumn() { + Matrix.builder().columns(0).build(); + } + + @Test + public void square() { + Matrix a = Matrix.builder().rows(2).columns(2).build(); + Assert.assertTrue(a.isSquare()); + } + + @Test + public void notSquare() { + Matrix a = Matrix.builder().rows(3).columns(4).build(); + Assert.assertFalse(a.isSquare()); + } + + @Test + public void valueAt() { + Matrix a = Matrix.builder().rows(1).columns(2) + .addRow(1.0, 2.0) + .build(); + + Assert.assertThat(a.valueAt(0, 0), is(1.0)); + Assert.assertThat(a.valueAt(0, 1), is(2.0)); + } + + @Test(expected=IndexOutOfBoundsException.class) + public void invalidValueOf() { + Matrix a = Matrix.builder().rows(1).columns(1).build(); + a.valueAt(1, 2); + } + + @Test + public void getRow() { + Matrix a = Matrix.builder().rows(2).columns(2) + .addRow(1.0, 1.0) + .addRow(2.0, 2.0) + .build(); + + Vector row = a.getRow(0); + + Assert.assertThat(row.getReal(0), is(1.0)); + Assert.assertThat(row.getReal(1), is(1.0)); + } + + @Test + public void rowNumber() { + Matrix a = Matrix.builder().rows(4).columns(5).build(); + Assert.assertThat(a.getRows(), is(4)); + } + + @Test + public void columnNumber() { + Matrix a = Matrix.builder().rows(5).columns(8).build(); + Assert.assertThat(a.getColumns(), is(8)); + } + + @Test + public void addition() { + Matrix a = Matrix.builder().rows(2).columns(2) + .addRow(1.0, 2.0) + .addRow(3.0, 4.0) + .build(); + Matrix b = Matrix.builder().rows(2).columns(2) + .addRow(1.0, 2.0) + .addRow(3.0, 4.0) + .build(); + + Matrix c = a.plus(b); + + Assert.assertThat(c.getRow(0), equalTo(Vectors.create(2.0, 4.0))); + Assert.assertThat(c.getRow(1), equalTo(Vectors.create(6.0, 8.0))); + } + + @Test(expected=IllegalArgumentException.class) + public void invalidAddition() { + Matrix a = Matrix.builder().rows(3).columns(2).build(); + Matrix b = Matrix.builder().rows(1).columns(2).build(); + a.plus(b); + } + + @Test + public void subtraction() { + Matrix a = Matrix.builder().rows(2).columns(2) + .addRow(2.0, 4.0) + .addRow(6.0, 8.0) + .build(); + Matrix b = Matrix.builder().rows(2).columns(2) + .addRow(1.0, 2.0) + .addRow(3.0, 4.0) + .build(); + + Matrix c = a.minus(b); + + Assert.assertThat(c.getRow(0), equalTo(Vectors.create(1.0, 2.0))); + Assert.assertThat(c.getRow(1), equalTo(Vectors.create(3.0, 4.0))); + } + + @Test(expected=IllegalArgumentException.class) + public void invalidSubtraction() { + Matrix a = Matrix.builder().rows(2).columns(2).build(); + Matrix b = Matrix.builder().rows(2).columns(3).build(); + a.minus(b); + } + + @Test + public void multiplication() { + Matrix a = Matrix.builder().rows(2).columns(2) + .addRow(2.0, 4.0) + .addRow(6.0, 8.0) + .build(); + Matrix b = Matrix.builder().rows(2).columns(2) + .addRow(1.0, 2.0) + .addRow(3.0, 4.0) + .build(); + + Matrix c = a.times(b); + + Assert.assertThat(c.getRow(0), equalTo(Vectors.create(14.0, 20.0))); + Assert.assertThat(c.getRow(1), equalTo(Vectors.create(30.0, 44.0))); + } + + @Test + public void squareTranspose() { + Matrix a = Matrix.builder().rows(2).columns(2) + .addRow(2.0, 4.0) + .addRow(6.0, 8.0) + .build(); + + Matrix c = a.transpose(); + + Assert.assertThat(c.getRow(0), equalTo(Vectors.create(2.0, 6.0))); + Assert.assertThat(c.getRow(1), equalTo(Vectors.create(4.0, 8.0))); + } + + @Test + public void transposeRowVector() { + Matrix a = Matrix.builder().rows(1).columns(2) + .addRow(2.0, 4.0) + .build(); + + Matrix c = a.transpose(); + + Assert.assertThat(c.getRows(), is(2)); + Assert.assertThat(c.getColumns(), is(1)); + } + + @Test + public void transposeColumnVector() { + Matrix a = Matrix.builder().rows(2).columns(1) + .addRow(2.0) + .addRow(4.0) + .build(); + + Matrix c = a.transpose(); + + Assert.assertThat(c.getRows(), is(1)); + Assert.assertThat(c.getColumns(), is(2)); + } + + @Test + public void identity() { + Matrix identity = Matrix.builder().rows(4).columns(4).identity().build(); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (i == j) Assert.assertThat(identity.valueAt(i, j), is(1.0)); + else Assert.assertThat(identity.valueAt(i, j), is(0.0)); + } + } + } + + @Test(expected=IllegalStateException.class) + public void invalidIdentity() { + Matrix.builder().rows(2).columns(5).identity().build(); + } + + @Test + public void uniquePositionSetting() { + Matrix a = Matrix.builder().rows(2).columns(2) + .valueAt(0, 0, 3.0) + .build(); + + Assert.assertThat(a.valueAt(0, 0), is(3.0)); + Assert.assertThat(a.valueAt(0, 1), is(0.0)); + Assert.assertThat(a.valueAt(1, 0), is(0.0)); + Assert.assertThat(a.valueAt(1, 1), is(0.0)); + } + + @Test + public void equal() { + Matrix.Builder builder = Matrix.builder(); + Matrix a = builder.rows(1).columns(1).valueAt(0, 0, 2.0).build(); + Matrix b = builder.rows(1).columns(1).valueAt(0, 0, 2.0).build(); + + Assert.assertTrue(a.equals(b)); + } + + @Test + public void hash() { + Matrix.Builder builder = Matrix.builder(); + Matrix a = builder.rows(1).columns(1).valueAt(0, 0, 2.0).build(); + Matrix b = builder.rows(1).columns(1).valueAt(0, 0, 2.0).build(); + + Assert.assertTrue(a.hashCode() == b.hashCode()); + } + +} -- 1.6.4 |