5

I'd like to zip two DenseVectors and perform an operation on each pair, and obtain a new vector as result. What is the best way to achieve this using scala-breeze?

I can work around it by using their data field, but I'd need to construct a new DenseVector from the resulting array.

Iulian Dragos
  • 5,692
  • 23
  • 31

2 Answers2

3

I should probably just make a method on DenseVector, but

breeze.linalg.zipValues(dv1, dv2){(v1, v2) => ??? }

should do it.

dlwh
  • 2,257
  • 11
  • 23
  • 1
    thanks for your answer but it cause `missing parameters type` error for me. I'm using breeze 0.10 with scala 2.11.5. – Ali Shirvani Jan 26 '15 at 18:58
  • 1
    Having a method for that would be very nice indeed. I am also getting this missing parameters type and it is not super easy to fix. – geoalgo Sep 22 '15 at 08:58
  • should be none. please file a bug on github if it's not – dlwh Jan 11 '18 at 01:07
  • This doesn't appear to work correctly. The mapped function treats `v1` and `v2` as the whole vector, not elementwise. I find that I am forced to do `dv1.toScalaVector zip dv2.toScalaVector` and then apply `map { case (v1, v2) => ... }`, and reconstruct a `DenseVector` from the result if required. – ely Aug 29 '18 at 14:31
0

The accepted answer does not appear to work as expected. Consider this example, trying to transform two DenseVector values into a Map[String -> Double], with a name for each of the original inputs.

scala> val dv1 = DenseVector.zeros[Double](4)
dv1: breeze.linalg.DenseVector[Double] = DenseVector(0.0, 0.0, 0.0, 0.0)

scala> val dv2 = DenseVector.ones[Double](4)
dv2: breeze.linalg.DenseVector[Double] = DenseVector(1.0, 1.0, 1.0, 1.0)

scala> breeze.linalg.zipValues(dv1, dv2) {(v1, v2) => Map("f1" -> v1, "f2" -> v2)}
res710: scala.collection.immutable.Map[String,breeze.linalg.DenseVector[Double]] = Map(f1 -> DenseVector(0.0, 0.0, 0.0, 0.0), f2 -> DenseVector(1.0, 1.0, 1.0, 1.0))

scala> (dv1.toScalaVector zip dv2.toScalaVector) map { case (v1, v2) => Map("f1" -> v1, "f2" -> v2)}
res711: scala.collection.immutable.Vector[scala.collection.immutable.Map[String,Double]] = Vector(Map(f1 -> 0.0, f2 -> 1.0), Map(f1 -> 0.0, f2 -> 1.0), Map(f1 -> 0.0, f2 -> 1.0), Map(f1 -> 0.0, f2 -> 1.0))

Notice how the use of breeze.linalg.zipValues treats the mapped function as a function of each entire DenseVector, so the output is one single Map instead of a Map for each component of the inputs (like in the second example).

Though inefficient (an unfortunate workaround for the limitations of breeze), the final line I gave above should generally work:

(dv1.toScalaVector zip dv2.toScalaVector) map { case (v1, v2) => ... }
ely
  • 74,674
  • 34
  • 147
  • 228