3

Using the Scala Breeze library :

How can I convert an instance of a breeze.linalg.DenseMatrix of Int values to a DenseMatrix of Doubles (both matrices have the same dimensions)?

(I am trying to get a image/picture in a matrix for image processing using Breeze)

fotNelton
  • 3,844
  • 2
  • 24
  • 35
kos
  • 51
  • 3

2 Answers2

6

fotNelton's answer works. Another option is:

dm.mapValues(_.toInt)

or

dm.values.map(_.toInt)

As of Breeze 0.6, you can also say:

convert(dm, Int)
dlwh
  • 2,257
  • 11
  • 23
  • Nice. And it makes me curious: For large matrices, my solution is obviously slow because `dm(_,_)` is called for each element. I haven't looked at the corresponding instance of `breeze.generic.CanMapValues` in detail, but is it correct to assume that it's faster? – fotNelton Jan 23 '14 at 07:11
  • Hrm, I think quite possibly it's not faster. If specialized does its job perfectly, it might avoid all the boxing. I haven't looked at the byte code in a while. (Specialized rarely does its job perfectly.) – dlwh Jan 23 '14 at 16:18
  • Apart from specialization I thought that maybe an instance of `CanMapValues` from `DenseMatrix` to `DenseMatrix` (I suppose there is such an instance?) wouldn't need to access the original matrix's elements by indexing each element via `apply` or the like. So it could save an umpteen number of calls and just map from one underlying array onto the other one. – fotNelton Jan 23 '14 at 16:29
  • Huh, I just realized that accessing the underlying array still depends on specialization. Well... – fotNelton Jan 23 '14 at 16:31
  • Yeah. So, this is why I implemented the [@]expand macro. It tries to do much less than [@]specialized, which is to say, expand doesn't try to make the specialized classes inherit from the non-specialized; it just does name mangling and code generation. So, I should be able to switch to @expand for CanMapValues, which will mean that the access to the array, at least, is guaranteed to be right. There's still the problem of the Function1 possibly introducing boxing if specialized messes up, but there's only so much we can do without implementing more macros. – dlwh Jan 24 '14 at 01:43
  • (It is now the case that dm.mapValues is typically as fast as a hand written loop for built-in types) – dlwh Jul 29 '15 at 19:50
2

You can use DenseMatrix.tabulate for this:

scala> val dm = DenseMatrix((1.0, 2.0), (3.0, 4.0))
dm: breeze.linalg.DenseMatrix[Double] =
1.0  2.0
3.0  4.0

scala> val im = DenseMatrix.tabulate(dm.rows, dm.cols)(dm(_,_).toInt)
im: breeze.linalg.DenseMatrix[Int] =
1  2
3  4
fotNelton
  • 3,844
  • 2
  • 24
  • 35