Ecuación de Onda¶

Introducción Teórica¶

Dada una ecuación de cómo vibra una cuerda

$c^2\cdot \frac{{\partial }^2u\left(x,t\right)}{\partial x^2}=\frac{{\partial }^2u(x,t)}{\partial t^2}$

Aplicando un cambio de variable y resolviendo un problema de contorno y una ecuación diferencial, se puede obtener la solución de la ecuación de onda [Véase TFG]

La solución de la ecuación de onda es: $u(x,t)=\sum_{n=1}^{\infty} \sin\left(\sqrt{\lambda_n} x\right)\left(A_n\cos\left(c\sqrt{\lambda_n} t\right) +B_n\sin\left(c\sqrt{\lambda_n} t\right)\right)$ donde

  • $\lambda_n=\left(\frac{n\pi}{L}\right)^2 \forall n\in\mathbb{N}$
  • $c = \sqrt{\frac{T}{\mu}}$ siendo $T$ la tensión de la cuerda y $\mu$ la densidad lineal.

Sabemos, además que se generan las relaciones:

  • $\omega_n = c\frac{n\pi}{L} = c\sqrt{\lambda_n}$
  • $f_n = \frac{\omega_n}{2\pi} = \frac{c\sqrt{\lambda_n}}{2\pi}=n\frac{c}{2L}$
  • $k_n= \frac{n\pi}{L} = \sqrt{\lambda_n}$

Índice¶

  1. Modelar la solución de la ecuación de onda a través de Python
  2. Aplicar condiciones de contorno para obtener modelos de instrumentos de cuerda
    1. Condiciones de contorno: Cuerda pulsada
    2. Condiciones de contorno: Cuerda Frotada
    3. Condiciones de contorno: Cuerda Percutida
    4. Condiciones de contorno aplicadas al modelo de la ecuación de Onda
  3. Entender el significado de las variables
    1. ¿Qué significan los autovalores?
    2. ¿Qué significan la solución previa a la superposición?
    3. ¿Qué significa $A_n$ y $B_n$?
  4. ¿Cómo suena la solución?

1. Modelización programática de la solución de la ecuación de onda¶

Una clase WaveEquation es creada para modelar la ecuación de onda.

Lo más importante para la creación de un modelo básico de cualquier cuerda es la inicialización de las variables:

  • $L$: Longitud de la cuerda
  • $f$: Frecuencia fundamental de vibración o lo que es lo mismo $f_1$

ya que $c=f_1\cdot 2L$ deja definida el valor $c$ de la cuerda.

In [3]:
weq = WEQ(fundamentalFreq=Symbol("f_1"),x=x,t=t,n=n,L=Symbol("L"))
display(weq)
$\displaystyle \psi_n(x,t)=\left(\operatorname{A_{n}}{\left(n \right)} \cos{\left(2 \pi f_{1} n t \right)} + \operatorname{B_{n}}{\left(n \right)} \sin{\left(2 \pi f_{1} n t \right)}\right) \sin{\left(\frac{\pi n x}{L} \right)}$

De ahora en adelante, definimos una cuerda con frecuencia fundamental $f_1=440\ Hz$ (la frecuencia de la nota La o A4 en la notación franco-belga) y longitud $L=3.3\ dm$ que equivale a la longitud de una cuerda de violín normal.

In [4]:
freq = 440
L = Rational(33,10)
violin = WEQ(fundamentalFreq=freq,x=x,t=t,n=n,L=L)
harp = WEQ(fundamentalFreq=freq,x=x,t=t,n=n,L=L)
piano = WEQ(fundamentalFreq=freq,x=x,t=t,n=n,L=5)
display(violin)
$\displaystyle \psi_n(x,t)=\left(\operatorname{A_{n}}{\left(n \right)} \cos{\left(880 \pi n t \right)} + \operatorname{B_{n}}{\left(n \right)} \sin{\left(880 \pi n t \right)}\right) \sin{\left(\frac{10 \pi n x}{33} \right)}$

2. Modelos de Instrumentos de cuerda¶

2.A Instrumentos de cuerda pulsada: Guitarra/Harpa/...¶

