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