Matrix multiplication in Scala

I am trying to transpose a matrix of size 3*2 by defining a empty matrix of size 2*3, how can i create an empty matrix?? I am missing something in the commented piece of code!!

type Row = List[Int]
type Matrix = List[Row]

val m:Matrix = List(1 :: 2 :: Nil, 3 :: 4 :: Nil, 5 :: 6 :: Nil)

def transpose(m:Matrix):Matrix = {

  val rows = m.size
  val cols = m.head.size
  val trans= List(List())(rows(cols)) // Int doesn't take parameter

  for (i <- 0 until  cols) {
    for (j <- 0 until  rows) {
      trans(i)(j) = this (j)(i)
    }
  }
  return trans
}

2 answers

  • answered 2018-10-11 20:17 jwvh

    An empty matrix has zero rows and zero columns, which isn't going to help you. You might build a matrix populated with some default value like -1 but a List is immutable so you can't replace values without rebuilding a fresh List.

    Here's one way to get what you want.

    type Row = List[Int]
    type Matrix = List[Row]
    
    def transpose(m:Matrix):Matrix = {
      val rLen = m.head.length
      val cLen = m.length
      List.tabulate(rLen)(cIdx =>
        List.tabulate(cLen)(rIdx =>
          m(rIdx)(cIdx)
        )
      )
    }
    

    This uses the "inbuilt" methods head, length, and tabulate.


    OK, so here's a solution that does no List indexing and uses only head, tail, reverse, pre-pending (no appending), flatten, and length (once).

    type Row = List[Int]
    type Matrix = List[Row]
    
    def transpose(m:Matrix):Matrix = {
      def loop(data :List[Int], result :Matrix, reserve :Matrix) :Matrix = {
        if (data.isEmpty) result
        else result match {
          case hd::Nil => loop(data.tail, ((data.head::hd)::reserve).reverse, Nil)
          case hd::tl  => loop(data.tail, tl, (data.head::hd)::reserve)
          case _ => Nil
        }
      }
      loop(m.reverse.flatten, List.fill(m.head.length)(Nil), Nil)
    }
    

  • answered 2018-10-12 03:19 RAGHHURAAMM

    When it is necessary to access elements by index, Vector or Array is more efficient than Lists. Here is the Vector version of solution.

    type Row = Vector[Int]
    type Matrix = Vector[Row]
    val m:Matrix = Vector(Vector(1,2), Vector(3,4), Vector(5,6))
    
    def transpose(mat:Matrix) = {
      def size[A](v: Vector[A]): Int = { var x =0; for(i<-v) x+=1; x}
      for (i <-Range(0,size(mat(0)))) yield for(j <-Range(0,size(mat))) yield mat(j)(i)
    }
    

    Test in REPL:

    scala> transpose(m)
    res12: scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[Int]] = Vector(Vector(1, 3, 5), Vector(2,
     4, 6))