Funciones de ventana de bricolaje

En el procesamiento de señales digitales, las funciones de ventana se utilizan ampliamente para limitar la señal en el tiempo, y sus nombres son bien conocidos por todos los que se han encontrado con la transformada discreta de Fourier de una forma u otra: Hann, Hamming, Blackman, Harris y otros. Pero, ¿son suficientes, es posible inventar algo nuevo y tiene algún sentido?



En este artículo, veremos la salida de una función de ventana con nuevas propiedades usando Wolfram Mathematica. También se supone que el lector tiene un conocimiento general del procesamiento de señales digitales en el contexto del tema en discusión y que al menos está familiarizado con el artículo de Wikipedia .







Introducción



Históricamente, las primeras funciones de ventana aparecieron en el proceso de intentos de mejorar sus propiedades espectrales reduciendo la amplitud de los lóbulos laterales, ya que cuando la señal se multiplica por la función de ventana, sus espectros son intrincados, lo que introduce algunas limitaciones para el análisis. En ese momento, los años 50 del siglo XX, la potencia informática no permitía manipular de forma fácil y natural los cálculos simbólicos, y la selección de los parámetros óptimos era bastante difícil. Esta es una de las razones por las que las funciones reciben diferentes nombres: ellas, o mejor dicho, sus propiedades espectrales, han sido estudiadas por diferentes investigadores durante bastante tiempo. Un efecto secundario de esto es que el conjunto existente de funciones de ventana nombradas se percibe como una especie de "conjunto estándar" fuera del cual no se puede encontrar nada;al mismo tiempo, los nombres de estas ventanas no contienen información sobre las propiedades y sugieren su estudio y memorización por separado.



Clasificación



Todas las funciones de ventana se obtienen multiplicando alguna función por una rectangular, lo que garantiza su limitación de tiempo. Por tanto, en primer lugar, se pueden clasificar según las funciones que utilicen:



  1. la suma de los cosenos. La clase más extensa debido al hecho de que su espectro es fácilmente computable y es la suma de funciones sinc ponderadas. Esto incluye a Hann, Hamming, Blackman, Harris ...
  2. polinomio continuo por partes. Se obtienen como resultado de la convolución de funciones simples, por ejemplo, rectangular y triangular. Al mismo tiempo, sus espectros se multiplican y su hallazgo tampoco es particularmente difícil. Estos incluyen Dirichlet, Triangular, Parzen, Welch ...
  3. todos los demás, utilizando exponenciales, gaussianos, sinc y otros, la elección de funciones específicas en las que es más de carácter ideológico que propiedades específicamente espectrales.


También se pueden dividir por propiedades en los bordes:



  1. sin espacios en los bordes - valores iguales a cero. Los descansos son de Dirichlet, Hamming, Blackman-Harris. No tengo - Triangular, Hann, Nuttal
  2. ausencia de discontinuidades de la 1a y otras derivadas


Dos funciones de ventana más se destacan por separado:



  1. Kaiser, que le permite establecer el ancho del pétalo principal;
  2. Dolph-Chebyshev, cuyos lóbulos laterales son iguales a una amplitud dada.


Ambos tienen discontinuidades en los bordes tanto de los valores como de las derivadas, y sus cálculos implican algunas dificultades: la función de Kaiser se calcula mediante una función especial (Bessel), y la función Dolph-Chebyshev se determina en el dominio de la frecuencia y se calcula mediante la transformada discreta inversa de Fourier. Encontrar sus antiderivadas analíticas también es particularmente difícil.



Puede examinar las funciones de la ventana en busca de interrupciones con el siguiente código simple:
wins = {DirichletWindow, HammingWindow, BlackmanWindow, 
   BartlettHannWindow, BartlettWindow, BlackmanHarrisWindow, 
   BlackmanNuttallWindow, BohmanWindow, ExactBlackmanWindow, 
   FlatTopWindow, KaiserBesselWindow, LanczosWindow, NuttallWindow};
Table[{f, 
  Table[Limit[D[f[x], {x, k}], x -> 1/2, 
    Direction -> "FromBelow"], {k, 0, 4}]}, {f, wins}]</code>