Sabemos que al tocar un instrumento de cuerda pulsada de manera simple lo que hacemos con el dedo es estirar la cuerda en un punto y soltará, por lo que no existirá ninguna velocidad inicial, pero si posición inicial, esto es, posición de la cuerda justo cuando la hemos estirado, como en el ejemplo de la imagen.

Imagen obtenida de "Slow Motion Orchestra: Harp": https://www.youtube.com/watch?v=emLXIFXie0k

Con esto en mente, procedemos a definir las variables de posición inicial de la cuerda y velocidad inicial como:

In [6]:
l = 0.6*harp.L # plucked position
h = 0.06 # plucked height
posInicialHarp = Piecewise(
    (h/l *x,And(0<=x,x<=l)),
    (h*(harp.L-x)/(harp.L-l),And(l<=x,x<=harp.L))
)
velocidadInicialHarp = 0

plotPrintCondiciones(harp,posInicialHarp,velocidadInicialHarp)
$\displaystyle \begin{array}{ll} \text{Posicion Inicial}: & \begin{cases} 0.0303030303030303 x & \text{for}\: x \geq 0 \wedge x \leq 1.98 \\0.15 - 0.0454545454545455 x & \text{for}\: x \geq 1.98 \wedge x \leq \frac{33}{10} \end{cases} \\ \text{Velocidad Inicial}: & 0 \end{array} $

2.B Instrumentos de cuerda frotada: Violín/Viola/...¶

A diferencia de la guitarra, los instrumentos de cuerda frotada dependen del arco, que se moverá a una velocidad (asumiéremos que es constante) y la posición inicial será 0, ya que parte de reposo la cuerda, pero lo que no es $0$ es la velocidad inicial de cada punto pues es movida/impuesta por el arco.

Veamos un ejemplo visual

Imagen obtenida de "Slow Motion Orchestra: Violin": https://www.youtube.com/watch?v=ETVg7Gk6ayE
Violin Bow Slow Motion 2: https://www.youtube.com/watch?v=6JeyiM0YNo4

A pesar de que no se observe la velocidad inicial en la imagen, el efecto que tiene el arco sobre la cuerda sí se observa y con esto podemos definir las variables de posición inicial de la cuerda y velocidad inicial como:

In [7]:
v = 1
p = 0.11
s = 3
posInicialViolin = 0
velocidadInicialViolin = Piecewise(
    (((v*x)/(s-p/2)),And(0<=x,x<=s-p/2)),
    ((v*(s-p/2))/(s-p/2),And(s-p/2<=x,x<=s+p/2)),
    ((v*(violin.L-x))/(violin.L-(s+p/2)),And(s+p/2<=x,x<=violin.L))
)
plotPrintCondiciones(violin,posInicialViolin,velocidadInicialViolin)
$\displaystyle \begin{array}{ll} \text{Posicion Inicial}: & 0 \\ \text{Velocidad Inicial}: & \begin{cases} 0.33955857385399 x & \text{for}\: x \geq 0 \wedge x \leq 2.945 \\1.0 & \text{for}\: x \geq 2.945 \wedge x \leq 3.055 \\13.4693877551021 - 4.08163265306123 x & \text{for}\: x \geq 3.055 \wedge x \leq \frac{33}{10} \end{cases} \end{array} $

2.C Instrumentos de cuerda Percutida: Piano/ Clavicordio/...¶

A diferencia de la guitarra o un violin, los instrumentos de cuerda percutida dependen de un martillo, que golpeara la cuerda a una velocidad (asumiéremos que es constante) y la posición inicial será 0, ya que parte de reposo la cuerda, pero lo que no es $0$ es la velocidad inicial de cada punto pues es determinada por la accion del martillo.

Veamos un ejemplo visual

Imagen obtenida de "Super Slow Motion Struck String at the University of St Andrews": https://www.youtube.com/watch?v=9O3VEXzuOKI

A pesar de que no se observe la velocidad inicial en la imagen, el efecto que tiene el martillo sobre la cuerda sí se observa y con esto podemos definir las variables de posición inicial de la cuerda y velocidad inicial como:

In [8]:
l = 0.075*piano.L # Tamaño Martillo
x0 = 0.72*piano.L # Posición Martillo
epsi = 0.005 # Pequeña propagacion del martillo
v = 3 # Velocidad del martillo

