docstr: Computes three types of Sobol indices:
  first order indices, total indices and second order indices (if specified ).
  
  Args:
      bounds: Parameter bounds over which to evaluate model sensitivity.
      input_function: The objective function.
      num_mc_samples: The number of montecarlo grid samples
      input_qmc: If True, a qmc Sobol grid is use instead of uniformly random.
      second_order: If True, the second order indices are computed.
      bootstrap: If true, the MC error is returned.
      num_bootstrap_samples: If bootstrap is true, the number of bootstraps has
          to be specified.
      bootstrap_array: If true, all the num_bootstrap_samples extimated indices
          are returned instead of their mean and Var.
docstr_tok: ["Computes","three","types","of","Sobol","indices",":","first","order","indices",",","total","indices","and","second","order","indices","(","if","specified",")",".","Args",":","bounds",":","Parameter","bounds","over","which","to","evaluate","model","sensitivity",".","input_function",":","The","objective","function",".","num_mc_samples",":","The","number","of","montecarlo","grid","samples","input_qmc",":","If","True",",","a","qmc","Sobol","grid","is","use","instead","of","uniformly","random",".","second_order",":","If","True",",","the","second","order","indices","are","computed",".","bootstrap",":","If","true",",","the","MC","error","is","returned",".","num_bootstrap_samples",":","If","bootstrap","is","true",",","the","number","of","bootstraps","has","to","be","specified",".","bootstrap_array",":","If","true",",","all","the","num_bootstrap_samples","extimated","indices","are","returned","instead","of","their","mean","and","Var","."]
code: def __init__(
      self,
      bounds: torch.Tensor,
      input_function: Optional[
          Callable[[torch.Tensor], torch.Tensor]
      ] = None,
      num_mc_samples: int = 10**4,
      input_qmc: bool = False,
      second_order: bool = False,
      num_bootstrap_samples: int = 1,
      bootstrap_array: bool = False,
  ) -> None:
      r"""Computes three types of Sobol indices:
      first order indices, total indices and second order indices (if specified ).
  
      Args:
          bounds: Parameter bounds over which to evaluate model sensitivity.
          input_function: The objective function.
          num_mc_samples: The number of montecarlo grid samples
          input_qmc: If True, a qmc Sobol grid is use instead of uniformly random.
          second_order: If True, the second order indices are computed.
          bootstrap: If true, the MC error is returned.
          num_bootstrap_samples: If bootstrap is true, the number of bootstraps has
              to be specified.
          bootstrap_array: If true, all the num_bootstrap_samples extimated indices
              are returned instead of their mean and Var.
      """
      self.input_function = input_function
      self.dim: int = bounds.shape[-1]
      self.num_mc_samples = num_mc_samples
      self.second_order = second_order
      self.bootstrap: bool = num_bootstrap_samples > 1
      self.num_bootstrap_samples: int = (
          num_bootstrap_samples - 1
      )  # deduct 1 because the first is meant to be the full grid
      self.bootstrap_array = bootstrap_array
      if input_qmc:
          sobol_kwargs = {"bounds": bounds, "n": num_mc_samples, "q": 1}
          seed_A, seed_B = 1234, 5678  # to make it reproducible
          # pyre-ignore
          self.A = draw_sobol_samples(
              **sobol_kwargs, seed=seed_A
          ).squeeze(1)
          # pyre-ignore
          self.B = draw_sobol_samples(
              **sobol_kwargs, seed=seed_B
          ).squeeze(1)
      else:
          self.A = unnormalize(
              torch.rand(num_mc_samples, self.dim), bounds=bounds
          )
          self.B = unnormalize(
              torch.rand(num_mc_samples, self.dim), bounds=bounds
          )
      # pyre-fixme[4]: Attribute must be annotated.
      self.A_B_ABi = self.generate_all_input_matrix().to(torch.double)
  
      if self.bootstrap:
          subset_size = 4
          # pyre-fixme[4]: Attribute must be annotated.
          self.bootstrap_indices = torch.randint(
              0,
              num_mc_samples,
              (self.num_bootstrap_samples, subset_size),
          )
      self.f_A: Optional[torch.Tensor] = None
      self.f_B: Optional[torch.Tensor] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_ABis: Optional[List] = None
      self.f_total_var: Optional[torch.Tensor] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_A_btsp: Optional[List] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_B_btsp: Optional[List] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_ABis_btsp: Optional[List] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_total_var_btsp: Optional[List] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_BAis: Optional[List] = None
      # pyre-fixme[24]: Generic type `list` expects 1 type parameter, use
      #  `typing.List` to avoid runtime subscripting errors.
      self.f_BAis_btsp: Optional[List] = None
      self.first_order_idxs: Optional[torch.Tensor] = None
      self.first_order_idxs_btsp: Optional[torch.Tensor] = None
  
imports: from copy import deepcopy
  from typing import Any, Callable, Dict, List, Optional, Union
  import numpy
  import torch
  from ax.modelbridge.torch import TorchModelBridge
  from ax.models.torch.botorch import BotorchModel
  from ax.models.torch.botorch_modular.model import BoTorchModel
  from ax.utils.common.typeutils import checked_cast
  from botorch.models.model import Model, ModelList
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from botorch.sampling.normal import SobolQMCNormalSampler
  from botorch.utils.sampling import draw_sobol_samples
  from botorch.utils.transforms import unnormalize
  from torch import Tensor
label_desc: Use image node_id 1 to create a new SobolSensitivity object from inherited base classes: object with example: obj = SobolSensitivity(bounds, input_function, num_mc_samples, input_qmc, second_order, num_bootstrap_samples, bootstrap_array)