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 }