posInicialPiano = 0
velocidadInicialPiano = Piecewise(
    (0,And(0<=x,x<=(x0-l/2-epsi))),
    ((v*(x-x0+l/2+epsi))/epsi,And((x0-l/2-epsi)<=x,x<=(x0-l/2))),
    (v,And((x0-l/2)<=x,x<=(x0+l/2))),
    ((v*(x0+l/2+epsi-x))/epsi,And((x0+l/2)<=x,x<=(x0+l/2+epsi))),
    (0,And((x0+l/2+epsi)<=x,x<=piano.L))
)
In [9]:
plotPrintCondiciones(piano,posInicialPiano,velocidadInicialPiano)
$\displaystyle \begin{array}{ll} \text{Posicion Inicial}: & 0 \\ \text{Velocidad Inicial}: & \begin{cases} 0 & \text{for}\: x \geq 0 \wedge x \leq 3.4075 \\600.0 x - 2044.5 & \text{for}\: x \geq 3.4075 \wedge x \leq 3.4125 \\3 & \text{for}\: x \geq 3.4125 \wedge x \leq 3.7875 \\2275.5 - 600.0 x & \text{for}\: x \geq 3.7875 \wedge x \leq 3.7925 \\0 & \text{for}\: x \geq 3.7925 \wedge x \leq 5 \end{cases} \end{array} $

2.D Imponemos condiciones de contorno del instrumento¶

Puesto que existen variables desconocidas imponiendo las condiciones las obtendremos, aquí entra en juego las series de Fourier y la completitud de la solución que hemos obtenido:

$A_n = \frac{2}{L}\int_a^b \psi(x,0) \sin({\frac{n\pi}{L}x}) dx$

$B_n = \frac{2}{n\pi c} \int_a^b \left(\frac{\partial \psi}{\partial t}(x,0)\right) \sin({\frac{n\pi}{L}x}) dx$

Hagamos la integral con nuestro modelo

Caso 1: Instrumento de cuerda pulsada¶

In [10]:
An = harp.findAn(posInicialHarp)
Bn = harp.findBn(velocidadInicialHarp)

showAnBn(An,Bn)
$\displaystyle \begin{array}{ll} A_n: & \frac{3.36431219583381 \cdot 10^{-17} \pi n \cos{\left(0.6 \pi n \right)} + 0.5 \sin{\left(0.6 \pi n \right)} - 0.3 \sin{\left(\pi n \right)}}{\pi^{2} n^{2}} \\ B_n: & 0 \end{array} $
In [11]:
harp.setAmplitudes(An,Bn)
display(harp)
$\displaystyle \psi_n(x,t)=\left(\frac{3.36431219583381 \cdot 10^{-17} \cos{\left(0.6 \pi n \right)}}{\pi n} + \frac{0.5 \sin{\left(0.6 \pi n \right)}}{\pi^{2} n^{2}} - \frac{0.3 \sin{\left(\pi n \right)}}{\pi^{2} n^{2}}\right) \sin{\left(\frac{10 \pi n x}{33} \right)} \cos{\left(880 \pi n t \right)}$

Caso 2: Instrumento de cuerda frotada¶

In [12]:
An = violin.findAn(posInicialViolin)
Bn = violin.findBn(velocidadInicialViolin)

showAnBn(An,Bn)
$\displaystyle \begin{array}{ll} A_n: & 0 \\ B_n: & \frac{- \pi n \left(3.05846563257619 \cdot 10^{-19} \cos{\left(0.892424242424242 \pi n \right)} + 1.83507937954571 \cdot 10^{-18} \cos{\left(0.925757575757576 \pi n \right)}\right) + 0.00254668930390492 \sin{\left(0.892424242424242 \pi n \right)} + 0.0306122448979592 \sin{\left(0.925757575757576 \pi n \right)} - 0.0306122448979592 \sin{\left(\pi n \right)}}{\pi^{3} n^{3}} \end{array} $
In [13]:
violin.setAmplitudes(An,Bn)
display(violin)
$\displaystyle \psi_n(x,t)=\frac{0.00068870523415978 \left(- \frac{4.44089209850063 \cdot 10^{-16} \cos{\left(0.892424242424242 \pi n \right)}}{\pi n} - \frac{2.66453525910038 \cdot 10^{-15} \cos{\left(0.925757575757576 \pi n \right)}}{\pi n} + \frac{3.69779286926995 \sin{\left(0.892424242424242 \pi n \right)}}{\pi^{2} n^{2}} + \frac{44.4489795918368 \sin{\left(0.925757575757576 \pi n \right)}}{\pi^{2} n^{2}} - \frac{44.4489795918368 \sin{\left(\pi n \right)}}{\pi^{2} n^{2}}\right) \sin{\left(880 \pi n t \right)} \sin{\left(\frac{10 \pi n x}{33} \right)}}{\pi n}$

