gonum.org/v1/gonum@v0.14.0/dsp/window/window_complex.go (about)

     1  // Copyright ©2020 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package window
     6  
     7  import "math"
     8  
     9  // Rectangular modifies seq in place by the Rectangular window and returns
    10  // the result.
    11  // See https://en.wikipedia.org/wiki/Window_function#Rectangular_window and
    12  // https://www.recordingblogs.com/wiki/rectangular-window for details.
    13  //
    14  // The rectangular window has the lowest width of the main lobe and largest
    15  // level of the side lobes. The result corresponds to a selection of
    16  // limited length sequence of values without any modification.
    17  //
    18  // The sequence weights are
    19  //
    20  //	w[k] = 1,
    21  //
    22  // for k=0,1,...,N-1 where N is the length of the window.
    23  //
    24  // Spectral leakage parameters: ΔF_0 = 2, ΔF_0.5 = 0.89, K = 1, ɣ_max = -13, β = 0.
    25  func RectangularComplex(seq []complex128) []complex128 {
    26  	return seq
    27  }
    28  
    29  // SineComplex modifies seq in place by the Sine window and returns the
    30  // result.
    31  // See https://en.wikipedia.org/wiki/Window_function#Sine_window and
    32  // https://www.recordingblogs.com/wiki/sine-window for details.
    33  //
    34  // Sine window is a high-resolution window.
    35  //
    36  // The sequence weights are
    37  //
    38  //	w[k] = sin(π*k/(N-1)),
    39  //
    40  // for k=0,1,...,N-1 where N is the length of the window.
    41  //
    42  // Spectral leakage parameters: ΔF_0 = 3, ΔF_0.5 = 1.23, K = 1.5, ɣ_max = -23, β = -3.93.
    43  func SineComplex(seq []complex128) []complex128 {
    44  	k := math.Pi / float64(len(seq)-1)
    45  	for i, v := range seq {
    46  		w := math.Sin(k * float64(i))
    47  		seq[i] = complex(w*real(v), w*imag(v))
    48  	}
    49  	return seq
    50  }
    51  
    52  // LanczosComplex modifies seq in place by the Lanczos window and returns
    53  // the result.
    54  // See https://en.wikipedia.org/wiki/Window_function#Lanczos_window and
    55  // https://www.recordingblogs.com/wiki/lanczos-window for details.
    56  //
    57  // The Lanczos window is a high-resolution window.
    58  //
    59  // The sequence weights are
    60  //
    61  //	w[k] = sinc(2*k/(N-1) - 1),
    62  //
    63  // for k=0,1,...,N-1 where N is the length of the window.
    64  //
    65  // Spectral leakage parameters: ΔF_0 = 3.24, ΔF_0.5 = 1.3, K = 1.62, ɣ_max = -26.4, β = -4.6.
    66  func LanczosComplex(seq []complex128) []complex128 {
    67  	k := 2 / float64(len(seq)-1)
    68  	for i, v := range seq {
    69  		x := math.Pi * (k*float64(i) - 1)
    70  		if x == 0 {
    71  			// Avoid NaN.
    72  			continue
    73  		}
    74  		w := math.Sin(x) / x
    75  		seq[i] = complex(w*real(v), w*imag(v))
    76  	}
    77  	return seq
    78  }
    79  
    80  // TriangularComplex modifies seq in place by the Triangular window and
    81  // returns the result.
    82  // See https://en.wikipedia.org/wiki/Window_function#Triangular_window and
    83  // https://www.recordingblogs.com/wiki/triangular-window for details.
    84  //
    85  // The Triangular window is a high-resolution window.
    86  //
    87  // The sequence weights are
    88  //
    89  //	w[k] = 1 - |k/A -1|, A=(N-1)/2,
    90  //
    91  // for k=0,1,...,N-1 where N is the length of the window.
    92  //
    93  // Spectral leakage parameters: ΔF_0 = 4, ΔF_0.5 = 1.33, K = 2, ɣ_max = -26.5, β = -6.
    94  func TriangularComplex(seq []complex128) []complex128 {
    95  	a := float64(len(seq)-1) / 2
    96  	for i, v := range seq {
    97  		w := 1 - math.Abs(float64(i)/a-1)
    98  		seq[i] = complex(w*real(v), w*imag(v))
    99  	}
   100  	return seq
   101  }
   102  
   103  // HannComplex modifies seq in place by the Hann window and returns the result.
   104  // See https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
   105  // and https://www.recordingblogs.com/wiki/hann-window for details.
   106  //
   107  // The Hann window is a high-resolution window.
   108  //
   109  // The sequence weights are
   110  //
   111  //	w[k] = 0.5*(1 - cos(2*π*k/(N-1))),
   112  //
   113  // for k=0,1,...,N-1 where N is the length of the window.
   114  //
   115  // Spectral leakage parameters: ΔF_0 = 4, ΔF_0.5 = 1.5, K = 2, ɣ_max = -31.5, β = -6.
   116  func HannComplex(seq []complex128) []complex128 {
   117  	k := 2 * math.Pi / float64(len(seq)-1)
   118  	for i, v := range seq {
   119  		w := 0.5 * (1 - math.Cos(k*float64(i)))
   120  		seq[i] = complex(w*real(v), w*imag(v))
   121  	}
   122  	return seq
   123  }
   124  
   125  // BartlettHannComplex modifies seq in place by the Bartlett-Hann window
   126  // and returns result.
   127  // See https://en.wikipedia.org/wiki/Window_function#Bartlett%E2%80%93Hann_window
   128  // and https://www.recordingblogs.com/wiki/bartlett-hann-window for details.
   129  //
   130  // The Bartlett-Hann window is a high-resolution window.
   131  //
   132  // The sequence weights are
   133  //
   134  //	w[k] = 0.62 - 0.48*|k/(N-1)-0.5| - 0.38*cos(2*π*k/(N-1)),
   135  //
   136  // for k=0,1,...,N-1 where N is the length of the window.
   137  //
   138  // Spectral leakage parameters: ΔF_0 = 4, ΔF_0.5 = 1.45, K = 2, ɣ_max = -35.9, β = -6.
   139  func BartlettHannComplex(seq []complex128) []complex128 {
   140  	const (
   141  		a0 = 0.62
   142  		a1 = 0.48
   143  		a2 = 0.38
   144  	)
   145  
   146  	k := 2 * math.Pi / float64(len(seq)-1)
   147  	for i, v := range seq {
   148  		w := a0 - a1*math.Abs(float64(i)/float64(len(seq)-1)-0.5) - a2*math.Cos(k*float64(i))
   149  		seq[i] = complex(w*real(v), w*imag(v))
   150  	}
   151  	return seq
   152  }
   153  
   154  // HammingComplex modifies seq in place by the Hamming window and returns
   155  // the result.
   156  // See https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
   157  // and https://www.recordingblogs.com/wiki/hamming-window for details.
   158  //
   159  // The Hamming window is a high-resolution window. Among K=2 windows it has
   160  // the highest ɣ_max.
   161  //
   162  // The sequence weights are
   163  //
   164  //	w[k] = 25/46 - 21/46 * cos(2*π*k/(N-1)),
   165  //
   166  // for k=0,1,...,N-1 where N is the length of the window.
   167  //
   168  // Spectral leakage parameters: ΔF_0 = 4, ΔF_0.5 = 1.33, K = 2, ɣ_max = -42, β = -5.37.
   169  func HammingComplex(seq []complex128) []complex128 {
   170  	const (
   171  		a0 = 0.54
   172  		a1 = 0.46
   173  	)
   174  
   175  	k := 2 * math.Pi / float64(len(seq)-1)
   176  	for i, v := range seq {
   177  		w := a0 - a1*math.Cos(k*float64(i))
   178  		seq[i] = complex(w*real(v), w*imag(v))
   179  	}
   180  	return seq
   181  }
   182  
   183  // BlackmanComplex modifies seq in place by the Blackman window and returns
   184  // the result.
   185  // See https://en.wikipedia.org/wiki/Window_function#Blackman_window and
   186  // https://www.recordingblogs.com/wiki/blackman-window for details.
   187  //
   188  // The Blackman window is a high-resolution window.
   189  //
   190  // The sequence weights are
   191  //
   192  //	w[k] = 0.42 - 0.5*cos(2*π*k/(N-1)) + 0.08*cos(4*π*k/(N-1)),
   193  //
   194  // for k=0,1,...,N-1 where N is the length of the window.
   195  //
   196  // Spectral leakage parameters: ΔF_0 = 6, ΔF_0.5 = 1.7, K = 3, ɣ_max = -58, β = -7.54.
   197  func BlackmanComplex(seq []complex128) []complex128 {
   198  	const (
   199  		a0 = 0.42
   200  		a1 = 0.5
   201  		a2 = 0.08
   202  	)
   203  
   204  	k := 2 * math.Pi / float64(len(seq)-1)
   205  	for i, v := range seq {
   206  		x := k * float64(i)
   207  		w := a0 - a1*math.Cos(x) + a2*math.Cos(2*x)
   208  		seq[i] = complex(w*real(v), w*imag(v))
   209  	}
   210  	return seq
   211  }
   212  
   213  // BlackmanHarrisComplex modifies seq in place by the Blackman-Harris window
   214  // and returns the result.
   215  // See https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window
   216  // and https://www.recordingblogs.com/wiki/blackman-harris-window for details.
   217  //
   218  // The Blackman-Harris window is a low-resolution window.
   219  //
   220  // The sequence weights are
   221  //
   222  //	w[k] = 0.35875 - 0.48829*cos(2*π*k/(N-1)) +
   223  //	       0.14128*cos(4*π*k/(N-1)) - 0.01168*cos(6*π*k/(N-1)),
   224  //
   225  // for k=0,1,...,N-1 where N is the length of the window.
   226  //
   227  // Spectral leakage parameters:  ΔF_0 = 8, ΔF_0.5 = 1.97, K = 4, ɣ_max = -92, β = -8.91.
   228  func BlackmanHarrisComplex(seq []complex128) []complex128 {
   229  	const (
   230  		a0 = 0.35875
   231  		a1 = 0.48829
   232  		a2 = 0.14128
   233  		a3 = 0.01168
   234  	)
   235  
   236  	k := 2 * math.Pi / float64(len(seq)-1)
   237  	for i, v := range seq {
   238  		x := k * float64(i)
   239  		w := a0 - a1*math.Cos(x) + a2*math.Cos(2*x) - a3*math.Cos(3*x)
   240  		seq[i] = complex(w*real(v), w*imag(v))
   241  	}
   242  	return seq
   243  }
   244  
   245  // NuttallComplex modifies seq in place by the Nuttall window and returns
   246  // the result.
   247  // See https://en.wikipedia.org/wiki/Window_function#Nuttall_window,_continuous_first_derivative
   248  // and https://www.recordingblogs.com/wiki/nuttall-window for details.
   249  //
   250  // The Nuttall window is a low-resolution window.
   251  //
   252  // The sequence weights are
   253  //
   254  //	w[k] = 0.355768 - 0.487396*cos(2*π*k/(N-1)) + 0.144232*cos(4*π*k/(N-1)) -
   255  //	       0.012604*cos(6*π*k/(N-1)),
   256  //
   257  // for k=0,1,...,N-1 where N is the length of the window.
   258  //
   259  // Spectral leakage parameters: ΔF_0 = 8, ΔF_0.5 = 1.98, K = 4, ɣ_max = -93, β = -9.
   260  func NuttallComplex(seq []complex128) []complex128 {
   261  	const (
   262  		a0 = 0.355768
   263  		a1 = 0.487396
   264  		a2 = 0.144232
   265  		a3 = 0.012604
   266  	)
   267  
   268  	k := 2 * math.Pi / float64(len(seq)-1)
   269  	for i, v := range seq {
   270  		x := k * float64(i)
   271  		w := a0 - a1*math.Cos(x) + a2*math.Cos(2*x) - a3*math.Cos(3*x)
   272  		seq[i] = complex(w*real(v), w*imag(v))
   273  	}
   274  	return seq
   275  }
   276  
   277  // BlackmanNuttallComplex modifies seq in place by the Blackman-Nuttall
   278  // window and returns the result.
   279  // See https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window
   280  // and https://www.recordingblogs.com/wiki/blackman-nuttall-window for details.
   281  //
   282  // The Blackman-Nuttall window is a low-resolution window.
   283  //
   284  // The sequence weights are
   285  //
   286  //	w[k] = 0.3635819 - 0.4891775*cos(2*π*k/(N-1)) + 0.1365995*cos(4*π*k/(N-1)) -
   287  //	       0.0106411*cos(6*π*k/(N-1)),
   288  //
   289  // for k=0,1,...,N-1 where N is the length of the window.
   290  //
   291  // Spectral leakage parameters: ΔF_0 = 8, ΔF_0.5 = 1.94, K = 4, ɣ_max = -98, β = -8.8.
   292  func BlackmanNuttallComplex(seq []complex128) []complex128 {
   293  	const (
   294  		a0 = 0.3635819
   295  		a1 = 0.4891775
   296  		a2 = 0.1365995
   297  		a3 = 0.0106411
   298  	)
   299  
   300  	k := 2 * math.Pi / float64(len(seq)-1)
   301  	for i, v := range seq {
   302  		x := k * float64(i)
   303  		w := a0 - a1*math.Cos(x) + a2*math.Cos(2*x) - a3*math.Cos(3*x)
   304  		seq[i] = complex(w*real(v), w*imag(v))
   305  	}
   306  	return seq
   307  }
   308  
   309  // FlatTopComplex modifies seq in place by the Flat Top window and returns
   310  // the result.
   311  // See https://en.wikipedia.org/wiki/Window_function#Flat_top_window and
   312  // https://www.recordingblogs.com/wiki/flat-top-window for details.
   313  //
   314  // The Flat Top window is a low-resolution window.
   315  //
   316  // The sequence weights are
   317  //
   318  //	w[k] = 0.21557895 - 0.41663158*cos(2*π*k/(N-1)) +
   319  //	       0.277263158*cos(4*π*k/(N-1)) - 0.083578947*cos(6*π*k/(N-1)) +
   320  //	       0.006947368*cos(4*π*k/(N-1)),
   321  //
   322  // for k=0,1,...,N-1 where N is the length of the window.
   323  //
   324  // Spectral leakage parameters: ΔF_0 = 10, ΔF_0.5 = 3.72, K = 5, ɣ_max = -93.0, β = -13.34.
   325  func FlatTopComplex(seq []complex128) []complex128 {
   326  	const (
   327  		a0 = 0.21557895
   328  		a1 = 0.41663158
   329  		a2 = 0.277263158
   330  		a3 = 0.083578947
   331  		a4 = 0.006947368
   332  	)
   333  
   334  	k := 2 * math.Pi / float64(len(seq)-1)
   335  	for i, v := range seq {
   336  		x := k * float64(i)
   337  		w := a0 - a1*math.Cos(x) + a2*math.Cos(2*x) - a3*math.Cos(3*x) + a4*math.Cos(4*x)
   338  		seq[i] = complex(w*real(v), w*imag(v))
   339  	}
   340  	return seq
   341  }