|
From: Gary P. <gpa...@gm...> - 2009-08-03 06:14:35
|
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
|