Caso 3: Instrumento de cuerda percutida¶

In [14]:
An = piano.findAn(posInicialPiano)
Bn = piano.findBn(velocidadInicialPiano)

showAnBn(An,Bn)
$\displaystyle \begin{array}{ll} A_n: & 0 \\ B_n: & \frac{8.26813365248117 \cdot 10^{-16} \pi n \cos{\left(0.6825 \pi n \right)} - 6.81818181818182 \sin{\left(0.6815 \pi n \right)} + 6.81818181818182 \sin{\left(0.6825 \pi n \right)} + 6.81818181818182 \sin{\left(0.7575 \pi n \right)} - 6.81818181818182 \sin{\left(0.7585 \pi n \right)}}{\pi^{3} n^{3}} \end{array} $
In [15]:
piano.setAmplitudes(An,Bn)
display(piano)
$\displaystyle \psi_n(x,t)=\frac{0.000454545454545455 \cdot \left(\frac{1.81898940354586 \cdot 10^{-12} \cos{\left(0.6825 \pi n \right)}}{\pi n} - \frac{15000.0 \sin{\left(0.6815 \pi n \right)}}{\pi^{2} n^{2}} + \frac{15000.0 \sin{\left(0.6825 \pi n \right)}}{\pi^{2} n^{2}} + \frac{15000.0 \sin{\left(0.7575 \pi n \right)}}{\pi^{2} n^{2}} - \frac{15000.0 \sin{\left(0.7585 \pi n \right)}}{\pi^{2} n^{2}}\right) \sin{\left(880 \pi n t \right)} \sin{\left(\frac{\pi n x}{5} \right)}}{\pi n}$

3. ¿Qué significa todo?¶

Las herramientas de programación nos ayudan a visualizar y entender de otro modo la abstracción matemática.

3.A ¿Qué significan los autovalores?¶

Fijado un valor $c$, los autovalores $\lambda_n$ nos dan las sucesivas frecuencias de vibración de la cuerda, es decir, las frecuencias a las que resuena la cuerda.

Las frecuencias a su vez se tratan de lo que se conoce como modos normales de la cuerda, se suelen llamar también frecuencias naturales y se tratan de frecuencias a las que la cuerda vibrara al ser perturbada.

In [17]:
for i in range(1,normalMode+1):
    print(violin.f_n.evalf(subs={n:i}))
440.000000000000
880.000000000000
1320.00000000000
1760.00000000000
2200.00000000000
2640.00000000000

En el mundo musical, estas frecuencias naturales son lo que se conocen como Armónicos y tienen un sonido muy característico, pues cambian el timbre del instrumento.

3.B ¿Qué interpretación tiene $\psi_n(x,t)$?¶

Sabemos que $\psi_n(x,t) = \sin\left(\sqrt{\lambda_n} x\right)\left(A_n\cos\left(c\sqrt{\lambda_n} t\right) +B_n\sin\left(c\sqrt{\lambda_n} t\right)\right)$

Usando las relaciones del principio nos permite simplificar obteniendo $\left(A_n{\mathrm{cos} \left(2\pi f_n t\right)\ }+B_n{\mathrm{sin} \left( 2\pi f_n t\right)\ }\right)\mathrm{\ sin}\left(\frac{2\pi f_n}{c} x\right)$

Es decir, se trata de una ecuación en un modo normal dado por $n$, y nos representa la posición de la cuerda en el instante $t$, veamos un ejemplo:

In [18]:
filename = f'./Graficas/normalMode_{normalMode}_{"Slow" if slowed else "Normal"}.gif'
ani = violin.plotNormalMode_Animated(normalMode,slow=slowed)
#ani.save(filename)
plt.close()
displayGif(filename)
Out[18]:

