code: def test_GPyTorchPosterior(self):
      # Test init & mvn property.
      mock_mvn = MockPosterior()
      with self.assertWarnsRegex(
          DeprecationWarning, "The `mvn` argument of"
      ):
          posterior = GPyTorchPosterior(mvn=mock_mvn)
      self.assertIs(posterior.mvn, mock_mvn)
      self.assertIs(posterior.distribution, mock_mvn)
      with self.assertRaisesRegex(
          RuntimeError, "Got both a `distribution`"
      ):
          GPyTorchPosterior(mvn=mock_mvn, distribution=mock_mvn)
      with self.assertRaisesRegex(
          RuntimeError, "GPyTorchPosterior must have"
      ):
          GPyTorchPosterior()
  
      for dtype in (torch.float, torch.double):
          n = 3
          mean = torch.rand(n, dtype=dtype, device=self.device)
          variance = 1 + torch.rand(n, dtype=dtype, device=self.device)
          covar = variance.diag()
          mvn = MultivariateNormal(mean, to_linear_operator(covar))
          posterior = GPyTorchPosterior(distribution=mvn)
          # basics
          self.assertEqual(posterior.device.type, self.device.type)
          self.assertTrue(posterior.dtype == dtype)
          self.assertEqual(
              posterior._extended_shape(), torch.Size([n, 1])
          )
          self.assertTrue(
              torch.equal(posterior.mean, mean.unsqueeze(-1))
          )
          self.assertTrue(
              torch.equal(posterior.variance, variance.unsqueeze(-1))
          )
          # rsample
          samples = posterior.rsample()
          self.assertEqual(samples.shape, torch.Size([1, n, 1]))
          for sample_shape in ([4], [4, 2]):
              samples = posterior.rsample(
                  sample_shape=torch.Size(sample_shape)
              )
              self.assertEqual(
                  samples.shape, torch.Size(sample_shape + [n, 1])
              )
          # check enabling of approximate root decomposition
          with ExitStack() as es:
              mock_func = es.enter_context(
                  mock.patch(
                      ROOT_DECOMP_PATH,
                      return_value=torch.linalg.cholesky(covar),
                  )
              )
              es.enter_context(gpt_settings.max_cholesky_size(0))
              es.enter_context(
                  gpt_settings.fast_computations(
                      covar_root_decomposition=True
                  )
              )
              # need to clear cache, cannot re-use previous objects
              mvn = MultivariateNormal(mean, to_linear_operator(covar))
              posterior = GPyTorchPosterior(distribution=mvn)
              posterior.rsample(sample_shape=torch.Size([4]))
              mock_func.assert_called_once()
  
          # rsample w/ base samples
          base_samples = torch.randn(
              4, 3, device=self.device, dtype=dtype
          )
          # incompatible shapes
          with self.assertRaisesRegex(RuntimeError, "sample_shape"):
              posterior.rsample_from_base_samples(
                  sample_shape=torch.Size([3]),
                  base_samples=base_samples,
              )
          with self.assertRaisesRegex(RuntimeError, "sample_shape"):
              posterior.rsample(
                  sample_shape=torch.Size([3]),
                  base_samples=base_samples,
              )
          # ensure consistent result
          for sample_shape in ([4], [4, 2]):
              base_samples = torch.randn(
                  *sample_shape, 3, device=self.device, dtype=dtype
              )
              samples = [
                  posterior.rsample_from_base_samples(
                      sample_shape=torch.Size(sample_shape),
                      base_samples=base_samples,
                  )
                  for _ in range(2)
              ]
              self.assertAllClose(*samples)
          # Quantile & Density.
          marginal = Normal(
              loc=mean.unsqueeze(-1),
              scale=variance.unsqueeze(-1).sqrt(),
          )
          q_val = torch.rand(2, dtype=dtype, device=self.device)
          quantile = posterior.quantile(q_val)
          self.assertEqual(
              quantile.shape, posterior._extended_shape(torch.Size([2]))
          )
          expected = torch.stack(
              [marginal.icdf(q) for q in q_val], dim=0
          )
          self.assertAllClose(quantile, expected)
          density = posterior.density(q_val)
          self.assertEqual(
              density.shape, posterior._extended_shape(torch.Size([2]))
          )
          expected = torch.stack(
              [marginal.log_prob(q).exp() for q in q_val], dim=0
          )
          self.assertAllClose(density, expected)
          # collapse_batch_dims
          b_mean = torch.rand(2, 3, dtype=dtype, device=self.device)
          b_variance = 1 + torch.rand(
              2, 3, dtype=dtype, device=self.device
          )
          b_covar = torch.diag_embed(b_variance)
          b_mvn = MultivariateNormal(
              b_mean, to_linear_operator(b_covar)
          )
          b_posterior = GPyTorchPosterior(distribution=b_mvn)
          b_base_samples = torch.randn(
              4, 1, 3, 1, device=self.device, dtype=dtype
          )
          with self.assertWarnsRegex(
              DeprecationWarning, "`base_samples` with `rsample`"
          ):
              b_samples = b_posterior.rsample(
                  sample_shape=torch.Size([4]),
                  base_samples=b_base_samples,
              )
          self.assertEqual(b_samples.shape, torch.Size([4, 2, 3, 1]))
  
file_path: botorch/test/posteriors/test_gpytorch.py
imports: import itertools
  import warnings
  from contextlib import ExitStack
  from unittest import mock
  import torch
  from botorch.exceptions import BotorchTensorDimensionError
  from botorch.posteriors.gpytorch import GPyTorchPosterior, scalarize_posterior
  from botorch.utils.testing import _get_test_posterior, BotorchTestCase, MockPosterior
  from gpytorch import settings
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from linear_operator.operators import to_linear_operator
  from torch.distributions.normal import Normal
label_desc: Use image node_id 1 for calling the TestGPyTorchPosterior obj's underlying member method code with example usage: obj.test_GPyTorchPosterior() without return types