HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Producing a matrix class that supports any size

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
classproducingsizeanysupportsthatmatrix

Problem

I'm doing exercise 11.8 from Scala for impatient, asking to write a matrix class:


Provide a class Matrix - you can choose whether you want to implement 2
x 2 matrices, square matrices of any size, or m x n matrices. Supply operations + and . The latter should also work with scalars, for example mat 2. A single element should be accessible as mat(row, col).

The code is working, but may be there can be improvements to make code more functional or more stable:

class Matrix(val n: Int, val m: Int, fun: (Int, Int) => Double) {
  private val matrix = Array.tabulate[Double](n,m)(fun)  

  def +(another: Matrix) = { 
    if (n != another.n || m != another.m) 
      throw new IllegalArgumentException("Sizes of arrays don't match.") 
    else 
      new Matrix(n, m, (i, j) => this(i)(j) + another(i)(j)) 
  }
  def *(another: Matrix) = { 
    if (m != another.n)
      throw new IllegalArgumentException("Sizes of arrays don't match.")
    else  
      new Matrix(n, another.m, (i,j) => { var sum = 0.0; 
                                          for (k <- matrix(i).indices) sum += matrix(i)(k) * another(k)(j); 
                                          sum } 
      ) 
  }
  def *(k: Int) = new Matrix(n, m, k * matrix(_)(_) )

  def apply(i: Int)(j: Int) = matrix(i)(j)

  override def toString = { 
    var result = ""
    for (row <- matrix) {
      for (value <- row)
        result += value + "  "

      result += "\n"
    }
    result
  }
}

Solution

Remove all var. Doesn't the book show for...yield by that point? For example:

(i,j) => { 
  var sum = 0.0; 
  for (k <- matrix(i).indices) sum += matrix(i)(k) * another(k)(j); 
  sum 
}


Can be replaced with:

(i,j) => (for (k <- matrix(i).indices) yield matrix(i)(k) * another(k)(j)).sum


The var on toString can be replaced by using mkString. I'll let you work out for yourself how to do that, now that I called your attention to that method. And, yes, it that method works on Array as well, though it doesn't appear on Scaladoc for Scala up to 2.9.2 because it is added implicitly. I suggest you use the nightly scaladoc to look things up -- the documentation there is better, though it may show things not available on release versions, and so is the tool itself.

Code Snippets

(i,j) => { 
  var sum = 0.0; 
  for (k <- matrix(i).indices) sum += matrix(i)(k) * another(k)(j); 
  sum 
}
(i,j) => (for (k <- matrix(i).indices) yield matrix(i)(k) * another(k)(j)).sum

Context

StackExchange Code Review Q#14483, answer score: 2

Revisions (0)

No revisions yet.