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