0

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.

Stephan Rozinsky
  • 553
  • 2
  • 6
  • 21

1 Answers1

0

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.

dlwh
  • 2,257
  • 11
  • 23
  • Thank you for hints. When I use `reduce`, it says `mat` is `DenseVector` while required `DenseMatrix`, so I convert `mat.asDenseMatrix` and then it fails on `v.asDenseMatrix` requiring `DenseVector` :) – Stephan Rozinsky Mar 25 '15 at 23:29
  • `DenseVector.vertcat(vs:_*)` is not working as I need a matrix in the end and this gives me a joined vector. What I'm doing is transforming a matrix from one state to another by changing some of the rows in it. And I do not want to mutate the matrix and achieve it in a functional style by using a `map`. – Stephan Rozinsky Mar 25 '15 at 23:32
  • About applying `map` only to columns. Why is that? Matrices are symmetric and rows should be treated evenly as columns. Multiplying rows by a constant and subtracting them is the basis of Gaussian elimination algorithm which reduces a matrix to the Entity matrix. – Stephan Rozinsky Mar 25 '15 at 23:37
  • Final solution - `DenseMatrix.vertcat(vs:_*)` – Stephan Rozinsky Mar 25 '15 at 23:52
  • Ah, so, `mat(*, ::).map( )` should do what you want. DenseVectors have a shape, which is a column vector (since Breeze is column major), and I never really fleshed out the transpose of that. I'm starting to, but it'll be a while. – dlwh Mar 26 '15 at 03:54
  • Thank you for your efforts. One more please: if I use `mat(*, ::).map(e => (e + 1) % 2)`, can I somehow in the code of map function access `e.row` or `e.column` (because my function depends on that information)? – Stephan Rozinsky Mar 26 '15 at 12:00
  • nope, sorry. i agree it would be nice to have. You can open an issue on github – dlwh Mar 26 '15 at 17:14