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

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 aList
is immutable so you can't replace values without rebuilding a freshList
.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
, andtabulate
.
OK, so here's a solution that does no
List
indexing and uses onlyhead
,tail
,reverse
, prepending (no appending),flatten
, andlength
(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) }

When it is necessary to access elements by
index
,Vector
orArray
is more efficient thanList
s. Here is theVector
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))