diff --git a/src/main/java/org/la4j/Matrix.java b/src/main/java/org/la4j/Matrix.java index 2e245bd4..35f53fd6 100644 --- a/src/main/java/org/la4j/Matrix.java +++ b/src/main/java/org/la4j/Matrix.java @@ -249,7 +249,7 @@ public static Matrix fromMatrixMarket(String mm) { } String symmetry = header.nextToken(); - if (!symmetry.equals("general")) { + if (!"general".equals(symmetry)) { throw new IllegalArgumentException("Unknown symmetry type: " + symmetry + "."); } @@ -565,13 +565,14 @@ public Matrix power(int n) { for (int i = 0; i < rows; i++) { result.set(i, i, 1.0); } - - while (n > 0) { - if (n % 2 == 1) { + + int m = n; + while (m > 0) { + if (m % 2 == 1) { result = result.multiply(that); } - n /= 2; + m /= 2; that = that.multiply(that); } @@ -2187,9 +2188,10 @@ protected void fail(String message) { } private void indent(StringBuilder sb, int howMany) { - while (howMany > 0) { + int n = howMany; + while (n > 0) { sb.append(" "); - howMany--; + n--; } } } diff --git a/src/main/java/org/la4j/Vector.java b/src/main/java/org/la4j/Vector.java index 218cc5d3..8d232a09 100644 --- a/src/main/java/org/la4j/Vector.java +++ b/src/main/java/org/la4j/Vector.java @@ -487,17 +487,6 @@ public Matrix outerProduct(Vector that) { return apply(LinearAlgebra.OO_PLACE_OUTER_PRODUCT, that); } - /** - * Calculates the cosine similarity between this vector and given {@code that}. - * - * @param that the vector to calculated cosine similarity with - * - * @return the cosine similarity of the two vectors - */ - public double cosineSimilarity(Vector that) { - return this.innerProduct(that) / (this.euclideanNorm() * that.euclideanNorm()); - } - /** * Calculates an Euclidean norm of this vector. * diff --git a/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java b/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java index 5825ccf1..9df89c09 100644 --- a/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java +++ b/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java @@ -506,6 +506,7 @@ public Matrix[] decompose() { iter = 0; p--; } + default: break; } } diff --git a/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java b/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java index 0a5691fb..ba525ae0 100644 --- a/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java +++ b/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java @@ -554,18 +554,19 @@ private int searchForRowIndex(int i, int left, int right) { return right; } - while (left < right) { - int p = (left + right) / 2; + int l = left, r = right; + while (l < r) { + int p = (l + r) / 2; if (rowIndices[p] > i) { - right = p; + r = p; } else if (rowIndices[p] < i) { - left = p + 1; + l = p + 1; } else { return p; } } - return left; + return l; } private void insert(int k, int i, int j, double value) { @@ -697,6 +698,47 @@ public double minInColumn(int j) { return (min < 0.0) ? min : 0.0; } + /** + * Calculates the cardinality + */ + public int getCardinality(int[] sizes, int[] rowIndices, int[] columnIndices, int newCardinality){ + int newRows = sizes[0]; + int newCols = sizes[1]; + + for (int i = 0; i < newRows; i++) { + for (int j = 0; j < newCols; j++) { + if (get(rowIndices[i], columnIndices[j]) != 0.0) { + newCardinality++; + } + } + } + + return newCardinality; + } + + /* + * Constructs the raw structure of a Sparse Matrix + */ + public void constructSparseMatrix(int[] sizes, int[] newColumnPointers,int[] rowIndices, int[] columnIndices, double[] newValues, int[] newRowIndices){ + int newRows = sizes[0]; + int newCols = sizes[1]; + + newColumnPointers[0] = 0; + int endPtr = 0; + for (int j = 0; j < newCols; j++) { + newColumnPointers[j + 1] = newColumnPointers[j]; + for (int i = 0; i < newRows; i++) { + double val = get(rowIndices[i], columnIndices[j]); + if (val != 0.0) { + newValues[endPtr] = val; + newRowIndices[endPtr] = i; + endPtr++; + newColumnPointers[j + 1]++; + } + } + } + } + /** * Returns a CCSMatrix with the selected rows and columns. */ @@ -713,36 +755,18 @@ public Matrix select(int[] rowIndices, int[] columnIndices) { // before allocating space, this is perhaps more efficient // than single pass and calling grow() when required. int newCardinality = 0; - for (int i = 0; i < newRows; i++) { - for (int j = 0; j < newCols; j++) { - if (get(rowIndices[i], columnIndices[j]) != 0.0) { - newCardinality++; - } - } - } + int[] sizes = {newRows, newCols}; + newCardinality = getCardinality(sizes, rowIndices, columnIndices, newCardinality); + // Construct the raw structure for the sparse matrix double[] newValues = new double[newCardinality]; int[] newRowIndices = new int[newCardinality]; int[] newColumnPointers = new int[newCols + 1]; - - newColumnPointers[0] = 0; - int endPtr = 0; - for (int j = 0; j < newCols; j++) { - newColumnPointers[j + 1] = newColumnPointers[j]; - for (int i = 0; i < newRows; i++) { - double val = get(rowIndices[i], columnIndices[j]); - if (val != 0.0) { - newValues[endPtr] = val; - newRowIndices[endPtr] = i; - endPtr++; - newColumnPointers[j + 1]++; - } - } - } - - return new CCSMatrix(newRows, newCols, newCardinality, newValues, - newRowIndices, newColumnPointers); + + constructSparseMatrix(sizes, newColumnPointers,rowIndices, columnIndices, newValues, newRowIndices); + + return new CCSMatrix(newRows, newCols, newCardinality, newValues, newRowIndices, newColumnPointers); } @Override diff --git a/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java b/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java index 6b57c7d2..e0a77b75 100644 --- a/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java +++ b/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java @@ -552,19 +552,20 @@ private int searchForColumnIndex(int j, int left, int right) { if (right - left == 0 || j > columnIndices[right - 1]) { return right; } - - while (left < right) { - int p = (left + right) / 2; + + int l = left, r = right; + while (l < r) { + int p = (l + r) / 2; if (columnIndices[p] > j) { - right = p; + r = p; } else if (columnIndices[p] < j) { - left = p + 1; + l = p + 1; } else { return p; } } - return left; + return l; } private void insert(int k, int i, int j, double value) { @@ -696,35 +697,31 @@ public double minInRow(int i) { } /** - * Returns a CRSMatrix with the selected rows and columns. + * Calculates the cardinality */ - @Override - public Matrix select(int[] rowIndices, int[] columnIndices) { - int newRows = rowIndices.length; - int newCols = columnIndices.length; - - if (newRows == 0 || newCols == 0) { - fail("No rows or columns selected."); - } - - // determine number of non-zero values (cardinality) - // before allocating space, this is perhaps more efficient - // than single pass and calling grow() when required. - int newCardinality = 0; - for (int i = 0; i < newRows; i++) { + public int getCardinality(int[] sizes, int[] rowIndices, int[] columnIndices, int newCardinality){ + int newRows = sizes[0]; + int newCols = sizes[1]; + + for (int i = 0; i < newRows; i++) { for (int j = 0; j < newCols; j++) { if (get(rowIndices[i], columnIndices[j]) != 0.0) { newCardinality++; } } } - - // Construct the raw structure for the sparse matrix - double[] newValues = new double[newCardinality]; - int[] newColumnIndices = new int[newCardinality]; - int[] newRowPointers = new int[newRows + 1]; - - newRowPointers[0] = 0; + + return newCardinality; + } + + /** + * Constructs the raw structure of a Sparse Matrix + */ + public void constructSparseMatrix(int[] sizes, int[] newRowPointers,int[] rowIndices, int[] columnIndices, double[] newValues, int[] newColumnIndices){ + int newRows = sizes[0]; + int newCols = sizes[1]; + + newRowPointers[0] = 0; int endPtr = 0; for (int i = 0; i < newRows; i++) { newRowPointers[i + 1] = newRowPointers[i]; @@ -739,6 +736,34 @@ public Matrix select(int[] rowIndices, int[] columnIndices) { } } } + } + + + /** + * Returns a CRSMatrix with the selected rows and columns. + */ + @Override + public Matrix select(int[] rowIndices, int[] columnIndices) { + int newRows = rowIndices.length; + int newCols = columnIndices.length; + + if (newRows == 0 || newCols == 0) { + fail("No rows or columns selected."); + } + + // determine number of non-zero values (cardinality) + // before allocating space, this is perhaps more efficient + // than single pass and calling grow() when required. + int newCardinality = 0; + int[] sizes = {newRows, newCols}; + newCardinality = getCardinality(sizes, rowIndices, columnIndices, newCardinality); + + // Construct the raw structure for the sparse matrix + double[] newValues = new double[newCardinality]; + int[] newColumnIndices = new int[newCardinality]; + int[] newRowPointers = new int[newRows + 1]; + + constructSparseMatrix(sizes, newRowPointers,rowIndices, columnIndices, newValues, newColumnIndices); return new CRSMatrix(newRows, newCols, newCardinality, newValues, newColumnIndices, newRowPointers); diff --git a/src/main/java/org/la4j/operation/CommonVectorOperation.java b/src/main/java/org/la4j/operation/CommonVectorOperation.java index 6c4cb6f0..79eba2e7 100644 --- a/src/main/java/org/la4j/operation/CommonVectorOperation.java +++ b/src/main/java/org/la4j/operation/CommonVectorOperation.java @@ -36,5 +36,5 @@ public R apply(final DenseVector a) { return applyCommon(a); } - abstract R applyCommon(final Vector a); + protected abstract R applyCommon(final Vector a); } diff --git a/src/test/java/org/la4j/vector/VectorTest.java b/src/test/java/org/la4j/vector/VectorTest.java index 5351cddb..52963f97 100644 --- a/src/test/java/org/la4j/vector/VectorTest.java +++ b/src/test/java/org/la4j/vector/VectorTest.java @@ -743,19 +743,4 @@ public void testFromMap_invalidMap() { public void testFromMap_NPE() { Vector v = Vector.fromMap(null, 4); } - - @Test - public void testCosineSimilarity() { - Vector a = v(5, 1, 0, 0, 0, 1, 10, 15); - Vector b = v(1, 8, 0, 9, 6, 4, 2, 5); - Vector c = v(9, 0, 2, 1, 1, 0, 8, 12); - Vector d = v(900, 0, 200, 100, 100, 0, 800, 1200); - - // a & c are more similar to each other than b - Assert.assertTrue(a.cosineSimilarity(b) < a.cosineSimilarity(c)); - Assert.assertTrue(c.cosineSimilarity(b) < c.cosineSimilarity(a)); - - Assert.assertEquals(1.0, c.cosineSimilarity(d), 0.00005); - Assert.assertEquals(1.0, d.cosineSimilarity(c), 0.00005); - } }