SegmentLocal

Podemos observar como la cuerda se mueve o vibra a medida que el tiempo avanza, un hecho a destacar es que cada elemento entre los nodos fijos oscila con la misma frecuencia.

3.C ¿Qué significan $A_n$ y $B_n$?¶

En vista de la ecuación, observamos que $A_n$ y $B_n$ son constantes, en función de n, que multiplican a los modos normales, es decir, se tratan de amplitudes o el "volumen" de los modos normales.

El hecho de que las amplitudes sean el "volumen" de los modos normales es lo que permite a nuestro oído detectar el timbre de la cuerda o instrumento, de ahí que un violín y una viola se oigan distintos.

Aqui se muestra un ejemplo de la amplitud de los modos normales:

In [19]:
harp.plotEspectro(N=normalMode)
In [20]:
violin.plotEspectro(N=normalMode)
In [21]:
piano.plotEspectro(N=normalMode)

3.D Y...¿Qué pasa cuando las sumamos?¶

Usando el principio de superposición de soluciones sabemos que la cuerda realmente es la suma de todos los modos normales junto a su "volumen".

$u(x,t)=\sum_{n=1}^{\infty} \psi_n(x,t)$

Veamos un ejemplo con 6 modos normales:

In [22]:
ani = violin.plotNormalModesCombined_Animated(slow=slowed)
plt.close()
#ani.save(f'./Graficas/normalModesCombined.gif')
In [23]:
displayGif(f'./Graficas/normalModesCombined.gif')
Out[23]:

SegmentLocal

In [24]:
filename = f'./Graficas/HarpString.gif'
ani = harp.plotString_Animated(normalMode)
#ani.save(filename)
plt.close()
displayGif(filename)
Out[24]:

SegmentLocal

In [25]:
filename = f'./Graficas/ViolinString.gif'
ani = violin.plotString_Animated(normalMode)
#ani.save(filename)
plt.close()
displayGif(filename)
Out[25]:

SegmentLocal

In [26]:
filename = f'./Graficas/PianoString.gif'
ani = piano.plotString_Animated(normalMode)
#ani.save(filename)
plt.close()
displayGif(filename)
Out[26]:

SegmentLocal

Onda Temporal¶

Fijando un punto de la cuerda y viendo cómo cambia según $t$ podemos ver el trazado de la onda en el tiempo.

In [27]:
harp.plotTimeWave(N=normalMode)
In [28]:
violin.plotTimeWave(N=normalMode)
In [29]:
piano.plotTimeWave(N=normalMode)

Comparemoslos (Normalizandolos)

In [30]:
violin.plotTimeWave_Compare([harp,piano],N=normalMode)

4. El sonido de la cuerda¶

Veamos el sonido que produce nuestro modelo

In [31]:
audio,dataAudio = (harp.makeSound(
                                    segundos = 5,
                                    modosNormales = 30,
                                    startAt=1,
                                    normalize=True,
                                    fadeOut=True,
                                    filename= f"./Sonidos/Plucked_{harp.fundamentalFreq}Hz",
                                    guitarCase=True
                                ))
In [32]:
audio,dataAudio = (violin.makeSound(
                                    segundos = 5,
                                    modosNormales = 20,
                                    startAt=1,
                                    normalize=True,
                                    fadeOut=True,
                                    filename= f"./Sonidos/Bowed_{violin.fundamentalFreq}Hz"
                                ))
In [33]:
audio,dataAudio = (piano.makeSound(
                                    segundos = 5,
                                    modosNormales = 20,
                                    startAt=1,
                                    normalize=True,
                                    fadeOut=True,
                                    filename= f"./Sonidos/Strucked_{piano.fundamentalFreq}Hz"
                                ))

El sonido pitagórico: La afinación por quintas¶

Partimos de un "Do" a 32 y construyamos las notas en 5 octavas distintas, moviéndonos por quintas

