class_docstr: Transform the `batch x (q * n_w) x m` posterior into a `batch x q x m`
  posterior of the expectation. The expectation is calculated over each
  consecutive `n_w` block of points in the posterior.
  
  This is intended for use with `InputPerturbation` or `AppendFeatures` for
  optimizing the expectation over `n_w` points. This should not be used when
  there are constraints present, since this does not take into account
  the feasibility of the objectives.
  
  Note: This is different than `ScalarizedPosteriorTransform` in that
  this operates over the q-batch dimension.
class_docstr_tok: ["Transform","the","`","batch","x","(","q","*","n_w",")","x","m","`","posterior","into","a","`","batch","x","q","x","m","`","posterior","of","the","expectation",".","The","expectation","is","calculated","over","each","consecutive","`","n_w","`","block","of","points","in","the","posterior",".","This","is","intended","for","use","with","`","InputPerturbation","`","or","`","AppendFeatures","`","for","optimizing","the","expectation","over","`","n_w","`","points",".","This","should","not","be","used","when","there","are","constraints","present",",","since","this","does","not","take","into","account","the","feasibility","of","the","objectives",".","Note",":","This","is","different","than","`","ScalarizedPosteriorTransform","`","in","that","this","operates","over","the","q-batch","dimension","."]
docstr: Compute the posterior of the expectation.
  
  Args:
      posterior: An `m`-outcome joint posterior over `q * n_w` points.
  
  Returns:
      An `m`-outcome joint posterior over `q` expectations.
code: def forward(self, posterior: GPyTorchPosterior) -> GPyTorchPosterior:
      r"""Compute the posterior of the expectation.
  
      Args:
          posterior: An `m`-outcome joint posterior over `q * n_w` points.
  
      Returns:
          An `m`-outcome joint posterior over `q` expectations.
      """
      org_mvn = posterior.distribution
      if getattr(org_mvn, "_interleaved", False):
          raise UnsupportedError(
              "`ExpectationPosteriorTransform` does not support "
              "interleaved posteriors."
          )
      # Initialize the weight matrix of shape compatible with the mvn.
      org_event_shape = org_mvn.event_shape
      batch_shape = org_mvn.batch_shape
      q = org_event_shape[0] // self.n_w
      m = 1 if len(org_event_shape) == 1 else org_event_shape[-1]
      tkwargs = {
          "device": org_mvn.loc.device,
          "dtype": org_mvn.loc.dtype,
      }
      weights = torch.zeros(q * m, q * self.n_w * m, **tkwargs)
      # Make sure self.weights has the correct dtype/device and shape.
      self.weights = self.weights.to(org_mvn.loc).expand(self.n_w, m)
      # Fill in the non-zero entries of the weight matrix.
      # We want each row to have non-zero weights for the corresponding
      # `n_w` sized diagonal. The `m` outcomes are not interleaved.
      for i in range(q * m):
          weights[i, self.n_w * i : self.n_w * (i + 1)] = self.weights[
              :, i // q
          ]
      # Trasform the mean.
      new_loc = (
          (weights @ org_mvn.loc.unsqueeze(-1))
          .view(*batch_shape, m, q)
          .transpose(-1, -2)
      )
      # Transform the covariance matrix.
      org_cov = (
          org_mvn.lazy_covariance_matrix
          if org_mvn.islazy
          else org_mvn.covariance_matrix
      )
      new_cov = weights @ (org_cov @ weights.t())
      if m == 1:
          new_mvn = MultivariateNormal(
              new_loc.squeeze(-1), to_linear_operator(new_cov)
          )
      else:
          # Using MTMVN since we pass a single loc and covar for all `m` outputs.
          new_mvn = MultitaskMultivariateNormal(
              new_loc, to_linear_operator(new_cov), interleaved=False
          )
      return GPyTorchPosterior(distribution=new_mvn)
  
imports: from __future__ import annotations
  import inspect
  import warnings
  from abc import ABC, abstractmethod
  from typing import Callable, List, Optional, TYPE_CHECKING, Union
  import torch
  from botorch.exceptions.errors import BotorchTensorDimensionError, UnsupportedError
  from botorch.exceptions.warnings import InputDataWarning
  from botorch.models.model import Model
  from botorch.models.transforms.outcome import Standardize
  from botorch.posteriors.gpytorch import GPyTorchPosterior, scalarize_posterior
  from botorch.sampling import IIDNormalSampler
  from botorch.utils import apply_constraints
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from linear_operator.operators.dense_linear_operator import to_linear_operator
  from torch import Tensor
  from torch.nn import Module
  from botorch.models.deterministic import DeterministicModel
label_desc: Use image node_id 3 for calling the ExpectationPosteriorTransform obj's underlying member method code with example usage: obj.forward(posterior) and returns: GPyTorchPosterior