class_docstr: Engine for qMC sampling from a Multivariate Normal `N(0, I_d)`.
  
  By default, this implementation uses Box-Muller transformed Sobol samples
  following pg. 123 in [Pages2018numprob]_. To use the inverse transform
  instead, set `inv_transform=True`.
  
  Example:
      >>> engine = NormalQMCEngine(3)
      >>> samples = engine.draw(16)
docstr: Draw `n` qMC samples from the standard Normal.
  
  Args:
      n: The number of samples to draw. As a best practice, use powers of 2.
      out: An option output tensor. If provided, draws are put into this
          tensor, and the function returns None.
      dtype: The desired torch data type (ignored if `out` is provided).
  
  Returns:
      A `n x d` tensor of samples if `out=None` and `None` otherwise.
code: def draw(
      self,
      n: int = 1,
      out: Optional[Tensor] = None,
      dtype: torch.dtype = torch.float,
  ) -> Optional[Tensor]:
      r"""Draw `n` qMC samples from the standard Normal.
  
      Args:
          n: The number of samples to draw. As a best practice, use powers of 2.
          out: An option output tensor. If provided, draws are put into this
              tensor, and the function returns None.
          dtype: The desired torch data type (ignored if `out` is provided).
  
      Returns:
          A `n x d` tensor of samples if `out=None` and `None` otherwise.
      """
      # get base samples
      samples = self._sobol_engine.draw(n, dtype=dtype)
      if self._inv_transform:
          # apply inverse transform (values to close to 0/1 result in inf values)
          v = 0.5 + (1 - torch.finfo(samples.dtype).eps) * (
              samples - 0.5
          )
          samples_tf = torch.erfinv(2 * v - 1) * math.sqrt(2)
      else:
          # apply Box-Muller transform (note: [1] indexes starting from 1)
          even = torch.arange(0, samples.shape[-1], 2)
          Rs = (-2 * torch.log(samples[:, even])).sqrt()
          thetas = 2 * math.pi * samples[:, 1 + even]
          cos = torch.cos(thetas)
          sin = torch.sin(thetas)
          samples_tf = torch.stack([Rs * cos, Rs * sin], -1).reshape(
              n, -1
          )
          # make sure we only return the number of dimension requested
          samples_tf = samples_tf[:, : self._d]
      if out is None:
          return samples_tf
      else:
          out.copy_(samples_tf)
  
file_path: botorch/botorch/sampling/qmc.py
imports: from __future__ import annotations
  import math
  from typing import Optional
  import torch
  from torch import Tensor
  from torch.quasirandom import SobolEngine
label_desc: Use image node_id 2 for calling the NormalQMCEngine obj's underlying member method code with example usage: obj.draw(n, out, dtype) and returns: samples_tf