How to zip two DenseVectors in Scala Breeze?

821 Views Asked by At

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.

2

There are 2 best solutions below

4
On BEST ANSWER

I should probably just make a method on DenseVector, but

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

should do it.

0
On

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) => ... }