class_docstr: Constrained max posterior sampling.
  
  Posterior sampling where we try to maximize an objective function while
  simulatenously satisfying a set of constraints c1(x) <= 0, c2(x) <= 0,
  ..., cm(x) <= 0 where c1, c2, ..., cm are black-box constraint functions.
  Each constraint function is modeled by a seperate GP model. We follow the
  procedure as described in https://doi.org/10.48550/arxiv.2002.08526.
  
  Example:
      >>> CMPS = ConstrainedMaxPosteriorSampling(
              model,
              constraint_model=ModelListGP(cmodel1, cmodel2),
          )
      >>> X = torch.rand(2, 100, 3)
      >>> sampled_X = CMPS(X, num_samples=5)
docstr: Constructor for the SamplingStrategy base class.
  
  Args:
      model: A fitted model.
      objective: The MCAcquisitionObjective under which the samples are evaluated.
          Defaults to `IdentityMCObjective()`.
      posterior_transform: An optional PosteriorTransform for the objective
          function (corresponding to `model`).
      replacement: If True, sample with replacement.
      constraint_model: either a ModelListGP where each submodel is a GP model for
          one constraint function, or a MultiTaskGP model where each task is one
          constraint function. All constraints are of the form c(x) <= 0. In the
          case when the constraint model predicts that all candidates
          violate constraints, we pick the candidates with minimum violation.
docstr_tok: ["Constructor","for","the","SamplingStrategy","base","class",".","Args",":","model",":","A","fitted","model",".","objective",":","The","MCAcquisitionObjective","under","which","the","samples","are","evaluated",".","Defaults","to","`","IdentityMCObjective","(",")","`",".","posterior_transform",":","An","optional","PosteriorTransform","for","the","objective","function","(","corresponding","to","`","model","`",")",".","replacement",":","If","True",",","sample","with","replacement",".","constraint_model",":","either","a","ModelListGP","where","each","submodel","is","a","GP","model","for","one","constraint","function",",","or","a","MultiTaskGP","model","where","each","task","is","one","constraint","function",".","All","constraints","are","of","the","form","c","(","x",")","<","=","0",".","In","the","case","when","the","constraint","model","predicts","that","all","candidates","violate","constraints",",","we","pick","the","candidates","with","minimum","violation","."]
code: def __init__(
      self,
      model: Model,
      constraint_model: Union[ModelListGP, MultiTaskGP],
      objective: Optional[MCAcquisitionObjective] = None,
      posterior_transform: Optional[PosteriorTransform] = None,
      replacement: bool = True,
  ) -> None:
      r"""Constructor for the SamplingStrategy base class.
  
      Args:
          model: A fitted model.
          objective: The MCAcquisitionObjective under which the samples are evaluated.
              Defaults to `IdentityMCObjective()`.
          posterior_transform: An optional PosteriorTransform for the objective
              function (corresponding to `model`).
          replacement: If True, sample with replacement.
          constraint_model: either a ModelListGP where each submodel is a GP model for
              one constraint function, or a MultiTaskGP model where each task is one
              constraint function. All constraints are of the form c(x) <= 0. In the
              case when the constraint model predicts that all candidates
              violate constraints, we pick the candidates with minimum violation.
      """
      if objective is not None:
          raise NotImplementedError(
              "`objective` is not supported for `ConstrainedMaxPosteriorSampling`."
          )
  
      super().__init__(
          model=model,
          objective=objective,
          posterior_transform=posterior_transform,
          replacement=replacement,
      )
      self.constraint_model = constraint_model
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from typing import Any, Optional, Union
  import torch
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.objective import IdentityMCObjective, MCAcquisitionObjective, PosteriorTransform
  from botorch.generation.utils import _flip_sub_unique
  from botorch.models.model import Model
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.models.multitask import MultiTaskGP
  from botorch.utils.sampling import batched_multinomial
  from botorch.utils.transforms import standardize
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 1 to create a new ConstrainedMaxPosteriorSampling object from inherited base classes: MaxPosteriorSampling with example: obj = ConstrainedMaxPosteriorSampling(model, constraint_model, objective, posterior_transform, replacement)