In [34]:
notas = violin.getMusicalNotes_Pythagoras(32,5)
notas.keys()
Out[34]:
dict_keys(['Do1', 'Reb1', 'Re1', 'Mib1', 'Mi1', 'Fa1', 'Fa#1', 'Sol1', 'Lab1', 'La1', 'Sib1', 'Si1', 'Do2', 'Reb2', 'Re2', 'Mib2', 'Mi2', 'Fa2', 'Fa#2', 'Sol2', 'Lab2', 'La2', 'Sib2', 'Si2', 'Do3', 'Reb3', 'Re3', 'Mib3', 'Mi3', 'Fa3', 'Fa#3', 'Sol3', 'Lab3', 'La3', 'Sib3', 'Si3', 'Do4', 'Reb4', 'Re4', 'Mib4', 'Mi4', 'Fa4', 'Fa#4', 'Sol4', 'Lab4', 'La4', 'Sib4', 'Si4', 'Do5', 'Reb5', 'Re5', 'Mib5', 'Mi5', 'Fa5', 'Fa#5', 'Sol5', 'Lab5', 'La5', 'Sib5', 'Si5', 'Shhh'])
In [36]:
display(tabla_notas)
Do Reb Re Mib Mi Fa Fa# Sol Lab La Sib Si
1 32.0 34.171875 36.0 37.925926 40.5 42.666667 45.5625 48.0 51.257812 54.0 56.888889 60.75
2 64.0 68.343750 72.0 75.851852 81.0 85.333333 91.1250 96.0 102.515625 108.0 113.777778 121.50
3 128.0 136.687500 144.0 151.703704 162.0 170.666667 182.2500 192.0 205.031250 216.0 227.555556 243.00
4 256.0 273.375000 288.0 303.407407 324.0 341.333333 364.5000 384.0 410.062500 432.0 455.111111 486.00
5 512.0 546.750000 576.0 606.814815 648.0 682.666667 729.0000 768.0 820.125000 864.0 910.222222 972.00

Enfrentamos las quintas: La perfección del sonido¶

In [37]:
Partitura = [
    (2,["Do4","Sol4"]),
    (2,["Reb4","Lab4"]),
    (2,["Re4","La4"]),
    (2,["Mib4","Sib4"]),
    (2,["Mi4","Si4"]),
    (2,["Fa4","Do5"]),
    (2,["Fa#4","Reb5"]),
    (2,["Sol4","Re5"]),
    (1,["Lab4","Mib5"]),  # Sol# - Mib
    ]

y_data = WEQ.makeSong(notas,Partitura,100,"Fifths_WolfInterval",normalMode=20)

Para acabar ... Componemos una canción en este sistema¶

Violin Sonata No.1 in G minor, BWV 1001, Mov. 2 https://imslp.org/wiki/Violin_Sonata_No.1_in_G_minor%2C_BWV_1001_(Bach%2C_Johann_Sebastian)
In [39]:
instruments = [harp,violin,piano]
for instrument in instruments:
    nombreInstrumento = [name for name in globals() if globals()[name] is instrument][0]
    WEQ.makeSong(instrument.getMusicalNotes_Pythagoras(32,5), bachFugue, 90, f"BachFugue_{nombreInstrumento}", 
                 normalMode=30,guitarCase="harp"==nombreInstrumento)

Violin Sonata No.1 in G minor, BWV 1001, Mov. 2 - J.S. Bach¶

Harpa¶
Violin¶
Piano¶
Caso Real¶
In [40]:
YouTubeVideo("oq6D5Ll1Rqw",width=800, height=480)
Out[40]:

¿Qué se utiliza hoy?¶

Ya hemos visto que este sistema de afinacion por quientas de Pitágoras está errado.

De ahí que a lo largo de la historia se hayan buscado distintas formas de afinar las notas, pero no se ha encontrado ninguna que funcione de manera "simple", es decir, con relaciones sencillas entre los números.

De ahí que se empezó a cambiar a otros sistemas de afinación con el objetivo de arreglar estos errores, es por ello que hoy en día se utiliza (en pianos sobre todo) el "Temperamento Igual" que consiste en que el semitono sea exactamente $\sqrt[12]{2}$, en definitiva, un número irracional.

La idea detrás de este número es que elevando 12 semitonos obtengamos la octava perfecta (Sí, la de Pitágoras) la 2

¿Quién soy yo?¶

Estudiante de Matemáticas e Informática de la Universidad Politécnica de Madrid

"The present is theirs; the future, for which I have really worked, is mine."- Nikola Tesla

  • Correo Institucional: f.bpazos@alumnos.upm.es
  • Github:https://github.com/fbellidopazos