Académique Documents
Professionnel Documents
Culture Documents
FIZ1405
S. Wallentowitz
Facultad de Física, UC
Parte I
FIZ1405
Bibliografía.
Programación:
B.W. Kernighan, D.M. Ritchie
Programación en C (Addison Wesley)
W.H. Press, S.A. Teukolsky, W.T. Vetterling, B.P. Flannery
Numerical Recipes en C
2nd ed. (Cambridge University Press)
Online: http://www.library.cornell.edu/nr/
Funciones especiales, integrales, etc.:
M. Abramowitz, I.A. Stegun
Handbook of mathematical functions
9th ed. (Dover Publications)
Online: http://www.math.sfu.ca/~cbm/aands/
Notas — Alternativa 1.
Tareas:
Desarollo de programas pequeños.
Aplicación de programas de la clase a un problema físico.
Examen final escrito:
Preguntas con respecto al contenido del curso.
Revisar y escribir pequeñas partes de un programa.
NF = (NT + NE )/2
NT = promedio de las notas de las tareas
NE = nota del examen final
Notas — Alternativa 1.
Tareas:
Desarollo de programas pequeños.
Aplicación de programas de la clase a un problema físico.
Examen final escrito:
Preguntas con respecto al contenido del curso.
Revisar y escribir pequeñas partes de un programa.
NF = (NT + NE )/2
NT = promedio de las notas de las tareas
NE = nota del examen final
Notas — Alternativa II.
Aviso:
Mejor no usar Windows!
Requisitos técnicos.
Aviso:
Mejor no usar Windows!
Objectivos.
1 Introducción
2 Ecuaciones diferenciales
3 Funciones especiales
4 Interpolación
5 Integración
6 Transformación de Fourier
7 Aproximación de Chebyshev
8 Números aleatorios
9 (Dinámica molecular)
10 (Monte-Carlo)
Parte II
Introducción
Una suma trivial.
¿Cómo sumar números punto flotante con el computador?
Un ejemplo:
1,0
+5,0 × 10−8
+5,0 × 10−8
+5,0 × 10−8
+5,0 × 10−8 = 1,0000002
Resultado es:
shell> cc -o sum2.bin intro_sum2.c [RETURN]
shell> ./sum2.bin [RETURN]
shell> x = 1.00000024
shell>
Representación binaria de un número punto flotante.
Estandard IEEE.
Sign bit s = 0, 1 → ±.
Mantisa m son p bits, donde p es la precisión, por ejemplo
m = 10101 con p = 5.
Exponente e de dos bits por ejemplo:
00 → −1
01 → 0
10 → +1
11 → +2
Representación decimal:
m
x = (−1)s × × 2e
2p
= (−1)s × m × 2e−p
Representación binaria de un número punto flotante.
Estandard IEEE.
Sign bit s = 0, 1 → ±.
Mantisa m son p bits, donde p es la precisión, por ejemplo
m = 10101 con p = 5.
Exponente e de dos bits por ejemplo:
00 → −1
01 → 0
10 → +1
11 → +2
Representación decimal:
m
x = (−1)s × × 2e
2p
= (−1)s × m × 2e−p
Representación binaria de un número punto flotante.
Estandard IEEE.
Sign bit s = 0, 1 → ±.
Mantisa m son p bits, donde p es la precisión, por ejemplo
m = 10101 con p = 5.
Exponente e de dos bits por ejemplo:
00 → −1
01 → 0
10 → +1
11 → +2
Representación decimal:
m
x = (−1)s × × 2e
2p
= (−1)s × m × 2e−p
Representación binaria de un número punto flotante.
Estandard IEEE.
Sign bit s = 0, 1 → ±.
Mantisa m son p bits, donde p es la precisión, por ejemplo
m = 10101 con p = 5.
Exponente e de dos bits por ejemplo:
00 → −1
01 → 0
10 → +1
11 → +2
Representación decimal:
m
x = (−1)s × × 2e
2p
= (−1)s × m × 2e−p
Representación binaria de un número punto flotante.
Estandard IEEE.
Sign bit s = 0, 1 → ±.
Mantisa m son p bits, donde p es la precisión, por ejemplo
m = 10101 con p = 5.
Exponente e de dos bits por ejemplo:
00 → −1
01 → 0
10 → +1
11 → +2
Representación decimal:
m
x = (−1)s × × 2e
2p
= (−1)s × m × 2e−p
Ejemplo.
x = 01010110
x = (−1)s × m × 2e−p
= (−1)0 × 21 × 25−1
= 21/16
= 1,3125
Ejemplo.
x = 01010110
x = (−1)s × m × 2e−p
= (−1)0 × 21 × 25−1
= 21/16
= 1,3125
Ejemplo.
x = 01010110
x = (−1)s × m × 2e−p
= (−1)0 × 21 × 25−1
= 21/16
= 1,3125
Posibles valores.
Representación de 8 bits con precisión p = 5 y dos bits para el
exponente (signo es irrelevante):
1 Existe un valor (absoluto) maximal:
x = 0 11111 11 → 3,875
x = 0 00001 00 → 0,015625
0,015625 0,125
x = 0 11111 11 → 3,875
x = 0 00001 00 → 0,015625
0,015625 0,125
x = 0 11111 11 → 3,875
x = 0 00001 00 → 0,015625
0,015625 0,125
x = 0 11111 11 → 3,875
x = 0 00001 00 → 0,015625
0,015625 0,125
Perdida de precisión:
Tiene muchas causas, la más comúna es la combinación de
numeros con valores muy distintos.
Error underflow:
Resultados temporarios son más pequeños que el valor minimal,
el procesador los reemplazo con ceros.
Error overflow:
Resultados temporarios son más grande que el valor maximal, el
procesador continua con números más o menos aleatorios. Sale
un mensaje “nan” (not a number) o “inf” (infinity).
¿Entonces qué se puede hacer?
Cuidarse mucho y obtener suficiente experiencia (trial & error).
Problemas típicos.
Perdida de precisión:
Tiene muchas causas, la más comúna es la combinación de
numeros con valores muy distintos.
Error underflow:
Resultados temporarios son más pequeños que el valor minimal,
el procesador los reemplazo con ceros.
Error overflow:
Resultados temporarios son más grande que el valor maximal, el
procesador continua con números más o menos aleatorios. Sale
un mensaje “nan” (not a number) o “inf” (infinity).
¿Entonces qué se puede hacer?
Cuidarse mucho y obtener suficiente experiencia (trial & error).
Problemas típicos.
Perdida de precisión:
Tiene muchas causas, la más comúna es la combinación de
numeros con valores muy distintos.
Error underflow:
Resultados temporarios son más pequeños que el valor minimal,
el procesador los reemplazo con ceros.
Error overflow:
Resultados temporarios son más grande que el valor maximal, el
procesador continua con números más o menos aleatorios. Sale
un mensaje “nan” (not a number) o “inf” (infinity).
¿Entonces qué se puede hacer?
Cuidarse mucho y obtener suficiente experiencia (trial & error).
Problemas típicos.
Perdida de precisión:
Tiene muchas causas, la más comúna es la combinación de
numeros con valores muy distintos.
Error underflow:
Resultados temporarios son más pequeños que el valor minimal,
el procesador los reemplazo con ceros.
Error overflow:
Resultados temporarios son más grande que el valor maximal, el
procesador continua con números más o menos aleatorios. Sale
un mensaje “nan” (not a number) o “inf” (infinity).
¿Entonces qué se puede hacer?
Cuidarse mucho y obtener suficiente experiencia (trial & error).
Otro ejemplo.
Compilar e ejecutar:
shell> cc -o number.bin intro_number.c [RETURN]
shell> ./number.bin [RETURN]
shell> 1.2 = 1.19999999999999995559
shell>
Números integros.
Formato Resultado
%f 0.001542
%e 1.542e-3
%g %f o %e
%d para números integros
Obtener información.
Para cualquier programa o función hay una “manual page”.
Resultado de:
shell> man 3 printf [RETURN]
Parte III
Ecuaciones Diferenciales
Ecuación diferencial ordinaria.
Ecuaciones diferenciales ordinarias del orden 1:
d ~x (t) ~
= f (~x , t)
dt
Es un sistema de ecuaciones diferenciales acopladas!
~x˙ = ~y
~y˙ = ~f (~x , ~y , t)
es lo mismo que:
d ~z ~y
d ~x
= ~y = ~f (~x , ~y , t) = ~g (~z , t)
dt dt
Ecuación diferencial ordinaria.
Ecuaciones diferenciales ordinarias del orden 1:
d ~x (t) ~
= f (~x , t)
dt
Es un sistema de ecuaciones diferenciales acopladas!
~x˙ = ~y
~y˙ = ~f (~x , ~y , t)
es lo mismo que:
d ~z ~y
d ~x
= ~y = ~f (~x , ~y , t) = ~g (~z , t)
dt dt
Ecuación diferencial ordinaria.
Ecuaciones diferenciales ordinarias del orden 1:
d ~x (t) ~
= f (~x , t)
dt
Es un sistema de ecuaciones diferenciales acopladas!
~x˙ = ~y
~y˙ = ~f (~x , ~y , t)
es lo mismo que:
d ~z ~y
d ~x
= ~y = ~f (~x , ~y , t) = ~g (~z , t)
dt dt
Ecuación diferencial ordinaria.
Ecuaciones diferenciales ordinarias del orden 1:
d ~x (t) ~
= f (~x , t)
dt
Es un sistema de ecuaciones diferenciales acopladas!
~x˙ = ~y
~y˙ = ~f (~x , ~y , t)
es lo mismo que:
d ~z ~y
d ~x
= ~y = ~f (~x , ~y , t) = ~g (~z , t)
dt dt
Método de Euler.
Ahora solo una ecuación diferencial: ~x → x.
Definición de la derivada:
dx(t)
x(t + ∆t) ≈ x(t) + ∆t
dt
= x(t) + ∆t f (x, t)
Método de Euler:
xn+1 ≈ xn + ∆t f (xn , tn )
donde xn = x(tn ) con tn+1 = tn + ∆t.
Método de Euler.
Ahora solo una ecuación diferencial: ~x → x.
Definición de la derivada:
dx(t)
x(t + ∆t) ≈ x(t) + ∆t
dt
= x(t) + ∆t f (x, t)
Método de Euler:
xn+1 ≈ xn + ∆t f (xn , tn )
donde xn = x(tn ) con tn+1 = tn + ∆t.
Error.
xn
t
tn
Idéa de Euler.
xn+1
xn
t
tn tn+1
Idéa de Euler.
xn+1
xn
t
tn tn+1
Idéa de Euler.
xn+1
xn
t
tn tn+1 tn+2
Idéa de Runge-Kutta.
Tomar derivada en la mitad!
xn
t
tn tn+1
Idéa de Runge-Kutta.
Tomar derivada en la mitad!
xn
t
tn tn+1
Idéa de Runge-Kutta.
Tomar derivada en la mitad!
xn
∆t ∆t
2 2
t
tn tn+1
Idéa de Runge-Kutta.
Tomar derivada en la mitad!
xn
∆t ∆t
2 2
t
tn tn+1
Runge-Kutta de orden 2.
x
k1
xn
∆t ∆t
2 2
t
tn tn+1
1 Derivada en el comienzo:
k1 = ∆t f (xn , tn )
2 Derivada en la mitad:
k1 ∆t
k2 = ∆t f xn + , tn +
2 2
3 Runge-Kutta del orden 2:
xn+1 = xn + k2 + O (∆t)3
Runge-Kutta de orden 2.
x
k1
xn
∆t ∆t
2 2
t
tn tn+1
1 Derivada en el comienzo:
k1 = ∆t f (xn , tn )
2 Derivada en la mitad:
k1 ∆t
k2 = ∆t f xn + , tn +
2 2
3 Runge-Kutta del orden 2:
xn+1 = xn + k2 + O (∆t)3
Runge-Kutta de orden 2.
x
k1
xn
∆t ∆t
2 2
t
tn tn+1
1 Derivada en el comienzo:
k1 = ∆t f (xn , tn )
2 Derivada en la mitad:
k1 ∆t
k2 = ∆t f xn + , tn +
2 2
3 Runge-Kutta del orden 2:
xn+1 = xn + k2 + O (∆t)3
Runge-Kutta de orden 2.
x
k1
xn
∆t ∆t
2 2
t
tn tn+1
1 Derivada en el comienzo:
k1 = ∆t f (xn , tn )
2 Derivada en la mitad:
k1 ∆t
k2 = ∆t f xn + , tn +
2 2
3 Runge-Kutta del orden 2:
xn+1 = xn + k2 + O (∆t)3
Evaluación del error.
RK2:
Calcular coeficientes:
k1 = ∆t f (xn , tn )
k1 ∆t
k2 = ∆t f xn + , tn +
2 2
Aproximación RK2:
xn+1 = xn + k2 + O (∆t)3
1
k1
xn
t
tn tn+1
RK4.
Runge-Kutta del orden 4.
xn
k2
2
t
tn tn+1
RK4.
Runge-Kutta del orden 4.
xn
2 k3
3
t
tn tn+1
RK4.
Runge-Kutta del orden 4.
xn
2
k4 3
t
tn tn+1
En detalle.
Secuencia de la calculación:
1 k1 = ∆t f (xn , tn )
k1 ∆t
2 k2 = ∆t f (xn + 2 , tn + 2 )
k2 ∆t
3 k3 = ∆t f (xn + 2 , tn + 2 )
4 k4 = ∆t f (xn + k3 , tn + ∆t)
1
(k1 + 2k2 + 2k3 + k4 ) + O (∆t)5
xn+1 = xn +
6
Se necesitan 4 evaluaciones de f (x, t)!
En detalle.
Secuencia de la calculación:
1 k1 = ∆t f (xn , tn )
k1 ∆t
2 k2 = ∆t f (xn + 2 , tn + 2 )
k2 ∆t
3 k3 = ∆t f (xn + 2 , tn + 2 )
4 k4 = ∆t f (xn + k3 , tn + ∆t)
1
(k1 + 2k2 + 2k3 + k4 ) + O (∆t)5
xn+1 = xn +
6
Se necesitan 4 evaluaciones de f (x, t)!
En detalle.
Secuencia de la calculación:
1 k1 = ∆t f (xn , tn )
k1 ∆t
2 k2 = ∆t f (xn + 2 , tn + 2 )
k2 ∆t
3 k3 = ∆t f (xn + 2 , tn + 2 )
4 k4 = ∆t f (xn + k3 , tn + ∆t)
1
(k1 + 2k2 + 2k3 + k4 ) + O (∆t)5
xn+1 = xn +
6
Se necesitan 4 evaluaciones de f (x, t)!
En detalle.
Secuencia de la calculación:
1 k1 = ∆t f (xn , tn )
k1 ∆t
2 k2 = ∆t f (xn + 2 , tn + 2 )
k2 ∆t
3 k3 = ∆t f (xn + 2 , tn + 2 )
4 k4 = ∆t f (xn + k3 , tn + ∆t)
1
(k1 + 2k2 + 2k3 + k4 ) + O (∆t)5
xn+1 = xn +
6
Se necesitan 4 evaluaciones de f (x, t)!
En detalle.
Secuencia de la calculación:
1 k1 = ∆t f (xn , tn )
k1 ∆t
2 k2 = ∆t f (xn + 2 , tn + 2 )
k2 ∆t
3 k3 = ∆t f (xn + 2 , tn + 2 )
4 k4 = ∆t f (xn + k3 , tn + ∆t)
1
(k1 + 2k2 + 2k3 + k4 ) + O (∆t)5
xn+1 = xn +
6
Se necesitan 4 evaluaciones de f (x, t)!
Runge-Kutta del orden N en general.
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
M−1
X
kM = ∆t f (xn + bM,m km , tn + aM ∆t)
m=1
M
X M
X
cm km + O (∆t)N+1 ,
xn+1 = xn + cm = 1
m=1 m=1
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
M−1
X
kM = ∆t f (xn + bM,m km , tn + aM ∆t)
m=1
M
X M
X
cm km + O (∆t)N+1 ,
xn+1 = xn + cm = 1
m=1 m=1
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
M−1
X
kM = ∆t f (xn + bM,m km , tn + aM ∆t)
m=1
M
X M
X
cm km + O (∆t)N+1 ,
xn+1 = xn + cm = 1
m=1 m=1
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
M−1
X
kM = ∆t f (xn + bM,m km , tn + aM ∆t)
m=1
M
X M
X
cm km + O (∆t)N+1 ,
xn+1 = xn + cm = 1
m=1 m=1
4 “Optimizar”:
1 h i
x (opt) (t + ∆t) = 16 x (2) (t + ∆t) − x (1) (t + ∆t) + O (∆t)6
15
Control del error.
Idéa simple.
4 “Optimizar”:
1 h i
x (opt) (t + ∆t) = 16 x (2) (t + ∆t) − x (1) (t + ∆t) + O (∆t)6
15
Control del error.
Idéa simple.
4 “Optimizar”:
1 h i
x (opt) (t + ∆t) = 16 x (2) (t + ∆t) − x (1) (t + ∆t) + O (∆t)6
15
Control del error.
Idéa simple.
4 “Optimizar”:
1 h i
x (opt) (t + ∆t) = 16 x (2) (t + ∆t) − x (1) (t + ∆t) + O (∆t)6
15
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Control adaptivo de pasos.
Si es verdad:
Usar la solución.
Aumentar ∆t para el proximo paso.
Si no es verdad:
Borrar la solución.
Empezar de nuevo (#1) con un paso ∆t mas pequeño.
Adapción de pasos.
¿Cómo calcular los nuevos pasos?
15
1
∆tnew = ∆told ×
R
15
1
∆tnew = ∆told ×
R
15
1
∆tnew = ∆told ×
R
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Problema: Es lento!
Problema:
Se necesitan 11 evaluaciones de la función f (x, t) para un paso
adaptivo (exitoso)!
Runge-Kutta embedded.
Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
X5
k6 = ∆t f (xn + b6,m km , tn + a6 ∆t)
m=1
(5) (4)
Estimación del error: error = |xn+1 − xn+1 | ∝ (∆t)5
Runge-Kutta embedded.
Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
X5
k6 = ∆t f (xn + b6,m km , tn + a6 ∆t)
m=1
(5) (4)
Estimación del error: error = |xn+1 − xn+1 | ∝ (∆t)5
Runge-Kutta embedded.
Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.
k1 = ∆t f (xn , tn )
k2 = ∆t f (xn + b2,1 k1 , tn + a2 ∆t)
..
.
X5
k6 = ∆t f (xn + b6,m km , tn + a6 ∆t)
m=1
(5) (4)
Estimación del error: error = |xn+1 − xn+1 | ∝ (∆t)5
Coeficientes de Cash-Karp.
1 1
53 53 9
~~
~a = 10
3
, b=
3
40 40
9 6
5
10 − 10 5
1 − 11 5
− 70 35
54 2 27 27
7 1631 175 575 44275 253
8 55296 512 13824 110592 4096
37
2825
378 27648
0 0
250 18575
~d =
~c =
621
125
,
48384
13525
594 55296
277
0
14336
512 1
1771 4
Implementación.
de_rkembedded.c
46 f(k1, x, t);
47
48 for (i = 0; i < sz; i++)
49 xout[i] = x[i] + b21 * dt * k1[i];
50 f(k2, xout, t + a2 * dt);
51
52 for (i = 0; i < sz; i++)
53 xout[i] = x[i] + dt * (b31 * k1[i] + b32 * k2[i]);
54 f(k3, xout, t + a3 * dt);
55
56 for (i = 0; i < sz; i++)
57 xout[i] = x[i] + dt * (b41 * k1[i] + b42 * k2[i]
58 + b43 * k3[i]);
59 f(k4, xout, t + a4 * dt);
60
61 for (i = 0; i < sz; i++)
62 xout[i] = x[i] + dt * (b51 * k1[i] + b52 * k2[i]
63 + b53 * k3[i] + b54 * k4[i]);
64 f(k5, xout, t + a5 * dt);
Implementación.
de_rkembedded.c
23 size_t i;
24 double t, dt, err, *ytmp;
25 int min_cnt;
26
27 dt = t2 - t1;
28 assert((dtmin >= 0.0) && (dt >= dtmin));
29 ytmp = malloc(sz * sizeof(double));
30 t = t1;
31 min_cnt = 0;
Implementación del control adaptivo.
de_solve.c
33 do {
34 for(;;) {
35 dt = ((t+dt) > t2) ? t2-t : dt;
36 err = rk_embedded(y, t, sz, dt, ytmp, f);
37 err /= eps;
38 if (err > 1.0) {
39 dt *= SAFETY_FACTOR * pow(err, -0.2);
40 if (dt < dtmin) {
41 min_cnt++;
42 dt = dtmin;
43 }
44 } else {
45 t += dt;
46 dt *= SAFETY_FACTOR * pow(err, -0.2);
47 for (i = 0; i < sz; i++)
48 y[i] = ytmp[i];
49 break;
50 }
51 }
52 } while ((t2-t) > DBL_MIN);
53 free(ytmp);
54 return min_cnt;
55 }
Implementación del control adaptivo.
de_solve.c
k12 ω2, γ2
ω1, γ1
m2
m1
Ecuaciones de movimiento:
dp1 d 2 x1
= m1 2 = −k1 x1 − m1 γ1 ẋ1 + k12 x2
dt dt
dp2 d 2 x2
= m2 2 = −k2 x2 − m2 γ2 ẋ2 + k12 x1
dt dt
Tiempo sin unidad.
τ = ω0 t = [rad]
τ = ω0 t = [rad]
τ = ω0 t = [rad]
xi = ∆x0 qi (i = 1, 2)
xi = ∆x0 qi (i = 1, 2)
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4
5 #define SZ 4
6 #define GAMMA1 0.1
7 #define OMEGA1 1.0
8 #define X_INI1 1.0
9 #define P_INI1 0.0
10 #define GAMMA2 0.1
11 #define OMEGA2 8.0
12 #define X_INI2 1.0
13 #define P_INI2 0.0
14 #define KAPPA1 1.0
15 #define KAPPA2 0.05
16 #define OMEGA1SQR (OMEGA1 * OMEGA1)
17 #define OMEGA2SQR (OMEGA2 * OMEGA2)
Implementación.
main_de_cho2.c
31 int main(void)
32 {
33 double x[SZ];
34 double t, tmax, tstep;
35 int min_cnt;
36
37 tmax = 40.0;
38 tstep = 0.01;
39
40 x[0] = X_INI1;
41 x[1] = P_INI1;
42 x[2] = X_INI2;
43 x[3] = P_INI2;
44
45 for (t = 0; t < tmax; t += tstep) {
46 printf(" %f %f %f %f %f\n", t, x[0], x[1], x[2], x[3]);
47 min_cnt = de_solve(x, SZ, t, t+tstep, 1.0e-7, 1.0e-10, f);
48 if (min_cnt != 0)
49 fprintf(stderr, "at t = %f - # of events h < hmin: %d\n",
50 t, min_cnt);
51 }
52 return 0;
53 }
Resultados.
1
0.8 Oscilador 1
0.6
0.4
0.2
0
k1
−0.2
−0.4
−0.6
−0.8
−1
−1.2
−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1
q1
Resultados.
8
Oscilador 2
6
2
k2
−2
−4
−6
−8
−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1
q2
Molecula en campo eléctrico.
z
E
ϕ
x
Ecuaciones de movimiento.
E 2 ∆α
V (ϑ) = −dE cos ϑ − cos2 ϑ
2
donde d = momento dipolar eléctrico permanente,
∆α = αk − α⊥ =polarisabilidad anisotropica.
Constante de movimiento (Θ = momento inercial):
dϕ
Lz = Θ sin2 ϑ
dt
Ecuación de movimiento (conservación de energía):
d 2 ϑ L2z ∂V (ϑ)
Θ − cot ϑ + =0
dt 2 Θ ∂ϑ
Ecuaciones de movimiento.
E 2 ∆α
V (ϑ) = −dE cos ϑ − cos2 ϑ
2
donde d = momento dipolar eléctrico permanente,
∆α = αk − α⊥ =polarisabilidad anisotropica.
Constante de movimiento (Θ = momento inercial):
dϕ
Lz = Θ sin2 ϑ
dt
Ecuación de movimiento (conservación de energía):
d 2 ϑ L2z ∂V (ϑ)
Θ − cot ϑ + =0
dt 2 Θ ∂ϑ
Ecuaciones de movimiento.
E 2 ∆α
V (ϑ) = −dE cos ϑ − cos2 ϑ
2
donde d = momento dipolar eléctrico permanente,
∆α = αk − α⊥ =polarisabilidad anisotropica.
Constante de movimiento (Θ = momento inercial):
dϕ
Lz = Θ sin2 ϑ
dt
Ecuación de movimiento (conservación de energía):
d 2 ϑ L2z ∂V (ϑ)
Θ − cot ϑ + =0
dt 2 Θ ∂ϑ
Tiempo sin dimensión.
dϕ
Lz = Θω0 sin2 ϑ = Θω0 ϕ̇ sin2 ϑ
dτ
2 Definimos una constante
Lz
a= = ϕ̇(0) sin2 ϑ(0)
Θω0
dϕ
Lz = Θω0 sin2 ϑ = Θω0 ϕ̇ sin2 ϑ
dτ
2 Definimos una constante
Lz
a= = ϕ̇(0) sin2 ϑ(0)
Θω0
dϕ
Lz = Θω0 sin2 ϑ = Θω0 ϕ̇ sin2 ϑ
dτ
2 Definimos una constante
Lz
a= = ϕ̇(0) sin2 ϑ(0)
Θω0
∆αE 2 ∆αE 2
erg.potencial
b = b2 = 2
= a2 2 = a2
Θω0 Lz /Θ erg.cinetica
∆αE 2 ∆αE 2
erg.potencial
b = b2 = 2
= a2 2 = a2
Θω0 Lz /Θ erg.cinetica
∆αE 2 ∆αE 2
erg.potencial
b = b2 = 2
= a2 2 = a2
Θω0 Lz /Θ erg.cinetica
2 El momento angular:
~ ϑ̇ cos ϕ − ϕ̇ sin ϑ cos ϑ sin ϕ
~l(τ ) = L(τ ) = ϑ̇ sin ϕ + ϕ̇ sin ϑ cos ϑ cos ϕ
Θω0
ϕ̇ sin2 ϑ
ϑ̇ cos ϕ − a cot ϑ sin ϕ
= ϑ̇ sin ϕ + a cot ϑ cos ϕ
a
Visualisación.
¿Qué vamos a graficar?
2 El momento angular:
~ ϑ̇ cos ϕ − ϕ̇ sin ϑ cos ϑ sin ϕ
~l(τ ) = L(τ ) = ϑ̇ sin ϕ + ϕ̇ sin ϑ cos ϑ cos ϕ
Θω0
ϕ̇ sin2 ϑ
ϑ̇ cos ϕ − a cot ϑ sin ϕ
= ϑ̇ sin ϕ + a cot ϑ cos ϕ
a
Implementación.
main_de_mol.c
58 int main(void)
59 {
60 double x[3];
61 double r[3], L[3];
62 double t, tmax, tstep;
63 int min_cnt;
64
65 tmax = 30.0;
66 tstep = 0.001;
67
68 x[0] = PHI_INI;
69 x[1] = THETA_INI;
70 x[2] = THETADOT_INI;
71 V_T = 0.0;
72 B = BFUNC(V_T);
73
74 printf("0.0 0.0 0.0 0.0 0.0 0.0 0.0\n\n\n");
75
76 orientation(r, x);
77 angular_momentum(L, x);
78 printf("0.0 %f %f %f %f %f %f\n\n\n",
79 r[0], r[1], r[2],
80 L[0], L[1], L[3]);
Implementación.
main_de_mol.c
r3
1
0.8
0.6
0.4
0.2
0
−0.2
−0.4
−0.6
−0.8
−1
1
0.8
0.6
−0.4 −0.2 0.4
0.2
0 0.2 0 r2
0.4 −0.2
r1 0.6 0.8 −0.4
1−0.6
Resultados.
l3
1
0.5
0
−0.5
−1
0.6
0.4
0.2
−0.8 −0.6 0
−0.4 −0.2 −0.2 l2
0 −0.4
l1 0.2 −0.6
0.4 −0.8
0.6
Constantes predefinidas.
#include <math.h>
r0
y
r0
y
Jm (kr0 ) = 0
Jm (kr0 ) = 0
Jm (kr0 ) = 0
Completitud:
X
ζλ∗ (x)ζλ (y ) = δ(x − y ), x, y ∈ S
λ
Conjunto completo de funciones ortonormales.
Completitud:
X
ζλ∗ (x)ζλ (y ) = δ(x − y ), x, y ∈ S
λ
Conjunto completo de funciones ortonormales.
Completitud:
X
ζλ∗ (x)ζλ (y ) = δ(x − y ), x, y ∈ S
λ
Ejemplos.
En el espacio S = R las tenemos el conjunto completo de
funciones ortonormales:
1
ζk (x) = √ eikx , k ∈R
2π
Ortonormalidad tenemos porque:
Z ∞
1
dxe−iqx eikx = δ(q − k )
2π −∞
Otros ejemplos:
(a) (a,b)
Polinomiales ortogonales: Ln (x), Hn (x), Tn (x), Pn (x), etc.
Funciones de Bessel Jn (x), Nn (x) etc.
y muchos más...
Ejemplos.
En el espacio S = R las tenemos el conjunto completo de
funciones ortonormales:
1
ζk (x) = √ eikx , k ∈R
2π
Ortonormalidad tenemos porque:
Z ∞
1
dxe−iqx eikx = δ(q − k )
2π −∞
Otros ejemplos:
(a) (a,b)
Polinomiales ortogonales: Ln (x), Hn (x), Tn (x), Pn (x), etc.
Funciones de Bessel Jn (x), Nn (x) etc.
y muchos más...
Ondas en un fluido.
Ondas superficiales de un fluido (ecuación linearisada):
1
∂x [h(x, y )∂x ] + ∂y [h(x, y )∂y ] − ∂t2 z(x, y , t) = 0
g
Z Z Z Z
X 2 ∗ ∗
1
cλ −κλ dξ dηζµ δζλ + dξ dηζµ (∇δ) · (∇ζλ ) − 2 c̈λ δµ,λ =
v
λ
| {z } | {z }
=Aµ,λ =Bµ,λ
d 2 cµ (τ ) X
= −v 2 Aµ,λ κ2λ − Bµ,λ cλ (τ )
dτ 2
λ
Z Z Z Z
X 2 ∗ ∗
1
cλ −κλ dξ dηζµ δζλ + dξ dηζµ (∇δ) · (∇ζλ ) − 2 c̈λ δµ,λ =
v
λ
| {z } | {z }
=Aµ,λ =Bµ,λ
d 2 cµ (τ ) X
= −v 2 Aµ,λ κ2λ − Bµ,λ cλ (τ )
dτ 2
λ
Z Z Z Z
X 2 ∗ ∗
1
cλ −κλ dξ dηζµ δζλ + dξ dηζµ (∇δ) · (∇ζλ ) − 2 c̈λ δµ,λ =
v
λ
| {z } | {z }
=Aµ,λ =Bµ,λ
d 2 cµ (τ ) X
= −v 2 Aµ,λ κ2λ − Bµ,λ cλ (τ )
dτ 2
λ
b
y
a hm«ın
x
hm«ax
Usamos:
∆x = a, ∆y = b, ∆z = (hm«ax + hm«ın )/2
de lo cual resulta que ρ = a/b y v 2 = g(hm«ax + hm«ın )/(2ω02 ab).
La ecuación de Helmholtz simplificada es:
1 2 2 2
∂ + ρ∂η + κλ ζλ (ξ, η) = 0
ρ ξ
Condiciones de borde son:
∇ξλ (ξ, η) = 0, (ξ, η) ∈ borde
Funciones ortonormales.
b
y
a hm«ın
x
hm«ax
y ∆h
h(y ) = hma«x −
b
donde ∆h = hm«ax − hm«ın , entonces tenemos
hm«ax − η∆h
δ(η) = = δ0 − ηδ1
(hm«ax + hm«ın )/2
Integrales Am,n .
La definición es:
Z 1 Z 1
∗
Am,n,m0 ,n0 = Nm,n Nm0 ,n0 dξ dηζm,n (ξ, η)δ(η)ζm0 ,n0 (ξ, η)
0 0
Definición:
Z 1 Z 1
∗ ∂ζm0 ,n0 (ξ, η)
Bm,n,m0 ,n0 = dξ dηζm,n (ξ, η)δ 0 (η)
0 0 ∂η
Después haber integrado ξ:
1
2πn0 ∆h
Z
Bm,n,m0 ,n0 = δm,m0 dη cos(nπη) sin(n0 πη)
hm«ax + hm«ın 0
Z 1
πn0 ∆h
= δm,m0 dη {sin[(n0 + n)πη] + sin[(n0 − n)πη]}
hm«ax + hm«ın 0
πn0 ∆h sin[(n0 + n)π] sin[(n0 − n)π]
= δm,m0 + =0
hm«ax + hm«ın (n0 + n)π (n0 − n)π
Ondas en piscina: sistema de ecuaciones.
ċm,n = dm,n
X
2
δ0 δn,n0 − Nm,n Nm,n0 δ1 In,n0 κ2m,n0 cm,n0 (τ )
ḋm,n = − Nm,n
n0
donde
m2
κ2m,n = π 2
+ ρn2
ρ
0
1 + δn,0 [(−1)n+n − 1](n2 + n02 )
In,n0 = δn,n0 + (1 − δn,n0 )
4 π 2 (n2 − n02 )2
¿Cómo implementar el vector de datos?
a b
×
M N
¿Cómo implementar el vector de datos?
a b
×
M N
¿Cómo implementar el vector de datos?
a b
×
M N
Construir un vector de datos eficiente:
c0,0
d 0,0
c 0,1
d0,1
..
.
d0,N−1
~x = c1,0
..
.
d1,N−1
..
.
..
.
dM−1,N−1
~
~x˙ (τ ) = M
~ · ~x (τ )
donde
0 0
0 0
0 1 0 0
x 0 x 0 x ···
~
~ =
0 0 0 1 0 ··· 0
M
c0,0 c0,0
.. ..
.
.
.. ..
.
.
d cm,n 0 1 cm,n
= ·
dt
dm,n x
0 x 0 x 0 x 0 x 0
dm,n
.. ..
.
.
.. ..
. .
dM−1,N−1 dM−1,N−1
¿Y donde esta el resultado?
donde
ζm,n (ξ, η) = Nm,n cos(mπξ) cos(nπη)
donde
ζm,n (ξ, η) = Nm,n cos(mπξ) cos(nπη)
donde
ζm,n (ξ, η) = Nm,n cos(mπξ) cos(nπη)
Objectivo:
Con coeficientes cn dados, calcular:
N−1
X
f (x) = cn gn (x)
n=0
Problema:
Coeficientes cn y/o gn (x) pueden ser oscilatorios con respecto a
n.
Suma no es convergente con errores numéricos (inevitables)!
Suma con parte recursiva.
Objectivo:
Con coeficientes cn dados, calcular:
N−1
X
f (x) = cn gn (x)
n=0
Problema:
Coeficientes cn y/o gn (x) pueden ser oscilatorios con respecto a
n.
Suma no es convergente con errores numéricos (inevitables)!
Construcción.
P
Recuerde: f (x) = n cn gn (x).
f (x) = ...
..
. h i
+ hN−3 (x) − αN−3 (x)hN−2 (x) − βN−2 (x)hN−1 (x) gN−3 (x)
+ hN−2 (x) − αN−2 (x)hN−1 (x) − βN−1 (x) hN (x) gN−2 (x)
| {z }
=0
+ hN−1 (x) − αN−1 (x) hN (x) −βN (x) hN+1 (x) gN−1 (x)
| {z } | {z }
=0 =0
ReordenarPla
N−1
suma.
Recuerde: f (x) = n=0 [hn (x) − αn (x)hn+1 (x) − βn+1 (x)hn+2 (x)] gn (x).
Tenemos entonces:
N−1
X
f (x) = cn gn (x) con : gn+1 (x) = αn (x)gn (x) + βn (x)gn−1 (x)
n=0
N−1
X
f (x) = cn gn (x) con : gn+1 (x) = αn (x)gn (x) + βn (x)gn−1 (x)
n=0
con la recursión:
donde:
(n) (n) (n)
hm (ξ) = 2 cos(πξ)hm+1 (ξ) − hm+2 (ξ) + c̃m,n (m = M − 1, . . . , 0)
donde ahora:
(ξ) (ξ) (ξ)
hn (η) = 2 cos(πη)hn+1 (η) − hn+2 (η) + Sn (ξ) (n = N − 1, . . . , 0)
=Sn (ξ)
X z
X }| {
ζ(ξ, η, τ ) = Cn (η) c̃m,n Cm (ξ), c̃m,n = cm,n Nm,n
n m
donde:
(n) (n) (n)
hm (ξ) = 2 cos(πξ)hm+1 (ξ) − hm+2 (ξ) + c̃m,n (m = M − 1, . . . , 0)
donde ahora:
(ξ) (ξ) (ξ)
hn (η) = 2 cos(πη)hn+1 (η) − hn+2 (η) + Sn (ξ) (n = N − 1, . . . , 0)
=Sn (ξ)
X z
X }| {
ζ(ξ, η, τ ) = Cn (η) c̃m,n Cm (ξ), c̃m,n = cm,n Nm,n
n m
donde:
(n) (n) (n)
hm (ξ) = 2 cos(πξ)hm+1 (ξ) − hm+2 (ξ) + c̃m,n (m = M − 1, . . . , 0)
donde ahora:
(ξ) (ξ) (ξ)
hn (η) = 2 cos(πη)hn+1 (η) − hn+2 (η) + Sn (ξ) (n = N − 1, . . . , 0)
Piscina: Condiciones iniciales.
pling!
plang!
plong!
(n̄)n −n̄
Pn = e
n!
Se requieren tres funciones:
Función exponential math.h: double exp(double);
Potencia math.h: double pow(double, double);
Factorial falta!
Factorial tiene una recursión:
n! = n · (n − 1)! = n · (n − 1) · (n − 2) · · · 2 · 1
1 #include <stdio.h>
2
3 int fac(int n)
4 {
5 int nfac;
6
7 if (n <= 1)
8 nfac = 1;
9 else {
10 nfac = n;
11 do {
12 n = n - 1;
13 nfac = nfac * n;
14 } while (n > 1);
15 }
16 return nfac;
17 }
Implementación con recursión I.
19 int main(void)
20 {
21 int n, m;
22
23 for (n = 0; n <= 40; n = n + 1) {
24 m = fac(n);
25 printf("fac( %d) = %d\n", n, m);
26 }
27 return 0;
28 }
Implementación con recursión II.
Esta vez con tipo double.
1 #include <stdio.h>
2
3 double fac(double n)
4 {
5 double nfac;
6
7 if (n <= 1.0)
8 nfac = 1.0;
9 else {
10 nfac = n;
11 do {
12 n -= 1.0;
13 nfac *= n;
14 } while (n > 1.0);
15 }
16 return nfac;
17 }
Implementación con recursión II.
Esta vez con tipo double.
19 int main(void)
20 {
21 int n;
22 double m;
23
24 for (n = 0; n <= 180; n++) {
25 /* Here: automatic type cast */
26 m = fac(n);
27 printf("fac( %d) = %g\n", n, m);
28 }
29 return 0;
30 }
Problema.
(n̄)n −n̄
Pn = e ∈ [0, 1]
n!
mientras:
(n̄)n −n̄
Pn = e
n!
n
eln[(n̄) ] −n̄
= e
eln(n!)
= exp n ln(n̄) − n̄ − ln(n!)
| {z }
∈[−∞,0]
Definición: Z ∞
Γ(z) = dxe−x x z−1 , <(z) > 0
0
Γ(z + 1) = z · (z − 1) · · · 1 · Γ(1) = z!
√ z+ 12
1 1
Γ(z + 1) ≈ 2πe−(z+γ+ 2 ) z + γ +
2
c1 c2 cN−1
× c0 + + + ... + +
z +1 z +2 z +N −1
Error solamente || < 2,0 × 10−10 para γ = 5 y
1,000000000190015
76,18009172947146
−86,50532032941677
~c =
24,01409824083091 ,
N=7
−1,231739572450155
0,1208650973866179 × 10−2
−0,5395239384953 × 10−5
Aproximación para ln[Γ(z)].
Γ(z + 1)
ln[Γ(z)] = ln
z
= ln[Γ(z + 1)] − ln(z)
1 1 1
≈ − z +γ+ + z+ ln z + γ +
2 2 2
√
cN−1
+ ln 2π c0 + . . . + − ln(z)
z +N −1
= − (z + 5,5) + (z + 0,5) ln (z + 5,5)
cN−1
+ ln s c0 + . . . + /z
z +N −1
√
donde s = 2π.
Implementación.
sf_log_gamma.c
21 tmp = x + 5.5;
22 erg = (x + 0.5) * log(tmp) - tmp;
23 tmp = c[0];
24 for (n = 1; n < 7; n++)
25 tmp += c[n] / (x + n);
26 return erg + log(s * tmp / x);
27 }
Distribución de Poisson.
sf_poisson.c
Implementación:
1 /*! \file sf_poisson.c */
2
3 #include <math.h>
4
5 /*! Calculates the Poisson probability distribution. */
6 double poisson(double n, double navg)
7 {
8 double log_gamma(double); /* Declaration */
9
10 return exp(n * log(navg) - log_gamma(n+1.0) - navg);
11 }
Coeficiente binomial.
sf_bico.c
Definición es:
m m!
= = exp {ln[Γ(m + 1)] − [ln[Γ(n + 1)] + ln[Γ(m − n + 1)]]}
n n!(m − n)!
Implementación:
1 /*! \file sf_bico.c */
2
3 #include <math.h>
4
5 /*! Calculates the binomial coefficient. */
6 double bico(double m, double n)
7 {
8 double log_gamma(double);
9
10 return exp(log_gamma(m+1.0) - (log_gamma(n+1.0) + log_gamma(m-n+1.0)
11 }
La función Beta.
sf_beta.c
Definición es:
Z 1
Γ(z)Γ(w)
B(z, w) = dx(1 − x)w−1 x z−1 =
0 Γ(z + w)
Implementacíon:
1 /*! \file sf_beta.c */
2
3 #include <math.h>
4
5 /*! Calculates the Beta function. */
6 double beta(double z, double w)
7 {
8 double log_gamma(double);
9
10 return exp((log_gamma(z) + log_gamma(w)) - log_gamma(z+w));
11 }
Polinomial orthogonal de Hermite.
Por ejemplo:
y tiene la relación:
Por ejemplo:
y tiene la relación:
Por ejemplo:
y tiene la relación:
Existe la recursión:
Existe la recursión:
Existe la recursión:
Entonces tenemos:
r r
2 1
H̃n (x) = x H̃n−1 (x) − 1 − H̃n−2 (x)
n n
1 2 √
con H̃0 (x) = π − 4 e−x /2 , y H̃1 = 2x H̃0 (x) (ver recursión).
Recursión modificada.
La recursión para la versión normalisada es diferente del original:
2
H (x)e−x /2
H̃n+1 (x) = p√n+1
π2n+1 (n + 1)!
2 2
2xH (x)e−x /2 2nHn−1 (x)e−x /2
= p√ n − p√
π2n+1 (n + 1)! π2n+1 (n + 1)!
2x 2n
= p H̃n (x) − p H̃n−1 (x)
2(n + 1) 2
2 (n + 1)n
r r
2 n
= x H̃n (x) − H̃n−1 (x)
n+1 n+1
Entonces tenemos:
r r
2 1
H̃n (x) = x H̃n−1 (x) − 1 − H̃n−2 (x)
n n
1 2 √
con H̃0 (x) = π − 4 e−x /2 , y H̃1 = 2x H̃0 (x) (ver recursión).
Implementación.
sf_hermite1.c
0.4
"h1main.dat" in 7
0.3
0.2
0.1
f(x)
-0.1
-0.2
-0.3
0 5 10 15 20 25 30 35 40 45 50
x
Resultados.
main_sf_hermite1.c
0.3
"h1main.dat" in 8
0.2
0.1
0
f(x)
-0.1
-0.2
-0.3
-0.4
-0.5
0 5 10 15 20 25 30 35 40 45 50
x
Resultados.
main_sf_hermite1.c
0.3
"h1main.dat" in 8
0.2
0.1
0
f(x)
-0.1
-0.2
-0.3
-0.4
-0.5
35 36 37 38 39 40
x
Versión con long double (ca. 25 % más lento).
sf_hermite2.c
5 #include <math.h>
6
7 #define LN_SQRT_PI (0.5 * log(M_PI))
8
9 /*! Calculates the normalized Hermite polynomial
10 using a recurrence. Works internally with
11 long double precision. */
12 double hermite2(int n, double x)
13 {
14 int m;
15 long double g_old, g, g_new;
16
17 g_old = 0.0;
18 g = expl(- 0.5 * (x * x + LN_SQRT_PI));
19 if (n > 0) {
20 for (m = 1; m <= n; m++) {
21 g_new = sqrt(2.0/m) * x * g - sqrt(1.0 - 1.0/m) * g_old;
22 g_old = g;
23 g = g_new;
24 }
25 }
26 return g;
27 }
Resultado.
main_sf_hermite2.c
0.4
"h2main.dat" in 8
"h1main.dat" in 8
0.3
0.2
0.1
0
f(x)
-0.1
-0.2
-0.3
-0.4
-0.5
35 36 37 38 39 40 41 42
x
¿Cuándo usar cuál versión?
Este valor tiene que estar más grande que el valor minimo
representable:
exp(−n) > DBL_MIN
es equivalente a exp(n) < DBL_MAX entonces:
n < ln(DBL_MAX)
¿Cuándo usar cuál versión?
Este valor tiene que estar más grande que el valor minimo
representable:
exp(−n) > DBL_MIN
es equivalente a exp(n) < DBL_MAX entonces:
n < ln(DBL_MAX)
¿Cuándo usar cuál versión?
Este valor tiene que estar más grande que el valor minimo
representable:
exp(−n) > DBL_MIN
es equivalente a exp(n) < DBL_MAX entonces:
n < ln(DBL_MAX)
¿Cuándo usar cuál versión?
Este valor tiene que estar más grande que el valor minimo
representable:
exp(−n) > DBL_MIN
es equivalente a exp(n) < DBL_MAX entonces:
n < ln(DBL_MAX)
Versión final.
sf_hermite.c
0.3
"hmain.dat" in 11
0.2
0.1
-0.1
-0.2
-0.3
145 146 147 148 149 150 151 152
¿Cuál es el limite?
main_sf_hermite.c
0.15
"hmain.dat" in 12
0.1
0.05
-0.05
-0.1
-0.15
-0.2
148 148.5 149 149.5 150 150.5 151 151.5 152
Economizar.
sf_hermite_array.c
Si uno necesita no solo una función H̃n (x) para un n, sino un set
n = 0, . . . , N − 1 para un valor de x, es mejor guardarlas en un vector:
6 #define LN_SQRT_PI (0.5 * log(M_PI))
7
8 /*! Calculates Hermite array h[0], h[1], ... ,h[nmax-1]
9 for the x value given. */
10 void hermite_array(double* h, int nmax, double x)
11 {
12 int n;
13 long double g, g_old, g_new;
14
15 g_old = 0.0;
16 g = expl(- 0.5 * (x * x + LN_SQRT_PI));
17 h[0] = (double)g;
18 if (nmax > 1) {
19 for (n = 1; n < nmax; n++) {
20 g_new = sqrt(2.0/n) * x * g - sqrt(1.0 - 1.0/n) * g_old;
21 g_old = g;
22 g = g_new;
23 h[n] = (double)g;
24 }
25 }
26 }
Soluciones de una recursión.
yn+1 + an yn + bn yn−1 = 0
yn+1 + an yn + bn yn−1 = 0
yn+1 + an yn + bn yn−1 = 0
yn+1 + an yn + bn yn−1 = 0
Aproximación: an → a = const:
Aproximación: an → a = const:
Aproximación: an → a = const:
Aproximación: an → a = const:
p̂2 mω 2 2
∂ 4
i~ |ψ(t)i = + x̂ + ax̂ + x̂F (t) |ψ(t)i
∂t 2m 2
Anarmonicidad a
Fuerza externa F (t)
p̂2 mω 2 2
∂ 4
i~ |ψ(t)i = + x̂ + ax̂ + x̂F (t) |ψ(t)i
∂t 2m 2
Anarmonicidad a
Fuerza externa F (t)
1 Expansión:
p̂2 mω 2 2
∂hn|ψ(t)i 4
i~ = hn| + x̂ + ax̂ + x̂F (t) |ψ(t)i
∂t 2m 2
mω 2 ax̂ 4
= hn| Ĥ0 + + x̂F (t) |ψ(t)i
2
∞
mω 2 ax̂ 4
X
= ~ωn hn|ψ(t)i + hn| + x̂F (t) |mihm|ψ(t)i
2
m=0 | {z }
=~Vn,m (t)
1 Expansión:
p̂2 mω 2 2
∂hn|ψ(t)i 4
i~ = hn| + x̂ + ax̂ + x̂F (t) |ψ(t)i
∂t 2m 2
mω 2 ax̂ 4
= hn| Ĥ0 + + x̂F (t) |ψ(t)i
2
∞
mω 2 ax̂ 4
X
= ~ωn hn|ψ(t)i + hn| + x̂F (t) |mihm|ψ(t)i
2
m=0 | {z }
=~Vn,m (t)
donde
1 ω
ωn0 = ω 0 (n + ), ω0 =
2 ωc
0 1
Vn,m (τ ) = Vn,m (τ )
ωc
Tiempo sin dimensión.
donde
1 ω
ωn0 = ω 0 (n + ), ω0 =
2 ωc
0 1
Vn,m (τ ) = Vn,m (τ )
ωc
Calculación de la matriz.
La matriz de perturbación (con respecto al oscilador armónico)
es:
mω 2 ax̂ 4
0 1
Vn,m (τ ) = hn| + x̂F (τ ) |mi
~ωc 2
Operadores de creación y destrucción de cuantas energeticas
del oscilador:
La matriz es ahora:
0 mω 2 a 4 F (τ )
(∆x0 )4 hn| ↠+ â |mi+ ∆x0 hn| ↠+ â |mi
Vn,m (τ ) =
2~ωc ~ω
| {z } | c{z }
=a0 =F 0 (τ )
Calculación de la matriz.
La matriz de perturbación (con respecto al oscilador armónico)
es:
mω 2 ax̂ 4
0 1
Vn,m (τ ) = hn| + x̂F (τ ) |mi
~ωc 2
Operadores de creación y destrucción de cuantas energeticas
del oscilador:
La matriz es ahora:
0 mω 2 a 4 F (τ )
(∆x0 )4 hn| ↠+ â |mi+ ∆x0 hn| ↠+ â |mi
Vn,m (τ ) =
2~ωc ~ω
| {z } | c{z }
=a0 =F 0 (τ )
Calculación de la matriz.
La matriz de perturbación (con respecto al oscilador armónico)
es:
mω 2 ax̂ 4
0 1
Vn,m (τ ) = hn| + x̂F (τ ) |mi
~ωc 2
Operadores de creación y destrucción de cuantas energeticas
del oscilador:
La matriz es ahora:
0 mω 2 a 4 F (τ )
(∆x0 )4 hn| ↠+ â |mi+ ∆x0 hn| ↠+ â |mi
Vn,m (τ ) =
2~ωc ~ω
| {z } | c{z }
=a0 =F 0 (τ )
Dimensiones de los coeficientes
F (τ )∆x0
F 0 (τ ) =
~ωc
0
4
(τ ) = a0 hn| ↠+ â |mi + F 0 (τ )hn| ↠+ â |mi
Vn,m
Dimensiones de los coeficientes
F (τ )∆x0
F 0 (τ ) =
~ωc
0
4
(τ ) = a0 hn| ↠+ â |mi + F 0 (τ )hn| ↠+ â |mi
Vn,m
Dimensiones de los coeficientes
F (τ )∆x0
F 0 (τ ) =
~ωc
0
4
(τ ) = a0 hn| ↠+ â |mi + F 0 (τ )hn| ↠+ â |mi
Vn,m
Elementos
†
de la matriz 1.
k
Calcular hn|(â + â) |mi (k = 1, 4).
Son transiciones m → m ± 1.
2 La segunda es más complicada (n̂ = ↠â):
2
4
hn| ↠+ â |mi = hn| ↠↠+ ââ + ↠â + â↠|mi
| {z }
=2n̂+1
h 2 i
↠↠+ ââ
+ (2n̂ + 1)2 + ↠↠+ ââ (2n̂ + 1) |mi
= hn|
+hn|(2n̂ + 1) ↠↠+ ââ |mi
2
= hn| ↠↠+ ââ |mi + (2m + 1)2 δn,m
+2(m + n + 1)hn| ↠↠+ ââ |mi
Elementos
†
de la matriz 1.
k
Calcular hn|(â + â) |mi (k = 1, 4).
Son transiciones m → m ± 1.
2 La segunda es más complicada (n̂ = ↠â):
2
4
hn| ↠+ â |mi = hn| ↠↠+ ââ + ↠â + â↠|mi
| {z }
=2n̂+1
h 2 i
↠↠+ ââ
+ (2n̂ + 1)2 + ↠↠+ ââ (2n̂ + 1) |mi
= hn|
+hn|(2n̂ + 1) ↠↠+ ââ |mi
2
= hn| ↠↠+ ââ |mi + (2m + 1)2 δn,m
+2(m + n + 1)hn| ↠↠+ ââ |mi
Elementos
† †
dek la matriz 2.
Calcular hn|(â â + ââ) |mi (k = 1, 2).
= hn|(↠↠↠↠+ ââââ + ↠↠ââ + ââ↠↠)|mi
p
= (m + 4)(m + 3)(m + 2)(m + 1)δn,m+4
p
+ (m − 3)(m − 2)(m − 1)mδn,m−4
+[m(m − 1) + (m + 2)(m + 1)]δn,m
s s
n! m!
= δn,m+4 + δn,m−4
(n − 4)! (m − 4)!
m! (m + 2)!
+ + δn,m
(m − 2)! m!
Elementos
† †
dek la matriz 2.
Calcular hn|(â â + ââ) |mi (k = 1, 2).
= hn|(↠↠↠↠+ ââââ + ↠↠ââ + ââ↠↠)|mi
p
= (m + 4)(m + 3)(m + 2)(m + 1)δn,m+4
p
+ (m − 3)(m − 2)(m − 1)mδn,m−4
+[m(m − 1) + (m + 2)(m + 1)]δn,m
s s
n! m!
= δn,m+4 + δn,m−4
(n − 4)! (m − 4)!
m! (m + 2)!
+ + δn,m
(m − 2)! m!
Matriz de perturbación completa.
0
Vn,m (τ ) = 3a0 [2m(m + 1) + 1] δn,m
√ √
+ F 0 (τ ) nδn,m+1 + mδn,m−1
" s s #
0 n! m!
+ 2a (2n − 1) δn,m+2 + (2m − 1) δn,m−2
(n − 2)! (m − 2)!
"s s #
n! m!
+ a0 δn,m+4 + δn,m−4
(n − 4)! (m − 4)!
Calcular la función de onda.
Queremos saber ψ(x, τ ) = hx|ψ(τ )i, o la densidad de probabilidad
2
p(x, τ ) = |ψ(x, τ )|
entonces:
2
√ √
q
dx
p̃(ξ, τ ) = p(x, τ ) = ∆x0 2p(x, τ ) =
2∆x0 ψ(x, τ )
dξ | {z }
=ψ̃(ξ,τ )
Calcular la función de onda.
Queremos saber ψ(x, τ ) = hx|ψ(τ )i, o la densidad de probabilidad
2
p(x, τ ) = |ψ(x, τ )|
entonces:
2
√ √
q
dx
p̃(ξ, τ ) = p(x, τ ) = ∆x0 2p(x, τ ) =
2∆x0 ψ(x, τ )
dξ | {z }
=ψ̃(ξ,τ )
Calcular la función de onda.
Queremos saber ψ(x, τ ) = hx|ψ(τ )i, o la densidad de probabilidad
2
p(x, τ ) = |ψ(x, τ )|
entonces:
2
√ √
q
dx
p̃(ξ, τ ) = p(x, τ ) = ∆x0 2p(x, τ ) =
2∆x0 ψ(x, τ )
dξ | {z }
=ψ̃(ξ,τ )
Auto-soluciones sin dimensión.
√
Nueva función de onda es (x = ∆x0 2ξ):
q√ N−1
X q√ √
ψ̃(ξ, τ ) = 2∆x0 ψ(x, τ ) = 2∆x0 φn (∆x0 2ξ) ψn (τ )
n=0
| {z }
=φ̃n (ξ)
√
Nueva función de onda es (x = ∆x0 2ξ):
q√ N−1
X q√ √
ψ̃(ξ, τ ) = 2∆x0 ψ(x, τ ) = 2∆x0 φn (∆x0 2ξ) ψn (τ )
n=0
| {z }
=φ̃n (ξ)
5 #include <math.h>
6 #include <complex.h>
7 #include <stdlib.h>
8
9 #define LN_SQRT_PI (0.5 * log(M_PI))
10
11 /*! Calculates the wavefunction at (dimensionless) position
12 ’x’ for the state being encoded by harmonic-oscillator
13 coeficients ’psi’. */
14 complex double wavefunction(double x, complex double* psi, size_t sz)
15 {
16 complex double y_old, y, y_new;
17
18 y_old = 0.0 + 0.0i;
19 y = 0.0 + 0.0i;
20 do {
21 y_new = x * sqrt(2.0 / sz) * y - sqrt(1.0-1.0/(sz+1.0)) * y_old
22 + psi[--sz];
23 y_old = y;
24 y = y_new;
25 } while (sz > 0);
26 return y * exp(-0.5 * (x * x + LN_SQRT_PI));
27 }
Programa.
main_de_wavefunc.c
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <math.h>
9 #include <complex.h>
10
11 #define SZ 200
12 #define A 0.02
13 #define F 0.0
14 #define OMEGA_F 1.0
15 #define R 2.0
16 #define PHI (0.1 * M_PI)
17
18 /* for printing */
19 #define X 7.0
20 #define N 150
21
22 double poisson(double, double);
23 complex double wavefunction(double x, complex double*, size_t);
24 int de_solve_cpx(complex double*, size_t, double, double, double, doub
25 void (*)(complex double*, complex double*, double));
Programa.
main_de_wavefunc.c
â|γi = γ|γi
Idéa:
<(γ) ∼ x, =(γ) ∼ p → espacio de fase
Falta solamente la probabilidad para estar en el estado |γi:
Pγ = |hγ|ψi|2
Espacio de fase y estados coherentes.
â|γi = γ|γi
Idéa:
<(γ) ∼ x, =(γ) ∼ p → espacio de fase
Falta solamente la probabilidad para estar en el estado |γi:
Pγ = |hγ|ψi|2
Espacio de fase y estados coherentes.
â|γi = γ|γi
Idéa:
<(γ) ∼ x, =(γ) ∼ p → espacio de fase
Falta solamente la probabilidad para estar en el estado |γi:
Pγ = |hγ|ψi|2
Husimi Q.
Problema:
Dado: Coeficientes ψn = hn|ψi del estado |ψi en base de
auto-estados |ni del oscilador armonico para n = 0, . . . , N − 1.
Queremos: Calcular la funcion Husimi Q
1 2
Q(γ) = |hγ|ψi|
π
Calculemos primero:
N−1
! N−1
X X
hγ|ψi = hγ|1̂|ψi ≈ hγ| |nihn| |ψi = φn (γ)ψn
n=0 n=0
Problema:
Dado: Coeficientes ψn = hn|ψi del estado |ψi en base de
auto-estados |ni del oscilador armonico para n = 0, . . . , N − 1.
Queremos: Calcular la funcion Husimi Q
1 2
Q(γ) = |hγ|ψi|
π
Calculemos primero:
N−1
! N−1
X X
hγ|ψi = hγ|1̂|ψi ≈ hγ| |nihn| |ψi = φn (γ)ψn
n=0 n=0
Problema:
Dado: Coeficientes ψn = hn|ψi del estado |ψi en base de
auto-estados |ni del oscilador armonico para n = 0, . . . , N − 1.
Queremos: Calcular la funcion Husimi Q
1 2
Q(γ) = |hγ|ψi|
π
Calculemos primero:
N−1
! N−1
X X
hγ|ψi = hγ|1̂|ψi ≈ hγ| |nihn| |ψi = φn (γ)ψn
n=0 n=0
Problema:
Dado: Coeficientes ψn = hn|ψi del estado |ψi en base de
auto-estados |ni del oscilador armonico para n = 0, . . . , N − 1.
Queremos: Calcular la funcion Husimi Q
1 2
Q(γ) = |hγ|ψi|
π
Calculemos primero:
N−1
! N−1
X X
hγ|ψi = hγ|1̂|ψi ≈ hγ| |nihn| |ψi = φn (γ)ψn
n=0 n=0
1 Recursion
(γ ∗ )n+1 −|γ|2 /2 γ∗
φn+1 (γ) = p e =√ φn (γ)
(n + 1)! n+1
| {z }
=αn (β)
√
2 Clenshaw dice βn (γ) = 0, αn (γ) = γ ∗ / n + 1:
γ∗
hn (γ) = √ hn+1 (γ) + ψn , (n = N − 1, . . . , 0), hN (γ) = 0
n+1
3 Resultado:
2
hγ|ψi = h0 (γ)φ0 (γ) + h1 (γ) [φ1 (γ) − α0 (γ)φ0 (γ)] = h0 (γ)e−|γ| /2
| {z }
=0
4 Husimi Q:
1 2 2
Q(γ) = |h0 (γ)| e−|γ|
π
ClenshawPpara Husimi Q.
N−1
Calcular hγ|ψi = n=0 φn (γ)ψn .
1 Recursion
(γ ∗ )n+1 −|γ|2 /2 γ∗
φn+1 (γ) = p e =√ φn (γ)
(n + 1)! n+1
| {z }
=αn (β)
√
2 Clenshaw dice βn (γ) = 0, αn (γ) = γ ∗ / n + 1:
γ∗
hn (γ) = √ hn+1 (γ) + ψn , (n = N − 1, . . . , 0), hN (γ) = 0
n+1
3 Resultado:
2
hγ|ψi = h0 (γ)φ0 (γ) + h1 (γ) [φ1 (γ) − α0 (γ)φ0 (γ)] = h0 (γ)e−|γ| /2
| {z }
=0
4 Husimi Q:
1 2 2
Q(γ) = |h0 (γ)| e−|γ|
π
ClenshawPpara Husimi Q.
N−1
Calcular hγ|ψi = n=0 φn (γ)ψn .
1 Recursion
(γ ∗ )n+1 −|γ|2 /2 γ∗
φn+1 (γ) = p e =√ φn (γ)
(n + 1)! n+1
| {z }
=αn (β)
√
2 Clenshaw dice βn (γ) = 0, αn (γ) = γ ∗ / n + 1:
γ∗
hn (γ) = √ hn+1 (γ) + ψn , (n = N − 1, . . . , 0), hN (γ) = 0
n+1
3 Resultado:
2
hγ|ψi = h0 (γ)φ0 (γ) + h1 (γ) [φ1 (γ) − α0 (γ)φ0 (γ)] = h0 (γ)e−|γ| /2
| {z }
=0
4 Husimi Q:
1 2 2
Q(γ) = |h0 (γ)| e−|γ|
π
ClenshawPpara Husimi Q.
N−1
Calcular hγ|ψi = n=0 φn (γ)ψn .
1 Recursion
(γ ∗ )n+1 −|γ|2 /2 γ∗
φn+1 (γ) = p e =√ φn (γ)
(n + 1)! n+1
| {z }
=αn (β)
√
2 Clenshaw dice βn (γ) = 0, αn (γ) = γ ∗ / n + 1:
γ∗
hn (γ) = √ hn+1 (γ) + ψn , (n = N − 1, . . . , 0), hN (γ) = 0
n+1
3 Resultado:
2
hγ|ψi = h0 (γ)φ0 (γ) + h1 (γ) [φ1 (γ) − α0 (γ)φ0 (γ)] = h0 (γ)e−|γ| /2
| {z }
=0
4 Husimi Q:
1 2 2
Q(γ) = |h0 (γ)| e−|γ|
π
Implementacion.
de_husimi.c
10 /*! Calculates the Husimi function Q(alpha) for the state psi
11 given in harmonic-oscillator coeficients. */
12 double husimiQ(complex double alpha, complex double* psi,
13 size_t sz)
14 {
15 complex double h_old, h;
16 double aabs, habs;
17
18 alpha = conj(alpha);
19 h_old = 0.0 + 0.0i;
20 do {
21 h = h_old * alpha / sqrt(sz) + psi[--sz];
22 h_old = h;
23 } while (sz > 0);
24 aabs = cabs(alpha);
25 habs = cabs(h);
26 return habs * habs * exp(-aabs*aabs) / M_PI;
27 }
Ejemplos.
main_de_husimi.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4 #include <complex.h>
5
6 #define SZ 200
7
8 /* for printing */
9 #define X 6.0
10 #define P 6.0
11 #define N 100
12
13 double poisson(double, double);
14 double husimiQ(complex double, complex double*, size_t);
Ejemplos.
main_de_husimi.c
39 int main(void)
40 {
41 complex double psi[SZ];
42 double r, phi;
43 int n;
44
45 /* coherent state with complex amplitude r*exp(i*phi) */
46 r = 2.0;
47 phi = 0.25;
48 for (n = 0; n < SZ; n++)
49 psi[n] = cexp(I * n * phi) * sqrt(poisson(n, r*r));
50 print_husimiQ(psi);
51
52 /* number state n */
53 for (n = 0; n < SZ; n++)
54 psi[n] = 0.0 + 0.0i;
55 psi[4] = 1.0;
56 print_husimiQ(psi);
57
58 return 0;
59 }
Resultados.
Auto estado |n = 4i y estado coherente |α = 2,0 × e0,25×i i.
6 0.07
0.06
4 0.05
0.04
2 0.03
Im(α)
0 0.02
0.01
−2 0
−4
−6
−6 −4 −2 0 2 4 6
Re(α)
Resultados.
Auto estado |n = 4i y estado coherente |α = 2,0 × e0,25×i i.
6 0.35
0.3
4 0.25
0.2
2 0.15
Im(α)
0 0.1
0.05
−2 0
−4
−6
−6 −4 −2 0 2 4 6
Re(α)
Función Gamma incompleta.
γ(x, a)
P(x, a) = , Q(x, a) = 1 − P(x, a)
Γ(x)
Notación común:
a1 a2 a3
f (x) = b0 + ···
b1 + b2 + b3 +
Aproximación hasta el orden n:
a1 a2 a3 an
fn (x) = b0 + ···
b1 + b2 + b3 + bn
Definición.
Notación común:
a1 a2 a3
f (x) = b0 + ···
b1 + b2 + b3 +
Aproximación hasta el orden n:
a1 a2 a3 an
fn (x) = b0 + ···
b1 + b2 + b3 + bn
Recursión de Wallis.
Del año 1655.
Idéa de Wallis:
An
fn =
Bn
con la recursión:
Am = bm Am−1 + am Am−2
Bm = bm Bm−1 + am Bm−2
A−1 = 1, A0 = b0 ; B−1 = 0, B0 = 1
Problema:
Posible UNDER-/OVERFLOW de los coeficientes Am y Bm !
Recursión de Wallis.
Del año 1655.
Idéa de Wallis:
An
fn =
Bn
con la recursión:
Am = bm Am−1 + am Am−2
Bm = bm Bm−1 + am Bm−2
A−1 = 1, A0 = b0 ; B−1 = 0, B0 = 1
Problema:
Posible UNDER-/OVERFLOW de los coeficientes Am y Bm !
Recursión de Lentz.
Mejor usar razones:
Am Bm−1
Cm = , Dm =
Am−1 Bm
con la recursión:
am
Cm = bm + , C0 = b0
Cm−1
1
Dm = , D0 = 0
bm + am Dm−1
fm = fm−1 Cm Dm , f0 = b0
Recursión de Lentz.
Mejor usar razones:
Am Bm−1
Cm = , Dm =
Am−1 Bm
con la recursión:
am
Cm = bm + , C0 = b0
Cm−1
1
Dm = , D0 = 0
bm + am Dm−1
fm = fm−1 Cm Dm , f0 = b0
gamma_incomplete.c
1 #include <math.h>
2 #include <float.h>
3 #include <assert.h>
4
5 #define EPS DBL_EPSILON
6
7 double gamma_incomplete(double x, double a)
8 {
9 double res, s, factor;
10 double b, a_inc, c, d;
11 double log_gamma(double);
12
13 assert((a >= 0.0) && (x > 0.0));
14
15 if (a == 0.0)
16 return 0.0;
17 else {
18 factor = exp(x * log(a) - a - log_gamma(x));
19
20 if (a < (x+1.0)) { /* series expansion */
21 s = 1.0 / x;
gamma_incomplete.c
22 res = s;
23 do {
24 x += 1.0;
25 s *= a / x;
26 res += s;
27 } while (fabs(s) > fabs(res) * EPS);
28 return res * factor;
29 }
30
31 else { /* continued fraction */
32 a_inc = x - 3.0;
33 x -= 1.0;
34 b = a - x;
35 c = 1.0 / DBL_MIN;
gamma_incomplete.c
36 d = 1.0 / b;
37 res = d;
38 do {
39 b += 2.0;
40 d = b + x * d;
41 d = (fabs(d) < DBL_MIN) ? DBL_MIN : d;
42 d = 1.0 / d;
43 c = b + x/c;
44 c = (fabs(c) < DBL_MIN) ? DBL_MIN : c;
45 s = c * d;
46 res *= s;
47 x += a_inc;
48 a_inc -= 2.0;
49 } while (fabs(s - 1.0) > EPS);
50 return 1.0 - res * factor;
51 }
52 }
53 }
Resultado.
1
x =1
0.8
0.6
P(x, a)
0.4
0.2
0
0 2 4 6 8 10 12 14 16
a
Resultado.
1
x =1
x =2
0.8
0.6
P(x, a)
0.4
0.2
0
0 2 4 6 8 10 12 14 16
a
Resultado.
1
x =1
x =2
x =3
0.8
0.6
P(x, a)
0.4
0.2
0
0 2 4 6 8 10 12 14 16
a
Resultado.
1
x =1
x =2
x =3
x = 10
0.8
0.6
P(x, a)
0.4
0.2
0
0 2 4 6 8 10 12 14 16
a
Parte V
Interpolación
Interpolación versus extrapolación.
Problema:
Dado: Datos {xi , yi } (i = 0, . . . , N − 1) como resultados de
una calculación o de un experimento.
Pregunta: ¿Como se puede obtener valores y para x 6= xi
(i = 0, . . . , N − 1)?
y1
y0
x
x0 x1 xN −1
Interpolación versus extrapolación.
Problema:
Dado: Datos {xi , yi } (i = 0, . . . , N − 1) como resultados de
una calculación o de un experimento.
Pregunta: ¿Como se puede obtener valores y para x 6= xi
(i = 0, . . . , N − 1)?
y
Interpolación
y1
y0
x
x0 x1 xN −1
Interpolación versus extrapolación.
Problema:
Dado: Datos {xi , yi } (i = 0, . . . , N − 1) como resultados de
una calculación o de un experimento.
Pregunta: ¿Como se puede obtener valores y para x 6= xi
(i = 0, . . . , N − 1)?
y
Interpolación
Extrapolación
y1
y0
x
x0 x1 xN −1
¿Para qué?
Limites en el tiempo:
Calculación de cada punto de dato necesita mucho tiempo.
Podemos calcular numericamente solo un numero limitado de
datos.
En el experimento solo tenemos un numero de realisaciones
suficiente para un numero limitado de datos.
P (x )
y1
y0
x
x0 x1
y1 − y0 (x − x1 ) (x − x0 )
P2 (x) = y0 + (x − x0 ) = y0 + y1
x1 − x0 (x0 − x1 ) (x1 − x0 )
Es una función polinomial de orden 1.
Interpolación entre datos vecinos.
Desventajas:
P 0 (x) tiene discontinuidades en cada punto de data!
⇒ Solo acceptable para integración.
Interpolación entre datos vecinos.
Desventajas:
P 0 (x) tiene discontinuidades en cada punto de data!
⇒ Solo acceptable para integración.
Formula de Lagrange.
(x − x1 ) (x − x0 )
P2 (x) = y0 + y1
(x0 − x1 ) (x1 − x0 )
Solución de Lagrange:
Para N datos hay una función polinomial de orden N − 1:
(x − x1 ) · · · (x − xN−1 )
PN (x) = y0 + ...
(x0 − x1 ) · · · (x0 − xN−1 )
(x − x0 ) · · · (x − xN−2 )
. . . + yN−1
(xN−1 − x0 ) · · · (xN−1 − xN−2 )
(x − x1 ) (x − x0 )
P2 (x) = y0 + y1
(x0 − x1 ) (x1 − x0 )
Solución de Lagrange:
Para N datos hay una función polinomial de orden N − 1:
(x − x1 ) · · · (x − xN−1 )
PN (x) = y0 + ...
(x0 − x1 ) · · · (x0 − xN−1 )
(x − x0 ) · · · (x − xN−2 )
. . . + yN−1
(xN−1 − x0 ) · · · (xN−1 − xN−2 )
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Caracteristica de la interpolación polinomial.
3
data
n=2
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Caracteristica de la interpolación polinomial.
3
data
n=3
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Caracteristica de la interpolación polinomial.
3
data
n=4
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Caracteristica de la interpolación polinomial.
3
data
n=5
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Caracteristica de la interpolación polinomial.
3
data
n=6
2.5
1.5
y
0.5
0
0 1 2 3 4 5
x
Interpolación para N datos a, . . . , b.
ya+1
ya
x
xa xa+1 xb−1 xb
(x − xa+1 ) · · · (x − xb )
Pa,...,b (x) = ya + ...
(xa − xa+1 ) · · · (x0 − xb )
(x − xa ) · · · (x − xb−1 )
. . . + yb
(xb − xa ) · · · (xb − xb−1 )
Recursión de Neville.
Recursión de Neville:
x − xb xa − x
Pa,...,b (x) = Pa,...,(b−1) (x) + P(a+1),...,b (x)
xa − xb xa − xb
(x − xa+1 ) · · · (x − xb )
Pa,...,b (x) = ya + ...
(xa − xa+1 ) · · · (xa − xb )
(x − xa ) · · · (x − xb−1 )
. . . + yb
(xb − xa ) · · · (xb − xb−1 )
b b
X Y x − xn
= ym
m=a
xm − xn
n(6=m)=a
Prueba de la recursión de Neville.
Es correcto que F (x) = Pa,...,b (x)?
Segun Neville:
x − xb xa − x
F (x) = Pa,...,(b−1) (x) + P(a+1),...,b (x)
xa − xb xa − xb
Usando formula de Lagrange:
b−1 b−1
x − xb X Y x − xn
F (x) = ym
xa − xb m=a xm − xn
n(6=m)=a
b b
xa − x X Y x − xn
+ ym
xa − xb xm − xn
m=a+1 n(6=m)=a+1
Prueba de la recursión de Neville.
Es correcto que F (x) = Pa,...,b (x)?
Segun Neville:
x − xb xa − x
F (x) = Pa,...,(b−1) (x) + P(a+1),...,b (x)
xa − xb xa − xb
Usando formula de Lagrange:
b−1 b−1
x − xb X Y x − xn
F (x) = ym
xa − xb m=a xm − xn
n(6=m)=a
b b
xa − x X Y x − xn
+ ym
xa − xb xm − xn
m=a+1 n(6=m)=a+1
Prueba de la recursión de Neville.
Es correcto que F (x) = Pa,...,b (x)?
Recombinación:
b−1 b−1
X x − xb Y x − xn
F (x) = ym
xa − xb xm − xn
m=a+1 n(6=m)=a
b
xa − x Y x − xn
+
xa − xb xm − xn
n(6=m)=a+1
b b−1
Y
Y x − xn x − xn
+ ya + yb
xa − xn n=a
xb − xn
n=a+1
Recombinación:
b−1 b−1
X x − xb Y x − xn
F (x) = ym
xa − xb xm − xn
m=a+1 n(6=m)=a
b
xa − x Y x − xn
+
xa − xb xm − xn
n(6=m)=a+1
b b−1
Y
Y x − xn x − xn
+ ya + yb
xa − xn n=a
xb − xn
n=a+1
Entonces:
b−1 b
X Y x − xn
F (x) = ym
xm − xn
m=a+1 n(6=m)=a
b b−1
Y
Y x − xn x − xn
+ ya + yb
xa − xn n=a
xb − xn
n=a+1
b b
X Y x − xn
= ym
m=a
xm − xn
n(6=m)=a
x0 x1 x2 x3
Recursión de Neville:
x − xb xa − x
Pa,...,b (x) = Pa,...,(b−1) (x) + P(a+1),...,b (x)
xa − xb xa − xb
Donde la interpolación con solo un dato es:
P0 (x) = y0 , . . . , P3 (x) = y3
Recursión simple.
x0 x1 x2 x3
P0 P1 P2 P3
Recursión simple.
x0 x1 x2 x3
P0 P1 P2 P3
P0 P1 P2 P3
P0,1,2 P1,2,3
Recursión simple.
x0 x1 x2 x3
P0 P1 P2 P3
P0,1,2 P1,2,3
P0,1,2,3
Complejitud computacional.
Formula de Lagrange.
Lagrange:
(x − x1 ) · · · (x − xN−1 )
P0,...,N−1 (x) = y0 + ...
(x0 − x1 ) · · · (x0 − xN−1 )
(x − x0 ) · · · (x − xN−2 )
. . . + yN−1
(xN−1 − x0 ) · · · (xN−1 − xN−2 )
Neville:
OpsNeville = [(N − 1) + (N − 2) + . . . + 2 + 1]
× [5 × ⊕ + 4 × ⊗]
9
= N(N − 1)
2
∼ 4,5 × N 2
Problemas:
Lagrange y Neville ambos van como N 2 !
Ademas falta control de errores!
Complejitud computacional.
Recursion de Neville simple.
Neville:
OpsNeville = [(N − 1) + (N − 2) + . . . + 2 + 1]
× [5 × ⊕ + 4 × ⊗]
9
= N(N − 1)
2
∼ 4,5 × N 2
Problemas:
Lagrange y Neville ambos van como N 2 !
Ademas falta control de errores!
Otra recursión.
(n)
Ra (x) = Pa,...,(a+n) (x) − Pa,...,(a+n−1) (x) ∼ xn
(n)
La (x) = Pa,...,(a+n) (x) − P(a+1),...,(a+n) (x) ∼ xn
(n+1) xa − x h
(n) (n)
i
Ra (x) = Ra+1 (x) − La (x)
xa − xa+n+1
(n+1) x − xa+n+1 h
(n) (n)
i
La (x) = La (x) − Ra+1 (x)
xa − xa+n+1
(0) (0)
con valores iniciales: Ra (x) = La (x) = Pa (x) = ya
Otra recursión.
(n)
Ra (x) = Pa,...,(a+n) (x) − Pa,...,(a+n−1) (x) ∼ xn
(n)
La (x) = Pa,...,(a+n) (x) − P(a+1),...,(a+n) (x) ∼ xn
(n+1) xa − x h
(n) (n)
i
Ra (x) = Ra+1 (x) − La (x)
xa − xa+n+1
(n+1) x − xa+n+1 h
(n) (n)
i
La (x) = La (x) − Ra+1 (x)
xa − xa+n+1
(0) (0)
con valores iniciales: Ra (x) = La (x) = Pa (x) = ya
Ventaja grande?
Ejemplo para N = 4 datos:
x
x0 x1 x2 x3
(0)
P0 P1 = L1 P2 P3
P0,1,2 P1,2,3
P0,1,2,3
Ventaja grande?
Ejemplo para N = 4 datos:
x
x0 x1 x2 x3
(0) (0)
P0 P1 = L1 P2 = R2 P3
(1)
R1
P0,1,2 P1,2,3
P0,1,2,3
Ventaja grande?
Ejemplo para N = 4 datos:
x
x0 x1 x2 x3
(0) (0)
P0 P1 = L1 P2 = R2 P3
(1) (1)
L0 R1
(2)
L0
P0,1,2 P1,2,3
P0,1,2,3
Ventaja grande?
Ejemplo para N = 4 datos:
x
x0 x1 x2 x3
(0) (0)
P0 P1 = L1 P2 = R2 P3
(1) (1)
L0 R1
(2) (2)
L0 R1
P0,1,2 P1,2,3
(3)
R0
P0,1,2,3
Prueba.
Idea:
El camino lo mas recto es optimal para usar la ultima iteración como
estimación de error!
Prueba.
Idea:
El camino lo mas recto es optimal para usar la ultima iteración como
estimación de error!
Prueba.
Idea:
El camino lo mas recto es optimal para usar la ultima iteración como
estimación de error!
Complejitud computacional.
Recursion de Neville inteligente.
Neville+:
Para una interpolación polinomial de orden N se necesita usar solo
N − 1 veces la recursión!?
OpsNeville+ = (N − 1) × [4 × ⊕ + 3 × ⊗]
= 7 × (N − 1)
∼ 7×N
Error:
Para eso hay que saber el camino apropriado antes!
Lamentablemente se necesitan también los otros coeficientes!
Otra vez también es como ∝ N 2 !
Complejitud computacional.
Recursion de Neville inteligente.
Neville+:
Para una interpolación polinomial de orden N se necesita usar solo
N − 1 veces la recursión!?
OpsNeville+ = (N − 1) × [4 × ⊕ + 3 × ⊗]
= 7 × (N − 1)
∼ 7×N
Error:
Para eso hay que saber el camino apropriado antes!
Lamentablemente se necesitan también los otros coeficientes!
Otra vez también es como ∝ N 2 !
Implementación de Neville+.
ip_neville.c
23 diff_min = fabs(xi-x[0]);
24 i_min = 0;
25 for (i = 0; i < n; i++) {
26 diff = fabs(xi-x[i]);
27 if (diff < diff_min) {
28 diff_min = diff;
29 i_min = i;
30 }
31 r[i] = y[i];
32 l[i] = y[i];
33 }
34 yi = y[i_min];
35 for (m = 1; m < n; m++) {
36 for (i = 0; i < n-m; i++) {
37 dx_lo = x[i]-xi;
38 dx_hi = x[i+m]-xi;
39 diff = (r[i+1]-l[i]) / (x[i]-x[i+m]);
40 r[i] = dx_lo * diff;
41 l[i] = dx_hi * diff;
42 }
43 yi += ( ((2*i_min) < (n-m)) ? r[i_min] : l[--i_min] );
44 }
Implementación de Neville+.
ip_neville.c
46 free(r);
47 free(l);
48 return yi;
49 }
Interpolación local.
y1
y0
x
x0 x1 xN −1
y x
y1
y0
x
x0 x1 xN −1
y x
y1
y0
x
x0 x1 xN −1
y x
y1
y0
x
x0 x1 xN −1
y x
y1
y0
x
x0 x1 xN −1
xk ≤ x < xk +1
Solución:
Metodo de bi-sección puede hacerlo en ∼ log2 (N) pasos!
Es mas eficiente que Neville+ (∼ N 2 ) entonces no va a afectar la
eficiencia total que va a ser ∼ N 2 .
Buscar en una lista ordenada.
xk ≤ x < xk +1
Solución:
Metodo de bi-sección puede hacerlo en ∼ log2 (N) pasos!
Es mas eficiente que Neville+ (∼ N 2 ) entonces no va a afectar la
eficiencia total que va a ser ∼ N 2 .
Metodo de bi-sección.
ip_searchidx.c
16 lo = 0;
17 hi = n-1;
18 do {
19 mid = (lo+hi)/2;
20 if (xi < x[mid])
21 hi = mid;
22 else
23 lo = mid;
24 } while (hi-lo > 1);
25 return lo;
26 }
Interpolación polinomial local.
ip_polylocal.c
1 #include <stdio.h>
2
3 #define GAMMA 0.1
4 #define X0 0.0
5 #define N 20
6 #define XMAX 1.0
7 #define DX (2.0*XMAX/(N-1.0))
8
9 double function(double x)
10 {
11 return 1.0 / ((x-X0)*(x-X0) + GAMMA*GAMMA);
12 }
13
14 double ip_neville(double, double*, double*, int);
15 double ip_polylocal(double, int, double*, double*, int);
Ejemplo.
main_ip_polylocal.c
17 int main(void)
18 {
19 int n;
20 double xi, yi, yi_local, ycorrect;
21 double x[N], y[N];
22
23 for (n = 0; n < N; n++) {
24 x[n] = n * DX - XMAX;
25 y[n] = function(x[n]);
26 printf(" %g %g\n", x[n], y[n]);
27 }
28 printf("\n\n");
29 for (xi = -XMAX; xi <= XMAX; xi += 0.005) {
30 yi = ip_neville(xi, x, y, N);
31 yi_local = ip_polylocal(xi, 4, x, y, N);
32 ycorrect = function(xi);
33 printf(" %g %g %g %g\n", xi, ycorrect, yi, yi_local);
34 }
35 return 0;
36 }
Resultado.
100
data
función
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Resultado.
100
data
función
polynomial
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Resultado.
100
data
función
poly local (4)
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Interpolación racional.
Pm (x) p0 + p1 x + . . . + pm x m
R(x) = =
Qn (x) q0 + q1 x + . . . qn x n
Definición:
p0 + p1 x + . . . + pm x m
R(x) =
q1 x + . . . qn x n
La función racional de interpolación R(x) es diagonal para los N
datos cuando:
(m + 1) + n = N
y también:
m+1 = n si N es pares
m = n si N es impares
Ventaja:
Se puede generar a través de una recursión de Burlisch-Stoer!
Interpolación racional diagonal.
Definición:
p0 + p1 x + . . . + pm x m
R(x) =
q1 x + . . . qn x n
La función racional de interpolación R(x) es diagonal para los N
datos cuando:
(m + 1) + n = N
y también:
m+1 = n si N es pares
m = n si N es impares
Ventaja:
Se puede generar a través de una recursión de Burlisch-Stoer!
Recursión de Burlisch-Stoer.
Recursión de Burlisch-Stoer:
Recursión de Burlisch-Stoer:
Recursión de Burlisch-Stoer:
4
data
2
y
−1
0 1 2 3 4 5
x
¿Como se ve?
main_ip_burlischstoer.c
4
data
n=2
2
y
−1
0 1 2 3 4 5
x
¿Como se ve?
main_ip_burlischstoer.c
4
data
n=3
2
y
−1
0 1 2 3 4 5
x
¿Como se ve?
main_ip_burlischstoer.c
4
data
n=4
2
y
−1
0 1 2 3 4 5
x
¿Como se ve?
main_ip_burlischstoer.c
4
data
n=5
2
y
−1
0 1 2 3 4 5
x
¿Como se ve?
main_ip_burlischstoer.c
4
data
n=6
2
y
−1
0 1 2 3 4 5
x
Recursión para diferencias.
(n)
Ra (x) = Ra,...,(a+n) (x) − Ra,...,(a+n−1) (x)
(n)
La (x) = Ra,...,(a+n) (x) − R(a+1),...,(a+n) (x)
h i
x−xa (n) (n) (n)
x−xa+n+1 La (x) Ra+1 (x) − La (x)
(n+1)
Ra (x) =
x−xa (n) (n)
x−xa+n+1 La (x) − Ra+1 (x)
h i
(n) (n) (n)
Ra+1 (x) Ra+1 (x) − La (x)
(n+1)
La (x) =
x−xa (n) (n)
x−xa+n+1 La (x) − Ra+1 (x)
(0) (0)
Valores iniciales: Ra (x) = La (x) = ya
Implementación.
ip_burlischstoer.c
22 diff_min = fabs(xi-x[0]);
23 i_min = 0;
24 for (i = 0; i < n; i++) {
25 diff = fabs(xi-x[i]);
26 if (diff == 0.0) {
27 free(r);
28 free(l);
29 return y[i];
30 }
31 else if (diff < diff_min) {
32 diff_min = diff;
33 i_min = i;
34 }
35 r[i] = y[i];
36 l[i] = y[i]; /* + DBL_MIN; */
37 }
38 yi = y[i_min];
Implementación.
ip_burlischstoer.c
100
data
función
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Resultado.
main_ip_burlischstoer.c
100
data
función
polinomial
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Resultado.
main_ip_burlischstoer.c
100
data
función
racional
80
60
y
40
20
0
−1 −0.5 0 0.5 1
x
Interpolación racional local.
ip_ratlocal.c
1 #include <stdio.h>
2
3 #define GAMMA 0.1
4 #define X0 0.1
5 #define N 41
6 #define XMAX 0.5
7 #define DX (2.0*XMAX/(N-1.0))
8
9 double function(double x)
10 {
11 double res;
12 res = 0.0008 / (x*x + 0.001* GAMMA*GAMMA);
13 res += 1.0 / ((x-X0)*(x-X0) + GAMMA*GAMMA);
14 return res;
15 }
16
17 double ip_polylocal(double, int, double*, double*, int);
18 double ip_burlischstoer(double, double*, double*, int);
19 double ip_ratlocal(double, int, double*, double*, int);
Comparación.
main_ip_ratlocal.c
21 int main(void)
22 {
23 int n;
24 double xi, yi, ycorrect;
25 double x[N], y[N];
26 double yi4, yi5, yi6;
27 double yp4, yp5, yp6;
28
29 for (n = 0; n < N; n++) {
30 x[n] = n * DX - XMAX;
31 y[n] = function(x[n]);
32 printf(" %g %g\n", x[n], y[n]);
33 }
Comparación.
main_ip_ratlocal.c
34 printf("\n\n");
35 for (xi = -XMAX; xi <= XMAX; xi += 0.005) {
36 yi = ip_burlischstoer(xi, x, y, N);
37 yi4 = ip_ratlocal(xi, 4, x, y, N);
38 yi5 = ip_ratlocal(xi, 5, x, y, N);
39 yi6 = ip_ratlocal(xi, 6, x, y, N);
40 yp4 = ip_polylocal(xi, 4, x, y, N);
41 yp5 = ip_polylocal(xi, 5, x, y, N);
42 yp6 = ip_polylocal(xi, 6, x, y, N);
43 ycorrect = function(xi);
44 printf(" %g %g %g %g %g %g %g %g %g\n",
45 xi, ycorrect, yi, yi4, yi5, yi6,
46 yp4, yp5, yp6);
47 }
48 return 0;
49 }
Resultado.
data
función
120
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 racional
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 rational local (4)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 rational local (5)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 rational local (6)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 poly local (4)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 poly local (5)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Resultado.
data
función
120 poly local (6)
100
80
y
60
40
20
0
−0.6 −0.4 −0.2 0 0.2 0.4 0.6
x
Pro y con.
Alerta:
Interpolación no se puede usar sin saber la forma de la función que
produce los datos!
Parte VI
Integración
Integración como una ecuación diferencial.
dI(x, a)
= f (x)
dx
donde la condición inicial es:
I(x, a)|x=a = 0
Aviso:
Integración es un problema equivalente a resolver una ecuación
diferencial!
Integración como una ecuación diferencial.
dI(x, a)
= f (x)
dx
donde la condición inicial es:
I(x, a)|x=a = 0
Aviso:
Integración es un problema equivalente a resolver una ecuación
diferencial!
Regla trapezoidal.
y
111111111111111
000000000000000
f1
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
f0 000000000000000
111111111111111
000000000000000111111111111111
111111111111111000000000000000
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000111111111111111
111111111111111000000000000000
000000000000000
111111111111111000000000000000
111111111111111
000000000000000
111111111111111000000000000000
111111111111111
000000000000000
111111111111111
000000000000000
111111111111111
000000000000000111111111111111
111111111111111000000000000000
000000000000000
111111111111111 x
x0 = a x1 = b
Z b
1 1
I(b, a) = dxf (x) = ∆x f0 + f1 + O ∆x 3 f (2) ,
a 2 2
∆x = b−a
Z b
1 2 1
I(b, a) = dxf (x) = ∆x f0 + f1 + f2 + O ∆x 5 f (4)
a 6 3 6
∆x = (b − a)/2
∆xN
x
x0 = a xN −1 = b
N−2
X
1 1
I(b, a) = ∆xN fk + fk +1 + O ∆xN3 f (2)
2 2
k =0
1 1
= ∆xN f0 + f1 + . . . + fN−2 + fN−1
2 2
" 3 #
∆x (2)
+(N − 1) × O f
N −1
∆x 3 f (2)
1 1
= ∆xN f0 + f1 + . . . + fN−2 + fN−1 +O
2 2 N2
| {z }
SN
−2
= SN + O N
Regla de Simpson extendida.
Con la regla de Simpson para pares de intervalos resulta:
N−1
2 −1
X
1 2 1
I(b, a) = ∆xN f2k + f2k +1 + f2k +2 + O ∆xN5 f (4)
6 3 6
k =0
1 2 1 1 2 1
= ∆xN f0 + f1 + f2 + f2 + f3 + f4 + . . .
6 3 6 6 3 6
1 2 1
... + fN−3 + fN−2 + fN−1
6 3 6
" 5 #
N −1 ∆x (4)
+ ×O f
2 N −1
1 2 1 2 2 1
= ∆xN f0 + f1 + f2 + f3 + . . . + fN−2 + fN−1
6 3 3 3 3 6
| {z }
SN
−4
+O N
Iteración con regla trapezoidal extendida.
N=2 x
a b
N=3 x
a b
N=5 x
a b
N=9 x
a b
N=9 x
a b
i
1 (i) X
S (i+1) = S + h(i+1) f a + h(i+1) + k · h(i)
2
k =0
1 1
S (0) = (b − a) f (a) + f (b)
2 2
Formula de Euler-Maclaurin:
Z b
I(b, a) = dxf (x) = SN + EN
a
1 1 1
B0 = 1, B2 = , B4 = − , B6 = , etc.
6 30 42
Orden del error en la recursión.
∞ 2k
X B2k (∆x N (i) )
h i
S (i) = SN (i) = I(b, a) + f (2k −1) (b) − f (2k −1) (a)
(2k )!
k =1
∞ 2k h
X B2k h(i) i
= I(b, a) + f (2k −1) (b) − f (2k −1) (a)
(2k )!
k =1
4S (i) − S (i−1)
C (i) = CN (i) =
3
1 2 1 2 2 1
= ∆xN (i) f0 + f1 + f2 + f3 + . . . + fNi −2 + fNi −1
6 3 3 3 3 6
19 h = (b-a);
20 s = h * 0.5 * (f(a) + f(b));
21 res = s;
22 nmax = 1;
23 do {
24 x = a + 0.5 * h;
25 sum = 0.0;
26 for (n = 1; n <= nmax; n++) {
27 sum += f(x);
28 x += h;
29 }
30 s = 0.5 * (s + h * sum);
31 res_old = res;
32 res = (4.0 * s - res_old) / 3.0; /* Simpson extended */
33 h *= 0.5;
34 nmax *= 2;
35 } while (fabs(res - res_old) > fabs(res) * eps);
36 return res;
37 }
Error es una serie de potencias.
Definimos:
2
h(i) (i)
(i) = , (i+1) = , (0) = 1
b−a 4
entonces el error es una serie de potencias en :
E (i) = E((i) )
Error en la recursión.
La recursión para la regla trapezoidal extendida es:
i
S (i) X b−a
S (i+1) = +h(i+1) f a + h(i+1) + k · h(i) , S (0) = [f (a) + f (b)]
2 2
k =0
Definimos:
2
h(i) (i)
(i) = , (i+1) = , (0) = 1
b−a 4
entonces el error es una serie de potencias en :
E (i) = E((i) )
Idéa de Romberg.
Nuestra aproximación es entonces una serie de potencias (∼un
polinomial):
S (i) = I(b, a) − E((i) ) → S((i) )
S ()
i=1
i=2
i=0
1 1
16 4
1
54 h = (b-a);
55 nmax = 1;
56 s[p-1] = h * 0.5 * (f(a) + f(b));
57 hv[p-1] = 1.0;
58 i = p-2;
59
60 res = 0.0;
61 err = DBL_MAX;
Romberg con regla trapezoidal extendida.
ig_romberg.c
63 do {
64 x = a + 0.5 * h;
65 sum = 0.0;
66 for (n = 1; n <= nmax; n++) {
67 sum += f(x);
68 x += h;
69 }
70 s[i] = 0.5 * (s[i+1] + h * sum);
71 hv[i] = 0.25 * hv[i+1];
72 h *= 0.5;
73 nmax *= 2;
74 if (i > 0)
75 i--;
76 else {
77 res = expol_to_zero(hv, s, p, &err, r, l);
78 for (n = p-1; n > 0; n--) {
79 s[n] = s[n-1];
80 hv[n] = hv[n-1];
81 }
82 }
83 } while (fabs(err) > fabs(res) * eps);
Romberg con regla trapezoidal extendida.
ig_romberg.c
85 free(s);
86 free(hv);
87 free(r);
88 free(l);
89
90 return res;
91 }
Romberg con regla de Simpson extendida.
ig_romberg_simpsonext.c
22
23 c = malloc(p * sizeof(double));
24 hv = malloc(p * sizeof(double));
25 r = malloc(p * sizeof(double));
26 l = malloc(p * sizeof(double));
27
28 h = (b-a);
29 nmax = 1;
30 s_old = h * 0.5 * (f(a) + f(b));
31 c[p-1] = s_old;
32 hv[p-1] = 1.0;
33 i = p-2;
34
35 res = 0.0;
36 err = DBL_MAX;
Romberg con regla de Simpson extendida.
ig_romberg_simpsonext.c
38 do {
39 x = a + 0.5 * h;
40 sum = 0.0;
41 for (n = 1; n <= nmax; n++) {
42 sum += f(x);
43 x += h;
44 }
45 s = 0.5 * (s_old + h * sum);
46 c[i] = (4.0 * s - s_old) / 3.0;
47 hv[i] = 0.0625 * hv[i+1];
48 h *= 0.5;
49 nmax *= 2;
50 s_old = s;
51 if (i > 0)
52 i--;
53 else {
54 res = expol_to_zero(hv, c, p, &err, r, l);
55 for (n = p-1; n > 0; n--) {
56 c[n] = c[n-1];
57 hv[n] = hv[n-1];
58 }
59 }
60 } while (fabs(err) > fabs(res) * eps);
Romberg con regla de Simpson extendida.
ig_romberg_simpsonext.c
62 free(c);
63 free(hv);
64 free(r);
65 free(l);
66
67 return res;
68 }
Intensidad transmitida de un resonador de laser.
L · λ0
Iin(ω) Iout(ω)
RS , TS γ , κ0 RS , TS
25
TS = 95 %
γ/ω0 = 0,5
20 κ0 /ω0 = −0,1
L = 29
15
Iout /Iin
10
0
0.4 0.6 0.8 1 1.2 1.4 1.6
ω/ω0
Comparación de métodos.
main_ig_romberg.c
1 #include <math.h>
2 #include <stdio.h>
3 #include <float.h>
4
5 /* Laser resonator: */
6 #define R_S 0.05 /* reflection of mirrors */
7 #define T_S (1.0-R_S) /* transmission of mirrors */
8 #define OMEGA_0 1.0 /* resonance frequency */
9 #define GAMMA 0.5 /* natural linewidth */
10 #define KAPPA_0 -0.10 /* absorption at OMEGA_0 */
11 #define L 29.0 /* effective length */
12
13 int count;
14
15 double ig_simpsonext(double (*f)(double), double, double,
16 double);
17 double ig_romberg(double (*f)(double), double, double, int,
18 double);
19 double ig_romberg_simpsonext(double (*f)(double), double,
20 double, int, double);
Comparación de métodos.
main_ig_romberg.c
35 int main(void)
36 {
37 double p, eps, x;
38
39 for (x = 0.4; x <= 1.6; x+= 0.0001)
40 printf(" %g %g\n", x, power(x));
41 printf("\n\n");
42
43 fprintf(stderr, "Simpson extended:\n"
44 "eps\t\teff. power\tfunction calls\n");
45 for (eps = 1.0e-5; eps >= 1.0e-6; eps *= 0.1) {
46 count = 0;
47 p = ig_simpsonext(power, 0.2, 2.0, eps);
48 fprintf(stderr, " %e\t %13.12f\t %d\n", eps, p, count);
49 }
50
51 fprintf(stderr, "Romberg extended trapezoidal:\n"
52 "eps\t\teff. power\tfunction calls\n");
53 for (eps = 1.0e-5; eps >= 1.0e-12; eps *= 0.1) {
54 count = 0;
55 p = ig_romberg(power, 0.2, 2.0, 5, eps);
56 fprintf(stderr, " %e\t %13.12f\t %d\n", eps, p, count);
57 }
Comparación de métodos.
main_ig_romberg.c
1 Simpson extended:
2 eps eff. power function calls
3 1.000000e-05 1.796780388508 131073
4 1.000000e-06 1.796777940861 524289
Resultado.
1 Simpson extended:
2 eps eff. power function calls
3 1.000000e-05 1.796780388508 131073
4 1.000000e-06 1.796777940861 524289
5 Romber extended trapezoidal:
6 eps eff. power function calls
7 1.000000e-05 1.797186829173 1025
8 1.000000e-06 1.796748783043 2049
9 1.000000e-07 1.796778097073 4097
10 1.000000e-08 1.796777633013 8193
11 1.000000e-09 1.796777633013 8193
12 1.000000e-10 1.796777634905 16385
13 1.000000e-11 1.796777634905 16385
14 1.000000e-12 1.796777634903 32769
Resultado.
1 #include <math.h>
2 #include <float.h>
3 #include <stdio.h>
4
5 double ig_romberg(double (*)(double), double, double,
6 int, double);
7 double log_gamma(double);
8
9 double x;
10
11 double function(double t)
12 {
13 return exp(-t+(x-1.0)*log(t)-log_gamma(x));
14 }
Funciona, pero:
Es 74 × mas lento que “gamma_incomplete(..)”!
Funcion especial: Gamma incompleta.
16 int main(void)
17 {
18 double a, res, eps;
19
20 eps = DBL_EPSILON;
21 for (x = 1.0; x <= 10.0; x += 1.0) {
22 for (a = 0.0; a <= 15.0; a += 0.005) {
23 res = (a == 0) ? 0.0
24 : ig_romberg(function, 0.0, a, 5, eps);
25 printf(" %g %g\n", a, res);
26 }
27 printf("\n\n");
28 }
29 return 0;
30 }
Funciona, pero:
Es 74 × mas lento que “gamma_incomplete(..)”!
Funcion especial: Gamma incompleta.
16 int main(void)
17 {
18 double a, res, eps;
19
20 eps = DBL_EPSILON;
21 for (x = 1.0; x <= 10.0; x += 1.0) {
22 for (a = 0.0; a <= 15.0; a += 0.005) {
23 res = (a == 0) ? 0.0
24 : ig_romberg(function, 0.0, a, 5, eps);
25 printf(" %g %g\n", a, res);
26 }
27 printf("\n\n");
28 }
29 return 0;
30 }
Funciona, pero:
Es 74 × mas lento que “gamma_incomplete(..)”!
Integral inpropia.
|E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
Error total:
X X
|E(∞, a)| ≤ |E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
k k
entonces: k ≤ .
Errores.
Cada parte se calcula con error relativo maximo k :
|E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
Error total:
X X
|E(∞, a)| ≤ |E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
k k
entonces: k ≤ .
Errores.
Cada parte se calcula con error relativo maximo k :
|E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
Error total:
X X
|E(∞, a)| ≤ |E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
k k
entonces: k ≤ .
Errores.
Cada parte se calcula con error relativo maximo k :
|E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
Error total:
X X
|E(∞, a)| ≤ |E(ak , ak −1 )| ≤ k |S(ak , ak −1 )|
k k
entonces: k ≤ .
Condición para terminar.
La aproximacion es I(∞, a) = S(∞, a) + E(∞, a) con
∞
X
S(∞, a) = S(ak +1 , ak )
k =0
Solamente usamos la suma con K terminos:
K
X −1 ∞
X
SK = S(ak +1 , ak ), EK = S(ak +1 , ak ) + E(∞, a)
k =0 k =K
Z x
2 2
E(x) = √ dte−t , l«ım E(x) = 1
π 0 x→∞
Z x
2 2
E(x) = √ dte−t , l«ım E(x) = 1
π 0 x→∞
17 int main(void)
18 {
19 double res, eps;
20
21 count = 0;
22 for (eps = 1.0e-4; eps >= 1.0e-10; eps *= 0.1) {
23 res = ig_improper(f, 0.0, 1.0, 0.1, 4, eps);
24 fprintf(stderr, " %e\t %13.12f\t %d\n", eps, res, count);
25 }
26 return 0;
27 }
Parte VII
Transformación de Fourier
Signal con ancho espectral limitado.
|ν| ≤ νc .
1 Simplificacion:
Z ∞ Z νc
−2πiνt
fc (t) = dνe fc (ν) = dνe−2πiνt fc (ν)
−∞ −νc
2 Consequencia:
∞
X 1
fc (ν) = ∆t e2πiνtn fc (tn ), tn = τ0 + n∆t, ∆t =
n=−∞
2νc
3 Resulta:
Z νc ∞
X Z νc
−2πiνt
fc (t) = dνe fc (ν) = fc (tn )∆t dνe2πiν(tn −t)
−νc n=−∞ −νc
∞
X sin [2πνc (tn − t)]
= fc (tn )
n=−∞
2πνc (tn − t)
X∞
= fc (tn )sinc [2πνc (tn − t)]
n=−∞
Signal con ancho espectral limitado.
|ν| ≤ νc .
1 Simplificacion:
Z ∞ Z νc
−2πiνt
fc (t) = dνe fc (ν) = dνe−2πiνt fc (ν)
−∞ −νc
2 Consequencia:
∞
X 1
fc (ν) = ∆t e2πiνtn fc (tn ), tn = τ0 + n∆t, ∆t =
n=−∞
2νc
3 Resulta:
Z νc ∞
X Z νc
−2πiνt
fc (t) = dνe fc (ν) = fc (tn )∆t dνe2πiν(tn −t)
−νc n=−∞ −νc
∞
X sin [2πνc (tn − t)]
= fc (tn )
n=−∞
2πνc (tn − t)
X∞
= fc (tn )sinc [2πνc (tn − t)]
n=−∞
Signal con ancho espectral limitado.
|ν| ≤ νc .
1 Simplificacion:
Z ∞ Z νc
−2πiνt
fc (t) = dνe fc (ν) = dνe−2πiνt fc (ν)
−∞ −νc
2 Consequencia:
∞
X 1
fc (ν) = ∆t e2πiνtn fc (tn ), tn = τ0 + n∆t, ∆t =
n=−∞
2νc
3 Resulta:
Z νc ∞
X Z νc
−2πiνt
fc (t) = dνe fc (ν) = fc (tn )∆t dνe2πiν(tn −t)
−νc n=−∞ −νc
∞
X sin [2πνc (tn − t)]
= fc (tn )
n=−∞
2πνc (tn − t)
X∞
= fc (tn )sinc [2πνc (tn − t)]
n=−∞
Teorema de muestra (sampling).
Teorema de muestra:
Dado un signal fc (t) con ancho espectral limitado, es decir fc (ν) 6= 0
solo para |ν| ≤ νc , resulta que:
∞
X
fc (t) = fc (tn )sinc [2πνc (tn − t)]
n=−∞
n=−∞ −∞ −νc
∞ Z νc Z ∞
X 0 0
= ∆t fc (tn ) dν 0 e2πiν tn
dte2πi(ν−ν )t
n=−∞ −νc −∞
| {z }
=δ(ν−ν 0 )
∞ νc
dΘ(ν − ν 0 )
X Z
= ∆t fc (tn )e2πiνtn dν 0 −
n=−∞ −νc dν 0
X∞
= [Θ(ν + νc ) − Θ(ν − νc )] ∆t fc (tn )e2πiνtn
| {z } n=−∞
=Π(ν)
Transformacion discreta.
Para signal fc (t) con ancho espectral limitado (|ν| ≤ νc ):
∞
X
fc (ν) = Π(ν)∆t fc (tn )e2πiνtn
n=−∞
N−1 N−1
mn
X X
fc (νm ) = Π(νm )∆t fc (tn )e2πiνm tn = e2πiνm τ0 ∆t fc (tn )e2πi N
n=0 n=0
| {z }
=Fm
Suma de Fourier:
Para los N (es numero pares) datos fn (n = 0, . . . , N − 1) resultan sus
N + 1 transformaciones discretas de Fourier como:
N−1
X mn N N
Fm = fn e2πi N (m = − ,..., )
2 2
n=0
N−1 N−1
mn
X X
fc (νm ) = Π(νm )∆t fc (tn )e2πiνm tn = e2πiνm τ0 ∆t fc (tn )e2πi N
n=0 n=0
| {z }
=Fm
Suma de Fourier:
Para los N (es numero pares) datos fn (n = 0, . . . , N − 1) resultan sus
N + 1 transformaciones discretas de Fourier como:
N−1
X mn N N
Fm = fn e2πi N (m = − ,..., )
2 2
n=0
N−1
mn
X
Fm = fn e2πi N
n=0
F− N
2
f0
.. ..
..
. .
. 2πi
F0 = · , W =e N
..
··· W mn ···
..
..
. .
.
FN fN−1
2
Multiplicacion de matriz (N + 1) × N:
Ops(N) ∝ O(N 2 )
Pares versus impares.
Gauss 1805; Cooley & Tukey en los años 60.
n=0
N N
2 −1 2 −1
X m(2k ) X m(2k +1)
2πi
= f2k e N + f2k +1 e2πi N
k =0 k =0
(0) 2πi m (1)
= Fm,N +e N Fm,N
Entonces tenemos:
(0) (1) 2πi
Fm = Fm,N + (WN )m Fm,N , WN = e N
Idea:
Iteracion posible hasta transformacion de Fourier de solo un dato si
N = 2k !
Separacion en pares e impares.
Entonces tenemos:
(0) (1) 2πi
Fm = Fm,N + (WN )m Fm,N , WN = e N
Idea:
Iteracion posible hasta transformacion de Fourier de solo un dato si
N = 2k !
Iteracion.
k
N=2 .
k N Fm
Iteracion.
k
N=2 .
k N Fm
(0) (1)
k − 1 N/2 Fm,N + (WN )m Fm,N
Iteracion.
k
N=2 .
k N Fm
(0) (1)
k − 1 N/2 Fm,N + (WN )m Fm,N
h i h i
(00) (01) (10) (11)
k − 2 N/4 Fm, N + (W N )m Fm, N + (WN )m Fm, N + (W N )m Fm, N
2 2 2 2 2 2
Iteracion.
k
N=2 .
k N Fm
(0) (1)
k − 1 N/2 Fm,N + (WN )m Fm,N
h i h i
(00) (01) (10) (11)
k − 2 N/4 Fm, N + (W N )m Fm, N + (WN )m Fm, N + (W N )m Fm, N
2 2 2 2 2 2
.. .. ..
. . .
(0010011010)
0 1 . . . (W2 )m . . . Fm,2 ...
Transformaciones de un punto.
(p p2 ...pk )
¿Que es Fm,21 ?
Es una transformacion de Fourier de un dato:
(p p ...pk )
Fm,21 2 = e4πim fn = fn
n = n(p1 p2 . . . pk )
Problema:
¿Cual es la dependencia entre n y los p1 p2 . . . pk ?
Transformaciones de un punto.
(p p2 ...pk )
¿Que es Fm,21 ?
Es una transformacion de Fourier de un dato:
(p p ...pk )
Fm,21 2 = e4πim fn = fn
n = n(p1 p2 . . . pk )
Problema:
¿Cual es la dependencia entre n y los p1 p2 . . . pk ?
Pares e impares en bits.
¿A que combinacion p1 p2 . . . pk corresponde el indice n de N = 2k datos?
(1) 1 3 5 7 9 11 13 15
Pares e impares en bits.
¿A que combinacion p1 p2 . . . pk corresponde el indice n de N = 2k datos?
(1) 1 3 5 7 9 11 13 15
(11) 3 7 11 15
Pares e impares en bits.
¿A que combinacion p1 p2 . . . pk corresponde el indice n de N = 2k datos?
(1) 1 3 5 7 9 11 13 15
(11) 3 7 11 15
(111) 7 15
Pares e impares en bits.
¿A que combinacion p1 p2 . . . pk corresponde el indice n de N = 2k datos?
(1) 1 3 5 7 9 11 13 15
(11) 3 7 11 15
(111) 7 15
(1110) 7
Pares e impares en bits.
¿A que combinacion p1 p2 . . . pk corresponde el indice n de N = 2k datos?
(1) 1 3 5 7 9 11 13 15
(11) 3 7 11 15
(111) 7 15
(1110) 7
(1) 1 3 5 7 9 11 13 15
(11) 3 7 11 15
(111) 7 15
(1110) 7
k =2 N=4 Fm
Ejemplo.
N = 22 = 4.
k =2 N=4 Fm
(0) (1)
1 2 Fm,4 + (W4 )m Fm,4
Ejemplo.
N = 22 = 4.
k =2 N=4 Fm
(0) (1)
1 2 Fm,4 + (W4 )m Fm,4
h i h i
(00) (01) (10) (11)
0 1 Fm,2 + (W2 )m Fm,2 + (W4 )m Fm,2 + (W2 )m Fm,2
Ejemplo.
N = 22 = 4.
k =2 N=4 Fm
(0) (1)
1 2 Fm,4 + (W4 )m Fm,4
h i h i
(00) (01) (10) (11)
0 1 Fm,2 + (W2 )m Fm,2 + (W4 )m Fm,2 + (W2 )m Fm,2
h i h i
= f̃(00) + (W2 )m f̃(01) + (W4 )m f̃(10) + (W2 )m f̃(11)
Ejemplo.
N = 22 = 4.
k =2 N=4 Fm
(0) (1)
1 2 Fm,4 + (W4 )m Fm,4
h i h i
(00) (01) (10) (11)
0 1 Fm,2 + (W2 )m Fm,2 + (W4 )m Fm,2 + (W2 )m Fm,2
h i h i
= f̃(00) + (W2 )m f̃(01) + (W4 )m f̃(10) + (W2 )m f̃(11)
f0 f1 f2 f3
Estrategia simple.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
Estrategia simple.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
+ ×(W2 )m + ×(W2 )m
Estrategia simple.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
+ ×(W2 )m + ×(W2 )m
+ ×(W4 )m
Fm
Complejitud computacional.
Es muy pobre!
Complejitud computacional:
Para calcular un Fm :
N N N
Ops(N) = OpsBR (N) + (⊕ + ⊗) + + + ... + 1
2 4 8
k −1
X 1 n
= OpsBR (N) + N
2
n=0
1
= OpsBR (N) + 2N 1 −
N
= OpsBR (N) + O(N)
Problema:
Para los N transformadas necesitamos tambien O(N 2 )!
Complejitud computacional.
Es muy pobre!
Complejitud computacional:
Para calcular un Fm :
N N N
Ops(N) = OpsBR (N) + (⊕ + ⊗) + + + ... + 1
2 4 8
k −1
X 1 n
= OpsBR (N) + N
2
n=0
1
= OpsBR (N) + 2N 1 −
N
= OpsBR (N) + O(N)
Problema:
Para los N transformadas necesitamos tambien O(N 2 )!
Idea.
2
N = 2 = 4: m = −2, . . . , +2.
2 En el segundo paso:
1, m=0
m
i, m=1
m 2πi/4 m
(W4 ) = e = (i) =
−i, m = −1
−1, m = ±2
Idea:
Calcular las transformadas para todas frecuencias en paralelo!
Idea.
2
N = 2 = 4: m = −2, . . . , +2.
2 En el segundo paso:
1, m=0
m
i, m=1
m 2πi/4 m
(W4 ) = e = (i) =
−i, m = −1
−1, m = ±2
Idea:
Calcular las transformadas para todas frecuencias en paralelo!
Idea.
2
N = 2 = 4: m = −2, . . . , +2.
2 En el segundo paso:
1, m=0
m
i, m=1
m 2πi/4 m
(W4 ) = e = (i) =
−i, m = −1
−1, m = ±2
Idea:
Calcular las transformadas para todas frecuencias en paralelo!
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
m = 0, ±2 m = 0, ±2
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
×(W2 )1 ×(W2 )1
m = 0, ±2 m = ±1 m = 0, ±2 m = ±1
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
×(W2 )1 ×(W2 )1
m = 0, ±2 m = ±1 m = 0, ±2 m = ±1
×(W4 )0
m=0
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
×(W2 )1 ×(W2 )1
m = 0, ±2 m = ±1 m = 0, ±2 m = ±1
×(W4 )0
×(W4 )2
m=0 m = ±2
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
×(W2 )1 ×(W2 )1
m = 0, ±2 m = ±1 m = 0, ±2 m = ±1
×(W4 )0 ×(W4 )1
×(W4 )2
m=0 m=1 m = ±2
Estrategia mas elaborada.
N = 22 = 4, W2 = −1, W4 = i.
00 01 10 11
f0 f1 f2 f3
Reversión
de Bits
f0 f1 f2 f3
×(W2 )0 ×(W2 )0
×(W2 )1 ×(W2 )1
m = 0, ±2 m = ±1 m = 0, ±2 m = ±1
×(W4 )0 ×(W4 )1
Complejitud computacional:
Para calcular todos los Fm :
Falta:
¿Complejitud computacional de la reversion de Bits?
Complejitud computacional.
Ahora es mejor.
Complejitud computacional:
Para calcular todos los Fm :
Falta:
¿Complejitud computacional de la reversion de Bits?
Estrategia.
n = 0000 1011 ñ = 00000000
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 000000 10 ñ = 00000 110
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 000000 10 ñ = 00000 110
m = (n %2); (m = 0) ñ+ = m;
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 000000 10 ñ = 00000 110
m = (n %2); (m = 0) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 0000000 1 ñ = 0000 1100
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 000000 10 ñ = 00000 110
m = (n %2); (m = 0) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 0000000 1 ñ = 0000 1100
m = (n %2); (m = 1) ñ+ = m;
Estrategia.
n = 0000 1011 ñ = 00000000
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 00000 101 ñ = 000000 10
m = (n %2); (m = 1) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 000000 10 ñ = 00000 110
m = (n %2); (m = 0) ñ+ = m;
n >>= 1; ñ <<= 1;
n = 0000000 1 ñ = 0000 1100
m = (n %2); (m = 1) ñ+ = m;
ñ = 0000 1101
Complejitud computacional.
Complejitud computacional:
Complejitud computacional:
lo = 0 b=0 hi = 2 b=1
blocks = N4
lines = 2
points = 4
Idea del programa.
ft_fft.c
000 001 010 011 100 101 110 111
lo = 0 b = 0 hi = 1 b=1 b=2 b=3 blocks = N2
lines = 1
points = 2
lo = 0 b=0 hi = 2 b=1
blocks = N4
lines = 2
points = 4
lo = 0 b=0 hi = 4
blocks = N8
lines = 4
points = 8
Recursion para WNm .
25 double xvalue(size_t n)
26 {
27 return XMAX * (n - 0.5 * N) / N;
28 }
29
30 double freqvalue(int n)
31 {
32 return n * 2.0 * VC / N;
33 }
34
35 complex double factor(int n)
36 {
37 return exp(-M_PI*I*freqvalue(n)*XMAX);
38 }
39
40 int main(void)
41 {
42 complex double data[N];
43 size_t n;
44 double x;
45 complex double res;
Resultado.
main_ft_fft.c
47 a = 100.0;
48 b = 0.0;
49 for (n = 0; n < N; n++) {
50 x = xvalue(n);
51 data[n] = function(x);
52 printf(" %f %f %f\n", x, creal(data[n]), cimag(data[n]));
53 }
54 printf("\n\n");
55
56 fft(data, bits, 1);
57 for (n = N/2+1; n < N; n++) {
58 res = data[n] * factor(n-N);
59 printf(" %f %f %f\n", freqvalue(n-N), creal(res), cimag(res));
60 }
61 for (n = 0; n <= N/2; n++) {
62 res = data[n] * factor(n);
63 printf(" %f %f %f\n", freqvalue(n), creal(res), cimag(res));
64 }
65 printf("\n\n");
Resultado.
main_ft_fft.c
0.8
0.6
f (t)
0.4
0.2
0
−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1
t
Ejemplo.
Funcion de Gauss sin y con ruido.
25
20
15
10
5
f (ν)
−5
−10
−15
−20
−25
−0.001 −0.0008 −0.0006 −0.0004 −0.0002 0 0.0002 0.0004 0.0006 0.0008 0.001
ν
Ejemplo.
Funcion de Gauss sin y con ruido.
1.2
0.8
0.6
f (t)
0.4
0.2
−0.2
−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1
t
Ejemplo.
Funcion de Gauss sin y con ruido.
25
20
15
10
5
f (ν)
−5
−10
−15
−20
−25
−0.001 −0.0008 −0.0006 −0.0004 −0.0002 0 0.0002 0.0004 0.0006 0.0008 0.001
ν
Parte VIII
Aproximación de Chebyshev
Polinomial de Chebyshev.
Polinomial de Chebyshev:
T0 (x) = 1
T1 (x) = x
T2 (x) = 2x 2 − 1
T3 (x) = 4x 3 − 3x
T4 (x) = 8x 4 − 8x 2 + 1
..
.
Recursión.
1 n=0
0.5
Tn (x)
−0.5
−1
−1 −0.5 0 0.5 1
x
¿Como se ve?
1 n=1
0.5
Tn (x)
−0.5
−1
−1 −0.5 0 0.5 1
x
¿Como se ve?
1 n=2
0.5
Tn (x)
−0.5
−1
−1 −0.5 0 0.5 1
x
¿Como se ve?
1 n=3
0.5
Tn (x)
−0.5
−1
−1 −0.5 0 0.5 1
x
¿Como se ve?
1 n=4
0.5
Tn (x)
−0.5
−1
−1 −0.5 0 0.5 1
x
Ceros.
(n)
Buscamos los ceros xk del polinomial Tn (x):
(n) (n)
Tn (xk ) = cos[n arc cos(xk )] = 0
Es equivalente a:
(n) π
n arc cos(xk ) = (2k + 1)
2
(n)
Buscamos los ceros xk del polinomial Tn (x):
(n) (n)
Tn (xk ) = cos[n arc cos(xk )] = 0
Es equivalente a:
(n) π
n arc cos(xk ) = (2k + 1)
2
Ortogonalidad discreta:
n−1 0, i 6= j n
(n) (n)
X
n
Ti xk Tj x k = , i =j =6 0 = δi,j (1 + δi,0 )
2 2
k =0 n, i = j = 0
(n) (n)
donde xk son los ceros de: Tn (xk ) = 0 y i, j < n.
Consequencia.
Expansión general de una función f (x) con x ∈ [−1, 1]:
∞
X
f (x) = di Ti (x)
i=0
(N)
Con N fijo, los valores en los ceros xk son:
∞
(N) (N)
X
f xk = dj Tj xk
j=0
Consequencia:
N−1 ∞ N−1
(N) (N) (N) (N)
X X X
Ti xk f xk = dj Ti x k Tj xk
k =0 j=0 k =0
N−1
X N N
= dj δi,j (1 + δi,0 ) = di (1 + δi,0 )
2 2
j=0
Consequencia.
Expansión general de una función f (x) con x ∈ [−1, 1]:
∞
X
f (x) = di Ti (x)
i=0
(N)
Con N fijo, los valores en los ceros xk son:
∞
(N) (N)
X
f xk = dj Tj xk
j=0
Consequencia:
N−1 ∞ N−1
(N) (N) (N) (N)
X X X
Ti xk f xk = dj Ti x k Tj xk
k =0 j=0 k =0
N−1
X N N
= dj δi,j (1 + δi,0 ) = di (1 + δi,0 )
2 2
j=0
Consequencia.
Expansión general de una función f (x) con x ∈ [−1, 1]:
∞
X
f (x) = di Ti (x)
i=0
(N)
Con N fijo, los valores en los ceros xk son:
∞
(N) (N)
X
f xk = dj Tj xk
j=0
Consequencia:
N−1 ∞ N−1
(N) (N) (N) (N)
X X X
Ti xk f xk = dj Ti x k Tj xk
k =0 j=0 k =0
N−1
X N N
= dj δi,j (1 + δi,0 ) = di (1 + δi,0 )
2 2
j=0
Formula de aproximación.
Vamos a definir:
N−1
2 X (N) (N)
ci = Ti xk f xk = di (1 + δi,0 )
N
k =0
Entonces:
N−1 N−1 c
(N) (N) (N) 0
X X
f xk = dj Tj xk = cj Tj xk −
2
j=0 j=0
Vamos a definir:
N−1
2 X (N) (N)
ci = Ti xk f xk = di (1 + δi,0 )
N
k =0
Entonces:
N−1 N−1 c
(N) (N) (N) 0
X X
f xk = dj Tj xk = cj Tj xk −
2
j=0 j=0
Vamos a definir:
N−1
2 X (N) (N)
ci = Ti xk f xk = di (1 + δi,0 )
N
k =0
Entonces:
N−1 N−1 c
(N) (N) (N) 0
X X
f xk = dj Tj xk = cj Tj xk −
2
j=0 j=0
N−1
X c0
f (x) ≈ cj Tj (x) −
2
j=0
donde:
N−1
2 X (N) (N)
ci = Ti xk f xk
N
k =0
Es un polinomial de orden N − 1.
(N)
Es exacto para x = xk .
Pregunta:
¿Es mejor que otra aproximación polinomial del mismo orden?
Respuesta: No!
Aproximación de Chebyshev.
N−1
X c0
f (x) ≈ cj Tj (x) −
2
j=0
donde:
N−1
2 X (N) (N)
ci = Ti xk f xk
N
k =0
Es un polinomial de orden N − 1.
(N)
Es exacto para x = xk .
Pregunta:
¿Es mejor que otra aproximación polinomial del mismo orden?
Respuesta: No!
Bajar el orden.
La verdadera aproximación de Chebyshev.
Aproximación de Chebyshev:
N−1
2 X (N) (N)
ci = Ti xk f xk
N
k =0
¿Cual es el error?
Si N 1 los c0 , . . . , cN−1 son casi perfecto.
Los cj estan disminuendo: cj+1 ≤ cj , entonces el error de una
truncación M N es:
error ≈ cM TM (x)
Ventaja:
Con la aproximación de Chebyshev se puede obtener una
aproximación polinomial con un orden muy bajo con propiedades
optimales.
Error.
¿Cual es el error?
Si N 1 los c0 , . . . , cN−1 son casi perfecto.
Los cj estan disminuendo: cj+1 ≤ cj , entonces el error de una
truncación M N es:
error ≈ cM TM (x)
Ventaja:
Con la aproximación de Chebyshev se puede obtener una
aproximación polinomial con un orden muy bajo con propiedades
optimales.
Error.
¿Cual es el error?
Si N 1 los c0 , . . . , cN−1 son casi perfecto.
Los cj estan disminuendo: cj+1 ≤ cj , entonces el error de una
truncación M N es:
error ≈ cM TM (x)
Ventaja:
Con la aproximación de Chebyshev se puede obtener una
aproximación polinomial con un orden muy bajo con propiedades
optimales.
Error.
¿Cual es el error?
Si N 1 los c0 , . . . , cN−1 son casi perfecto.
Los cj estan disminuendo: cj+1 ≤ cj , entonces el error de una
truncación M N es:
error ≈ cM TM (x)
Ventaja:
Con la aproximación de Chebyshev se puede obtener una
aproximación polinomial con un orden muy bajo con propiedades
optimales.
Error.
¿Cual es el error?
Si N 1 los c0 , . . . , cN−1 son casi perfecto.
Los cj estan disminuendo: cj+1 ≤ cj , entonces el error de una
truncación M N es:
error ≈ cM TM (x)
Ventaja:
Con la aproximación de Chebyshev se puede obtener una
aproximación polinomial con un orden muy bajo con propiedades
optimales.
Cambio del intervalo.
Inversión es:
b+a b−a
x= + ξ
2 2
Cambio del intervalo.
Inversión es:
b+a b−a
x= + ξ
2 2
Cambio del intervalo.
Inversión es:
b+a b−a
x= + ξ
2 2
Implementación.
ch_coef.c
Problema:
Usando los coeficientes ci hay que calcular ahora la aproximación de
Chebyshev:
M−1
X c0
f (x) ≈ cj Tj [ξ(x)] −
2
j=0
Problema:
Usando los coeficientes ci hay que calcular ahora la aproximación de
Chebyshev:
M−1
X c0
f (x) ≈ cj Tj [ξ(x)] −
2
j=0
Problema:
Usando los coeficientes ci hay que calcular ahora la aproximación de
Chebyshev:
M−1
X c0
f (x) ≈ cj Tj [ξ(x)] −
2
j=0
Problema:
Usando los coeficientes ci hay que calcular ahora la aproximación de
Chebyshev:
M−1
X c0
f (x) ≈ cj Tj [ξ(x)] −
2
j=0
Problema:
Usando los coeficientes ci hay que calcular ahora la aproximación de
Chebyshev:
M−1
X c0
f (x) ≈ cj Tj [ξ(x)] −
2
j=0
Resultado:
c0
fCA [x(ξ)] = h0 (ξ)T0 (ξ) + h1 (ξ) [T1 (ξ) − α0 (ξ)T0 (ξ)] −
2
c0
= h0 (ξ) − ξh1 (ξ) −
2
Clenshaw para Chebyshev.
Nosotros tenemos la suma:
M−1
X c0
fCA (x) = cj Tj [ξ(x)] − , Tn+1 (ξ) = 2ξTn (ξ) − Tn−1 (ξ)
2
j=0
Resultado:
c0
fCA [x(ξ)] = h0 (ξ)T0 (ξ) + h1 (ξ) [T1 (ξ) − α0 (ξ)T0 (ξ)] −
2
c0
= h0 (ξ) − ξh1 (ξ) −
2
Clenshaw para Chebyshev.
Nosotros tenemos la suma:
M−1
X c0
fCA (x) = cj Tj [ξ(x)] − , Tn+1 (ξ) = 2ξTn (ξ) − Tn−1 (ξ)
2
j=0
Resultado:
c0
fCA [x(ξ)] = h0 (ξ)T0 (ξ) + h1 (ξ) [T1 (ξ) − α0 (ξ)T0 (ξ)] −
2
c0
= h0 (ξ) − ξh1 (ξ) −
2
Clenshaw para Chebyshev.
Nosotros tenemos la suma:
M−1
X c0
fCA (x) = cj Tj [ξ(x)] − , Tn+1 (ξ) = 2ξTn (ξ) − Tn−1 (ξ)
2
j=0
Resultado:
c0
fCA [x(ξ)] = h0 (ξ)T0 (ξ) + h1 (ξ) [T1 (ξ) − α0 (ξ)T0 (ξ)] −
2
c0
= h0 (ξ) − ξh1 (ξ) −
2
Clenshaw para Chebyshev.
Nosotros tenemos la suma:
M−1
X c0
fCA (x) = cj Tj [ξ(x)] − , Tn+1 (ξ) = 2ξTn (ξ) − Tn−1 (ξ)
2
j=0
Resultado:
c0
fCA [x(ξ)] = h0 (ξ)T0 (ξ) + h1 (ξ) [T1 (ξ) − α0 (ξ)T0 (ξ)] −
2
c0
= h0 (ξ) − ξh1 (ξ) −
2
Implementación.
ch_approx.c
1 #include <math.h>
2 #include <stdio.h>
3
4 #define GAMMA 0.1
5 #define X0 0.1
6 #define XMAX 0.5
7
8 double function1(double x)
9 {
10 double res;
11 res = 0.0008 / (x*x + 0.001* GAMMA*GAMMA);
12 res += 1.0 / ((x-X0)*(x-X0) + GAMMA*GAMMA);
13 return res;
14 }
15
16 double function2(double x)
17 {
18 double res;
19 res = 1.0 / ((x-X0)*(x-X0) + GAMMA*GAMMA);
20 return res;
21 }
Resultado.
main_ch_approx.c
22
23 void chebyshev_coef(double (*)(double), double, double,
24 double*, int);
25 double chebyshev_approx(double, double, double, double*,
26 int);
27
28 int main(void)
29 {
30 double x, c[200];
31
32 for (x = -XMAX; x <= XMAX; x += 0.005)
33 printf(" %g %g %g\n",
34 x, function1(x), function2(x));
35 printf("\n\n");
36
37 chebyshev_coef(function2, -XMAX, XMAX, c, 5);
38 for (x = -XMAX; x <= XMAX; x += 0.005)
39 printf(" %g %g\n",
40 x, chebyshev_approx(x, -XMAX, XMAX, c, 5));
41 printf("\n\n");
Resultado.
main_ch_approx.c
100 f (x)
Chebyshev 5/5
80
60
f (x)
40
20
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Ejemplos.
100 f (x)
Chebyshev 10/10
80
60
f (x)
40
20
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Ejemplos.
100 f (x)
Chebyshev 20/20
80
60
f (x)
40
20
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Ejemplos.
100 f (x)
Chebyshev 10/20
80
60
f (x)
40
20
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Ejemplos.
f (x)
Chebyshev 100/100
120
100
80
f (x)
60
40
20
0
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Ejemplos.
f (x)
Chebyshev 200/200
120
100
80
f (x)
60
40
20
0
−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5
x
Integral de una aproximación de Chebyshev.
Tenemos la aproximación de Chebyshev de una funcion f (x),
x ∈ [−1, 1], a través de los coeficientes cn :
M−1
X c0
fCA (x) = cj Tj [ξ(x)] −
2
j=0
Z ξ
= dξ 0 cos[n arc cos(ξ 0 )]
Z arc cos(ξ)
= − dθ sin(θ) cos(nθ)
Z arc cos(ξ)
1
eiθ − e−iθ einθ + e−inθ
= − dθ
4i
θ=arc cos(ξ)
ei(n+1)θ e−i(n+1)θ ei(n−1)θ e−i(n−1)
1
= − − − +
4i i(n + 1) −i(n + 1) i(n − 1) −i(n − 1)
θ=arc cos(ξ)
i(n+1)θ
e−i(n+1)θ ei(n−1)θ e−i(n−1)
1 e
= + − −
4 n+1 n+1 n−1 n−1
cos[(n + 1) arc cos(ξ)] cos[(n − 1) arc cos(ξ)]
= −
2(n + 1) 2(n − 1)
Tn+1 (ξ) Tn−1 (ξ)
= −
2(n + 1) 2(n − 1)
Nuevos coeficientes.
M−1 Z ξ(x)
b−a X c0
FCA (x) = cn dξ 0 Tn (ξ 0 ) + x + const
2 2
n=1
M−1
b−a X Tn+1 [ξ(x)] Tn−1 [ξ(x)] c0
= cn − + x + const
2 2(n + 1) 2(n − 1) 2
n=1
( M M−2
)
b−a X Tn [ξ(x)] X Tn [ξ(x)]
= cn−1 − cn+1
2 2n 2n
n=2 n=0
b − a c0
+ T1 [ξ(x)] + const
2 2
Nuevos coeficientes.
Entonces la integral de la aproximación de Chebyshev es:
b−a cM−1 cM−2
= TM [ξ(x)] + TM−1 [ξ(x)]
2 2M 2(M − 1)
M−2
X cn−1 − cn+1 c0 − c2
+ Tn [ξ(x)] + T1 [ξ(x)] + const
2n 2 }
n=2 | {z } | {z
∝Cn ∝C1
M−1
X
≈ Cn Tn [ξ(x)] + const
n=1
(M−1 )
X C0
= Cn Tn [ξ(x)] − + const
2
n=0
Queremos la derivada:
M−1
d 0
X ∂
fCA (x) = fCA (x) = cn Tn [ξ(x)]
dx ∂x
n=0
0 0 4n
cn−1 = cn+1 + cn
b−a
Derivada.
Queremos la derivada:
M−1
d 0
X ∂
fCA (x) = fCA (x) = cn Tn [ξ(x)]
dx ∂x
n=0
0 0 4n
cn−1 = cn+1 + cn
b−a
Derivada.
Queremos la derivada:
M−1
d 0
X ∂
fCA (x) = fCA (x) = cn Tn [ξ(x)]
dx ∂x
n=0
0 0 4n
cn−1 = cn+1 + cn
b−a
Implementación.
ch_coefder.c
Maquina deterministica:
Una maquina deterministica (computador) no es capaz de generar
numeros aleatorios!
Compromiso:
Computador produce sequencias s de numeros pseudo-aleatorios
(s)
Ni .
(s) (s)
1 Se repiten despues una sequencia de largo L: Ni+L = Ni .
(s) (s)
2 Tienen correlaciones en la sequencia: hNi Nj i =
6 δi,j .
(s) (q)
3 Tienen correlaciones entre sequencias: hNi Ni i =
6 δs,q .
Problema.
Maquina deterministica:
Una maquina deterministica (computador) no es capaz de generar
numeros aleatorios!
Compromiso:
Computador produce sequencias s de numeros pseudo-aleatorios
(s)
Ni .
(s) (s)
1 Se repiten despues una sequencia de largo L: Ni+L = Ni .
(s) (s)
2 Tienen correlaciones en la sequencia: hNi Nj i =
6 δi,j .
(s) (q)
3 Tienen correlaciones entre sequencias: hNi Ni i =
6 δs,q .
Problema.
Maquina deterministica:
Una maquina deterministica (computador) no es capaz de generar
numeros aleatorios!
Compromiso:
Computador produce sequencias s de numeros pseudo-aleatorios
(s)
Ni .
(s) (s)
1 Se repiten despues una sequencia de largo L: Ni+L = Ni .
(s) (s)
2 Tienen correlaciones en la sequencia: hNi Nj i =
6 δi,j .
(s) (q)
3 Tienen correlaciones entre sequencias: hNi Ni i =
6 δs,q .
Problema.
Maquina deterministica:
Una maquina deterministica (computador) no es capaz de generar
numeros aleatorios!
Compromiso:
Computador produce sequencias s de numeros pseudo-aleatorios
(s)
Ni .
(s) (s)
1 Se repiten despues una sequencia de largo L: Ni+L = Ni .
(s) (s)
2 Tienen correlaciones en la sequencia: hNi Nj i =
6 δi,j .
(s) (q)
3 Tienen correlaciones entre sequencias: hNi Ni i =
6 δs,q .
Problema.
Maquina deterministica:
Una maquina deterministica (computador) no es capaz de generar
numeros aleatorios!
Compromiso:
Computador produce sequencias s de numeros pseudo-aleatorios
(s)
Ni .
(s) (s)
1 Se repiten despues una sequencia de largo L: Ni+L = Ni .
(s) (s)
2 Tienen correlaciones en la sequencia: hNi Nj i =
6 δi,j .
(s) (q)
3 Tienen correlaciones entre sequencias: hNi Ni i =
6 δs,q .
Numeros aleatorios en C.
Alerta Roja:
Estos son correlaciones muy fuertes!
Correlaciones.
Alerta Roja:
Estos son correlaciones muy fuertes!
Correlaciones.
Alerta Roja:
Estos son correlaciones muy fuertes!
Correlaciones.
Alerta Roja:
Estos son correlaciones muy fuertes!
Pequeño programa.
main_de_corr.c
1 #include <stdio.h>
2
3 #define M 64
4
5 int main(void)
6 {
7 int a, c, r[M], n;
8
9 a = 165;
10 c = 87;
11
12 r[0] = 1;
13 for (n = 1; n < M; n++)
14 r[n] = (a * r[n-1] + c) % M;
15
16 for (n = 0; n < M-1; n += 2)
17 printf(" %d %d\n", r[n], r[n+1]);
18
19 return 0;
20 }
Correlaciones - 2D vectores.
m = 64, a = 165, c = 87.
60
50
40
30
20
10
0
0 10 20 30 40 50 60
¿Que necesitamos?
a = 75 = 16807
m = 231 − 1 = 2,147,483,647
a = 75 = 16807
m = 231 − 1 = 2,147,483,647
a = 75 = 16807
m = 231 − 1 = 2,147,483,647
a = 75 = 16807
m = 231 − 1 = 2,147,483,647
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define NBIN 50
5 #define N 40000000L
6 #define P (2.0/N)
7
8 double rand_parkmiller(long long int*);
9 int searchidx(double, double*, int);
10
11 int main(void)
12 {
13 long long int irnd;
14 long int n;
15 int xpos, ypos;
16 double x, y;
17 double bin[NBIN][NBIN];
18 double binscale[NBIN+1];
19
20 for (xpos = 0; xpos <= NBIN; xpos++)
21 binscale[xpos] = xpos / ((double)NBIN);
Comparacion Park & Miller con rand().
main_rn_pm.c
1
0.9 0.000825
0.00082
0.8 0.000815
0.00081
0.7 0.000805
0.0008
0.6 0.000795
0.00079
0.5 0.000785
0.00078
0.4 0.000775
0.3
0.2
0.1
0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
Correlaciones en una secuencia.
Park & Miller versus rand(): 40,000,000 numeros pseudo-aleatorios en 50 × 50 bins.
1
0.9 0.000825
0.8 0.00082
0.000815
0.7 0.00081
0.000805
0.6 0.0008
0.000795
0.5 0.00079
0.000785
0.4 0.00078
0.3
0.2
0.1
0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
Version con “Shuffle”.
rn_shuffle.c
18 if (init) {
19 for (j = RND_NTAB+7; j >= 0; j--) {
20 (*irnd) = (RND_A * (*irnd)) % RND_M;
21 if (j < RND_NTAB)
22 iv[j] = (*irnd);
23 }
24 iy = iv[0];
25 init = 0;
26 }
27
28 (*irnd) = (RND_A * (*irnd)) % RND_M;
29 j = iy / RND_NDIV;
30 iy = iv[j];
31 iv[j] = (*irnd);
32
33 return RND_CONVERSION * iy;
34 }
Resultados.
main_rn_shuffle.c
1
0.9 2.7e−05
0.8 2.6e−05
2.5e−05
0.7 2.4e−05
2.3e−05
0.6 2.2e−05
2.1e−05
0.5 2e−05
1.9e−05
0.4 1.8e−05
0.3
0.2
0.1
0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
Resultados.
main_rn_shuffle.c
1
0.9 2.7e−05
0.8 2.6e−05
2.5e−05
0.7 2.4e−05
2.3e−05
0.6 2.2e−05
2.1e−05
0.5 2e−05
1.9e−05
0.4 1.8e−05
0.3
0.2
0.1
0
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
Parte X
Trayectorias cuánticas
Operador de densidad.
En la mecánica cuántica tenemos la ecuación de Schrödinger:
∂
i~ |Ψ(t)i = Ĥ|Ψ(t)i
∂t
donde en una representación de la posición (auto-estados
x̂|xi = x|xi) tenemos la función de onda:
Ψ(x, t) = hx|Ψ(t)i
%̂(t) = |Ψ(t)ihΨ(t)|
∂
i~ |Ψ(t)i = Ĥ|Ψ(t)i
∂t
donde en una representación de la posición (auto-estados
x̂|xi = x|xi) tenemos la función de onda:
Ψ(x, t) = hx|Ψ(t)i
%̂(t) = |Ψ(t)ihΨ(t)|
∂
i~ |Ψ(t)i = Ĥ|Ψ(t)i
∂t
donde en una representación de la posición (auto-estados
x̂|xi = x|xi) tenemos la función de onda:
Ψ(x, t) = hx|Ψ(t)i
%̂(t) = |Ψ(t)ihΨ(t)|
∂ 1 X † 1 † 1 †
%̂ = [Ĥ, %̂] + Ŝλ %̂Ŝλ − Ŝλ Ŝλ %̂ − %̂Ŝλ Ŝλ
∂t i~ 2 2
λ
∂ 1 X † 1 † 1 †
%̂ = [Ĥ, %̂] + Ŝλ %̂Ŝλ − Ŝλ Ŝλ %̂ − %̂Ŝλ Ŝλ
∂t i~ 2 2
λ
∂ 1 X † 1 † 1 †
%̂ = [Ĥ, %̂] + Ŝλ %̂Ŝλ − Ŝλ Ŝλ %̂ − %̂Ŝλ Ŝλ
∂t i~ 2 2
λ
Como:
0 0
i Ĥef† (t−t 0 )/~
eL̂0 (t−t ) . . . = e
|
−i Ĥef (t−t
{z
)/~
} . . . |e {z }, L̂1 = Ŝ . . . Ŝ †
Ûef (t,t 0 ) Ûef† (t,t 0 )
|Ψ(t; {tn , . . . , t1 })i = Ûef (t, tn )Ŝ Ûef (tn , tn−1 )Ŝ . . . Ŝ Ûef (t1 , t0 )|Ψ(t0 )i
Trayectorias cuánticas.
Esta solución se puede escribir en una expansión:
∞ Z
X t Z t2
%̂(t) = dtn . . . dt1 eL̂0 (t−tn ) L̂1 eL̂0 (tn −tn−1 ) L̂1 . . . L̂1 eL̂0 (t1 −t0 ) %̂(t0 )
n=0 t0 t0
Como:
0 0
i Ĥef† (t−t 0 )/~
eL̂0 (t−t ) . . . = e
|
−i Ĥef (t−t
{z
)/~
} . . . |e {z }, L̂1 = Ŝ . . . Ŝ †
Ûef (t,t 0 ) Ûef† (t,t 0 )
|Ψ(t; {tn , . . . , t1 })i = Ûef (t, tn )Ŝ Ûef (tn , tn−1 )Ŝ . . . Ŝ Ûef (t1 , t0 )|Ψ(t0 )i
Una trayectoria cuántica.
Trayectora cuantica:
|Ψ(t; {tn , . . . , t1 })i = Ûef (t, tn )Ŝ Ûef (tn , tn−1 )Ŝ . . . Ŝ Ûef (t1 , t0 )|Ψ(t0 )i
promedio estatistico:
∞ Z
X t Z t2
%̂(t) = dtn . . . dt1 |Ψ(t; {tn , . . . , t1 })ihΨ(t; {tn , . . . , t1 })|
n=0 t0 t0
Probabilidades.
Vamos a definir:
P0 (t1 ) = hΨ̃(t1 )|Ψ̃(t1 )i
Poco calculus:
d
Ṗ0 (t1 ) = hΨ(t0 )|Ûef† (t1 , t0 )Ûef (t1 , t0 )|Ψ(t0 )i
dt1
i h † i
= hΨ(t0 )|Ûef† (t1 , t0 ) Ĥef (t1 ) − Ĥef (t1 ) Ûef (t1 , t0 )|Ψ(t0 )i
|~ {z }
=−Ŝ † Ŝ
†
= −hΨ̃(t1 )|Ŝ Ŝ|Ψ̃(t1 )i
Probabilidad para no evento.
Vamos a definir:
P0 (t1 ) = hΨ̃(t1 )|Ψ̃(t1 )i
Poco calculus:
d
Ṗ0 (t1 ) = hΨ(t0 )|Ûef† (t1 , t0 )Ûef (t1 , t0 )|Ψ(t0 )i
dt1
i h † i
= hΨ(t0 )|Ûef† (t1 , t0 ) Ĥef (t1 ) − Ĥef (t1 ) Ûef (t1 , t0 )|Ψ(t0 )i
|~ {z }
=−Ŝ † Ŝ
†
= −hΨ̃(t1 )|Ŝ Ŝ|Ψ̃(t1 )i
Conexion.
Conclusion:
dP0 (t1 )
P(t1 ; {t1 }) = p(t1 ; {t1 })dt1 = − dt1
dt1
Entonces:
Z t1
P0 (t1 ) = 1− dτ p(τ ; {τ }) = Prob. p. no evento en [t0 , t1 ]
t0
| {z }
=Prob. p. evento en [t0 , t1 ]
Conexion.
Conclusion:
dP0 (t1 )
P(t1 ; {t1 }) = p(t1 ; {t1 })dt1 = − dt1
dt1
Entonces:
Z t1
P0 (t1 ) = 1− dτ p(τ ; {τ }) = Prob. p. no evento en [t0 , t1 ]
t0
| {z }
=Prob. p. evento en [t0 , t1 ]
Algoritmo.
|Ψ(t0 )i
tk = t0
1 − P0 (tk +1 ) > R ?
NO SI
Evento al tiempo tk +1 :
|Ψ(tk +1 )i = Ŝ|Ψ̃(tk +1 )i/| . . . |
tk = tk +1
Implementacion.
qt_qtsolve.c
49 if (init) {
50 rnd = rand_shuffle(irnd);
51 init = 0;
52 }
53
54 dt = t2 - t1;
55 assert((dtmin >= 0.0) && (dt >= dtmin));
56 ytmp = malloc(sz * sizeof(complex double));
57 t = t1;
58 min_cnt = 0;
59 ok = 0;
Implementacion.
qt_qtsolve.c
61 do {
62 dt = ((t+dt) > t2) ? t2-t : dt;
63 dtmin = 0.001 * dt;
64 for (i = 0; i < sz; i++)
65 ytmp[i] = y[i];
66 min_cnt += de_solve_cpx(ytmp, sz, t, t+dt, eps, dtmin, derivs);
67 diff_prob = qt_jumpprob(ytmp, sz) - rnd;
68 if (diff_prob > 0.0) /* go back */
69 dt *= 0.5;
70 else { /* go forward, check jump */
71 for (i = 0; i < sz; i++)
72 y[i] = ytmp[i];
73 t += dt;
74 if (fabs(diff_prob) < eps) { /* jump time */
75 rnd = rand_shuffle(irnd);
76 norm = jump(y, t);
77 if (norm > DBL_MIN) {
78 norm = 1.0 / sqrt(norm);
79 for (i = 0; i < sz; i++)
80 y[i] *= norm;
81 }
Implementacion.
qt_qtsolve.c
82 else {
83 free(ytmp);
84 return min_cnt;
85 }
86 }
87 }
88 } while ((t2-t) > DBL_MIN);
89
90 free(ytmp);
91 return min_cnt;
92 }
Resultados.
main_qt_oscidamped.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4 #include <float.h>
5 #include <complex.h>
6
7 #define TRAJ_MAX 1000
8 #define POINTS 1000
9 #define SZ 11
10 #define GAMMA 0.05
11
12 int qt_solve(complex double*, size_t, double, double, double,
13 void (*)(complex double*, complex double*, double),
14 double (*)(complex double*, double), long long int*);
Resultados.
main_qt_oscidamped.c
50 int main(void)
51 {
52 complex double psi[SZ];
53 double t, tmax, tstep, tmp, norm, quanta;
54 int traj, i;
55 long long int irnd;
56 size_t k;
57 double data[POINTS];
58
59 tmax = 100.0;
60 tstep = tmax / POINTS;
61
62 for (i = 0; i < POINTS; i++)
63 data[i] = 0.0;
Resultados.
main_qt_oscidamped.c
10
N=1
0
0 10 20 30 40 50 60 70 80 90 100
Promedio de trayectorias.
10
N=5
0
0 10 20 30 40 50 60 70 80 90 100
Promedio de trayectorias.
10
N = 50
9
0
0 10 20 30 40 50 60 70 80 90 100
Promedio de trayectorias.
10
N = 100
9
0
0 10 20 30 40 50 60 70 80 90 100