<img src="https://habrastorage.org/webt/rm/wq/8f/rmwq8fjkjxjcox-czh8zevkbd0m.png" />

<code>Plot[Evaluate[Through[wins[x]]], {x, -1, 1}, PlotRange -> {-0.25, 1}, 
 GridLines -> {{-0.5, -0.25, 0.25, 0.5, 1}}, AspectRatio -> 5/8, 
 PlotLegends -> "Expressions"]








Ingeniería inversa



Veamos las definiciones de las funciones de Blackman y Nuttel:



BlackmanWindow[x] // FunctionExpand




{150(25porque(2πX)+4porque(4πX)+21)-12X120|X|>12



NuttallWindow[x] // FunctionExpand




{121849porque(2πX)+36058porque(4πX)+3151porque(6πX)+88942250.000-12X120|X|>12



Son sumas de ondas coseno 3 y 4 con frecuencias pares (comenzando desde cero) y algunos coeficientes. ¿De dónde proceden estos coeficientes? Es poco probable que hayan sido seleccionados a mano, al menos cada uno por separado; después de todo, hay condiciones de contorno que las ventanas deben cumplir independientemente de sus propiedades espectrales, al menos iguales a la unidad en el centro.



Intentemos "inventar" la función Blackman por nuestra cuenta. Para hacer esto, definimos una función con coeficientes aún desconocidos



f = Function[x, a + b Cos[2 Pi x] + c Cos[4 Pi x]];


y componga un sistema de ecuaciones que definan las condiciones de contorno: igualdad a la unidad en el centro, cero en los bordes e igualdad a cero de las derivadas en los bordes:



ss = Solve[{
   f[0] == 1,
   f[1/2] == 0,
   f'[1/2] == 0
   }, {a, b, c}]








{{segundo12,C12-un}}



Se encontró la solución, pero no una, sino muchas, dependiendo del coeficiente a , sobre el cual Wolfram nos advirtió cortésmente. Ahora, a partir de la solución encontrada, definimos una nueva función en función del coeficiente desconocido: Es fácil ver que para a = 0,42 obtenemos la función de Blackman. Pero, ¿por qué exactamente 0,42? Para responder a esta pregunta, necesitamos trazar su espectro. La Transformada Analítica de Fourier no es una tarea fácil, pero Wolfram también puede manejarla, salvándonos de la tarea.



hx = Function[{x, a},

Piecewise[{{f[x] /. ss[[1]], -1/2 < x < 1/2}}, 0] // Evaluate]
















hw = Function[{w, a}, 
  FourierTransform[hx[x, a], x, w] // #/Limit[#, w -> 0] & // 
    Simplify // Evaluate]






Nota
, FourierTransform , — , , — . w. — w, , .







De esta forma, el gráfico de la función todavía no es muy informativo, ya que es más conveniente analizar el espectro en una escala logarítmica. Añadiendo la conversión apropiada a decibelios20Iniciar sesióndiez(|X|), obtenemos el mismo gráfico habitual del espectro de funciones de ventana:



el código
Manipulate[
 Plot[{
      hw[w, a],
      hw[w, 0.42]
      } // Abs // 20 Log[10, #] & // Evaluate
  , {w, -111, 111}, PlotRange -> {-120, 0}, GridLines -> Automatic, 
  PlotStyle -> {Default, Thin}, PlotPoints -> 50]
 , {{a, 0.409}, 0.3, 0.5}]








En el proceso de cambio de parámetro observaremos algo similar:







Dependiendo del parámetro a, el nivel de los lóbulos laterales cambia, y a a = 0,42 es más o menos mínimo y uniforme. Con a = 0,409, podemos obtener un resultado ligeramente mejor si por “mejor” nos referimos al nivel mínimo posible de lóbulos laterales.



Nota
, , .



Desarrollo



Obviamente, tal microoptimización no valió la pena el esfuerzo. ¿Es posible mejorar cualitativamente las propiedades de esta ventana sin cambiar los datos iniciales?



Anteriormente, analizamos la salida de las funciones de ventana que suman uno, lo que le permite restaurar la señal original. Probemos esta técnica para nuestra ventana y veamos cómo afecta el espectro.



Definamos una función auxiliar para construir ventanas superpuestas, teniendo en cuenta los límites del argumento en el rango de -1/2 a 1/2:







Encuentre la antiderivada, muévala al centro de coordenadas y escale a uno:











mostrarla en el gráfico:







Como puede ver, Wolfram lo hizo solo aquí también, y no tuvimos que establecer manualmente una definición continua por partes de una antiderivada. Ahora, la vista de nuestra ventana depende no solo de la variable a , sino del grado de superposición, y a medida que aumenta, tenderá a la forma de la derivada:



el código
Manipulate[
 Plot[
  OverlapShape[hsx, x, a, t]
  , {x, -1, 1}, PlotRange -> All, GridLines -> Automatic]
 , {{a, 0.404}, 0.4, 0.5}, {{t, 4}, 3, 11}]






Y el toque final es encontrar una función analítica para el espectro con el fin de determinar el valor óptimo del parámetro a .



Aquí, si intentamos calcular la transformación directamente, como la última vez, llevaremos a Wolfram a un pensamiento profundo. Hay varias formas de acelerar este proceso:



- use una transformación discreta en lugar de una analítica - la más simple. Pero un verdadero matemático no aplicará métodos numéricos donde se pueda encontrar una solución puramente analítica, y nosotros no lo haremos (todavía); además, tiene limitaciones obvias (en términos de resolución y limitación de espectro);



- pasar valores específicos como un parámetro de superposición y, mirando los resultados, intentar ver el patrón y generalizarlos. Una opción bastante funcional, pero que requiere esfuerzos mentales y creativos adicionales. Dejémoslo como último recurso.



- realizar cálculos directamente en el dominio de la frecuencia. Esto es posible debido a las siguientes propiedades de la transformada de Fourier:



1) es lineal, es decir la suma de las imágenes es igual a la imagen de la suma;

2) la integración en el dominio del tiempo es equivalente a dividir por iw en el dominio de la frecuencia.

3) el desplazamiento en el tiempo es equivalente a la modulación con una sinusoide compleja.

(más en wikipedia o aquí ).



Por lo tanto, teniendo el espectro hw de una función de ventana arbitraria, podemos obtener de él el espectro hwo de una función sumada a uno con t superpuesto :











Ahora podemos ver cómo cambia el espectro en dinámica:







Aquí, cambiar el parámetro de superposición ya afectará al espectro de ventana de una manera ligeramente diferente :







Habiendo jugado un poco con los parámetros, es fácil notar que “más grande no es mejor”, y el grado óptimo de superposición para esa función está en la región de cuatro. Específicamente, para t = 4 y a= 0,404 obtenemos que el nivel del lóbulo lateral no supere los -80 dB. Este es un muy buen resultado, especialmente considerando que la función coseno elevado, usada tradicionalmente para ventanas sumadas, da un nivel de lóbulo de aproximadamente -30 dB. Bueno, cuando se escribe explícitamente, nuestra nueva función de ventana se verá así:



el código
OverlapShape[hsx, x, 404/1000, 4] // PiecewiseExpand // FullSimplify




{404π(1-2X)+36pecado(13(dieciséisπX+π))+375pecado(13(π-8πX))606π14<X12404(2πX+π)+36pecado(23π(8X+1))+375pecado(13(8πX+π))606π-12<X-143(125porque(8πX3)+12porque(dieciséisπX3))202π+13-14<X140|X|>12



Mayor desarrollo



¿Qué más puede hacer para reducir aún más el nivel de los lóbulos laterales? Puede tomar cosenos no con frecuencias pares, sino con frecuencias impares (aquí, por compacidad, la solución del sistema de ecuaciones está incrustada directamente en la definición de la función):



el código
hx1 = Function[{x, a},
  a Cos[1 Pi #] + b Cos[3 Pi #] + c Cos[5 Pi #] & // #[x] /. Solve[{
          #[0] == 1,
          #[1/2] == 0,
          #'[1/2] == 0,
          #''[1/2] == 0
          }, {a, b, c}][[1]] & // # UnitBox[x] & // Evaluate]




(unporque(πX)+(cinco8-un2)porque(3πX)+(38-un2)porque(cincoπX))Π(X)



y tras la integración con los parámetros a = 0,6628 y un nivel de superposición de 4,5, obtener una atenuación de -90 dB:







Explícitamente:

{327pecado(17π(45X+2))+24855pecado(17π(1-nueveX))+3670porque(1catorceπ(54X+1))+2151243024cincoDieciocho<X1224855pecado(17π(nueveX+1))+3670pecado(37π(nueveX+1))+327pecado(cinco7π(nueveX+1))+2151243024-12<X-cincoDieciocho-3670pecado(37π(nueveX-1))+24855pecado(17π(nueveX+1))+327pecado(cinco7π(nueveX+1))43024++3670pecado(37π(nueveX+1))+327pecado(17π(45X+2))+24855pecado(17π(1-nueveX))43024-cincoDieciocho<XcincoDieciocho0|X|>12



Puede agregar un coseno más y aumentar el número de derivadas cero:



el código
hx2 = Function[{x, a},
  a Cos[1 Pi #] + b Cos[3 Pi #] + c Cos[5 Pi #] + 
       d Cos[7 Pi #] & // #[x] /. Solve[{
          #[0] == 1,
          #[1/2] == 0,
          #'[1/2] == 0,
          #''[1/2] == 0,
          #'''[1/2] == 0,
          #''''[1/2] == 0
          }, {b, c, d}][[1]] & // # UnitBox[x] & // Evaluate]




(unporque(πX)+180(35-dieciséisun)porque(3πX)+180(35-48un)porque(cincoπX)+140(cinco-8un)porque(7πX))Π(X)



y después de la integración con los parámetros a = 0.5862 y un nivel de superposición de 6.4 para obtener una supresión de -110 dB:







Explícitamente:

{-3077550pecado(154π(64X-cinco))-90069pecado(cinco54π(64X-cinco))-5820pecado(754π(64X-cinco))-560455porque(1nueveπ(7-32X))+26013445202688once32<X12560455pecado(1Dieciochoπ(64X+cinco))+3077550pecado(154π(64X+cinco))+90069pecado(cinco54π(64X+cinco))+5820pecado(754π(64X+cinco))+26013445202688-12<X-once32-3077550pecado(154π(64X-cinco))-90069pecado(cinco54π(64X-cinco))-5820pecado(754π(64X-cinco))-560455porque(1nueveπ(7-32X))5202688++560455pecado(1Dieciochoπ(64X+cinco))+3077550pecado(154π(64X+cinco))+90069pecado(cinco54π(64X+cinco))+5820pecado(754π(64X+cinco))5202688-once32<Xonce320|X|>12



Se puede lograr una reducción aún más significativa en el nivel de lóbulos laterales elevando al cuadrado la transformada de Fourier y reduciendo así el nivel de lóbulos laterales en un factor de 2 a la vez. Esto le permite deshacerse del aumento en el número de parámetros para su selección manual, pero agrega complejidad al calcular la convolución en el dominio del tiempo.



el código
hx3 = Function[{x, a}, 
  Convolve[hx1[x, a], hx1[x, a], x, y] /. y -> 2 x
 // FullSimplify // Evaluate]








y aquí ya es posible lograr una supresión de más de 160 dB:







no daremos la fórmula explícitamente debido a su impresionante tamaño.



Funciones de ventana hipergeométrica



Para asegurar el número requerido de ceros en los límites de nuestra función, usamos una búsqueda a través de la solución de un sistema de ecuaciones con integración posterior. Esto no es muy conveniente: debe cambiar el número de ecuaciones cada vez. ¿Quizás haya una solución más simple y hermosa? ¡Ahi esta! Y la función hipergeométrica nos ayudará con esto.



brevemente sobre las funciones hipergeométricas
, . — , . — .



Nuestra solución se verá así:

2zΓ(norte+32)2F1(12,-norte2;32;z2)πΓ(norte2+1)+un(z+segundoz3)(1-z2)norte/2

Dónde z=pecado(πX2)



Consiste en la suma de dos partes: la antiderivada de la función (1-z2)norte2, normalizada en amplitud al punto (1,1) y una función con parámetros libres, multiplicada por la misma (1-z2)norte2para preservar el número requerido de derivadas cero: La







precisión del ajuste y su influencia en la distribución de los lóbulos laterales dependerá de la función que elijamos para corregir la forma; existen opciones posibles que requieren estudios separados. En este caso, la funciónun(z+segundoz3)ofrece una opción bastante aceptable y, debido a dos parámetros, le permite realizar ajustes más precisos.



La fórmula en sí es interesante (y conveniente) porque para n par se simplifica a un polinomio, y para n impar se simplifica a la suma de un polinomio con arcoseno y raíz cuadrada, lo que hace que la fórmula final sea más compacta y más fácil de calcular.



Ya es más fácil (y más rápido) seleccionar los parámetros aquí a través de la transformada discreta de Fourier. También necesitamos una definición adicional de la función de superposición para trabajar con tres parámetros:



















Como ejemplo, después de sustituir los parámetros de la imagen, nuestra función se simplificará a



el código


-288zonce+2315znueve-7380z7+12330zcinco-11940z3+8163z3200





Ventana de Kaiser inverso



Si la tarea de sumar las ventanas en una no vale la pena, entonces la ventana más óptima es la ventana de Kaiser, que le permite ajustar sin problemas el ancho del lóbulo principal. Sin embargo, tiene un inconveniente: dado que se expresa en términos de la función de Bessel , es algo difícil de leer fuera de los paquetes matemáticos. Por supuesto, puede implementar la función Bessel por separado, o también puede buscar una aproximación a través de funciones elementales. Y de repente resultó que al usar la función del espectro de la ventana de Kaiser (limitada en el tiempo) para esto, puede obtener un resultado incluso un poco mejor:



pecado(k1-4X2)pecado(k)1-4X2Π(X)

Nota
±12 , kpecado(k).


El pago por una decisión tan astuta fue la imposibilidad de expresar su espectro de forma puramente analítica, pero esto no es tan importante, ya que en la práctica, en cualquier caso, operamos y analizamos datos en forma discreta utilizando la transformada discreta de Fourier. A continuación, en el gráfico, puede comparar sus espectros, donde el rojo es la ventana original de Kaiser, el verde es su aproximación:



el código








Con el mismo ancho del pétalo principal, el nivel de los lóbulos laterales es ligeramente más bajo. Y para facilitar su uso, puede elaborar una tabla con valores aproximados del parámetro k para obtener el nivel requerido de supresión de lóbulos laterales:

-60 dBk = 8,8-90 dBk = 11,36-120 dBk = 15,18-150 dBk = 18,88



Encontrar una aproximación de la antiderivada de la ventana de Kaiser inversa sigue siendo un problema interesante aparte. Hasta ahora, solo ha sido posible expresarlo a través de una serie de potencias, que converge con bastante lentitud:



pecado(k1-4X2)pecado(k)1-4X2reX=norte=1-212-norteknorte-1X2norte-1(-k(-1)norteKnorte-12(-k)+kKnorte-12(k))π(2norte-1)pecado(k)Γ(norte)



Quizás los expertos en matemáticas puedan sugerir una mejor solución en los comentarios.



Conclusión



A pesar de que el procesamiento de señales digitales es una disciplina completamente formada, todavía hay espacio para el desarrollo y algo nuevo en él; al menos en la literatura especial y científica existente, no se consideran los problemas de la construcción de funciones de ventana resumidas en una unidad; y las capacidades de los sistemas de álgebra computacional modernos permiten repensar el conocimiento acumulado a un nivel cualitativamente nuevo.



El documento original de Wolfram Mathematica con todos los cálculos está disponible en GitHub .



All Articles