class_docstr: Standardize outcomes (zero mean, unit variance).
  
  This module is stateful: If in train mode, calling forward updates the
  module state (i.e. the mean/std normalizing constants). If in eval mode,
  calling forward simply applies the standardization using the current module
  state.
docstr: Un-standardize the posterior.
  
  Args:
      posterior: A posterior in the standardized space.
  
  Returns:
      The un-standardized posterior. If the input posterior is a
      `GPyTorchPosterior`, return a `GPyTorchPosterior`. Otherwise, return a
      `TransformedPosterior`.
docstr_tok: ["Un-standardize","the","posterior",".","Args",":","posterior",":","A","posterior","in","the","standardized","space",".","Returns",":","The","un-standardized","posterior",".","If","the","input","posterior","is","a","`","GPyTorchPosterior","`",",","return","a","`","GPyTorchPosterior","`",".","Otherwise",",","return","a","`","TransformedPosterior","`","."]
code: def untransform_posterior(
      self, posterior: Posterior
  ) -> Union[GPyTorchPosterior, TransformedPosterior]:
      r"""Un-standardize the posterior.
  
      Args:
          posterior: A posterior in the standardized space.
  
      Returns:
          The un-standardized posterior. If the input posterior is a
          `GPyTorchPosterior`, return a `GPyTorchPosterior`. Otherwise, return a
          `TransformedPosterior`.
      """
      if self._outputs is not None:
          raise NotImplementedError(
              "Standardize does not yet support output selection for "
              "untransform_posterior"
          )
      if not self._is_trained:
          raise RuntimeError(
              "`Standardize` transforms must be called on outcome data "
              "(e.g. `transform(Y)`) before calling `untransform_posterior`, since "
              "means and standard deviations need to be computed."
          )
      is_mtgp_posterior = False
      if type(posterior) is GPyTorchPosterior:
          is_mtgp_posterior = posterior._is_mt
      if (
          not self._m == posterior._extended_shape()[-1]
          and not is_mtgp_posterior
      ):
          raise RuntimeError(
              "Incompatible output dimensions encountered. Transform has output "
              f"dimension {self._m} and posterior has "
              f"{posterior._extended_shape()[-1]}."
          )
  
      if type(posterior) is not GPyTorchPosterior:
          # fall back to TransformedPosterior
          # this applies to subclasses of GPyTorchPosterior like MultitaskGPPosterior
          return TransformedPosterior(
              posterior=posterior,
              sample_transform=lambda s: self.means + self.stdvs * s,
              mean_transform=lambda m, v: self.means + self.stdvs * m,
              variance_transform=lambda m, v: self._stdvs_sq * v,
          )
      # GPyTorchPosterior (TODO: Should we Lazy-evaluate the mean here as well?)
      mvn = posterior.distribution
      offset = self.means
      scale_fac = self.stdvs
      if not posterior._is_mt:
          mean_tf = (
              offset.squeeze(-1) + scale_fac.squeeze(-1) * mvn.mean
          )
          scale_fac = scale_fac.squeeze(-1).expand_as(mean_tf)
      else:
          mean_tf = offset + scale_fac * mvn.mean
          reps = mean_tf.shape[-2:].numel() // scale_fac.size(-1)
          scale_fac = scale_fac.squeeze(-2)
          if mvn._interleaved:
              scale_fac = scale_fac.repeat(
                  *[1 for _ in scale_fac.shape[:-1]], reps
              )
          else:
              scale_fac = torch.repeat_interleave(
                  scale_fac, reps, dim=-1
              )
  
      if (
          not mvn.islazy
          # TODO: Figure out attribute namming weirdness here
          or mvn._MultivariateNormal__unbroadcasted_scale_tril
          is not None
      ):
          # if already computed, we can save a lot of time using scale_tril
          covar_tf = CholLinearOperator(
              mvn.scale_tril * scale_fac.unsqueeze(-1)
          )
      else:
          lcv = mvn.lazy_covariance_matrix
          scale_fac = scale_fac.expand(lcv.shape[:-1])
          scale_mat = DiagLinearOperator(scale_fac)
          covar_tf = scale_mat @ lcv @ scale_mat
  
      kwargs = (
          {"interleaved": mvn._interleaved} if posterior._is_mt else {}
      )
      mvn_tf = mvn.__class__(
          mean=mean_tf, covariance_matrix=covar_tf, **kwargs
      )
      return GPyTorchPosterior(mvn_tf)
  
imports: from __future__ import annotations
  import warnings
  from abc import ABC, abstractmethod
  from collections import OrderedDict
  from typing import Any, List, Mapping, Optional, Tuple, Union
  import torch
  from botorch.models.transforms.utils import norm_to_lognorm_mean, norm_to_lognorm_variance
  from botorch.posteriors import GPyTorchPosterior, Posterior, TransformedPosterior
  from botorch.utils.transforms import normalize_indices
  from linear_operator.operators import CholLinearOperator, DiagLinearOperator
  from torch import Tensor
  from torch.nn import Module, ModuleDict
label_desc: Use image node_id 7 for calling the Standardize obj's underlying member method code with example usage: obj.untransform_posterior(posterior) and returns: GPyTorchPosterior, TransformedPosterior