docstr: Computes the Second order Sobol indices:
  Args:
      first_order_idxs: Tensor of first order indices.
      first_order_idxs_btsp: Tensor of all first order indices given by bootstrap.
  Returns:
      if num_bootstrap_samples>1
          Tensor: (values,var_mc,stderr_mc)x dim
      else
          Tensor: (values)x dim
docstr_tok: ["Computes","the","Second","order","Sobol","indices",":","Args",":","first_order_idxs",":","Tensor","of","first","order","indices",".","first_order_idxs_btsp",":","Tensor","of","all","first","order","indices","given","by","bootstrap",".","Returns",":","if","num_bootstrap_samples",">","1","Tensor",":","(","values",",","var_mc",",","stderr_mc",")","x","dim","else","Tensor",":","(","values",")","x","dim"]
code: def second_order_indices(
      self,
      first_order_idxs: Optional[torch.Tensor] = None,
      first_order_idxs_btsp: Optional[torch.Tensor] = None,
  ) -> Tensor:
      r"""Computes the Second order Sobol indices:
      Args:
          first_order_idxs: Tensor of first order indices.
          first_order_idxs_btsp: Tensor of all first order indices given by bootstrap.
      Returns:
          if num_bootstrap_samples>1
              Tensor: (values,var_mc,stderr_mc)x dim
          else
              Tensor: (values)x dim
      """
  
      if not self.second_order:
          raise ValueError(
              "Second order indices has to be specified in the sensitivity definition"
          )
      if first_order_idxs is None:
          first_order_idxs = self.first_order_idxs
      second_order_idxs = []
      for i in range(self.dim):
          for j in range(i + 1, self.dim):
              vij = torch.mean(
                  self.f_BAis[i] * self.f_ABis[j]
                  - self.f_A * self.f_B  # pyre-ignore
              )
              vij = (
                  (vij / self.f_total_var)
                  - first_order_idxs[i]  # pyre-ignore
                  - first_order_idxs[j]
              )
              second_order_idxs.append(vij.unsqueeze(0))
      if not (self.bootstrap):
          second_order_idxs = torch.cat(
              second_order_idxs, dim=0
          ).detach()
          return second_order_idxs
      else:
          second_order_idxs_btsp = [
              torch.cat(second_order_idxs, dim=0).unsqueeze(0)
          ]
          if first_order_idxs_btsp is None:
              first_order_idxs_btsp = self.first_order_idxs_btsp
          for b in range(self.num_bootstrap_samples):
              second_order_idxs = []
              for i in range(self.dim):
                  for j in range(i + 1, self.dim):
                      vij = torch.mean(
                          self.f_BAis_btsp[b][i]
                          * self.f_ABis_btsp[b][j]
                          - self.f_A_btsp[b] * self.f_B_btsp[b]
                      )
                      vij = (
                          (vij / self.f_total_var_btsp[b])
                          - first_order_idxs_btsp[b][i]
                          - first_order_idxs_btsp[b][j]
                      )
                      second_order_idxs.append(vij.unsqueeze(0))
              second_order_idxs_btsp.append(
                  torch.cat(second_order_idxs, dim=0).unsqueeze(0)
              )
          second_order_idxs_btsp = torch.cat(
              second_order_idxs_btsp, dim=0
          )
          if self.bootstrap_array:
              return second_order_idxs_btsp.detach()
          else:
              return (
                  torch.cat(
                      [
                          second_order_idxs_btsp.mean(dim=0).unsqueeze(
                              0
                          ),
                          second_order_idxs_btsp.var(dim=0).unsqueeze(
                              0
                          ),
                          torch.sqrt(
                              second_order_idxs_btsp.var(dim=0)
                              / (self.num_bootstrap_samples + 1)
                          ).unsqueeze(0),
                      ],
                      dim=0,
                  )
                  .t()
                  .detach()
              )
  
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 6 for calling the SobolSensitivity obj's underlying member method code with example usage: obj.second_order_indices(first_order_idxs, first_order_idxs_btsp) and returns: second_order_idxs, second_order_idxs_btsp, torch