Sum of a sequence of vectors in Scala

I have a sequence of doubling vectors: val vectors = Seq[Vector[Double]]

I would like to summarize all the vectors in the sequence, i.e. val total = vectors.sum

For example, if I have a sequence with two vectors [1,2]and [3,4], then the result should be[4,6]

However, a sumtype method Vectorrequires implicit Numeric.

Now I have:

val total = vectors.reduce( (one,two) => one.zip(two).map(tuple => tuple._1 + tuple._2) )

I am new to Scala, but I find this confusing and I guess it is probably inefficient.

Is there a better way to do this?

+4
source share
3 answers

This tail recursive function will work even if the vectors have different lengths and can be applied to any number type:

@scala.annotation.tailrec
def recSum[T : Numeric](s : Iterable[Iterable[T]]) : List[T] = {
  val goodVecs = s.filterNot(_.isEmpty)

  if(goodVecs.isEmpty) 
    List.empty[T]
  else 
    goodVecs.map(_.head).sum :: recSum(goodVecs.map(_.tail))
}

:

recSum(Seq(Vector(1.0,2.0), Vector(3.0,4.0,5.0))) //List(4.0,6.0,5.0)

recSum(Seq.empty[Vector[Double]]) // List()
+3

, , - , . , , zip map , . .

:

val vecs = Seq(   
  Vector(1,2,3,4,5),
  Vector(2,3,4,5,6),
  Vector(8,2,6,4,2),
  Vector(2,8,4,8,8) 
)

, Seq [Vector] Seq [Iterator]

val iterators: Seq[Iterator[Int]] = vecs.map(_.iterator)

reduce, Seq . , :

val sumIterator = iterators.reduce[Iterator[Int]]{ (itrA, itrB) =>
  // combine 2 of the iterators into a sum of their individual parts
  // the resulting iterator will then be combined with the next iterator
  // so you end up with a single iterator of the total sum for each 'column'

  (itrA zip itrB) map { case (a, b) => a + b }
}

sumIterator "".

sumIterator.toList
// List(13, 15, 17, 21, 21)
+1

Vector sum, Seq sum:

scala> val vectors: Seq[Vector[Double]] = List(Vector(.1,.2),Vector(.3,.4))
vectors: Seq[Vector[Double]] = List(Vector(0.1, 0.2), Vector(0.3, 0.4))

scala> vectors.map(_.sum).sum
res10 Double = 1.0
0

Source: https://habr.com/ru/post/1622253/


All Articles