code: def scalarize_posterior(
      posterior: Union[GPyTorchPosterior, PosteriorList],
      weights: Tensor,
      offset: float = 0.0,
  ) -> GPyTorchPosterior:
      r"""Affine transformation of a multi-output posterior.
  
      Args:
          posterior: The posterior over `m` outcomes to be scalarized.
              Supports `t`-batching. Can be either a `GPyTorchPosterior`,
              or a `PosteriorList` that contains GPyTorchPosteriors all with q=1.
          weights: A tensor of weights of size `m`.
          offset: The offset of the affine transformation.
  
      Returns:
          The transformed (single-output) posterior. If the input posterior has
              mean `mu` and covariance matrix `Sigma`, this posterior has mean
              `weights^T * mu` and variance `weights^T Sigma w`.
  
      Example:
          Example for a model with two outcomes:
  
          >>> X = torch.rand(1, 2)
          >>> posterior = model.posterior(X)
          >>> weights = torch.tensor([0.5, 0.25])
          >>> new_posterior = scalarize_posterior(posterior, weights=weights)
      """
      # GPyTorchPosterior case
      if hasattr(posterior, "distribution"):
          mean, cov = scalarize_posterior_gpytorch(
              posterior, weights, offset
          )
          mvn = MultivariateNormal(mean, cov)
          return GPyTorchPosterior(mvn)
  
      # PosteriorList case
      if not hasattr(posterior, "posteriors"):
          raise NotImplementedError(
              "scalarize_posterior only works with a posterior that has an attribute "
              "`distribution`, such as a GPyTorchPosterior, or a posterior that contains "
              "sub-posteriors in an attribute `posteriors`, as in a PosteriorList."
          )
  
      mean = posterior.mean
      q, m = mean.shape[-2:]
  
      _validate_scalarize_inputs(weights, m)
      batch_shape = mean.shape[:-2]
  
      if q != 1:
          raise NotImplementedError(
              "scalarize_posterior only works with a PosteriorList if each sub-posterior "
              "has q=1."
          )
  
      means = [post.mean for post in posterior.posteriors]
      if {mean.shape[-1] for mean in means} != {1}:
          raise NotImplementedError(
              "scalarize_posterior only works with a PosteriorList if each sub-posterior "
              "has one outcome."
          )
  
      new_mean = offset + (mean @ weights).view(*batch_shape, q)
      new_cov = (posterior.variance @ (weights**2))[:, None]
      mvn = MultivariateNormal(new_mean, new_cov)
      return GPyTorchPosterior(mvn)
  
imports: from __future__ import annotations
  import warnings
  from contextlib import ExitStack
  from typing import Optional, Tuple, TYPE_CHECKING, Union
  import torch
  from botorch.exceptions.errors import BotorchTensorDimensionError
  from botorch.posteriors.base_samples import _reshape_base_samples_non_interleaved
  from botorch.posteriors.torch import TorchPosterior
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from linear_operator import settings
  from linear_operator.operators import BlockDiagLinearOperator, DenseLinearOperator, LinearOperator, SumLinearOperator
  from torch import Tensor
  from torch.distributions import Normal
label_desc: Use image node_id 3 for calling a global function with example usage: scalarize_posterior(posterior, weights, offset) and returns: GPyTorchPosterior, GPyTorchPosterior