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