From: Gary P. <gpa...@gm...> - 2009-08-13 06:46:12
|
The second revision of the Immutable Matrix type. Added the ability to obtain permutations of a list and the determinant of a Matrix. |
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 |
From: Gary P. <gpa...@gm...> - 2009-08-13 06:46:17
|
The current implementation of the rotation and the determinant. These implementations are restricted to 2-dimensions at the moment. Plans to extend this to n-dimensions is planned. Signed-off-by: Gary Pampara <gpa...@gm...> --- pom.xml | 5 ---- .../cilib/type/types/container/Matrix.java | 23 ++++++++++++++++++++ .../cilib/type/types/container/MatrixTest.java | 19 ++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index bf3b9f4..fcc9dff 100644 --- a/pom.xml +++ b/pom.xml @@ -163,11 +163,6 @@ </configuration> </plugin> <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>2.4.2</version> - </plugin> - <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>javacc-maven-plugin</artifactId> <version>2.5</version> 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 index f42abb6..913ff7f 100644 --- a/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java +++ b/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java @@ -169,6 +169,29 @@ public final class Matrix implements Type { } /** + * + * @param angle The rotation angle defined in radians. + * @return + */ + public Matrix rotate(double angle) { + Matrix rotation = new Matrix(2, 2); + rotation.contents[0][0] = Math.cos(angle); + rotation.contents[0][1] = -Math.sin(angle); + rotation.contents[1][0] = Math.sin(angle); + rotation.contents[1][1] = Math.cos(angle); + + return this.times(rotation); + } + + /** + * + * @return + */ + public double determinant() { + return contents[0][0]*contents[1][1] - contents[1][0]*contents[0][1]; + } + + /** * {@inheritDoc} */ @Override 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 index 6144707..0c2c98e 100644 --- a/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java +++ b/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java @@ -211,6 +211,25 @@ public class MatrixTest { } } + @Test + public void rotation() { + double angle = Math.PI / 4.0; + + Matrix matrix = Matrix.builder().rows(2).columns(2).addRow(1.0, 1.0).addRow(1.0, 1.0).build(); + Matrix result = matrix.rotate(angle); + + Assert.assertThat(result.valueAt(0, 0), is(1.414213562373095)); + Assert.assertThat(result.valueAt(0, 1), is(1.1102230246251565E-16)); + Assert.assertThat(result.valueAt(1, 0), is(1.414213562373095)); + Assert.assertThat(result.valueAt(1, 1), is(1.1102230246251565E-16)); + } + + @Test + public void determinant() { + Matrix matrix = Matrix.builder().rows(2).columns(2).addRow(1.0, 1.0).addRow(1.0, 1.0).build(); + Assert.assertThat(matrix.determinant(), is(0.0)); + } + @Test(expected=IllegalStateException.class) public void invalidIdentity() { Matrix.builder().rows(2).columns(5).identity().build(); -- 1.6.4 |
From: Gary P. <gpa...@gm...> - 2009-08-13 06:46:23
|
Added another method for the Matrix.times() operation. Matrix.multiply() defers to Matrix.times() Signed-off-by: Gary Pampara <gpa...@gm...> --- .../cilib/type/types/container/Matrix.java | 22 ++++++++++++++++--- 1 files changed, 18 insertions(+), 4 deletions(-) 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 index 913ff7f..807f7ff 100644 --- a/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java +++ b/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java @@ -142,6 +142,20 @@ public final class Matrix implements Type { * 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. + * @see Matrix#times(net.sourceforge.cilib.type.types.container.Matrix) + */ + public Matrix multiply(Matrix b) { + return this.times(b); + } + + /** + * 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."); @@ -169,9 +183,9 @@ public final class Matrix implements Type { } /** - * + * Perform a rotation on the provided matrix by the specified {@code angle}. * @param angle The rotation angle defined in radians. - * @return + * @return A rotated {@code Matrix}, which is a new instance. */ public Matrix rotate(double angle) { Matrix rotation = new Matrix(2, 2); @@ -184,8 +198,8 @@ public final class Matrix implements Type { } /** - * - * @return + * Obtain the determinant of the current matrix. + * @return The determinant value. */ public double determinant() { return contents[0][0]*contents[1][1] - contents[1][0]*contents[0][1]; -- 1.6.4 |
From: Gary P. <gpa...@gm...> - 2009-08-13 06:46:21
|
Added the option of obtaining a list of permutations for a list and to create a LU decomposition matrix in order to get the determinant of a n x n matrix class. Signed-off-by: Gary Pampara <gpa...@gm...> --- .../java/net/sourceforge/cilib/math/Maths.java | 104 +++++++++++++++ .../problem/dataset/MatrixDataSetBuilder.java | 2 +- .../problem/mappingproblem/MappingProblem.java | 2 +- .../cilib/type/types/container/Matrix.java | 134 +++++++++++++++++--- .../java/net/sourceforge/cilib/math/MathsTest.java | 67 ++++++---- .../cilib/type/types/container/MatrixTest.java | 65 +++++----- 6 files changed, 299 insertions(+), 75 deletions(-) diff --git a/src/main/java/net/sourceforge/cilib/math/Maths.java b/src/main/java/net/sourceforge/cilib/math/Maths.java index fce85e5..db2e489 100644 --- a/src/main/java/net/sourceforge/cilib/math/Maths.java +++ b/src/main/java/net/sourceforge/cilib/math/Maths.java @@ -21,6 +21,9 @@ */ package net.sourceforge.cilib.math; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import net.sourceforge.cilib.math.random.generator.MersenneTwister; import net.sourceforge.cilib.math.random.generator.Random; @@ -91,6 +94,107 @@ public final class Maths { return factorial(n) / factorial(n-r); } + public static <T> Iterator<List<T>> permutation(final List<T> input, final int number) { + return new Iterator<List<T>>() { + private List<T> internalList = new ArrayList<T>(input); // Keep our own copy + private int n = input.size(); + private int m = number; + private int[] index = initialize(); + private boolean hasMore = true; + + @Override + public boolean hasNext() { + return this.hasMore; + } + + @Override + public List<T> next() { + if (!this.hasMore){ + return null; + } + List<T> list = new ArrayList<T>(this.m); + for (int i = 0; i < this.m; i++) { + int thisIndexI = this.index[i]; + T element = internalList.get(thisIndexI); + list.add(element); + } + moveIndex(); + return list; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Not supported yet."); + } + + private int[] initialize() { + if (!(this.n >= m && m >= 0)) + throw new IllegalStateException("Permutation error! n >= m"); + + int[] tmp = new int[this.n]; + for (int i = 0; i < this.n; i++) { + tmp[i] = i; + } + + reverseAfter(tmp, m - 1); + return tmp; + } + + /** + * Reverse the index elements to the right of the specified index. + */ + private void reverseAfter(int[] indicies, int i) { + int start = i + 1; + int end = this.n - 1; + while (start < end) { + int t = indicies[start]; + indicies[start] = indicies[end]; + indicies[end] = t; + start++; + end--; + } + } + + private void moveIndex(){ + // find the index of the first element that dips + int i = rightmostDip(); + if (i < 0) { + this.hasMore = false; + return; + } + + // find the least greater element to the right of the dip + int leastToRightIndex = i + 1; + for (int j = i + 2; j < this.n; j++){ + if (this.index[j] < this.index[leastToRightIndex] && this.index[j] > this.index[i]) { + leastToRightIndex = j; + } + } + + // switch dip element with least greater element to its right + int t = this.index[i]; + this.index[i] = this.index[leastToRightIndex]; + this.index[leastToRightIndex] = t; + + if (this.m - 1 > i) { + // reverse the elements to the right of the dip + reverseAfter(this.index, i); + // reverse the elements to the right of m - 1 + reverseAfter(this.index, this.m - 1); + } + } + + private int rightmostDip() { + for (int i = this.n - 2; i >= 0; i--){ + if (this.index[i] < this.index[i+1]){ + return i; + } + } + return -1; + } + }; + } + /** * Determine if a "flip" would occur given the provided probability value. * @param probability The provided probability value. This value must be in [0,1] 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 43d97ea..2712b29 100644 --- a/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java +++ b/src/main/java/net/sourceforge/cilib/problem/dataset/MatrixDataSetBuilder.java @@ -81,7 +81,7 @@ public class MatrixDataSetBuilder extends BinaryDataSetBuilder { if (m <= 0) throw new IllegalStateException("Need to have a positive number as the input dimensions"); - matrixBuilder = Matrix.builder().rows(numvectors).columns(m); + matrixBuilder = Matrix.builder().dimensions(numvectors, m); if (tok.nextToken() != StreamTokenizer.TT_NUMBER) throw new IllegalStateException("Expected an integer number as the third token in the dataset"); 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 71a6f73..57d529f 100644 --- a/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java +++ b/src/main/java/net/sourceforge/cilib/problem/mappingproblem/MappingProblem.java @@ -195,7 +195,7 @@ public abstract class MappingProblem extends OptimisationProblemAdapter { MatrixDataSetBuilder matrixDataSetBuilder = (MatrixDataSetBuilder) dataSetBuilder; inputs = matrixDataSetBuilder.getMatrix(); - Matrix.Builder matrixBuilder = Matrix.builder().rows(numvectors).columns(numvectors); + Matrix.Builder matrixBuilder = Matrix.builder().dimensions(numvectors, numvectors); for(int i = 0; i < numvectors; i++) { for(int j = 0; j < i; j++) { 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 index 807f7ff..12ca4db 100644 --- a/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java +++ b/src/main/java/net/sourceforge/cilib/type/types/container/Matrix.java @@ -198,11 +198,22 @@ public final class Matrix implements Type { } /** - * Obtain the determinant of the current matrix. + * Obtain the determinant of the current matrix. The determinant is obtained + * by creating a LU decomposition matrix. The determinant is then calculated by: + * <p> + * <pre> + * \begin{equation} + * \mbox{det($A$)} = |L| \dot |U| + * \end{equation} + * </pre> + * where |L| = 1 and |U| is the product of the diagonal elements. * @return The determinant value. */ public double determinant() { - return contents[0][0]*contents[1][1] - contents[1][0]*contents[0][1]; + Preconditions.checkState(isSquare(), "Cannot obtain determinant of a non-square matrix"); + + LUDecomposition decomposition = new LUDecomposition(this); + return decomposition.determinant(); } /** @@ -260,22 +271,19 @@ public final class Matrix implements Type { } /** - * 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}. + * Define the dimensions (rows and coloums) that the bult up {@code Matrix} will + * contain. + * @param rows The number of rows. + * @param columns The number of columns. + * @return The current {@code Builder) + * @throws IllegalArgumentException if {@code rows} or {@code columns} are less than 1. */ - public Builder rows(int rows) { - this.rowNumber = rows; - return this; - } + public Builder dimensions(int rows, int columns) { + Preconditions.checkArgument(rows >= 1); + Preconditions.checkArgument(columns >= 1); - /** - * 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; + this.rowNumber = rows; + this.colNumber = columns; return this; } @@ -410,4 +418,98 @@ public final class Matrix implements Type { return y; } } + + /** + * This class is an implementation of the Doolittle / Crout algorithms. + * <p> + * Please refer to <a href=http://en.wikipedia.org/wiki/LU_decomposition#Doolittle_algorithm> + * the Wikipedia entry</a> for more information. + * <p> + * Additional help and code was obtained from the JAMA project (which seems to + * be stagnant) and from the commons-math. + */ + private static final class LUDecomposition { + private double[][] lu; + + private int m; + private int n; + private int pivsign; + private int[] piv; + + private LUDecomposition(Matrix matrix) { + m = matrix.getRows(); + n = matrix.getColumns(); + pivsign = 1; + + lu = new double[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + lu[i][j] = matrix.contents[i][j]; + } + } + + piv = new int[m]; + for (int i = 0; i < m; i++) + piv[i] = i; + + double[] LUrowi; + double[] LUcolj = new double[m]; + + // Outer-loop + for (int j = 0; j < n; j++) { + // Make a copy of the j-th column. + for (int i = 0; i < m; i++) { + LUcolj[i] = lu[i][j]; + } + + // Apply previous transformations + for (int i = 0; i < m; i++) { + LUrowi = lu[i]; + + int kmax = Math.min(i, j); + double s = 0.0; + for (int k = 0; k < kmax; k++) { + s += LUrowi[k]*LUcolj[k]; + } + + LUcolj[i] -= s; + LUrowi[j] = LUcolj[i]; + } + + // Find the pivot and exchange if needed + int p = j; + for (int i = j+1; i < m; i++) { + if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) { + p = i; + } + } + + if (p != j) { + for (int k = 0; k < n; k++) { + double t = lu[p][k]; lu[p][k] = lu[j][k]; lu[j][k] = t; + } + int k = piv[p]; piv[p] = piv[j]; piv[j] = k; + pivsign = -pivsign; + } + + // Compute multipliers. + if (j < m & lu[j][j] != 0.0) { + for (int i = j+1; i < m; i++) { + lu[i][j] /= lu[j][j]; + } + } + } + } + + public double determinant() { + Preconditions.checkState(m == n, "Matrix must be square."); + + double d = Integer.valueOf(pivsign).doubleValue(); + for (int j = 0; j < n; j++) { + d *= lu[j][j]; + } + + return d; + } + } } diff --git a/src/test/java/net/sourceforge/cilib/math/MathsTest.java b/src/test/java/net/sourceforge/cilib/math/MathsTest.java index 96f98e1..a774623 100644 --- a/src/test/java/net/sourceforge/cilib/math/MathsTest.java +++ b/src/test/java/net/sourceforge/cilib/math/MathsTest.java @@ -21,10 +21,15 @@ */ package net.sourceforge.cilib.math; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import org.junit.Assert; import org.junit.Test; +import static org.hamcrest.CoreMatchers.is; + /** * @@ -39,38 +44,50 @@ public class MathsTest { @Test public void testFactorial() { - assertEquals(1.0, Maths.factorial(0.0), Double.MIN_NORMAL); - assertEquals(1.0, Maths.factorial(1.0), Double.MIN_NORMAL); - assertEquals(6.0, Maths.factorial(3), Double.MIN_NORMAL); - assertEquals(720.0, Maths.factorial(6), Double.MIN_NORMAL); - assertEquals(9.33262154439441E157, Maths.factorial(100), Double.MIN_NORMAL); + Assert.assertEquals(1.0, Maths.factorial(0.0), Double.MIN_NORMAL); + Assert.assertEquals(1.0, Maths.factorial(1.0), Double.MIN_NORMAL); + Assert.assertEquals(6.0, Maths.factorial(3), Double.MIN_NORMAL); + Assert.assertEquals(720.0, Maths.factorial(6), Double.MIN_NORMAL); + Assert.assertEquals(9.33262154439441E157, Maths.factorial(100), Double.MIN_NORMAL); } @Test public void testCombination() { - assertEquals(792.0, Maths.combination(12, 5), Double.MIN_NORMAL); + Assert.assertEquals(792.0, Maths.combination(12, 5), Double.MIN_NORMAL); + } - try { - Maths.combination(-1, -5); - fail("Invalid input!"); - } - catch (Exception e) {} + @Test(expected=IllegalArgumentException.class) + public void combinationInvalidN() { + Maths.combination(-1, 5); + } - try { - Maths.combination(-1, 5); - fail("Invalid input!"); - } - catch (Exception e) {} + @Test(expected=IllegalArgumentException.class) + public void combinationInvalidR() { + Maths.combination(1, -5); + } - try { - Maths.combination(1, -5); - fail("Invalid input!"); + @Test + public void combinationSpecialCase() { + Assert.assertEquals(1.0, Maths.combination(0, 0), Double.MIN_NORMAL); + Assert.assertEquals(1.0, Maths.combination(1, 0), Double.MIN_NORMAL); + Assert.assertEquals(1.0, Maths.combination(1, 1), Double.MIN_NORMAL); + } + + @Test + public void listPermutation() { + List<Integer> numbers = Arrays.asList(1, 2); + List<List<Integer>> permutationList = new ArrayList<List<Integer>>(); + + for (Iterator<List<Integer>> permutations = Maths.permutation(numbers, 2); permutations.hasNext(); ) { + permutationList.add(permutations.next()); } - catch (Exception e) {} - assertEquals(1.0, Maths.combination(0, 0), Double.MIN_NORMAL); - assertEquals(1.0, Maths.combination(1, 0), Double.MIN_NORMAL); - assertEquals(1.0, Maths.combination(1, 1), Double.MIN_NORMAL); + Assert.assertThat(permutationList.size(), is(2)); + + List<Integer> expected1 = Arrays.asList(1, 2); + List<Integer> expected2 = Arrays.asList(2, 1); + Assert.assertTrue(permutationList.contains(expected1)); + Assert.assertTrue(permutationList.contains(expected2)); } } 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 index 0c2c98e..498951d 100644 --- a/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java +++ b/src/test/java/net/sourceforge/cilib/type/types/container/MatrixTest.java @@ -35,29 +35,29 @@ public class MatrixTest { @Test(expected=IllegalArgumentException.class) public void constructionZeroRow() { - Matrix.builder().rows(0).build(); + Matrix.builder().dimensions(0, 1).build(); } @Test(expected=IllegalArgumentException.class) public void constructionZeroColumn() { - Matrix.builder().columns(0).build(); + Matrix.builder().dimensions(1, 0).build(); } @Test public void square() { - Matrix a = Matrix.builder().rows(2).columns(2).build(); + Matrix a = Matrix.builder().dimensions(2, 2).build(); Assert.assertTrue(a.isSquare()); } @Test public void notSquare() { - Matrix a = Matrix.builder().rows(3).columns(4).build(); + Matrix a = Matrix.builder().dimensions(3, 4).build(); Assert.assertFalse(a.isSquare()); } @Test public void valueAt() { - Matrix a = Matrix.builder().rows(1).columns(2) + Matrix a = Matrix.builder().dimensions(1, 2) .addRow(1.0, 2.0) .build(); @@ -67,13 +67,13 @@ public class MatrixTest { @Test(expected=IndexOutOfBoundsException.class) public void invalidValueOf() { - Matrix a = Matrix.builder().rows(1).columns(1).build(); + Matrix a = Matrix.builder().dimensions(1, 1).build(); a.valueAt(1, 2); } @Test public void getRow() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .addRow(1.0, 1.0) .addRow(2.0, 2.0) .build(); @@ -86,23 +86,23 @@ public class MatrixTest { @Test public void rowNumber() { - Matrix a = Matrix.builder().rows(4).columns(5).build(); + Matrix a = Matrix.builder().dimensions(4, 5).build(); Assert.assertThat(a.getRows(), is(4)); } @Test public void columnNumber() { - Matrix a = Matrix.builder().rows(5).columns(8).build(); + Matrix a = Matrix.builder().dimensions(5, 8).build(); Assert.assertThat(a.getColumns(), is(8)); } @Test public void addition() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .addRow(1.0, 2.0) .addRow(3.0, 4.0) .build(); - Matrix b = Matrix.builder().rows(2).columns(2) + Matrix b = Matrix.builder().dimensions(2, 2) .addRow(1.0, 2.0) .addRow(3.0, 4.0) .build(); @@ -115,18 +115,18 @@ public class MatrixTest { @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(); + Matrix a = Matrix.builder().dimensions(3, 2).build(); + Matrix b = Matrix.builder().dimensions(1, 2).build(); a.plus(b); } @Test public void subtraction() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .addRow(2.0, 4.0) .addRow(6.0, 8.0) .build(); - Matrix b = Matrix.builder().rows(2).columns(2) + Matrix b = Matrix.builder().dimensions(2, 2) .addRow(1.0, 2.0) .addRow(3.0, 4.0) .build(); @@ -139,18 +139,18 @@ public class MatrixTest { @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(); + Matrix a = Matrix.builder().dimensions(2, 2).build(); + Matrix b = Matrix.builder().dimensions(2, 3).build(); a.minus(b); } @Test public void multiplication() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .addRow(2.0, 4.0) .addRow(6.0, 8.0) .build(); - Matrix b = Matrix.builder().rows(2).columns(2) + Matrix b = Matrix.builder().dimensions(2, 2) .addRow(1.0, 2.0) .addRow(3.0, 4.0) .build(); @@ -163,7 +163,7 @@ public class MatrixTest { @Test public void squareTranspose() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .addRow(2.0, 4.0) .addRow(6.0, 8.0) .build(); @@ -176,7 +176,7 @@ public class MatrixTest { @Test public void transposeRowVector() { - Matrix a = Matrix.builder().rows(1).columns(2) + Matrix a = Matrix.builder().dimensions(1, 2) .addRow(2.0, 4.0) .build(); @@ -188,7 +188,7 @@ public class MatrixTest { @Test public void transposeColumnVector() { - Matrix a = Matrix.builder().rows(2).columns(1) + Matrix a = Matrix.builder().dimensions(2, 1) .addRow(2.0) .addRow(4.0) .build(); @@ -201,7 +201,7 @@ public class MatrixTest { @Test public void identity() { - Matrix identity = Matrix.builder().rows(4).columns(4).identity().build(); + Matrix identity = Matrix.builder().dimensions(4, 4).identity().build(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -215,7 +215,7 @@ public class MatrixTest { public void rotation() { double angle = Math.PI / 4.0; - Matrix matrix = Matrix.builder().rows(2).columns(2).addRow(1.0, 1.0).addRow(1.0, 1.0).build(); + Matrix matrix = Matrix.builder().dimensions(2, 2).addRow(1.0, 1.0).addRow(1.0, 1.0).build(); Matrix result = matrix.rotate(angle); Assert.assertThat(result.valueAt(0, 0), is(1.414213562373095)); @@ -226,18 +226,19 @@ public class MatrixTest { @Test public void determinant() { - Matrix matrix = Matrix.builder().rows(2).columns(2).addRow(1.0, 1.0).addRow(1.0, 1.0).build(); - Assert.assertThat(matrix.determinant(), is(0.0)); + Matrix matrix = Matrix.builder().dimensions(3, 3).addRow(2.0, 1.0, 0.0).addRow(1.0, 2.0, -1.0).addRow(3.0, 2.0, 1.0).build(); + double value = matrix.determinant(); + Assert.assertEquals(4.0, value, 0.00001); } @Test(expected=IllegalStateException.class) public void invalidIdentity() { - Matrix.builder().rows(2).columns(5).identity().build(); + Matrix.builder().dimensions(2, 5).identity().build(); } @Test public void uniquePositionSetting() { - Matrix a = Matrix.builder().rows(2).columns(2) + Matrix a = Matrix.builder().dimensions(2, 2) .valueAt(0, 0, 3.0) .build(); @@ -250,8 +251,8 @@ public class MatrixTest { @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(); + Matrix a = builder.dimensions(1, 1).valueAt(0, 0, 2.0).build(); + Matrix b = builder.dimensions(1, 1).valueAt(0, 0, 2.0).build(); Assert.assertTrue(a.equals(b)); } @@ -259,8 +260,8 @@ public class MatrixTest { @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(); + Matrix a = builder.dimensions(1, 1).valueAt(0, 0, 2.0).build(); + Matrix b = builder.dimensions(1, 1).valueAt(0, 0, 2.0).build(); Assert.assertTrue(a.hashCode() == b.hashCode()); } -- 1.6.4 |