class_docstr: A kernel that supports spectral learning for GPs, where the underlying spectral density is modeled as a mixture
  of delta distributions (e.g., with point masses). This has been explored e.g. in Lazaro-Gredilla et al., 2010.
  
  Conceptually, this kernel is similar to random Fourier features as implemented in RFFKernel, but instead of sampling
  a Gaussian to determine the spectrum sites, they are treated as learnable parameters.
  
  When using CG for inference, this kernel supports linear space and time (in N) for training and inference.
  
  :param int num_dims: Dimensionality of input data that this kernel will operate on. Note that if active_dims is
      used, this should be the length of the active dim set.
  :param int num_deltas: Number of point masses to learn.
docstr: Initialize the point masses for this kernel from the empirical spectrum of the data. To do this, we estimate
  the empirical spectrum's CDF and then simply sample from it. This is analogous to how the SM kernel's mixture
  is initialized, but we skip the last step of fitting a GMM to the samples and just use the samples directly.
docstr_tok: ["Initialize","the","point","masses","for","this","kernel","from","the","empirical","spectrum","of","the","data",".","To","do","this",",","we","estimate","the","empirical","spectrum","'s","CDF","and","then","simply","sample","from","it",".","This","is","analogous","to","how","the","SM","kernel","'s","mixture","is","initialized",",","but","we","skip","the","last","step","of","fitting","a","GMM","to","the","samples","and","just","use","the","samples","directly","."]
code: def initialize_from_data(self, train_x, train_y):
      """
      Initialize the point masses for this kernel from the empirical spectrum of the data. To do this, we estimate
      the empirical spectrum's CDF and then simply sample from it. This is analogous to how the SM kernel's mixture
      is initialized, but we skip the last step of fitting a GMM to the samples and just use the samples directly.
      """
      import numpy as np
      from scipy.fftpack import fft
      from scipy.integrate import cumtrapz
  
      N = train_x.size(-2)
      emp_spect = np.abs(fft(train_y.cpu().detach().numpy())) ** 2 / N
      M = math.floor(N / 2)
  
      freq1 = np.arange(M + 1)
      freq2 = np.arange(-M + 1, 0)
      freq = np.hstack((freq1, freq2)) / N
      freq = freq[: M + 1]
      emp_spect = emp_spect[: M + 1]
  
      total_area = np.trapz(emp_spect, freq)
      spec_cdf = np.hstack((np.zeros(1), cumtrapz(emp_spect, freq)))
      spec_cdf = spec_cdf / total_area
  
      a = np.random.rand(self.raw_Z.size(-2), 1)
      p, q = np.histogram(a, spec_cdf)
      bins = np.digitize(a, q)
      slopes = (spec_cdf[bins] - spec_cdf[bins - 1]) / (
          freq[bins] - freq[bins - 1]
      )
      intercepts = spec_cdf[bins - 1] - slopes * freq[bins - 1]
      inv_spec = (a - intercepts) / slopes
  
      self.Z = inv_spec
  
file_path: gpytorch/gpytorch/kernels/spectral_delta_kernel.py
imports: import math
  from typing import Optional
  import torch
  from linear_operator.operators import MatmulLinearOperator, RootLinearOperator
  from ..constraints import Interval, Positive
  from .kernel import Kernel
label_desc: Use image node_id 2 for calling the SpectralDeltaKernel obj's underlying member method code with example usage: obj.initialize_from_data(train_x, train_y) without return types