class_docstr: A cost-aware utility using inverse cost weighting based on a model.
  
  Computes the cost-aware utility by inverse-weighting samples
  `U = (u_1, ..., u_N)` of the increase in utility. If `use_mean=True`, this
  uses the posterior mean `mean_cost` of the cost model, i.e.
  `weighted utility = mean(U) / mean_cost`. If `use_mean=False`, it uses
  samples `C = (c_1, ..., c_N)` from the posterior of the cost model and
  performs the inverse weighting on the sample level:
  `weighted utility = mean(u_1 / c_1, ..., u_N / c_N)`.
  
  The cost is additive across multiple elements of a q-batch.
class_docstr_tok: ["A","cost-aware","utility","using","inverse","cost","weighting","based","on","a","model",".","Computes","the","cost-aware","utility","by","inverse-weighting","samples","`","U","=","(","u_1",",","...",",","u_N",")","`","of","the","increase","in","utility",".","If","`","use_mean=True","`",",","this","uses","the","posterior","mean","`","mean_cost","`","of","the","cost","model",",","i.e",".","`","weighted","utility","=","mean","(","U",")","\/","mean_cost","`",".","If","`","use_mean=False","`",",","it","uses","samples","`","C","=","(","c_1",",","...",",","c_N",")","`","from","the","posterior","of","the","cost","model","and","performs","the","inverse","weighting","on","the","sample","level",":","`","weighted","utility","=","mean","(","u_1","\/","c_1",",","...",",","u_N","\/","c_N",")","`",".","The","cost","is","additive","across","multiple","elements","of","a","q-batch","."]
docstr: Evaluate the cost function on the candidates and improvements.
  
  Args:
      X: A `batch_shape x q x d`-dim Tensor of with `q` `d`-dim design
          points each for each t-batch.
      deltas: A `num_fantasies x batch_shape`-dim Tensor of `num_fantasy`
          samples from the marginal improvement in utility over the
          current state at `X` for each t-batch.
      sampler: A sampler used for sampling from the posterior of the cost
          model (required if `use_mean=False`, ignored if `use_mean=True`).
      X_evaluation_mask: A `q x m`-dim boolean tensor indicating which
          outcomes should be evaluated for each design in the batch.
  
  Returns:
      A `num_fantasies x batch_shape`-dim Tensor of cost-weighted utilities.
docstr_tok: ["Evaluate","the","cost","function","on","the","candidates","and","improvements",".","Args",":","X",":","A","`","batch_shape","x","q","x","d","`","-dim","Tensor","of","with","`","q","`","`","d","`","-dim","design","points","each","for","each","t-batch",".","deltas",":","A","`","num_fantasies","x","batch_shape","`","-dim","Tensor","of","`","num_fantasy","`","samples","from","the","marginal","improvement","in","utility","over","the","current","state","at","`","X","`","for","each","t-batch",".","sampler",":","A","sampler","used","for","sampling","from","the","posterior","of","the","cost","model","(","required","if","`","use_mean=False","`",",","ignored","if","`","use_mean=True","`",")",".","X_evaluation_mask",":","A","`","q","x","m","`","-dim","boolean","tensor","indicating","which","outcomes","should","be","evaluated","for","each","design","in","the","batch",".","Returns",":","A","`","num_fantasies","x","batch_shape","`","-dim","Tensor","of","cost-weighted","utilities","."]
code: def forward(
      self,
      X: Tensor,
      deltas: Tensor,
      sampler: Optional[MCSampler] = None,
      X_evaluation_mask: Optional[Tensor] = None,
      **kwargs: Any,
  ) -> Tensor:
      r"""Evaluate the cost function on the candidates and improvements.
  
      Args:
          X: A `batch_shape x q x d`-dim Tensor of with `q` `d`-dim design
              points each for each t-batch.
          deltas: A `num_fantasies x batch_shape`-dim Tensor of `num_fantasy`
              samples from the marginal improvement in utility over the
              current state at `X` for each t-batch.
          sampler: A sampler used for sampling from the posterior of the cost
              model (required if `use_mean=False`, ignored if `use_mean=True`).
          X_evaluation_mask: A `q x m`-dim boolean tensor indicating which
              outcomes should be evaluated for each design in the batch.
  
      Returns:
          A `num_fantasies x batch_shape`-dim Tensor of cost-weighted utilities.
      """
      if not self._use_mean and sampler is None:
          raise RuntimeError(
              "Must provide `sampler` if `use_mean=False`"
          )
      if X_evaluation_mask is not None:
          # TODO: support different evaluation masks for each X. This requires
          # either passing evaluation_mask to `cost_model.posterior`
          # or assuming that evaluating `cost_model.posterior(X)` on all
          # `q` points and then only selecting the costs for relevant points
          # does not change the cost function for each point. This would not be
          # true for instance if the incremental cost of evaluating an additional
          # point decreased as the number of points increased.
          if not all(
              torch.equal(X_evaluation_mask[0], X_evaluation_mask[i])
              for i in range(1, X_evaluation_mask.shape[0])
          ):
              raise NotImplementedError(
                  "Currently, all candidates must be evaluated on the same outputs."
              )
          output_indices = (
              X_evaluation_mask[0].nonzero().view(-1).tolist()
          )
      else:
          output_indices = None
      cost_posterior = self.cost_model.posterior(
          X, output_indices=output_indices
      )
      if self._use_mean:
          cost = cost_posterior.mean  # batch_shape x q x m'
      else:
          # This will be of shape num_fantasies x batch_shape x q x m'
          cost = sampler(cost_posterior)
          # TODO: Make sure this doesn't change base samples in-place
      cost = self.cost_objective(cost)
  
      # Ensure non-negativity of the cost
      if settings.debug.on():
          if torch.any(cost < -1e-7):
              warnings.warn(
                  "Encountered negative cost values in InverseCostWeightedUtility",
                  CostAwareWarning,
              )
      # clamp (away from zero) and sum cost across elements of the q-batch -
      # this will be of shape `num_fantasies x batch_shape` or `batch_shape`
      cost = cost.clamp_min(self._min_cost).sum(dim=-1)
  
      # if we are doing inverse weighting on the sample level, clamp numerator.
      if not self._use_mean:
          deltas = deltas.clamp_min(0.0)
  
      # compute and return the ratio on the sample level - If `use_mean=True`
      # this operation involves broadcasting the cost across fantasies
      return deltas / cost
  
imports: from __future__ import annotations
  import warnings
  from abc import ABC, abstractmethod
  from typing import Any, Callable, Optional, Union
  import torch
  from botorch import settings
  from botorch.acquisition.objective import GenericMCObjective, IdentityMCObjective, MCAcquisitionObjective
  from botorch.exceptions.warnings import CostAwareWarning
  from botorch.models.deterministic import DeterministicModel
  from botorch.models.gpytorch import GPyTorchModel
  from botorch.sampling.base import MCSampler
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 2 for calling the InverseCostWeightedUtility obj's underlying member method code with example usage: obj.forward(X, deltas, sampler, X_evaluation_mask) and returns: unknown