3

Is there a generic way using Breeze to achieve what you can do using broadcasting in NumPy?

Specifically, if I have an operator I'd like to apply to two 3x4 matrices, I can apply that operation element-wise. However, what I have is a 3x4 matrix and a 3-element column vector. I'd like a function which produces a 3x4 matrix created from applying the operator to each element of the matrix with the element from the vector for the corresponding row.

So for a division:

2 4 6   /  2 3  = 1 2 3
3 6 9             1 2 3

If this isn't available. I'd be willing to look at implementing it.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
Dave DeCaprio
  • 2,051
  • 17
  • 31

2 Answers2

3

You can use mapPairs to achieve what I 'think' you're looking for:

  val adder = DenseVector(1, 2, 3, 4)

  val result = DenseMatrix.zeros[Int](3, 4).mapPairs({
    case ((row, col), value) => {
      value + adder(col)
    }
  })

  println(result)

1  2  3  4  
1  2  3  4  
1  2  3  4  

I'm sure you can adapt what you want from simple 'adder' above.

Noah
  • 13,821
  • 4
  • 36
  • 45
  • Thanks, yes that's a useful way to accomplish a class of things I will need to do. Is there ANY documentation of Breeze anywhere. For example, when I look up mapPairs in the Scaladoc, it just says "Creates a new map containing a transformed copy of this map"? Looks like a very powerful library, but hard to come into without any doc. – Dave DeCaprio Feb 14 '13 at 22:28
  • 1
    I wish there was more documentation. I've learned mostly by using the REPL to experiment with features. The library does follow a generic pattern that seems rather idiomatic in scala with interfaces like CanBuildFrom or in this case CanMapKeyValuePairs. For instance, mapPairs is part of the TensorLike trait, so you see it in other objects as well. – Noah Feb 15 '13 at 14:22
3

Breeze now supports broadcasting of this sort:

scala> val dm = DenseMatrix( (2, 4, 6), (3, 6, 9) )
dm: breeze.linalg.DenseMatrix[Int] = 
2  4  6  
3  6  9  

scala> val dv = DenseVector(2,3)
dv: breeze.linalg.DenseVector[Int] = DenseVector(2, 3)

scala> dm(::, *) :/ dv
res4: breeze.linalg.DenseMatrix[Int] = 
1  2  3  
1  2  3  

The * operator says which axis to broadcast along. Breeze doesn't allow implicit broadcasting, except for scalar types.

dlwh
  • 2,257
  • 11
  • 23