/** * Creates a new matrix consisting out of polynomials of the input matrix.<br/> * Considering you want to do a 2 polynomial out of 3 columns you get:<br/> * (SEED: x^1 | y^1 | z^1 )| x^2 | y^2 | z^2 for the columns of the returned * matrix. * * @param seed matrix to add polynoms of it. * @param num how many polynoms, 2 for quadratic, 3 for cubic and so forth. * @return the new matrix. */ public static DenseDoubleMatrix createPolynomials(DenseDoubleMatrix seed, int num) { if (num == 1) return seed; DenseDoubleMatrix m = new DenseDoubleMatrix(seed.getRowCount(), seed.getColumnCount() * num); int index = 0; for (int c = 0; c < m.getColumnCount(); c += num) { double[] column = seed.getColumn(index++); m.setColumn(c, column); for (int i = 2; i < num + 1; i++) { DoubleVector pow = new DenseDoubleVector(column).pow(i); m.setColumn(c + i - 1, pow.toArray()); } } return m; }
@Override public DoubleMatrix slice(int rowOffset, int rowMax, int colOffset, int colMax) { DenseDoubleMatrix m = new DenseDoubleMatrix(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; }
@Override public DenseDoubleMatrix subtract(DoubleVector vec) { DenseDoubleMatrix cop = new DenseDoubleMatrix(this.getRowCount(), this.getColumnCount()); for (int i = 0; i < this.getColumnCount(); i++) { cop.setColumnVector(i, getColumnVector(i).subtract(vec)); } return cop; }
@Override public double[][] toArray() { double[][] mat = new double[getRowCount()][getColumnCount()]; int index = 0; for (int col = 0; col < getColumnCount(); col++) { for (int row = 0; row < getRowCount(); row++) { mat[row][col] = matrix[index++]; } } return mat; }
@Override public double max(int column) { double max = Double.MIN_VALUE; int offset = translate(0, column, numRows); for (int i = 0; i < getRowCount(); i++) { double d = matrix[offset + i]; if (d > max) { max = d; } } return max; }
/** * Reads a dense matrix from the given input stream. * * @param in the input stream. * @return a new dense matrix from the stream. * @throws IOException in case of an IO error. */ public static DenseDoubleMatrix readDenseMatrix(DataInput in) throws IOException { DenseDoubleMatrix mat = new DenseDoubleMatrix(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.readDouble()); } } return mat; }
@Override public DenseDoubleMatrix subtract(double amount) { double[] csjr = new double[this.numRows * this.numColumns]; for (int i = 0; i < matrix.length; i++) { csjr[i] = this.matrix[i] - amount; } return new DenseDoubleMatrix(csjr, this.numRows, this.numColumns, false); }
/** * Writes a dense matrix to the given output stream. The layout is as simple * as in memory, first the dimension is written (row count, column count as * integer) afterwards there are following row*columns doubles in a row major * fashion. * * @param mat the dense matrix to serialize. * @param out the output. * @throws IOException in case of an IO error. */ public static void writeDenseMatrix(DenseDoubleMatrix 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.writeDouble(mat.get(row, col)); } } }
@Override public DenseDoubleMatrix transpose() { DenseDoubleMatrix m = new DenseDoubleMatrix(this.numColumns, this.numRows); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { m.set(j, i, this.matrix[translate(i, j, numRows)]); } } return m; }
/** * Get a single row of the matrix as a double array. */ public double[] getRow(int row) { double[] rowArray = new double[getColumnCount()]; for (int i = 0; i < getColumnCount(); i++) { rowArray[i] = get(row, i); } return rowArray; }
@Override public DoubleMatrix subtract(DoubleMatrix other) { DoubleMatrix m = new DenseDoubleMatrix(this.numRows, this.numColumns); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { m.set(i, j, this.matrix[translate(i, j, numRows)] - other.get(i, j)); } } return m; }
/** * A distance matrix (NxN) based on n given points and a distance measurer. */ private DoubleMatrix generateDistanceMatrix(DistanceMeasurer measurer, List<DoubleVector> pointList) { final int n = pointList.size(); DenseDoubleMatrix matrix = new DenseDoubleMatrix(n, n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { final double distance = measurer.measureDistance(pointList.get(i), pointList.get(j)); matrix.set(i, j, distance); } } return matrix; }
@Override public DoubleMatrix deepCopy() { return new DenseDoubleMatrix(toArray()); }
/** * @return the normalized matrix (0 mean and stddev of 1) as well as the mean * and the stddev. */ public static Tuple3<DoubleMatrix, DoubleVector, DoubleVector> meanNormalizeColumns( DoubleMatrix x) { DenseDoubleMatrix toReturn = new DenseDoubleMatrix(x.getRowCount(), x.getColumnCount()); final int length = x.getColumnCount(); DoubleVector meanVector = new DenseDoubleVector(length); DoubleVector stddevVector = new DenseDoubleVector(length); for (int col = 0; col < length; col++) { DoubleVector column = x.getColumnVector(col); double mean = column.sum() / column.getLength(); meanVector.set(col, mean); double var = column.subtract(mean).pow(2).sum() / column.getLength(); stddevVector.set(col, Math.sqrt(var)); } for (int col = 0; col < length; col++) { DoubleVector column = x.getColumnVector(col) .subtract(meanVector.get(col)).divide(stddevVector.get(col)); toReturn.setColumn(col, column.toArray()); } return new Tuple3<>(toReturn, meanVector, stddevVector); }
@Override public DoubleVector multiplyVectorColumn(DoubleVector v) { DoubleVector vector = new DenseDoubleVector(this.getColumnCount()); for (int col = 0; col < numColumns; col++) { double sum = 0.0d; for (int row = 0; row < numRows; row++) { sum += (matrix[translate(row, col, numRows)] * v.get(row)); } vector.set(col, sum); } return vector; }
/** * Simple copy constructor, does a deep copy of the given parameter. * * @param otherMatrix the other matrix. */ public DenseDoubleMatrix(double[][] otherMatrix) { this(otherMatrix.length, otherMatrix[0].length); for (int row = 0; row < otherMatrix.length; row++) { for (int col = 0; col < otherMatrix[row].length; col++) { set(row, col, otherMatrix[row][col]); } } }
DenseDoubleMatrix start = new DenseDoubleMatrix(layerSizes[i] + 1, currentTrainingSet[0].getDimension() + 1, new Random(seed)) .multiply(0.1d); DoubleVector folded = DenseMatrixFolder.foldMatrices(start); start = null;
@Override public CostGradientTuple evaluateCost(DoubleVector theta) { DoubleVector activation = SIGMOID.get().apply(x.multiplyVectorRow(theta)); DenseDoubleMatrix hypo = new DenseDoubleMatrix(Arrays.asList(activation)); double error = ERROR_FUNCTION.calculateLoss(y, hypo); DoubleMatrix loss = hypo.subtract(y); double j = error / m; DoubleVector gradient = xTransposed.multiplyVectorRow(loss.getRowVector(0)) .divide(m); if (lambda != 0d) { DoubleVector reg = theta.multiply(lambda / m); // don't regularize the bias reg.set(0, 0d); gradient = gradient.add(reg); j += lambda * theta.pow(2).sum() / m; } return new CostGradientTuple(j, gradient); } }
@Override public int[] columnIndices() { int[] x = new int[getColumnCount()]; for (int i = 0; i < getColumnCount(); i++) x[i] = i; return x; }
@Override public int[] rowIndices() { int[] x = new int[getRowCount()]; for (int i = 0; i < getRowCount(); i++) x[i] = i; return x; }