class_docstr: The multivariate Value-at-Risk as introduced in [Prekopa2012MVaR]_.
  
  MVaR is defined as the non-dominated set of points in the extended domain
  of the random variable that have multivariate CDF greater than or equal to
  `alpha`. Note that MVaR is set valued and the size of the set depends on the
  particular realizations of the random variable. [Cousin2013MVaR]_ instead
  propose to use the expectation of the set-valued MVaR as the multivariate
  VaR. We support this alternative with an `expectation` flag.
  
  This supports approximate gradients as discussed in [Daulton2022MARS]_.
docstr: Find MVaR set based on the definition in [Prekopa2012MVaR]_.
  
  This first calculates the CDF for each point on the extended domain of the
  random variable (the grid defined by the given samples), then takes the
  values with CDF equal to (rounded if necessary) `alpha`. The non-dominated
  subset of these form the MVaR set.
  
  This implementation uses computes the CDF of each point using highly vectorized
  operations. As such, it may use large amounts of memory, particularly when the
  batch size and/or `n_w` are large. It is typically faster than the alternative
  implementation when computing MVaR of a large batch of points with small to
  moderate (<128 for m=2, <64 for m=3) `n_w`.
  
  Args:
      Y: A `batch x n_w x m`-dim tensor of observations.
  
  Returns:
      A `batch` length list of `k x m`-dim tensor of MVaR values, where `k`
      depends on the corresponding batch inputs. Note that MVaR values in general
      are not in-sample points.
docstr_tok: ["Find","MVaR","set","based","on","the","definition","in","[","Prekopa2012MVaR","]","_",".","This","first","calculates","the","CDF","for","each","point","on","the","extended","domain","of","the","random","variable","(","the","grid","defined","by","the","given","samples",")",",","then","takes","the","values","with","CDF","equal","to","(","rounded","if","necessary",")","`","alpha","`",".","The","non-dominated","subset","of","these","form","the","MVaR","set",".","This","implementation","uses","computes","the","CDF","of","each","point","using","highly","vectorized","operations",".","As","such",",","it","may","use","large","amounts","of","memory",",","particularly","when","the","batch","size","and\/or","`","n_w","`","are","large",".","It","is","typically","faster","than","the","alternative","implementation","when","computing","MVaR","of","a","large","batch","of","points","with","small","to","moderate","(","<","128","for","m=2",",","<","64","for","m=3",")","`","n_w","`",".","Args",":","Y",":","A","`","batch","x","n_w","x","m","`","-dim","tensor","of","observations",".","Returns",":","A","`","batch","`","length","list","of","`","k","x","m","`","-dim","tensor","of","MVaR","values",",","where","`","k","`","depends","on","the","corresponding","batch","inputs",".","Note","that","MVaR","values","in","general","are","not","in-sample","points","."]
code: def get_mvar_set_vectorized(self, Y: Tensor) -> List[Tensor]:
      r"""Find MVaR set based on the definition in [Prekopa2012MVaR]_.
  
      This first calculates the CDF for each point on the extended domain of the
      random variable (the grid defined by the given samples), then takes the
      values with CDF equal to (rounded if necessary) `alpha`. The non-dominated
      subset of these form the MVaR set.
  
      This implementation uses computes the CDF of each point using highly vectorized
      operations. As such, it may use large amounts of memory, particularly when the
      batch size and/or `n_w` are large. It is typically faster than the alternative
      implementation when computing MVaR of a large batch of points with small to
      moderate (<128 for m=2, <64 for m=3) `n_w`.
  
      Args:
          Y: A `batch x n_w x m`-dim tensor of observations.
  
      Returns:
          A `batch` length list of `k x m`-dim tensor of MVaR values, where `k`
          depends on the corresponding batch inputs. Note that MVaR values in general
          are not in-sample points.
      """
      if Y.dim() == 2:
          Y = Y.unsqueeze(0)
      batch, m = Y.shape[0], Y.shape[-1]
      # Note that points in MVaR are bounded from above by the
      # independent VaR of each objective. Hence, we only need to
      # consider the unique outcomes that are less than or equal to
      # the VaR of the independent objectives
      var_alpha_idx = ceil(self.alpha * self.n_w) - 1
      n_points = Y.shape[-2] - var_alpha_idx
      Y_sorted = Y.topk(n_points, dim=-2, largest=False).values
      # `y_grid` is the grid formed by all inputs in each batch.
      if m == 2:
          # This is significantly faster but only works with m=2.
          y_grid = torch.stack(
              [
                  Y_sorted[..., 0].repeat_interleave(
                      repeats=n_points, dim=-1
                  ),
                  Y_sorted[..., 1].repeat(1, n_points),
              ],
              dim=-1,
          )
      else:
          y_grid = torch.stack(
              [
                  torch.stack(
                      torch.meshgrid(
                          [Y_sorted[b, :, i] for i in range(m)],
                          indexing="ij",
                      ),
                      dim=-1,
                  ).view(-1, m)
                  for b in range(batch)
              ],
              dim=0,
          )
      # Get the non-normalized CDF.
      cdf = (
          (Y.unsqueeze(-2) >= y_grid.unsqueeze(-3))
          .all(dim=-1)
          .sum(dim=-2)
      )
      # Get the alpha level points
      alpha_count = ceil(self.alpha * self.n_w)
      # NOTE: Need to loop here since mvar may have different shapes.
      mvar = []
      for b in range(batch):
          alpha_level_points = y_grid[b][cdf[b] == alpha_count]
          # If there are no exact alpha level points, get the smallest alpha' > alpha
          # and find the corresponding alpha level indices.
          if alpha_level_points.numel() == 0:
              min_greater_than_alpha = cdf[b][
                  cdf[b] > alpha_count
              ].min()
              alpha_level_points = y_grid[b][
                  cdf[b] == min_greater_than_alpha
              ]
          # MVaR is the non-dominated subset of alpha level points.
          if self.filter_dominated:
              mask = is_non_dominated(alpha_level_points)
              mvar.append(alpha_level_points[mask])
          else:
              mvar.append(alpha_level_points)
      return mvar
  
imports: import warnings
  from abc import ABC, abstractmethod
  from math import ceil
  from typing import Callable, List, Optional, Union
  import torch
  from botorch.acquisition.multi_objective.objective import IdentityMCMultiOutputObjective, MCMultiOutputObjective
  from botorch.acquisition.risk_measures import CVaR, RiskMeasureMCObjective, VaR
  from botorch.exceptions.errors import UnsupportedError
  from botorch.exceptions.warnings import BotorchWarning
  from botorch.models.model import Model
  from botorch.utils.multi_objective.pareto import is_non_dominated
  from botorch.utils.transforms import normalize
  from torch import Tensor
label_desc: Use image node_id 3 for calling the MVaR obj's underlying member method code with example usage: obj.get_mvar_set_vectorized(Y) and returns: mvar