class_docstr: Module which computes SIFT descriptors of given patches.
  
  Args:
      patch_size: Input patch size in pixels.
      num_ang_bins: Number of angular bins.
      num_spatial_bins: Number of spatial bins.
      clipval: clipping value to reduce single-bin dominance
      rootsift: if ``True``, RootSIFT (Arandjelović et. al, 2012) is computed.
  
  Returns:
      SIFT descriptor of the patches with shape.
  
  Shape:
      - Input: :math:`(B, 1, \text{num_spatial_bins}, \text{num_spatial_bins})`
      - Output: :math:`(B, \text{num_ang_bins * num_spatial_bins ** 2})`
  
  Example:
      >>> input = torch.rand(23, 1, 32, 32)
      >>> SIFT = SIFTDescriptor(32, 8, 4)
      >>> descs = SIFT(input) # 23x128
code: def __init__(
      self,
      patch_size: int = 41,
      num_ang_bins: int = 8,
      num_spatial_bins: int = 4,
      rootsift: bool = True,
      clipval: float = 0.2,
  ) -> None:
      super().__init__()
      self.eps = 1e-10
      self.num_ang_bins = num_ang_bins
      self.num_spatial_bins = num_spatial_bins
      self.clipval = clipval
      self.rootsift = rootsift
      self.patch_size = patch_size
  
      ks: int = self.patch_size
      sigma: float = float(ks) / math.sqrt(2.0)
      self.gk = get_gaussian_kernel2d((ks, ks), (sigma, sigma), True)
  
      (
          self.bin_ksize,
          self.bin_stride,
          self.pad,
      ) = get_sift_bin_ksize_stride_pad(patch_size, num_spatial_bins)
  
      nw = get_sift_pooling_kernel(ksize=self.bin_ksize).float()
      self.pk = nn.Conv2d(
          1,
          1,
          kernel_size=(nw.size(0), nw.size(1)),
          stride=(self.bin_stride, self.bin_stride),
          padding=(self.pad, self.pad),
          bias=False,
      )
      self.pk.weight.data.copy_(
          nw.reshape(1, 1, nw.size(0), nw.size(1))
      )
  
imports: import math
  from typing import Tuple
  import torch
  from torch import nn
  from kornia.core import Module, Tensor, concatenate, eye, normalize
  from kornia.core.check import KORNIA_CHECK_SHAPE
  from kornia.filters import get_gaussian_kernel2d, spatial_gradient
  from kornia.geometry.conversions import pi
label_desc: Use image node_id 2 to create a new SIFTDescriptor object from inherited base classes: Module with example: obj = SIFTDescriptor(patch_size, num_ang_bins, num_spatial_bins, rootsift, clipval)