Поэлементное умножение итераторов и вычисление суммы

#scala #elementwise-operations

#scala #поэлементные операции

Вопрос:

Используя два списка, поэлементное умножение этих списков и сумму результирующего списка можно вычислить следующим образом.

 (List1 , List2).zipped.foldLeft(0.0) { case (a, (b, c)) => a   b * c }
  

Как я могу выполнить эту операцию для двух итераторов в Scala оптимальным и быстрым способом?

Комментарии:

1. Извините, я не понимаю, в чем вопрос.

2. Напишите тест, иначе это просто предположение. Итераторы могут быть быстрыми, потому что они могут проходить структуру, не вычисляя вещи дважды, но я бы избегал любых заявлений об оптимальности этого или любого другого решения. Ваш текущий может быть близок к «оптимальному» или, по крайней мере, достаточно быстр.

3. Я тоже немного смущен. Помимо части производительности, оба zip и fold присутствуют в итераторах. Не уверен, что вас смутило в итераторах. Код будет выглядеть почти идентично. Вы реализовали это и не были удовлетворены его производительностью?

4. какое улучшение производительности вы ищете для памяти (этот список слишком большой) или временной сложности? ваша текущая реализация выглядит достаточно хорошо.

5. @sinanspd Я использовал код aboove и предоставил итератор вместо списка. Но этот код не работает

Ответ №1:

 (iterator1 zip iterator2).foldLeft(0.0) { case (a, (b, c)) => a   b * c }
  

я полагаю, все в порядке. Если вы хотите выжать из него последнюю каплю производительности, используйте массивы и цикл while.

Ответ №2:

Вы можете использовать этот фрагмент кода, который должен работать с любой коллекцией и любым числовым типом.
Он пытается быть эффективным, делая все за один обход. Однако, как сказал @Martijn, если вам нужно, чтобы это было наиболее эффективным решением, тогда просто используйте простые массивы примитивного типа, такие как Int или Double и a while .

 def dotProduct[N : Numeric](l1: IterableOnce[N], l2: IterableOnce[N]): N =
  l1.iterator.zip(l2).map {
    case (x, y) => Numeric[N].times(x, y)
  }.sum
  

(примечание: этот код предназначен для 2.13 , для 2.12- вы можете использовать Iterable вместо IterableOnce)