-1

I have a mllib matrix like,

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

According to my scala code, the diagonals of the matrix is 0.0. I need to replace this value as 1.0 like

mat: org.apache.spark.mllib.linalg.Matrix =
1.0  2.0  1.0  2.0
2.0  1.0  2.0  4.0
1.0  2.0  1.0  3.0
2.0  4.0  3.0  1.0

How can I achieve this? Please provide me an optimized solution.

PRIYA M
  • 181
  • 2
  • 3
  • 19
  • isn't this the same question as https://stackoverflow.com/questions/51242763/create-a-diagonal-matrix-with-specified-number-of-rows-and-columns-in-scala – Ramesh Maharjan Jul 10 '18 at 04:58
  • There I provided a solution like adding diagonal matrix to the input matrix. But creating a diagonal matrix is unoptimized one. Here am looking for any other alternative solution to replace the values. – PRIYA M Jul 10 '18 at 05:07
  • then you should have waited without accepting the answer on that question instead of creating a duplicate question – Ramesh Maharjan Jul 10 '18 at 05:14
  • As am very new to stack overflow I did this. – PRIYA M Jul 10 '18 at 05:15
  • 1
    Try using `new DenseMatrix(mat.numRows, mat.numCols, mat.rowIter.zipWithIndex.flatMap(x=> { x._1.toArray(x._2) = 1.0; x._1.toArray }).toArray)`, It will replace all diagonals with `1`. – vindev Jul 10 '18 at 05:38
  • @vindev This works perfect. Can you explain this transformation by adding as solution? – PRIYA M Jul 10 '18 at 05:47

1 Answers1

1

For changing the diagonals you need to convert your matrix to row iterator so that you can iterate over it, then zip this iterator with index for replacing the elements on each row as per the index, which is the diagonal element of the matrix. Below is the code with required comments.

import org.apache.spark.mllib.linalg.DenseMatrix

//creating initial matrix which needs to be changes
val arr = Array(0.0,2.0,1.0,2.0,2.0,0.0,2.0,4.0,1.0,2.0,0.0,3.0,2.0,4.0,3.0,0.0)
val mat = new DenseMatrix(4,4,arr)

//output
//0.0  2.0  1.0  2.0
//2.0  0.0  2.0  4.0
//1.0  2.0  0.0  3.0
//2.0  4.0  3.0  0.0

//make the iterator and change the element at the index of each row
val changedArr = mat.rowIter.zipWithIndex.flatMap(x => {
  val ar = x._1.toArray
  ar(x._2) = 1.0
  ar
}).toArray

//create new matrix from it
val changedMat = new DenseMatrix(mat.numRows, mat.numCols, changedArr)

//output
//1.0  2.0  1.0  2.0
//2.0  1.0  2.0  4.0
//1.0  2.0  1.0  3.0
//2.0  4.0  3.0  1.0
vindev
  • 2,240
  • 2
  • 13
  • 20
  • Can you please provide me the same solution for creating Block Matrix. So that I can use its inbuilt functions. Or is there any solution to convert Dense matrix into Block Matrix? – PRIYA M Jul 10 '18 at 10:52
  • This should help you. https://stackoverflow.com/questions/31647589/distributed-blockmatrix-out-of-spark-matrices – vindev Jul 10 '18 at 11:07