class_docstr: Trainer class for OpenAI Evolution Strategies.
  
  :param algorithm_config: Algorithm parameters.
  :param torch_policy: Multi-step policy encapsulating the policy networks
  :param shared_noise: The noise table, with the same content for every worker and the master.
  :param normalization_stats: Normalization statistics as calculated by the NormalizeObservationWrapper.
class_docstr_tok: ["Trainer","class","for","OpenAI","Evolution","Strategies",".",":","param","algorithm_config",":","Algorithm","parameters",".",":","param","torch_policy",":","Multi-step","policy","encapsulating","the","policy","networks",":","param","shared_noise",":","The","noise","table",",","with","the","same","content","for","every","worker","and","the","master",".",":","param","normalization_stats",":","Normalization","statistics","as","calculated","by","the","NormalizeObservationWrapper","."]
docstr: calculate a weighted sum of the given vectors, in steps of at most `batch_size` vectors
docstr_tok: ["calculate","a","weighted","sum","of","the","given","vectors",",","in","steps","of","at","most","`","batch_size","`","vectors"]
code: def _batched_weighted_sum(
      cls,
      weights: Iterable[float],
      vectors: Iterable[np.ndarray],
      batch_size: int,
  ) -> np.ndarray:
      """calculate a weighted sum of the given vectors, in steps of at most `batch_size` vectors"""
      # start with float, at the first operation numpy broadcasting takes care of the correct shape
      total: Union[np.array, float] = 0.0
  
      for batch_weights, batch_vectors in zip(
          cls._iter_groups(weights, batch_size),
          cls._iter_groups(vectors, batch_size),
      ):
          assert len(batch_weights) == len(batch_vectors) <= batch_size
          total += np.dot(
              np.asarray(batch_weights, dtype=np.float32),
              np.asarray(batch_vectors, dtype=np.float32),
          )
  
      return total
  
imports: import itertools
  import logging
  import time
  from typing import Optional, Iterable, Generator, Tuple, Union, Dict
  import numpy
  import torch
  from typing.io import BinaryIO
  from maze.core.agent.policy import Policy
  from maze.core.agent.torch_model import TorchModel
  from maze.core.agent.torch_policy import TorchPolicy
  from maze.core.annotations import override
  from maze.core.env.base_env_events import BaseEnvEvents
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel, get_stats_logger, increment_log_step
  from maze.core.utils.factory import Factory
  from maze.train.trainers.common.model_selection.model_selection_base import ModelSelectionBase
  from maze.train.trainers.common.trainer import Trainer
  from maze.train.trainers.es.distributed.es_distributed_rollouts import ESDistributedRollouts, ESRolloutResult
  from maze.train.trainers.es.es_algorithm_config import ESAlgorithmConfig
  from maze.train.trainers.es.es_events import ESEvents
  from maze.train.trainers.es.es_shared_noise_table import SharedNoiseTable
  from maze.train.trainers.es.es_utils import get_flat_parameters
  from maze.train.trainers.es.optimizers.base_optimizer import Optimizer
label_desc: Use image node_id 8 for calling the ESTrainer obj's underlying member method code with example usage: obj._batched_weighted_sum(cls, weights, vectors, batch_size) and returns: total