code: def fix_features(
      X: Tensor,
      fixed_features: Optional[Dict[int, Optional[float]]] = None,
  ) -> Tensor:
      r"""Fix feature values in a Tensor.
  
      The fixed features will have zero gradient in downstream calculations.
  
      Args:
          X: input Tensor with shape `... x p`, where `p` is the number of features
          fixed_features: A dictionary with keys as column indices and values
              equal to what the feature should be set to in `X`. If the value is
              None, that column is just considered fixed. Keys should be in the
              range `[0, p - 1]`.
  
      Returns:
          The tensor X with fixed features.
      """
      if fixed_features is None:
          return X
  
      columns = list(X.unbind(dim=-1))
      for index, value in fixed_features.items():
          if value is None:
              columns[index] = columns[index].detach()
          else:
              columns[index] = torch.full_like(columns[index], value)
  
      return torch.stack(columns, dim=-1)
  
file_path: botorch/botorch/optim/utils/acquisition_utils.py
imports: from __future__ import annotations
  from typing import Dict, Optional, Union
  from warnings import warn
  import torch
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.exceptions.errors import BotorchError
  from botorch.exceptions.warnings import BotorchWarning
  from botorch.models.gpytorch import ModelListGPyTorchModel
  from torch import Tensor
label_desc: Use image node_id 2 for calling a global function with example usage: fix_features(X, fixed_features) and returns: torch, X