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