code: def test_expand_and_copy_tensor(self):
      for input_batch_shape, batch_shape in product(
          (torch.Size([4, 1]), torch.Size([2, 3, 1])),
          (torch.Size([5]), torch.Size([])),
      ):
          with self.subTest(
              input_batch_shape=input_batch_shape,
              batch_shape=batch_shape,
          ):
              if len(batch_shape) == 0:
                  input_batch_shape = input_batch_shape[:-1]
              X = torch.rand(input_batch_shape + torch.Size([2, 1]))
              expand_shape = (
                  torch.broadcast_shapes(input_batch_shape, batch_shape)
                  + X.shape[-2:]
              )
              X_tf = expand_and_copy_tensor(X, batch_shape=batch_shape)
              self.assertEqual(X_tf.shape, expand_shape)
              self.assertFalse(X_tf is X.expand(expand_shape))
      with self.assertRaisesRegex(
          RuntimeError, "are not broadcastable"
      ):
          expand_and_copy_tensor(
              X=torch.rand(2, 2, 3), batch_shape=torch.Size([3])
          )
  
file_path: botorch/test/models/transforms/test_utils.py
imports: import math
  from itertools import product
  import torch
  from botorch.models.transforms.utils import expand_and_copy_tensor, lognorm_to_norm, norm_to_lognorm, norm_to_lognorm_mean, norm_to_lognorm_variance
  from botorch.utils.testing import BotorchTestCase
label_desc: Use image node_id 4 for calling the TestTransformUtils obj's underlying member method code with example usage: obj.test_expand_and_copy_tensor() without return types