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