code: def normalize(X: Tensor, bounds: Tensor) -> Tensor:
      r"""Min-max normalize X w.r.t. the provided bounds.
  
      Args:
          X: `... x d` tensor of data
          bounds: `2 x d` tensor of lower and upper bounds for each of the X's d
              columns.
  
      Returns:
          A `... x d`-dim tensor of normalized data, given by
              `(X - bounds[0]) / (bounds[1] - bounds[0])`. If all elements of `X`
              are contained within `bounds`, the normalized values will be
              contained within `[0, 1]^d`.
  
      Example:
          >>> X = torch.rand(4, 3)
          >>> bounds = torch.stack([torch.zeros(3), 0.5 * torch.ones(3)])
          >>> X_normalized = normalize(X, bounds)
      """
      return (X - bounds[0]) / (bounds[1] - bounds[0])
  
file_path: botorch/botorch/utils/transforms.py
imports: from __future__ import annotations
  import warnings
  from functools import wraps
  from typing import Any, Callable, List, Optional, TYPE_CHECKING
  import torch
  from botorch.utils.safe_math import logmeanexp
  from torch import Tensor
label_desc: Use image node_id 2 for calling a global function with example usage: normalize(X, bounds) and returns: unknown