code: def test_boltzmann_sampling(self):
      dtypes = (torch.float, torch.double)
      batch_shapes = (torch.Size(), torch.Size([3]))
  
      # test a bunch of combinations
      for (
          batch_shape,
          N,
          d,
          num_samples,
          repl,
          dtype,
      ) in itertools.product(
          batch_shapes, [6, 7], [1, 2], [4, 5], [True, False], dtypes
      ):
          tkwargs = {"device": self.device, "dtype": dtype}
          X = torch.rand(*batch_shape, N, d, **tkwargs)
          acqval = torch.randn(N, *batch_shape, **tkwargs)
          acqf = mock.Mock(return_value=acqval)
          BS = BoltzmannSampling(acqf, replacement=repl, eta=2.0)
          samples = BS(X, num_samples=num_samples)
          self.assertEqual(
              samples.shape, batch_shape + torch.Size([num_samples, d])
          )
          self.assertEqual(samples.dtype, dtype)
          if not repl:
              # check that we don't repeat points
              self.assertEqual(
                  torch.unique(samples, dim=-2).size(-2), num_samples
              )
  
      # check that we do indeed pick the maximum for large eta
      for N, d, dtype in itertools.product([6, 7], [1, 2], dtypes):
          tkwargs = {"device": self.device, "dtype": dtype}
          X = torch.rand(N, d, **tkwargs)
          acqval = torch.zeros(N, **tkwargs)
          max_idx = torch.randint(N, (1,))
          acqval[max_idx] = 10.0
          acqf = mock.Mock(return_value=acqval)
          BS = BoltzmannSampling(acqf, eta=10.0)
          samples = BS(X, num_samples=1)
          self.assertTrue(torch.equal(samples, X[max_idx, :]))
  
imports: from __future__ import annotations
  import itertools
  from unittest import mock
  import torch
  from botorch.acquisition.analytic import PosteriorMean
  from botorch.acquisition.objective import IdentityMCObjective, LinearMCObjective, ScalarizedPosteriorTransform
  from botorch.generation.sampling import BoltzmannSampling, ConstrainedMaxPosteriorSampling, MaxPosteriorSampling, SamplingStrategy
  from botorch.models import SingleTaskGP
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.utils.testing import BotorchTestCase, MockModel, MockPosterior
label_desc: Use image node_id 2 for calling the TestBoltzmannSampling obj's underlying member method code with example usage: obj.test_boltzmann_sampling() without return types