Repository: hama Updated Branches: refs/heads/master 5da38ec6b -> fb28bcbcf
HAMA-991: Add math classes for float16/32 Project: http://git-wip-us.apache.org/repos/asf/hama/repo Commit: http://git-wip-us.apache.org/repos/asf/hama/commit/fb28bcbc Tree: http://git-wip-us.apache.org/repos/asf/hama/tree/fb28bcbc Diff: http://git-wip-us.apache.org/repos/asf/hama/diff/fb28bcbc Branch: refs/heads/master Commit: fb28bcbcff97872ecd4434bfa7b934c48d1ce3ee Parents: 5da38ec Author: Edward J. Yoon <[email protected]> Authored: Tue May 24 22:28:20 2016 +0900 Committer: Edward J. Yoon <[email protected]> Committed: Wed May 25 11:52:20 2016 +0900 ---------------------------------------------------------------------- .../hama/commons/io/FloatMatrixWritable.java | 75 ++ .../hama/commons/io/FloatVectorWritable.java | 142 +++ .../hama/commons/math/DenseFloatMatrix.java | 902 +++++++++++++++++++ .../hama/commons/math/DenseFloatVector.java | 714 +++++++++++++++ .../hama/commons/math/FloatFloatFunction.java | 40 + .../apache/hama/commons/math/FloatFunction.java | 38 + .../apache/hama/commons/math/FloatMatrix.java | 269 ++++++ .../apache/hama/commons/math/FloatVector.java | 366 ++++++++ .../hama/commons/math/NamedFloatVector.java | 233 +++++ 9 files changed, 2779 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/io/FloatMatrixWritable.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/io/FloatMatrixWritable.java b/commons/src/main/java/org/apache/hama/commons/io/FloatMatrixWritable.java new file mode 100644 index 0000000..a009001 --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/io/FloatMatrixWritable.java @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.io; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.io.Writable; +import org.apache.hama.commons.math.DenseFloatMatrix; +import org.apache.hama.commons.math.FloatMatrix; + +public class FloatMatrixWritable implements Writable { + + + private FloatMatrix mat; + + public FloatMatrixWritable() { + } + + public FloatMatrixWritable(FloatMatrix mat) { + this.mat = mat; + + } + + @Override + public void readFields(DataInput in) throws IOException { + mat = read(in); + } + + @Override + public void write(DataOutput out) throws IOException { + write(mat, out); + } + + public static void write(FloatMatrix mat, DataOutput out) throws IOException { + out.writeInt(mat.getRowCount()); + out.writeInt(mat.getColumnCount()); + for (int row = 0; row < mat.getRowCount(); row++) { + for (int col = 0; col < mat.getColumnCount(); col++) { + out.writeFloat(mat.get(row, col)); + } + } + } + + public static FloatMatrix read(DataInput in) throws IOException { + FloatMatrix mat = new DenseFloatMatrix(in.readInt(), in.readInt()); + for (int row = 0; row < mat.getRowCount(); row++) { + for (int col = 0; col < mat.getColumnCount(); col++) { + mat.set(row, col, in.readFloat()); + } + } + return mat; + } + + public FloatMatrix getMatrix() { + return this.mat; + } + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/io/FloatVectorWritable.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/io/FloatVectorWritable.java b/commons/src/main/java/org/apache/hama/commons/io/FloatVectorWritable.java new file mode 100644 index 0000000..82b7ec2 --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/io/FloatVectorWritable.java @@ -0,0 +1,142 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.io; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.io.WritableComparable; +import org.apache.hama.commons.math.DenseFloatVector; +import org.apache.hama.commons.math.FloatVector; +import org.apache.hama.commons.math.NamedFloatVector; + +public class FloatVectorWritable implements WritableComparable<FloatVectorWritable> { + + private FloatVector vector; + + public FloatVectorWritable() { + super(); + } + + public FloatVectorWritable(FloatVectorWritable v) { + this.vector = v.getVector(); + } + + public FloatVectorWritable(FloatVector v) { + this.vector = v; + } + + @Override + public void write(DataOutput out) throws IOException { + writeVector(this.vector, out); + } + + @Override + public void readFields(DataInput in) throws IOException { + this.vector = readVector(in); + } + + @Override + public final int compareTo(FloatVectorWritable o) { + return compareVector(this, o); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((vector == null) ? 0 : vector.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FloatVectorWritable other = (FloatVectorWritable) obj; + if (vector == null) { + if (other.vector != null) + return false; + } else if (!vector.equals(other.vector)) + return false; + return true; + } + + /** + * @return the embedded vector + */ + public FloatVector getVector() { + return vector; + } + + @Override + public String toString() { + return vector.toString(); + } + + public static void writeVector(FloatVector vector, DataOutput out) + throws IOException { + out.writeInt(vector.getLength()); + for (int i = 0; i < vector.getDimension(); i++) { + out.writeFloat(vector.get(i)); + } + + if (vector.isNamed() && vector.getName() != null) { + out.writeBoolean(true); + out.writeUTF(vector.getName()); + } else { + out.writeBoolean(false); + } + } + + public static FloatVector readVector(DataInput in) throws IOException { + int length = in.readInt(); + FloatVector vector; + vector = new DenseFloatVector(length); + for (int i = 0; i < length; i++) { + vector.set(i, in.readFloat()); + } + + if (in.readBoolean()) { + vector = new NamedFloatVector(in.readUTF(), vector); + } + return vector; + } + + public static int compareVector(FloatVectorWritable a, FloatVectorWritable o) { + return compareVector(a.getVector(), o.getVector()); + } + + public static int compareVector(FloatVector a, FloatVector o) { + FloatVector subtract = a.subtractUnsafe(o); + return (int) subtract.sum(); + } + + public static FloatVectorWritable wrap(FloatVector a) { + return new FloatVectorWritable(a); + } + + public void set(FloatVector vector) { + this.vector = vector; + } +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/DenseFloatMatrix.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/DenseFloatMatrix.java b/commons/src/main/java/org/apache/hama/commons/math/DenseFloatMatrix.java new file mode 100644 index 0000000..4ab2441 --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/DenseFloatMatrix.java @@ -0,0 +1,902 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Random; + +import com.google.common.base.Preconditions; + +public final class DenseFloatMatrix implements FloatMatrix { + + protected float[][] matrix; + protected int numRows; + protected int numColumns; + + public DenseFloatMatrix() { } + + /** + * Creates a new empty matrix from the rows and columns. + * + * @param rows the num of rows. + * @param columns the num of columns. + */ + public DenseFloatMatrix(int rows, int columns) { + this.numRows = rows; + this.numColumns = columns; + this.matrix = new float[rows][columns]; + } + + /** + * Creates a new empty matrix from the rows and columns filled with the given + * default value. + * + * @param rows the num of rows. + * @param columns the num of columns. + * @param defaultValue the default value. + */ + public DenseFloatMatrix(int rows, int columns, float defaultValue) { + this.numRows = rows; + this.numColumns = columns; + this.matrix = new float[rows][columns]; + + for (int i = 0; i < numRows; i++) { + Arrays.fill(matrix[i], defaultValue); + } + } + + /** + * Creates a new empty matrix from the rows and columns filled with the given + * random values. + * + * @param rows the num of rows. + * @param columns the num of columns. + * @param rand the random instance to use. + */ + public DenseFloatMatrix(int rows, int columns, Random rand) { + this.numRows = rows; + this.numColumns = columns; + this.matrix = new float[rows][columns]; + + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + matrix[i][j] = rand.nextFloat(); + } + } + } + + /** + * Simple copy constructor, but does only bend the reference to this instance. + * + * @param otherMatrix the other matrix. + */ + public DenseFloatMatrix(float[][] otherMatrix) { + this.matrix = otherMatrix; + this.numRows = otherMatrix.length; + if (matrix.length > 0) + this.numColumns = matrix[0].length; + else + this.numColumns = numRows; + } + + /** + * Generates a matrix out of an vector array. it treats the array entries as + * rows and the vector itself contains the values of the columns. + * + * @param vectorArray the array of vectors. + */ + public DenseFloatMatrix(FloatVector[] vectorArray) { + this.matrix = new float[vectorArray.length][]; + this.numRows = vectorArray.length; + + for (int i = 0; i < vectorArray.length; i++) { + this.setRowVector(i, vectorArray[i]); + } + + if (matrix.length > 0) + this.numColumns = matrix[0].length; + else + this.numColumns = numRows; + } + + /** + * Sets the first column of this matrix to the given vector. + * + * @param first the new first column of the given vector + */ + public DenseFloatMatrix(DenseFloatVector first) { + this(first.getLength(), 1); + setColumn(0, first.toArray()); + } + + /** + * Copies the given float array v into the first row of this matrix, and + * creates this with the number of given rows and columns. + * + * @param v the values to put into the first row. + * @param rows the number of rows. + * @param columns the number of columns. + */ + public DenseFloatMatrix(float[] v, int rows, int columns) { + this.matrix = new float[rows][columns]; + + for (int i = 0; i < rows; i++) { + System.arraycopy(v, i * columns, this.matrix[i], 0, columns); + } + + int index = 0; + for (int col = 0; col < columns; col++) { + for (int row = 0; row < rows; row++) { + matrix[row][col] = v[index++]; + } + } + + this.numRows = rows; + this.numColumns = columns; + } + + /** + * Creates a new matrix with the given vector into the first column and the + * other matrix to the other columns. + * + * @param first the new first column. + * @param otherMatrix the other matrix to set on from the second column. + */ + public DenseFloatMatrix(DenseFloatVector first, FloatMatrix otherMatrix) { + this(otherMatrix.getRowCount(), otherMatrix.getColumnCount() + 1); + setColumn(0, first.toArray()); + for (int col = 1; col < otherMatrix.getColumnCount() + 1; col++) + setColumnVector(col, otherMatrix.getColumnVector(col - 1)); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#get(int, int) + */ + @Override + public final float get(int row, int col) { + return this.matrix[row][col]; + } + + /** + * Gets a whole column of the matrix as a float array. + */ + public final float[] getColumn(int col) { + final float[] column = new float[numRows]; + for (int r = 0; r < numRows; r++) { + column[r] = matrix[r][col]; + } + return column; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#getColumnCount() + */ + @Override + public final int getColumnCount() { + return numColumns; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#getColumnVector(int) + */ + @Override + public final FloatVector getColumnVector(int col) { + return new DenseFloatVector(getColumn(col)); + } + + /** + * Get the matrix as 2-dimensional float array (first dimension is the row, + * second the column) to faster access the values. + */ + public final float[][] getValues() { + return matrix; + } + + /** + * Get a single row of the matrix as a float array. + */ + public final float[] getRow(int row) { + return matrix[row]; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#getRowCount() + */ + @Override + public final int getRowCount() { + return numRows; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#getRowVector(int) + */ + @Override + public final FloatVector getRowVector(int row) { + return new DenseFloatVector(getRow(row)); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#set(int, int, float) + */ + @Override + public final void set(int row, int col, float value) { + this.matrix[row][col] = value; + } + + /** + * Sets the row to a given float array. This does not copy, rather than just + * bends the references. + */ + public final void setRow(int row, float[] value) { + this.matrix[row] = value; + } + + /** + * Sets the column to a given float array. This does not copy, rather than + * just bends the references. + */ + public final void setColumn(int col, float[] values) { + for (int i = 0; i < getRowCount(); i++) { + this.matrix[i][col] = values[i]; + } + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#setColumnVector(int, + * de.jungblut.math.FloatVector) + */ + @Override + public void setColumnVector(int col, FloatVector column) { + this.setColumn(col, column.toArray()); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#setRowVector(int, + * de.jungblut.math.FloatVector) + */ + @Override + public void setRowVector(int rowIndex, FloatVector row) { + this.setRow(rowIndex, row.toArray()); + } + + /** + * Returns the size of the matrix as string (ROWSxCOLUMNS). + */ + public String sizeToString() { + return numRows + "x" + numColumns; + } + + /** + * Splits the last column from this matrix. Usually used to get a prediction + * column from some machine learning problem. + * + * @return a tuple of a new sliced matrix and a vector which was the last + * column. + */ + public final Tuple<DenseFloatMatrix, DenseFloatVector> splitLastColumn() { + DenseFloatMatrix m = new DenseFloatMatrix(getRowCount(), + getColumnCount() - 1); + for (int i = 0; i < getRowCount(); i++) { + for (int j = 0; j < getColumnCount() - 1; j++) { + m.set(i, j, get(i, j)); + } + } + DenseFloatVector v = new DenseFloatVector(getColumn(getColumnCount() - 1)); + return new Tuple<DenseFloatMatrix, DenseFloatVector>(m, v); + } + + /** + * Creates two matrices out of this by the given percentage. It uses a random + * function to determine which rows should belong to the matrix including the + * given percentage amount of rows. + * + * @param percentage A float value between 0.0f and 1.0f + * @return A tuple which includes two matrices, the first contains the + * percentage of the rows from the original matrix (rows are chosen + * randomly) and the second one contains all other rows. + */ + public final Tuple<DenseFloatMatrix, DenseFloatMatrix> splitRandomMatrices( + float percentage) { + if (percentage < 0.0f || percentage > 1.0f) { + throw new IllegalArgumentException( + "Percentage must be between 0.0 and 1.0! Given " + percentage); + } + + if (percentage == 1.0f) { + return new Tuple<DenseFloatMatrix, DenseFloatMatrix>(this, null); + } else if (percentage == 0.0f) { + return new Tuple<DenseFloatMatrix, DenseFloatMatrix>(null, this); + } + + final Random rand = new Random(System.nanoTime()); + int firstMatrixRowsCount = Math.round(percentage * numRows); + + // we first choose needed rows number of items to pick + final HashSet<Integer> lowerMatrixRowIndices = new HashSet<Integer>(); + int missingRows = firstMatrixRowsCount; + while (missingRows > 0) { + final int nextIndex = rand.nextInt(numRows); + if (lowerMatrixRowIndices.add(nextIndex)) { + missingRows--; + } + } + + // make to new matrixes + final float[][] firstMatrix = new float[firstMatrixRowsCount][numColumns]; + int firstMatrixIndex = 0; + final float[][] secondMatrix = new float[numRows - firstMatrixRowsCount][numColumns]; + int secondMatrixIndex = 0; + + // then we loop over all items and put split the matrix + for (int r = 0; r < numRows; r++) { + if (lowerMatrixRowIndices.contains(r)) { + firstMatrix[firstMatrixIndex++] = matrix[r]; + } else { + secondMatrix[secondMatrixIndex++] = matrix[r]; + } + } + + return new Tuple<DenseFloatMatrix, DenseFloatMatrix>( + new DenseFloatMatrix(firstMatrix), new DenseFloatMatrix(secondMatrix)); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#multiply(float) + */ + @Override + public final DenseFloatMatrix multiply(float scalar) { + DenseFloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] * scalar); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#multiply(de.jungblut.math.FloatMatrix) + */ + @Override + public final FloatMatrix multiplyUnsafe(FloatMatrix other) { + DenseFloatMatrix matrix = new DenseFloatMatrix(this.getRowCount(), + other.getColumnCount()); + + final int m = this.numRows; + final int n = this.numColumns; + final int p = other.getColumnCount(); + + for (int j = p; --j >= 0;) { + for (int i = m; --i >= 0;) { + float s = 0; + for (int k = n; --k >= 0;) { + s += get(i, k) * other.get(k, j); + } + matrix.set(i, j, s + matrix.get(i, j)); + } + } + + return matrix; + } + + /* + * (non-Javadoc) + * @see + * de.jungblut.math.FloatMatrix#multiplyElementWise(de.jungblut.math.FloatMatrix + * ) + */ + @Override + public final FloatMatrix multiplyElementWiseUnsafe(FloatMatrix other) { + DenseFloatMatrix matrix = new DenseFloatMatrix(this.numRows, + this.numColumns); + + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + matrix.set(i, j, this.get(i, j) * (other.get(i, j))); + } + } + + return matrix; + } + + /* + * (non-Javadoc) + * @see + * de.jungblut.math.FloatMatrix#multiplyVector(de.jungblut.math.FloatVector) + */ + @Override + public final FloatVector multiplyVectorUnsafe(FloatVector v) { + FloatVector vector = new DenseFloatVector(this.getRowCount()); + for (int row = 0; row < numRows; row++) { + float sum = 0.0f; + for (int col = 0; col < numColumns; col++) { + sum += (matrix[row][col] * v.get(col)); + } + vector.set(row, sum); + } + + return vector; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#transpose() + */ + @Override + public DenseFloatMatrix transpose() { + DenseFloatMatrix m = new DenseFloatMatrix(this.numColumns, this.numRows); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(j, i, this.matrix[i][j]); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#subtractBy(float) + */ + @Override + public DenseFloatMatrix subtractBy(float amount) { + DenseFloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, amount - this.matrix[i][j]); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#subtract(float) + */ + @Override + public DenseFloatMatrix subtract(float amount) { + DenseFloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] - amount); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#subtract(de.jungblut.math.FloatMatrix) + */ + @Override + public FloatMatrix subtractUnsafe(FloatMatrix other) { + FloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] - other.get(i, j)); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#subtract(de.jungblut.math.FloatVector) + */ + @Override + public DenseFloatMatrix subtractUnsafe(FloatVector vec) { + DenseFloatMatrix cop = new DenseFloatMatrix(this.getRowCount(), + this.getColumnCount()); + for (int i = 0; i < this.getColumnCount(); i++) { + cop.setColumn(i, getColumnVector(i).subtract(vec.get(i)).toArray()); + } + return cop; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#divide(de.jungblut.math.FloatVector) + */ + @Override + public FloatMatrix divideUnsafe(FloatVector vec) { + FloatMatrix cop = new DenseFloatMatrix(this.getRowCount(), + this.getColumnCount()); + for (int i = 0; i < this.getColumnCount(); i++) { + cop.setColumnVector(i, getColumnVector(i).divide(vec.get(i))); + } + return cop; + } + + /** + * {@inheritDoc} + */ + @Override + public FloatMatrix divide(FloatVector vec) { + Preconditions.checkArgument(this.getColumnCount() == vec.getDimension(), + "Dimension mismatch."); + return this.divideUnsafe(vec); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#divide(de.jungblut.math.FloatMatrix) + */ + @Override + public FloatMatrix divideUnsafe(FloatMatrix other) { + FloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] / other.get(i, j)); + } + } + return m; + } + + @Override + public FloatMatrix divide(FloatMatrix other) { + Preconditions.checkArgument(this.getRowCount() == other.getRowCount() + && this.getColumnCount() == other.getColumnCount()); + return divideUnsafe(other); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#divide(float) + */ + @Override + public FloatMatrix divide(float scalar) { + FloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] / scalar); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#add(de.jungblut.math.FloatMatrix) + */ + @Override + public FloatMatrix add(FloatMatrix other) { + FloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, this.matrix[i][j] + other.get(i, j)); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#pow(int) + */ + @Override + public FloatMatrix pow(int x) { + FloatMatrix m = new DenseFloatMatrix(this.numRows, this.numColumns); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + m.set(i, j, (float) Math.pow(matrix[i][j], x)); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#max(int) + */ + @Override + public float max(int column) { + float max = Float.MIN_VALUE; + for (int i = 0; i < getRowCount(); i++) { + float d = matrix[i][column]; + if (d > max) { + max = d; + } + } + return max; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#min(int) + */ + @Override + public float min(int column) { + float min = Float.MAX_VALUE; + for (int i = 0; i < getRowCount(); i++) { + float d = matrix[i][column]; + if (d < min) { + min = d; + } + } + return min; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#slice(int, int) + */ + @Override + public FloatMatrix slice(int rows, int cols) { + return slice(0, rows, 0, cols); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#slice(int, int, int, int) + */ + @Override + public FloatMatrix slice(int rowOffset, int rowMax, int colOffset, int colMax) { + DenseFloatMatrix m = new DenseFloatMatrix(rowMax - rowOffset, colMax + - colOffset); + for (int row = rowOffset; row < rowMax; row++) { + for (int col = colOffset; col < colMax; col++) { + m.set(row - rowOffset, col - colOffset, this.get(row, col)); + } + } + return m; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#isSparse() + */ + @Override + public boolean isSparse() { + return false; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#sum() + */ + @Override + public float sum() { + float x = 0.0f; + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numColumns; j++) { + x += Math.abs(matrix[i][j]); + } + } + return x; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatMatrix#columnIndices() + */ + @Override + public int[] columnIndices() { + int[] x = new int[getColumnCount()]; + for (int i = 0; i < getColumnCount(); i++) + x[i] = i; + return x; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(matrix); + result = prime * result + numColumns; + result = prime * result + numRows; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DenseFloatMatrix other = (DenseFloatMatrix) obj; + if (!Arrays.deepEquals(matrix, other.matrix)) + return false; + if (numColumns != other.numColumns) + return false; + return numRows == other.numRows; + } + + @Override + public String toString() { + if (numRows < 10) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < numRows; i++) { + sb.append(Arrays.toString(matrix[i])); + sb.append('\n'); + } + return sb.toString(); + } else { + return numRows + "x" + numColumns; + } + } + + /** + * Gets the eye matrix (ones on the main diagonal) with a given dimension. + */ + public static DenseFloatMatrix eye(int dimension) { + DenseFloatMatrix m = new DenseFloatMatrix(dimension, dimension); + + for (int i = 0; i < dimension; i++) { + m.set(i, i, 1); + } + + return m; + } + + /** + * Deep copies the given matrix into a new returned one. + */ + public static DenseFloatMatrix copy(DenseFloatMatrix matrix) { + final float[][] src = matrix.getValues(); + final float[][] dest = new float[matrix.getRowCount()][matrix + .getColumnCount()]; + + for (int i = 0; i < dest.length; i++) + System.arraycopy(src[i], 0, dest[i], 0, src[i].length); + + return new DenseFloatMatrix(dest); + } + + /** + * Some strange function I found in octave but I don't know what it was named. + * It does however multiply the elements from the transposed vector and the + * normal vector and sets it into the according indices of a new constructed + * matrix. + */ + public static DenseFloatMatrix multiplyTransposedVectors( + FloatVector transposed, FloatVector normal) { + DenseFloatMatrix m = new DenseFloatMatrix(transposed.getLength(), + normal.getLength()); + for (int row = 0; row < transposed.getLength(); row++) { + for (int col = 0; col < normal.getLength(); col++) { + m.set(row, col, transposed.get(row) * normal.get(col)); + } + } + + return m; + } + + /** + * Just a absolute error function. + */ + public static float error(DenseFloatMatrix a, DenseFloatMatrix b) { + return a.subtractUnsafe(b).sum(); + } + + @Override + /** + * {@inheritDoc} + */ + public FloatMatrix applyToElements(FloatFunction fun) { + for (int r = 0; r < this.numRows; ++r) { + for (int c = 0; c < this.numColumns; ++c) { + this.set(r, c, fun.apply(this.get(r, c))); + } + } + return this; + } + + @Override + /** + * {@inheritDoc} + */ + public FloatMatrix applyToElements(FloatMatrix other, + FloatFloatFunction fun) { + Preconditions + .checkArgument(this.numRows == other.getRowCount() + && this.numColumns == other.getColumnCount(), + "Cannot apply float float function to matrices with different sizes."); + + for (int r = 0; r < this.numRows; ++r) { + for (int c = 0; c < this.numColumns; ++c) { + this.set(r, c, fun.apply(this.get(r, c), other.get(r, c))); + } + } + + return this; + } + + /* + * (non-Javadoc) + * @see + * org.apache.hama.ml.math.FloatMatrix#safeMultiply(org.apache.hama.ml.math + * .FloatMatrix) + */ + @Override + public FloatMatrix multiply(FloatMatrix other) { + Preconditions + .checkArgument( + this.numColumns == other.getRowCount(), + String + .format( + "Matrix with size [%d, %d] cannot multiple matrix with size [%d, %d]", + this.numRows, this.numColumns, other.getRowCount(), + other.getColumnCount())); + + return this.multiplyUnsafe(other); + } + + /* + * (non-Javadoc) + * @see + * org.apache.hama.ml.math.FloatMatrix#safeMultiplyElementWise(org.apache + * .hama.ml.math.FloatMatrix) + */ + @Override + public FloatMatrix multiplyElementWise(FloatMatrix other) { + Preconditions.checkArgument(this.numRows == other.getRowCount() + && this.numColumns == other.getColumnCount(), + "Matrices with different dimensions cannot be multiplied elementwise."); + return this.multiplyElementWiseUnsafe(other); + } + + /* + * (non-Javadoc) + * @see + * org.apache.hama.ml.math.FloatMatrix#safeMultiplyVector(org.apache.hama + * .ml.math.FloatVector) + */ + @Override + public FloatVector multiplyVector(FloatVector v) { + Preconditions.checkArgument(this.numColumns == v.getDimension(), + "Dimension mismatch."); + return this.multiplyVectorUnsafe(v); + } + + /* + * (non-Javadoc) + * @see org.apache.hama.ml.math.FloatMatrix#subtract(org.apache.hama.ml.math. + * FloatMatrix) + */ + @Override + public FloatMatrix subtract(FloatMatrix other) { + Preconditions.checkArgument(this.numRows == other.getRowCount() + && this.numColumns == other.getColumnCount(), "Dimension mismatch."); + return subtractUnsafe(other); + } + + /* + * (non-Javadoc) + * @see org.apache.hama.ml.math.FloatMatrix#subtract(org.apache.hama.ml.math. + * FloatVector) + */ + @Override + public FloatMatrix subtract(FloatVector vec) { + Preconditions.checkArgument(this.numColumns == vec.getDimension(), + "Dimension mismatch."); + return null; + } + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/DenseFloatVector.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/DenseFloatVector.java b/commons/src/main/java/org/apache/hama/commons/math/DenseFloatVector.java new file mode 100644 index 0000000..367da9e --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/DenseFloatVector.java @@ -0,0 +1,714 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import com.google.common.base.Preconditions; +import com.google.common.collect.AbstractIterator; + +public final class DenseFloatVector implements FloatVector { + + + private float[] vector; + + public DenseFloatVector() { } + + /** + * Creates a new vector with the given length. + */ + public DenseFloatVector(int length) { + this.vector = new float[length]; + } + + /** + * Creates a new vector with the given length and default value. + */ + public DenseFloatVector(int length, float val) { + this(length); + Arrays.fill(vector, val); + } + + /** + * Creates a new vector with the given array. + */ + public DenseFloatVector(float[] arr) { + this.vector = arr; + } + + /** + * Creates a new vector with the given array and the last value f1. + */ + public DenseFloatVector(float[] array, float f1) { + this.vector = new float[array.length + 1]; + System.arraycopy(array, 0, this.vector, 0, array.length); + this.vector[array.length] = f1; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#get(int) + */ + @Override + public final float get(int index) { + return vector[index]; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#getLength() + */ + @Override + public final int getLength() { + return vector.length; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#getDimension() + */ + @Override + public int getDimension() { + return getLength(); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#set(int, float) + */ + @Override + public final void set(int index, float value) { + vector[index] = value; + } + + /** + * Apply a function to the element of the vector and returns a result vector. + * Note that the function is applied on the copy of the original vector. + */ + @Override + public FloatVector applyToElements(FloatFunction func) { + FloatVector newVec = new DenseFloatVector(this.getDimension()); + for (int i = 0; i < vector.length; i++) { + newVec.set(i, func.apply(vector[i])); + } + return newVec; + } + + /** + * Apply a function to the element of the vector and another vector, and then returns a result vector. + * Note that the function is applied on the copy of the original vectors. + */ + @Override + public FloatVector applyToElements(FloatVector other, + FloatFloatFunction func) { + FloatVector newVec = new DenseFloatVector(this.getDimension()); + for (int i = 0; i < vector.length; i++) { + newVec.set(i, func.apply(vector[i], other.get(i))); + } + return newVec; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#add(de.jungblut.math.FloatVector) + */ + @Override + public final FloatVector addUnsafe(FloatVector v) { + DenseFloatVector newv = new DenseFloatVector(v.getLength()); + for (int i = 0; i < v.getLength(); i++) { + newv.set(i, this.get(i) + v.get(i)); + } + return newv; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#add(float) + */ + @Override + public final FloatVector add(float scalar) { + FloatVector newv = new DenseFloatVector(this.getLength()); + for (int i = 0; i < this.getLength(); i++) { + newv.set(i, this.get(i) + scalar); + } + return newv; + } + + @Override + public final FloatVector subtractUnsafe(FloatVector v) { + FloatVector newv = new DenseFloatVector(v.getLength()); + for (int i = 0; i < v.getLength(); i++) { + newv.set(i, this.get(i) - v.get(i)); + } + return newv; + } + + @Override + public final FloatVector subtract(float v) { + DenseFloatVector newv = new DenseFloatVector(vector.length); + for (int i = 0; i < vector.length; i++) { + newv.set(i, vector[i] - v); + } + return newv; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#subtractFrom(float) + */ + @Override + public final FloatVector subtractFrom(float v) { + DenseFloatVector newv = new DenseFloatVector(vector.length); + for (int i = 0; i < vector.length; i++) { + newv.set(i, v - vector[i]); + } + return newv; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#multiply(float) + */ + @Override + public FloatVector multiply(float scalar) { + FloatVector v = new DenseFloatVector(this.getLength()); + for (int i = 0; i < v.getLength(); i++) { + v.set(i, this.get(i) * scalar); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#multiply(de.jungblut.math.FloatVector) + */ + @Override + public FloatVector multiplyUnsafe(FloatVector vector) { + FloatVector v = new DenseFloatVector(this.getLength()); + for (int i = 0; i < v.getLength(); i++) { + v.set(i, this.get(i) * vector.get(i)); + } + return v; + } + + @Override + public FloatVector multiply(FloatMatrix matrix) { + Preconditions.checkArgument(this.vector.length == matrix.getRowCount(), + "Dimension mismatch when multiply a vector to a matrix."); + return this.multiplyUnsafe(matrix); + } + + @Override + public FloatVector multiplyUnsafe(FloatMatrix matrix) { + FloatVector vec = new DenseFloatVector(matrix.getColumnCount()); + for (int i = 0; i < vec.getDimension(); ++i) { + vec.set(i, this.multiplyUnsafe(matrix.getColumnVector(i)).sum()); + } + return vec; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#divide(float) + */ + @Override + public FloatVector divide(float scalar) { + DenseFloatVector v = new DenseFloatVector(this.getLength()); + for (int i = 0; i < v.getLength(); i++) { + v.set(i, this.get(i) / scalar); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#pow(int) + */ + @Override + public FloatVector pow(int x) { + DenseFloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < v.getLength(); i++) { + float value = 0.0f; + // it is faster to multiply when we having ^2 + if (x == 2) { + value = vector[i] * vector[i]; + } else { + value = (float) Math.pow(vector[i], x); + } + v.set(i, value); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#sqrt() + */ + @Override + public FloatVector sqrt() { + FloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < v.getLength(); i++) { + v.set(i, (float) Math.sqrt(vector[i])); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#sum() + */ + @Override + public float sum() { + float sum = 0.0f; + for (float aVector : vector) { + sum += aVector; + } + return sum; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#abs() + */ + @Override + public FloatVector abs() { + FloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < v.getLength(); i++) { + v.set(i, Math.abs(vector[i])); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#divideFrom(float) + */ + @Override + public FloatVector divideFrom(float scalar) { + FloatVector v = new DenseFloatVector(this.getLength()); + for (int i = 0; i < v.getLength(); i++) { + if (this.get(i) != 0.0d) { + float result = scalar / this.get(i); + v.set(i, result); + } else { + v.set(i, 0.0f); + } + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#dot(de.jungblut.math.FloatVector) + */ + @Override + public float dotUnsafe(FloatVector vector) { + BigDecimal dotProduct = BigDecimal.valueOf(0.0d); + for (int i = 0; i < getLength(); i++) { + dotProduct = dotProduct.add(BigDecimal.valueOf(this.get(i)).multiply(BigDecimal.valueOf(vector.get(i)))); + } + return dotProduct.floatValue(); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#slice(int) + */ + @Override + public FloatVector slice(int length) { + return slice(0, length - 1); + } + + @Override + public FloatVector sliceUnsafe(int length) { + return sliceUnsafe(0, length - 1); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#slice(int, int) + */ + @Override + public FloatVector slice(int start, int end) { + Preconditions.checkArgument(start >= 0 && start <= end + && end < vector.length, "The given from and to is invalid"); + + return sliceUnsafe(start, end); + } + + /** + * Get a subset of the original vector starting from 'start' and end to 'end', + * with both ends inclusive. + */ + @Override + public FloatVector sliceUnsafe(int start, int end) { + FloatVector newVec = new DenseFloatVector(end - start + 1); + for (int i = start, j = 0; i <= end; ++i, ++j) { + newVec.set(j, vector[i]); + } + + return newVec; + } + + /* + * Return the maximum. + */ + @Override + public float max() { + float max = -Float.MAX_VALUE; + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + if (d > max) { + max = d; + } + } + return max; + } + + /** + * Return the index of the first maximum. + * @return the index where the maximum resides. + */ + public int maxIndex() { + float max = -Float.MAX_VALUE; + int maxIndex = 0; + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + if (d > max) { + max = d; + maxIndex = i; + } + } + return maxIndex; + } + + /* + * Return the minimum. + */ + @Override + public float min() { + float min = Float.MAX_VALUE; + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + if (d < min) { + min = d; + } + } + return min; + } + + /** + * Return the index of the first minimum. + * @return the index where the minimum resides. + */ + public int minIndex() { + float min = Float.MAX_VALUE; + int minIndex = 0; + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + if (d < min) { + min = d; + minIndex = i; + } + } + return minIndex; + } + + /** + * Round each of the element in the vector to the integer. + * @return a new vector which has rinted each element. + */ + public DenseFloatVector rint() { + DenseFloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + v.set(i, (float) Math.rint(d)); + } + return v; + } + + /** + * @return a new vector which has rounded each element. + */ + public DenseFloatVector round() { + DenseFloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + v.set(i, Math.round(d)); + } + return v; + } + + /** + * @return a new vector which has ceiled each element. + */ + public DenseFloatVector ceil() { + DenseFloatVector v = new DenseFloatVector(getLength()); + for (int i = 0; i < getLength(); i++) { + float d = vector[i]; + v.set(i, (float) Math.ceil(d)); + } + return v; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#toArray() + */ + @Override + public final float[] toArray() { + return vector; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#isSparse() + */ + @Override + public boolean isSparse() { + return false; + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#deepCopy() + */ + @Override + public FloatVector deepCopy() { + final float[] src = vector; + final float[] dest = new float[vector.length]; + System.arraycopy(src, 0, dest, 0, vector.length); + return new DenseFloatVector(dest); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#iterateNonZero() + */ + @Override + public Iterator<FloatVectorElement> iterateNonDefault() { + return new NonDefaultIterator(); + } + + /* + * (non-Javadoc) + * @see de.jungblut.math.FloatVector#iterate() + */ + @Override + public Iterator<FloatVectorElement> iterate() { + return new DefaultIterator(); + } + + @Override + public final String toString() { + if (getLength() < 20) { + return Arrays.toString(vector); + } else { + return getLength() + "x1"; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(vector); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DenseFloatVector other = (DenseFloatVector) obj; + return Arrays.equals(vector, other.vector); + } + + /** + * Non-default iterator for vector elements. + */ + private final class NonDefaultIterator extends + AbstractIterator<FloatVectorElement> { + + private final FloatVectorElement element = new FloatVectorElement(); + private final float[] array; + private int currentIndex = 0; + + private NonDefaultIterator() { + this.array = vector; + } + + @Override + protected final FloatVectorElement computeNext() { + if (currentIndex >= array.length) { + return endOfData(); + } + while (array[currentIndex] == 0.0d) { + currentIndex++; + if (currentIndex >= array.length) + return endOfData(); + } + element.setIndex(currentIndex); + element.setValue(array[currentIndex]); + ++currentIndex; + return element; + } + } + + /** + * Iterator for all elements. + */ + private final class DefaultIterator extends + AbstractIterator<FloatVectorElement> { + + private final FloatVectorElement element = new FloatVectorElement(); + private final float[] array; + private int currentIndex = 0; + + private DefaultIterator() { + this.array = vector; + } + + @Override + protected final FloatVectorElement computeNext() { + if (currentIndex < array.length) { + element.setIndex(currentIndex); + element.setValue(array[currentIndex]); + currentIndex++; + return element; + } else { + return endOfData(); + } + } + + } + + /** + * Generate a vector with all element to be 1. + * @return a new vector with dimension num and a default value of 1. + */ + public static DenseFloatVector ones(int num) { + return new DenseFloatVector(num, 1.0f); + } + + /** + * Generate a vector whose elements are in increasing order, + * where the start value is 'from', end value is 'to', with increment 'stepsize'. + * @return a new vector filled from index, to index, with a given stepsize. + */ + public static DenseFloatVector fromUpTo(float from, float to, + float stepsize) { + DenseFloatVector v = new DenseFloatVector( + (int) (Math.round(((to - from) / stepsize) + 0.5))); + + for (int i = 0; i < v.getLength(); i++) { + v.set(i, from + i * stepsize); + } + return v; + } + + /** + * Some crazy sort function. + */ + public static List<Tuple<Float, Integer>> sort(FloatVector vector, + final Comparator<Float> scoreComparator) { + List<Tuple<Float, Integer>> list = new ArrayList<Tuple<Float, Integer>>( + vector.getLength()); + for (int i = 0; i < vector.getLength(); i++) { + list.add(new Tuple<Float, Integer>(vector.get(i), i)); + } + Collections.sort(list, new Comparator<Tuple<Float, Integer>>() { + @Override + public int compare(Tuple<Float, Integer> o1, Tuple<Float, Integer> o2) { + return scoreComparator.compare(o1.getFirst(), o2.getFirst()); + } + }); + return list; + } + + @Override + public boolean isNamed() { + return false; + } + + @Override + public String getName() { + return null; + } + + /* + * (non-Javadoc) + * @see org.apache.hama.ml.math.FloatVector#safeAdd(org.apache.hama.ml.math. + * FloatVector) + */ + @Override + public FloatVector add(FloatVector vector) { + Preconditions.checkArgument(this.vector.length == vector.getDimension(), + "Dimensions of two vectors do not equal."); + return this.addUnsafe(vector); + } + + /* + * (non-Javadoc) + * @see + * org.apache.hama.ml.math.FloatVector#safeSubtract(org.apache.hama.ml.math + * .FloatVector) + */ + @Override + public FloatVector subtract(FloatVector vector) { + Preconditions.checkArgument(this.vector.length == vector.getDimension(), + "Dimensions of two vectors do not equal."); + return this.subtractUnsafe(vector); + } + + /* + * (non-Javadoc) + * @see + * org.apache.hama.ml.math.FloatVector#safeMultiplay(org.apache.hama.ml.math + * .FloatVector) + */ + @Override + public FloatVector multiply(FloatVector vector) { + Preconditions.checkArgument(this.vector.length == vector.getDimension(), + "Dimensions of two vectors do not equal."); + return this.multiplyUnsafe(vector); + } + + /* + * (non-Javadoc) + * @see org.apache.hama.ml.math.FloatVector#safeDot(org.apache.hama.ml.math. + * FloatVector) + */ + @Override + public float dot(FloatVector vector) { + Preconditions.checkArgument(this.vector.length == vector.getDimension(), + "Dimensions of two vectors do not equal."); + return this.dotUnsafe(vector); + } + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/FloatFloatFunction.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/FloatFloatFunction.java b/commons/src/main/java/org/apache/hama/commons/math/FloatFloatFunction.java new file mode 100644 index 0000000..ad32472 --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/FloatFloatFunction.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +public abstract class FloatFloatFunction extends Function { + + /** + * Apply the function to elements to two given arguments. + * + * @param x1 + * @param x2 + * @return The result based on the calculation on two arguments. + */ + public abstract float apply(float x1, float x2); + + /** + * Apply the derivative of this function to two given arguments. + * + * @param x1 + * @param x2 + * @return The result based on the calculation on two arguments. + */ + public abstract float applyDerivative(float x1, float x2); + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/FloatFunction.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/FloatFunction.java b/commons/src/main/java/org/apache/hama/commons/math/FloatFunction.java new file mode 100644 index 0000000..012b6bc --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/FloatFunction.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +public abstract class FloatFunction extends Function { + + /** + * Apply the function to element. + * + * @param value The element that the function apply to. + * @return The result after applying the function. + */ + public abstract float apply(float value); + + /** + * Apply the gradient of the function. + * + * @param value + * @return The result after applying the function. + */ + public abstract float applyDerivative(float value); + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/FloatMatrix.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/FloatMatrix.java b/commons/src/main/java/org/apache/hama/commons/math/FloatMatrix.java new file mode 100644 index 0000000..39c0fb0 --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/FloatMatrix.java @@ -0,0 +1,269 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +public interface FloatMatrix { + + /** + * Not flagged value for sparse matrices, it is default to 0.0f. + */ + public static final float NOT_FLAGGED = 0.0f; + + /** + * Get a specific value of the matrix. + * + * @return Returns the integer value at in the column at the row. + */ + public float get(int row, int col); + + /** + * Returns the number of columns in the matrix. Always a constant time + * operation. + */ + public int getColumnCount(); + + /** + * Get a whole column of the matrix as vector. + */ + public FloatVector getColumnVector(int col); + + /** + * Returns the number of rows in this matrix. Always a constant time + * operation. + */ + public int getRowCount(); + + /** + * Get a single row of the matrix as a vector. + */ + public FloatVector getRowVector(int row); + + /** + * Sets the value at the given row and column index. + */ + public void set(int row, int col, float value); + + /** + * Sets a whole column at index col with the given vector. + */ + public void setColumnVector(int col, FloatVector column); + + /** + * Sets the whole row at index rowIndex with the given vector. + */ + public void setRowVector(int rowIndex, FloatVector row); + + /** + * Multiplies this matrix (each element) with the given scalar and returns a + * new matrix. + */ + public FloatMatrix multiply(float scalar); + + /** + * Multiplies this matrix with the given other matrix. + * + * @param other the other matrix. + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix multiplyUnsafe(FloatMatrix other); + + /** + * Validates the input and multiplies this matrix with the given other matrix. + * + * @param other the other matrix. + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix multiply(FloatMatrix other); + + /** + * Multiplies this matrix per element with a given matrix. + */ + public FloatMatrix multiplyElementWiseUnsafe(FloatMatrix other); + + /** + * Validates the input and multiplies this matrix per element with a given + * matrix. + * + * @param other the other matrix + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix multiplyElementWise(FloatMatrix other); + + /** + * Multiplies this matrix with a given vector v. The returning vector contains + * the sum of the rows. + */ + public FloatVector multiplyVectorUnsafe(FloatVector v); + + /** + * Multiplies this matrix with a given vector v. The returning vector contains + * the sum of the rows. + * + * @param v the vector + * @return a new vector with the result of the operation. + */ + public FloatVector multiplyVector(FloatVector v); + + /** + * Transposes this matrix. + */ + public FloatMatrix transpose(); + + /** + * Substracts the given amount by each element in this matrix. <br/> + * = (amount - matrix value) + */ + public FloatMatrix subtractBy(float amount); + + /** + * Subtracts each element in this matrix by the given amount.<br/> + * = (matrix value - amount) + */ + public FloatMatrix subtract(float amount); + + /** + * Subtracts this matrix by the given other matrix. + */ + public FloatMatrix subtractUnsafe(FloatMatrix other); + + /** + * Validates the input and subtracts this matrix by the given other matrix. + * + * @param other + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix subtract(FloatMatrix other); + + /** + * Subtracts each element in a column by the related element in the given + * vector. + */ + public FloatMatrix subtractUnsafe(FloatVector vec); + + /** + * Validates and subtracts each element in a column by the related element in + * the given vector. + * + * @param vec + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix subtract(FloatVector vec); + + /** + * Divides each element in a column by the related element in the given + * vector. + */ + public FloatMatrix divideUnsafe(FloatVector vec); + + /** + * Validates and divides each element in a column by the related element in + * the given vector. + * + * @param vec + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix divide(FloatVector vec); + + /** + * Divides this matrix by the given other matrix. (Per element division). + */ + public FloatMatrix divideUnsafe(FloatMatrix other); + + /** + * Validates and divides this matrix by the given other matrix. (Per element + * division). + * + * @param other + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix divide(FloatMatrix other); + + /** + * Divides each element in this matrix by the given scalar. + */ + public FloatMatrix divide(float scalar); + + /** + * Adds the elements in the given matrix to the elements in this matrix. + */ + public FloatMatrix add(FloatMatrix other); + + /** + * Pows each element by the given argument. <br/> + * = (matrix element^x) + */ + public FloatMatrix pow(int x); + + /** + * Returns the maximum value of the given column. + */ + public float max(int column); + + /** + * Returns the minimum value of the given column. + */ + public float min(int column); + + /** + * Sums all elements. + */ + public float sum(); + + /** + * Returns an array of column indices existing in this matrix. + */ + public int[] columnIndices(); + + /** + * Returns true if the underlying implementation is sparse. + */ + public boolean isSparse(); + + /** + * Slices the given matrix from 0-rows and from 0-columns. + */ + public FloatMatrix slice(int rows, int cols); + + /** + * Slices the given matrix from rowOffset-rowMax and from colOffset-colMax. + */ + public FloatMatrix slice(int rowOffset, int rowMax, int colOffset, int colMax); + + /** + * Apply a float function f(x) onto each element of the matrix. After + * applying, each element of the current matrix will be changed from x to + * f(x). + * + * @param fun The function. + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix applyToElements(FloatFunction fun); + + /** + * Apply a float float function f(x, y) onto each pair of the current matrix + * elements and given matrix. After applying, each element of the current + * matrix will be changed from x to f(x, y). + * + * @param other The matrix contributing the second argument of the function. + * @param fun The function that takes two arguments. + * @return The matrix itself, supply for chain operation. + */ + public FloatMatrix applyToElements(FloatMatrix other, + FloatFloatFunction fun); + +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/FloatVector.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/FloatVector.java b/commons/src/main/java/org/apache/hama/commons/math/FloatVector.java new file mode 100644 index 0000000..3725e8f --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/FloatVector.java @@ -0,0 +1,366 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +import java.util.Iterator; + +public interface FloatVector { + + + /** + * Retrieves the value at given index. + * + * @param index the index. + * @return a float value at the index. + */ + public float get(int index); + + /** + * Get the length of a vector, for sparse instance it is the actual length. + * (not the dimension!) Always a constant time operation. + * + * @return the length of the vector. + */ + public int getLength(); + + /** + * Get the dimension of a vector, for dense instance it is the same like the + * length, for sparse instances it is usually not the same. Always a constant + * time operation. + * + * @return the dimension of the vector. + */ + public int getDimension(); + + /** + * Set a value at the given index. + * + * @param index the index of the vector to set. + * @param value the value at the index of the vector to set. + */ + public void set(int index, float value); + + /** + * Apply a given {@link FloatVectorFunction} to this vector and return a new + * one. + * + * @param func the function to apply. + * @return a new vector with the applied function. + */ + public FloatVector applyToElements(FloatFunction func); + + /** + * Apply a given {@link DoubleFloatVectorFunction} to this vector and the + * other given vector. + * + * @param other the other vector. + * @param func the function to apply on this and the other vector. + * @return a new vector with the result of the function of the two vectors. + */ + public FloatVector applyToElements(FloatVector other, + FloatFloatFunction func); + + /** + * Adds the given {@link FloatVector} to this vector. + * + * @param vector the other vector. + * @return a new vector with the sum of both vectors at each element index. + */ + public FloatVector addUnsafe(FloatVector vector); + + /** + * Validates the input and adds the given {@link FloatVector} to this vector. + * + * @param vector the other vector. + * @return a new vector with the sum of both vectors at each element index. + */ + public FloatVector add(FloatVector vector); + + /** + * Adds the given scalar to this vector. + * + * @param scalar the scalar. + * @return a new vector with the result at each element index. + */ + public FloatVector add(float scalar); + + /** + * Subtracts this vector by the given {@link FloatVector}. + * + * @param vector the other vector. + * @return a new vector with the difference of both vectors. + */ + public FloatVector subtractUnsafe(FloatVector vector); + + /** + * Validates the input and subtracts this vector by the given + * {@link FloatVector}. + * + * @param vector the other vector. + * @return a new vector with the difference of both vectors. + */ + public FloatVector subtract(FloatVector vector); + + /** + * Subtracts the given scalar to this vector. (vector - scalar). + * + * @param scalar the scalar. + * @return a new vector with the result at each element index. + */ + public FloatVector subtract(float scalar); + + /** + * Subtracts the given scalar from this vector. (scalar - vector). + * + * @param scalar the scalar. + * @return a new vector with the result at each element index. + */ + public FloatVector subtractFrom(float scalar); + + /** + * Multiplies the given scalar to this vector. + * + * @param scalar the scalar. + * @return a new vector with the result of the operation. + */ + public FloatVector multiply(float scalar); + + /** + * Multiplies the given {@link FloatVector} with this vector. + * + * @param vector the other vector. + * @return a new vector with the result of the operation. + */ + public FloatVector multiplyUnsafe(FloatVector vector); + + /** + * Validates the input and multiplies the given {@link FloatVector} with this + * vector. + * + * @param vector the other vector. + * @return a new vector with the result of the operation. + */ + public FloatVector multiply(FloatVector vector); + + /** + * Validates the input and multiplies the given {@link FloatMatrix} with this + * vector. + * + * @param matrix + * @return a new vector with the result of the operation. + */ + public FloatVector multiply(FloatMatrix matrix); + + /** + * Multiplies the given {@link FloatMatrix} with this vector. + * + * @param matrix + * @return a new vector with the result of the operation. + */ + public FloatVector multiplyUnsafe(FloatMatrix matrix); + + /** + * Divides this vector by the given scalar. (= vector/scalar). + * + * @param scalar the given scalar. + * @return a new vector with the result of the operation. + */ + public FloatVector divide(float scalar); + + /** + * Divides the given scalar by this vector. (= scalar/vector). + * + * @param scalar the given scalar. + * @return a new vector with the result of the operation. + */ + public FloatVector divideFrom(float scalar); + + /** + * Powers this vector by the given amount. (=vector^x). + * + * @param x the given exponent. + * @return a new vector with the result of the operation. + */ + public FloatVector pow(int x); + + /** + * Absolutes the vector at each element. + * + * @return a new vector that does not contain negative values anymore. + */ + public FloatVector abs(); + + /** + * Square-roots each element. + * + * @return a new vector. + */ + public FloatVector sqrt(); + + /** + * @return the sum of all elements in this vector. + */ + public float sum(); + + /** + * Calculates the dot product between this vector and the given vector. + * + * @param vector the given vector. + * @return the dot product as a float. + */ + public float dotUnsafe(FloatVector vector); + + /** + * Validates the input and calculates the dot product between this vector and + * the given vector. + * + * @param vector the given vector. + * @return the dot product as a float. + */ + public float dot(FloatVector vector); + + /** + * Validates the input and slices this vector from index 0 to the given + * length. + * + * @param length must be > 0 and smaller than the dimension of the vector. + * @return a new vector that is only length long. + */ + public FloatVector slice(int length); + + /** + * Slices this vector from index 0 to the given length. + * + * @param length must be > 0 and smaller than the dimension of the vector. + * @return a new vector that is only length long. + */ + public FloatVector sliceUnsafe(int length); + + /** + * Validates the input and then slices this vector from start to end, both are + * INCLUSIVE. For example vec = [0, 1, 2, 3, 4, 5], vec.slice(2, 5) = [2, 3, + * 4, 5]. + * + * @param start must be >= 0 and smaller than the dimension of the vector + * @param end must be >= 0 and smaller than the dimension of the vector. + * This must be greater than or equal to the start. + * @return a new vector that is only (length) long. + */ + public FloatVector slice(int start, int end); + + /** + * Slices this vector from start to end, both are INCLUSIVE. For example vec = + * [0, 1, 2, 3, 4, 5], vec.slice(2, 5) = [2, 3, 4, 5]. + * + * @param start must be >= 0 and smaller than the dimension of the vector + * @param end must be >= 0 and smaller than the dimension of the vector. + * This must be greater than or equal to the start. + * @return a new vector that is only (length) long. + */ + public FloatVector sliceUnsafe(int start, int end); + + /** + * @return the maximum element value in this vector. + */ + public float max(); + + /** + * @return the minimum element value in this vector. + */ + public float min(); + + /** + * @return an array representation of this vector. + */ + public float[] toArray(); + + /** + * @return a fresh new copy of this vector, copies all elements to a new + * vector. (Does not reuse references or stuff). + */ + public FloatVector deepCopy(); + + /** + * @return an iterator that only iterates over non default elements. + */ + public Iterator<FloatVectorElement> iterateNonDefault(); + + /** + * @return an iterator that iterates over all elements. + */ + public Iterator<FloatVectorElement> iterate(); + + /** + * Return whether the vector is a sparse vector. + * @return true if this instance is a sparse vector. Smarter and faster than + * instanceof. + */ + public boolean isSparse(); + + /** + * Return whether the vector is a named vector. + * @return true if this instance is a named vector.Smarter and faster than + * instanceof. + */ + public boolean isNamed(); + + /** + * Get the name of the vector. + * + * @return If this vector is a named instance, this will return its name. Or + * null if this is not a named instance. + * + */ + public String getName(); + + /** + * Class for iteration of elements, consists of an index and a value at this + * index. Can be reused for performance purposes. + */ + public static final class FloatVectorElement { + + private int index; + private float value; + + public FloatVectorElement() { + super(); + } + + public FloatVectorElement(int index, float value) { + super(); + this.index = index; + this.value = value; + } + + public final int getIndex() { + return index; + } + + public final float getValue() { + return value; + } + + public final void setIndex(int in) { + this.index = in; + } + + public final void setValue(float in) { + this.value = in; + } + } +} http://git-wip-us.apache.org/repos/asf/hama/blob/fb28bcbc/commons/src/main/java/org/apache/hama/commons/math/NamedFloatVector.java ---------------------------------------------------------------------- diff --git a/commons/src/main/java/org/apache/hama/commons/math/NamedFloatVector.java b/commons/src/main/java/org/apache/hama/commons/math/NamedFloatVector.java new file mode 100644 index 0000000..844c32f --- /dev/null +++ b/commons/src/main/java/org/apache/hama/commons/math/NamedFloatVector.java @@ -0,0 +1,233 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.commons.math; + +import java.util.Iterator; + +public class NamedFloatVector implements FloatVector { + + private final String name; + private final FloatVector vector; + + public NamedFloatVector(String name, FloatVector deepCopy) { + super(); + this.name = name; + this.vector = deepCopy; + } + + @Override + public float get(int index) { + return vector.get(index); + } + + @Override + public int getLength() { + return vector.getLength(); + } + + @Override + public int getDimension() { + return vector.getDimension(); + } + + @Override + public void set(int index, float value) { + vector.set(index, value); + } + + @Override + public FloatVector applyToElements(FloatFunction func) { + return vector.applyToElements(func); + } + + @Override + public FloatVector applyToElements(FloatVector other, FloatFloatFunction func) { + return vector.applyToElements(other, func); + } + + @Override + public FloatVector addUnsafe(FloatVector vector2) { + return vector.addUnsafe(vector2); + } + + @Override + public FloatVector add(FloatVector vector2) { + return vector.add(vector2); + } + + @Override + public FloatVector add(float scalar) { + return vector.add(scalar); + } + + @Override + public FloatVector subtractUnsafe(FloatVector vector2) { + return vector.subtractUnsafe(vector2); + } + + @Override + public FloatVector subtract(FloatVector vector2) { + return vector.subtract(vector2); + } + + @Override + public FloatVector subtract(float scalar) { + return vector.subtract(scalar); + } + + @Override + public FloatVector subtractFrom(float scalar) { + return vector.subtractFrom(scalar); + } + + @Override + public FloatVector multiply(float scalar) { + return vector.multiply(scalar); + } + + @Override + public FloatVector multiplyUnsafe(FloatVector vector2) { + return vector.multiplyUnsafe(vector2); + } + + @Override + public FloatVector multiply(FloatVector vector2) { + return vector.multiply(vector2); + } + + @Override + public FloatVector multiply(FloatMatrix matrix) { + return vector.multiply(matrix); + } + + @Override + public FloatVector multiplyUnsafe(FloatMatrix matrix) { + return vector.multiplyUnsafe(matrix); + } + + @Override + public FloatVector divide(float scalar) { + return vector.divide(scalar); + } + + @Override + public FloatVector divideFrom(float scalar) { + return vector.divideFrom(scalar); + } + + @Override + public FloatVector pow(int x) { + return vector.pow(x); + } + + @Override + public FloatVector abs() { + return vector.abs(); + } + + @Override + public FloatVector sqrt() { + return vector.sqrt(); + } + + @Override + public float sum() { + return vector.sum(); + } + + @Override + public float dotUnsafe(FloatVector vector2) { + return vector.dotUnsafe(vector2); + } + + @Override + public float dot(FloatVector vector2) { + return vector.dot(vector2); + } + + @Override + public FloatVector slice(int length) { + return vector.slice(length); + } + + @Override + public FloatVector sliceUnsafe(int length) { + return vector.sliceUnsafe(length); + } + + @Override + public FloatVector slice(int start, int end) { + return vector.slice(start, end); + } + + @Override + public FloatVector sliceUnsafe(int start, int end) { + return vector.sliceUnsafe(start, end); + } + + @Override + public float max() { + return vector.max(); + } + + @Override + public float min() { + return vector.min(); + } + + @Override + public float[] toArray() { + return vector.toArray(); + } + + @Override + public FloatVector deepCopy() { + return new NamedFloatVector(name, vector.deepCopy()); + } + + @Override + public Iterator<FloatVectorElement> iterateNonDefault() { + return vector.iterateNonDefault(); + } + + @Override + public Iterator<FloatVectorElement> iterate() { + return vector.iterate(); + } + + @Override + public boolean isSparse() { + return vector.isSparse(); + } + + @Override + public boolean isNamed() { + return true; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return String.format("%s: %s", name, vector.toString()); + } + +}
