class_docstr: Feasibility-weighted objective.
  
  An Objective allowing to maximize some scalable objective on the model
  outputs subject to a number of constraints. Constraint feasibilty is
  approximated by a sigmoid function.
  
      mc_acq(X) = (
      (objective(X) + infeasible_cost) * \prod_i (1  - sigmoid(constraint_i(X)))
      ) - infeasible_cost
  
  See `botorch.utils.objective.apply_constraints` for details on the constraint
  handling.
  
  Example:
      >>> bound = 0.0
      >>> objective = lambda Y: Y[..., 0]
      >>> # apply non-negativity constraint on f(x)[1]
      >>> constraint = lambda Y: bound - Y[..., 1]
      >>> constrained_objective = ConstrainedMCObjective(objective, [constraint])
      >>> samples = sampler(posterior)
      >>> objective = constrained_objective(samples)
  
  TODO: Deprecate this as default way to handle constraints with MC acquisition
  functions once we have data on how well SampleReducingMCAcquisitionFunction works.
class_docstr_tok: ["Feasibility-weighted","objective",".","An","Objective","allowing","to","maximize","some","scalable","objective","on","the","model","outputs","subject","to","a","number","of","constraints",".","Constraint","feasibilty","is","approximated","by","a","sigmoid","function",".","mc_acq","(","X",")","=","(","(","objective","(","X",")","+","infeasible_cost",")","*","\\prod_i","(","1","-","sigmoid","(","constraint_i","(","X",")",")",")",")","-","infeasible_cost","See","`","botorch.utils.objective.apply_constraints","`","for","details","on","the","constraint","handling",".","Example",":",">",">",">","bound","=","0.0",">",">",">","objective","=","lambda","Y",":","Y","[","...",",","0","]",">",">",">","#","apply","non-negativity","constraint","on","f","(","x",")","[","1","]",">",">",">","constraint","=","lambda","Y",":","bound","-","Y","[","...",",","1","]",">",">",">","constrained_objective","=","ConstrainedMCObjective","(","objective",",","[","constraint","]",")",">",">",">","samples","=","sampler","(","posterior",")",">",">",">","objective","=","constrained_objective","(","samples",")","TODO",":","Deprecate","this","as","default","way","to","handle","constraints","with","MC","acquisition","functions","once","we","have","data","on","how","well","SampleReducingMCAcquisitionFunction","works","."]
docstr: Args:
      objective: A callable `f(samples, X)` mapping a
          `sample_shape x batch-shape x q x m`-dim Tensor `samples` and
          an optional `batch-shape x q x d`-dim Tensor `X` to a
          `sample_shape x batch-shape x q`-dim Tensor of objective values.
      constraints: A list of callables, each mapping a Tensor of dimension
          `sample_shape x batch-shape x q x m` to a Tensor of dimension
          `sample_shape x batch-shape x q`, where negative values imply
          feasibility.
      infeasible_cost: The cost of a design if all associated samples are
          infeasible.
      eta: The temperature parameter of the sigmoid function approximating
          the constraint. Can be either a float or a 1-dim tensor. In case
          of a float the same eta is used for every constraint in
          constraints. In case of a tensor the length of the tensor must
          match the number of provided constraints. The i-th constraint is
          then estimated with the i-th eta value.
code: def __init__(
      self,
      objective: Callable[[Tensor, Optional[Tensor]], Tensor],
      constraints: List[Callable[[Tensor], Tensor]],
      infeasible_cost: Union[Tensor, float] = 0.0,
      eta: Union[Tensor, float] = 1e-3,
  ) -> None:
      r"""
      Args:
          objective: A callable `f(samples, X)` mapping a
              `sample_shape x batch-shape x q x m`-dim Tensor `samples` and
              an optional `batch-shape x q x d`-dim Tensor `X` to a
              `sample_shape x batch-shape x q`-dim Tensor of objective values.
          constraints: A list of callables, each mapping a Tensor of dimension
              `sample_shape x batch-shape x q x m` to a Tensor of dimension
              `sample_shape x batch-shape x q`, where negative values imply
              feasibility.
          infeasible_cost: The cost of a design if all associated samples are
              infeasible.
          eta: The temperature parameter of the sigmoid function approximating
              the constraint. Can be either a float or a 1-dim tensor. In case
              of a float the same eta is used for every constraint in
              constraints. In case of a tensor the length of the tensor must
              match the number of provided constraints. The i-th constraint is
              then estimated with the i-th eta value.
      """
      super().__init__(objective=objective)
      self.constraints = constraints
      if type(eta) is not Tensor:
          eta = torch.full((len(constraints),), eta)
      self.register_buffer("eta", eta)
      self.register_buffer(
          "infeasible_cost", torch.as_tensor(infeasible_cost)
      )
  
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 1 to create a new ConstrainedMCObjective object from inherited base classes: GenericMCObjective with example: obj = ConstrainedMCObjective(objective, constraints, infeasible_cost, eta)