Search code examples
javamatrixjava-8java-streammultiplication

Java 8 matrix * vector multiplication


I'm wondering if there is a more condensed way of doing the following in Java 8 with streams:

public static double[] multiply(double[][] matrix, double[] vector) {
    int rows = matrix.length;
    int columns = matrix[0].length;

    double[] result = new double[rows];

    for (int row = 0; row < rows; row++) {
        double sum = 0;
        for (int column = 0; column < columns; column++) {
            sum += matrix[row][column]
                    * vector[column];
        }
        result[row] = sum;
    }
    return result;
}

Making an Edit. I received a very good answer, however the performance is about 10X slower than the old implementation, so I'm adding the test code here in case anyone wants to investigate it:

@Test
public void profile() {
    long start;
    long stop;
    int tenmillion = 10000000;
    double[] vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    double[][] matrix = new double[tenmillion][10];

    for (int i = 0; i < tenmillion; i++) {
        matrix[i] = vector.clone();
    }
    start = System.currentTimeMillis();
    multiply(matrix, vector);
    stop = System.currentTimeMillis();
 }

Solution

  • A direct way using Stream would be the following:

    public static double[] multiply(double[][] matrix, double[] vector) {
        return Arrays.stream(matrix)
                .mapToDouble(row -> IntStream.range(0, row.length)
                        .mapToDouble(col -> row[col] * vector[col])
                        .sum())
                .toArray();
    }
    

    This creates a Stream of each row of the matrix (Stream<double[]>), then maps each row to the double value resulting of calculating the product with the vector array.

    We have to use a Stream over the indexes to calculate the product because there are unfortunately no built-in facility to zip two Streams together.