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