Search code examples
scalascala-breeze

Breeze change DenseMatrix using vector decomposition


Code below generates a 0-1 matrix, changes every odd row and composes a new matrix. I want to concat the vectors using foldLeft but I get Not all matrices have the same number of columns, probably because zero (or unit) element of foldLeft is an empty vector of unknown size.

import breeze.linalg._
import breeze.stats.distributions._
object ZeroOneMatrix {
  def main(args: Array[String]) {
    val n = 4
    val m = DenseMatrix.rand[Int](n, n, rand = Rand.randInt(2))
    println(m)

    // vs is of type Vector[DenseVector[Int]]
    val vs = for (r <- 0 until n)
      yield {
        if (r % 2 == 1)
          m(r, ::).t map (e => (e + 1) % 2)
        else m(r, ::).t
      }
    println(vs)

    // compose matrix back from the list of vectors vs
    val f = (vs foldLeft DenseVector[Int]().asDenseMatrix)(
        (mat, v) => DenseMatrix.vertcat(v.asDenseMatrix, mat))
    println(f)
  }
}

How could it be fixed? Also why map can not be called on m(r, ::) without doing transponation? Ideally I would map a chosen vector into a new one and then would use DenseMatrix.horzcat to build the matrix.

The reason of not using the map function on entire matrix is that some rows are not going to be changed.


Solution

  • You're right about why it's not working. Why not just use reduce? Or: DenseVector.vertcat(vs:_*)

    Map: Breeze privileges column vectors, and a lot of functionality is missing for row vectors. In general, you should probably get in the habit of working with columns rather than rows.