0
votes

I have an input mllib matrix like,

matrix1: org.apache.spark.mllib.linalg.Matrix =
1.0  0.0  2.0  1.0
0.0  3.0  1.0  1.0
2.0  1.0  0.0  0.0

The dimensions of matrix1 is 3*4. I need to do an element by element matrix multiplication with another matrix so that dimensions of two matrices will be the same in all cases. Let us assume I have another matrix named matrix2 like

matrix2: org.apache.spark.mllib.linalg.Matrix =
3.0  0.0  2.0  1.0
1.0  9.0  5.0  1.0
2.0  5.0  0.0  0.0

with dimensions 3*4 My resultant matrix should be,

result: org.apache.spark.mllib.linalg.Matrix =
3.0  0.0   4.0  1.0
0.0  27.0  5.0  1.0
4.0  5.0   0.0  0.0

How can I achieve this in Scala ? (Note: inbuilt function multiply of spark mllib works as per exact matrix multiplication.)

1

1 Answers

1
votes

Below is one way of doing it. Here we iterate both the matrix column wise and find their element multiplication. This solution assumes that both the matrix are of same dimensions.
First let's create test matrix as given in question.

//creating example matrix as per the question
val m1: Matrix = new DenseMatrix(3, 4, Array(1.0, 0.0, 2.0, 0.0, 3.0, 1.0, 2.0, 1.0, 0.0, 1.0, 1.0, 0.0))
val m2: Matrix = new DenseMatrix(3, 4, Array(3.0, 1.0, 2.0, 0.0, 9.0, 5.0, 2.0, 5.0, 0.0, 1.0, 1.0, 0.0))

Now let's define a function which takes two Matrix and returns their element multiplication.

//define a function to calculate element wise multiplication
def elemWiseMultiply(m1: Matrix, m2: Matrix): Matrix = {
  val arr = new ArrayBuffer[Array[Double]]()
  val m1Itr = m1.colIter //operate on each columns
  val m2Itr = m2.colIter
  while (m1Itr.hasNext)
    //zip both the columns and then multiple element by element
    arr += m1Itr.next.toArray.zip(m2Itr.next.toArray).map { case (a, b) => a * b }
  //return the resultant matrix
  new DenseMatrix(m1.numRows, m1.numCols, arr.flatten.toArray)
}

You can then call this function for your element multiplication.

//call the function to m1 and m2
elemWiseMultiply(m1, m2)

//output
//3.0  0.0   4.0  1.0
//0.0  27.0  5.0  1.0
//4.0  5.0   0.0  0.0