Métodos Numéricos en Física

Post on 05-Jan-2017

241 views 0 download

Transcript of Métodos Numéricos en Física

Métodos Numéricos en FísicaFIZ1405

S. Wallentowitz

Facultad de Física, UC

Parte IFIZ1405

Bibliografía.

Programación:

B.W. Kernighan, D.M. RitchieProgramación en C (Addison Wesley)W.H. Press, S.A. Teukolsky, W.T. Vetterling, B.P. FlanneryNumerical Recipes en C2nd ed. (Cambridge University Press)Online: http://www.library.cornell.edu/nr/

Funciones especiales, integrales, etc.:

M. Abramowitz, I.A. StegunHandbook of mathematical functions9th 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.

Determinación de la nota final:

NF = (NT + NE)/2

NT = promedio de las notas de las tareasNE= 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.

Determinación de la nota final:

NF = (NT + NE)/2

NT = promedio de las notas de las tareasNE= nota del examen final

Notas — Alternativa II.

Cada alumno hace una presentación de ca. 30min con data-showsobre un problema de la física completamente resuelto:

Presentación del problema físicoPresentación de la idéa para resolverlo numericamentePresentación del programaPresentación de los resultados y discusión de errores

Requisitos técnicos.

Todos los programas funcionan con un sistema LINUX que contengalos siguentes programas:

GNU C CompilerGNU makeOpcional: doxygen para producir una documentación de losprogramas

Editores posibles:

Todos son posibles, pero por favor con “UNIX carriage return”.GNU EmacsKDE kate (voy a usar este para la clase)

Aviso:Mejor no usar Windows!

Requisitos técnicos.

Todos los programas funcionan con un sistema LINUX que contengalos siguentes programas:

GNU C CompilerGNU makeOpcional: doxygen para producir una documentación de losprogramas

Editores posibles:

Todos son posibles, pero por favor con “UNIX carriage return”.GNU EmacsKDE kate (voy a usar este para la clase)

Aviso:Mejor no usar Windows!

Objectivos.

Darse cuenta de la complejitud de calculos numéricos con elcomputador.Desarollo de un conjunto de programas para una variedad deproblemas físicos.Aprender la programación de un punto de visto científico:

lengua C (ANSI C99).automatisación de la compilación (make).documentación de programas (doxygen).visualisación de datos y resultados (gnuplot, etc.).

Contenido.

1 Introducción2 Ecuaciones diferenciales3 Funciones especiales4 Interpolación5 Integración6 Transformación de Fourier7 Aproximación de Chebyshev8 Números aleatorios9 (Dinámica molecular)10 (Monte-Carlo)

Parte IIIntroducció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

Parece trivial pero no es trivial para el computador.

Implementación en C.1 /*! \file intro_sum1.c */2 #include <stdio.h>3

4 int main (void)5 6 float x;7

8 x = 1.0;9 x = x + 5.0e-8;

10 x += 5.0e-8;11 x += 5.0e-8;12 x += 5.0e-8;13

14 printf("x = %10.8f\n", x);15 return 0;16

main(): función principal del programa.x += a es lo mismo que x = x + a; /* ... */ es uncomentario.printf() es la función declarada en stdio.h para imprimir;%10.8f es el formato para imprimir.

Implementación en C.1 /*! \file intro_sum1.c */2 #include <stdio.h>3

4 int main (void)5 6 float x;7

8 x = 1.0;9 x = x + 5.0e-8;

10 x += 5.0e-8;11 x += 5.0e-8;12 x += 5.0e-8;13

14 printf("x = %10.8f\n", x);15 return 0;16

main(): función principal del programa.x += a es lo mismo que x = x + a; /* ... */ es uncomentario.printf() es la función declarada en stdio.h para imprimir;%10.8f es el formato para imprimir.

Implementación en C.1 /*! \file intro_sum1.c */2 #include <stdio.h>3

4 int main (void)5 6 float x;7

8 x = 1.0;9 x = x + 5.0e-8;

10 x += 5.0e-8;11 x += 5.0e-8;12 x += 5.0e-8;13

14 printf("x = %10.8f\n", x);15 return 0;16

main(): función principal del programa.x += a es lo mismo que x = x + a; /* ... */ es uncomentario.printf() es la función declarada en stdio.h para imprimir;%10.8f es el formato para imprimir.

Implementación en C.1 /*! \file intro_sum1.c */2 #include <stdio.h>3

4 int main (void)5 6 float x;7

8 x = 1.0;9 x = x + 5.0e-8;

10 x += 5.0e-8;11 x += 5.0e-8;12 x += 5.0e-8;13

14 printf("x = %10.8f\n", x);15 return 0;16

main(): función principal del programa.x += a es lo mismo que x = x + a; /* ... */ es uncomentario.printf() es la función declarada en stdio.h para imprimir;%10.8f es el formato para imprimir.

Compilar e ejecutar.

1 En un terminal se compila un programa:

shell> cc -o sum1.bin intro_sum1.c [RETURN]

2 Luego se ejecuta el programa:

shell> ./sum1.bin [RETURN]shell> x = 1.00000000shell>

3 Observación: Resultado no es exactamente correcto.Sale x=1.00000000 pero el resultado correcto es x = 1,00000020

Compilar e ejecutar.

1 En un terminal se compila un programa:

shell> cc -o sum1.bin intro_sum1.c [RETURN]

2 Luego se ejecuta el programa:

shell> ./sum1.bin [RETURN]shell> x = 1.00000000shell>

3 Observación: Resultado no es exactamente correcto.Sale x=1.00000000 pero el resultado correcto es x = 1,00000020

Compilar e ejecutar.

1 En un terminal se compila un programa:

shell> cc -o sum1.bin intro_sum1.c [RETURN]

2 Luego se ejecuta el programa:

shell> ./sum1.bin [RETURN]shell> x = 1.00000000shell>

3 Observación: Resultado no es exactamente correcto.Sale x=1.00000000 pero el resultado correcto es x = 1,00000020

Método más inteligente.

1 /*! \file intro_sum2.c */2 /* First small then large stuff. */3 #include <stdio.h>4

5 int main (void)6 7 float x;8

9 x = 5.0e-8;10 x += 5.0e-8;11 x += 5.0e-8;12 x += 5.0e-8;13 x += 1.0;14

15 printf("x = %10.8f\n", x);16 return 0;17

Resultado es:

shell> cc -o sum2.bin intro_sum2.c [RETURN]shell> ./sum2.bin [RETURN]shell> x = 1.00000024shell>

Representación binaria de un número punto flotante.Estandard IEEE.

x = (sign bit) (mantisa) (exponente)

Sign bit s = 0,1 → ±.Mantisa m son p bits, donde p es la precisión, por ejemplom = 10101 con p = 5.Exponente e de dos bits por ejemplo:

00 → −101 → 010 → +111 → +2

Representación decimal:

x = (−1)s ×(m

2p

)× 2e

= (−1)s ×m × 2e−p

Representación binaria de un número punto flotante.Estandard IEEE.

x = (sign bit) (mantisa) (exponente)

Sign bit s = 0,1 → ±.Mantisa m son p bits, donde p es la precisión, por ejemplom = 10101 con p = 5.Exponente e de dos bits por ejemplo:

00 → −101 → 010 → +111 → +2

Representación decimal:

x = (−1)s ×(m

2p

)× 2e

= (−1)s ×m × 2e−p

Representación binaria de un número punto flotante.Estandard IEEE.

x = (sign bit) (mantisa) (exponente)

Sign bit s = 0,1 → ±.Mantisa m son p bits, donde p es la precisión, por ejemplom = 10101 con p = 5.Exponente e de dos bits por ejemplo:

00 → −101 → 010 → +111 → +2

Representación decimal:

x = (−1)s ×(m

2p

)× 2e

= (−1)s ×m × 2e−p

Representación binaria de un número punto flotante.Estandard IEEE.

x = (sign bit) (mantisa) (exponente)

Sign bit s = 0,1 → ±.Mantisa m son p bits, donde p es la precisión, por ejemplom = 10101 con p = 5.Exponente e de dos bits por ejemplo:

00 → −101 → 010 → +111 → +2

Representación decimal:

x = (−1)s ×(m

2p

)× 2e

= (−1)s ×m × 2e−p

Representación binaria de un número punto flotante.Estandard IEEE.

x = (sign bit) (mantisa) (exponente)

Sign bit s = 0,1 → ±.Mantisa m son p bits, donde p es la precisión, por ejemplom = 10101 con p = 5.Exponente e de dos bits por ejemplo:

00 → −101 → 010 → +111 → +2

Representación decimal:

x = (−1)s ×(m

2p

)× 2e

= (−1)s ×m × 2e−p

Ejemplo.

Una representación de un número punto flotante de 8 bit (1 byte) conprecisión p = 5 y dos bits para el exponente:

x = 01010110

Coresponde a s = 0, m = 10101 (= decimal 21), y e = 10(→ +1)El número decimal es:

x = (−1)s ×m × 2e−p

= (−1)0 × 21× 25−1

= 21/16= 1,3125

Ejemplo.

Una representación de un número punto flotante de 8 bit (1 byte) conprecisión p = 5 y dos bits para el exponente:

x = 01010110

Coresponde a s = 0, m = 10101 (= decimal 21), y e = 10(→ +1)El número decimal es:

x = (−1)s ×m × 2e−p

= (−1)0 × 21× 25−1

= 21/16= 1,3125

Ejemplo.

Una representación de un número punto flotante de 8 bit (1 byte) conprecisión p = 5 y dos bits para el exponente:

x = 01010110

Coresponde a s = 0, m = 10101 (= decimal 21), y e = 10(→ +1)El número decimal es:

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 elexponente (signo es irrelevante):

1 Existe un valor (absoluto) maximal:

x = 0 11111 11 → 3,875

2 Existe un valor (absoluto) minimal diferente de cero:

x = 0 00001 00 → 0,015625

3 Los posibles valores actualmente no son equidistantes en unarepresentación decimal:

0,015625

0 0,015625 0,03125 0,046875 3,75 3,875

0,125

Posibles valores.

Representación de 8 bits con precisión p = 5 y dos bits para elexponente (signo es irrelevante):

1 Existe un valor (absoluto) maximal:

x = 0 11111 11 → 3,875

2 Existe un valor (absoluto) minimal diferente de cero:

x = 0 00001 00 → 0,015625

3 Los posibles valores actualmente no son equidistantes en unarepresentación decimal:

0,015625

0 0,015625 0,03125 0,046875 3,75 3,875

0,125

Posibles valores.

Representación de 8 bits con precisión p = 5 y dos bits para elexponente (signo es irrelevante):

1 Existe un valor (absoluto) maximal:

x = 0 11111 11 → 3,875

2 Existe un valor (absoluto) minimal diferente de cero:

x = 0 00001 00 → 0,015625

3 Los posibles valores actualmente no son equidistantes en unarepresentación decimal:

0,015625

0 0,015625 0,03125 0,046875 3,75 3,875

0,125

Posibles valores.

Representación de 8 bits con precisión p = 5 y dos bits para elexponente (signo es irrelevante):

1 Existe un valor (absoluto) maximal:

x = 0 11111 11 → 3,875

2 Existe un valor (absoluto) minimal diferente de cero:

x = 0 00001 00 → 0,015625

3 Los posibles valores actualmente no son equidistantes en unarepresentación decimal:

0,015625

0 0,015625 0,03125 0,046875 3,75 3,875

0,125

Tipos punto flotante para AMD/Intel.

Tipo en ANSI C float double

# bits 32 64precisión binaria (p) 24 53precisión decimal 6 15val. bin. del exp. −125 . . .128 −1021 . . .1024val. dec. del exp. −37 . . .38 −307 . . .308

valor minimal ≈ 1,18× 10−38 ≈ 2,23× 10−308

valor maximal ≈ 3,40× 1038 ≈ 1,80× 10308

epsilon ≈ 1,19× 10−7 ≈ 2,22× 10−16

Existen también long double y long long double.

Significativo del “epsilon”:Es el valor minimal para que 1.0 + epsilon != 1.0

Entonces es la precisión decimal para valores alrededor de 1,0.

Tipos punto flotante para AMD/Intel.

Tipo en ANSI C float double

# bits 32 64precisión binaria (p) 24 53precisión decimal 6 15val. bin. del exp. −125 . . .128 −1021 . . .1024val. dec. del exp. −37 . . .38 −307 . . .308

valor minimal ≈ 1,18× 10−38 ≈ 2,23× 10−308

valor maximal ≈ 3,40× 1038 ≈ 1,80× 10308

epsilon ≈ 1,19× 10−7 ≈ 2,22× 10−16

Existen también long double y long long double.

Significativo del “epsilon”:Es el valor minimal para que 1.0 + epsilon != 1.0

Entonces es la precisión decimal para valores alrededor de 1,0.

Problemas típicos.

Perdida de precisión:Tiene muchas causas, la más comúna es la combinación denumeros 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, elprocesador continua con números más o menos aleatorios. Saleun 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 denumeros 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, elprocesador continua con números más o menos aleatorios. Saleun 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 denumeros 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, elprocesador continua con números más o menos aleatorios. Saleun 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 denumeros 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, elprocesador continua con números más o menos aleatorios. Saleun mensaje “nan” (not a number) o “inf” (infinity).¿Entonces qué se puede hacer?Cuidarse mucho y obtener suficiente experiencia (trial & error).

Otro ejemplo.

1 /*! \file intro_number.c */2

3 #include <stdio.h>4

5 int main (void)6 7 printf("1.2 = %21.20f\n", 1.2);8 return 0;9

Compilar e ejecutar:

shell> cc -o number.bin intro_number.c [RETURN]shell> ./number.bin [RETURN]shell> 1.2 = 1.19999999999999995559shell>

Números integros.

Tipo integro valor minimal valor maximalint −32767 +32767

long int −2147483647 +2147483647long long int −(263 − 1) 263 − 1unsigned int 0 65535

unsigned long int 0 4294967295unsigned long long int 0 264 − 1

Aparte de eso hay:short int = int

unsigned short int = unsigned int.Otros tipos importantes:

char para letras (−127 . . .+ 127 o 0 . . .255)void para “nada”.

Formatos para imprimir.

1 /*! \file intro_print.c */2 #include <stdio.h>3

4 int main(void)5 6 float x;7 int i;8

9 x = 1.542e-3;10 i = 9845;11 printf("Huhu...some stupid output:\n"12 "x = %f = %e\n"13 "i = %d\n", x, x, i);14 return 0;15

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 IIIEcuaciones Diferenciales

Ecuación diferencial ordinaria.Ecuaciones diferenciales ordinarias del orden 1:

d~x(t)dt

= ~f (~x , t)

Es un sistema de ecuaciones diferenciales acopladas!

Siempre se puede escribir una ecuación diferencial ordinaria enel orden 1:

~x = ~f (~x , ~x , t)

Vamos a definir ~y = ~x :

~x = ~y

~y = ~f (~x , ~y , t)

es lo mismo que:

d~zdt

=ddt

(~x~y

)=

(~y

~f (~x , ~y , t)

)= ~g(~z, t)

Ecuación diferencial ordinaria.Ecuaciones diferenciales ordinarias del orden 1:

d~x(t)dt

= ~f (~x , t)

Es un sistema de ecuaciones diferenciales acopladas!

Siempre se puede escribir una ecuación diferencial ordinaria enel orden 1:

~x = ~f (~x , ~x , t)

Vamos a definir ~y = ~x :

~x = ~y

~y = ~f (~x , ~y , t)

es lo mismo que:

d~zdt

=ddt

(~x~y

)=

(~y

~f (~x , ~y , t)

)= ~g(~z, t)

Ecuación diferencial ordinaria.Ecuaciones diferenciales ordinarias del orden 1:

d~x(t)dt

= ~f (~x , t)

Es un sistema de ecuaciones diferenciales acopladas!

Siempre se puede escribir una ecuación diferencial ordinaria enel orden 1:

~x = ~f (~x , ~x , t)

Vamos a definir ~y = ~x :

~x = ~y

~y = ~f (~x , ~y , t)

es lo mismo que:

d~zdt

=ddt

(~x~y

)=

(~y

~f (~x , ~y , t)

)= ~g(~z, t)

Ecuación diferencial ordinaria.Ecuaciones diferenciales ordinarias del orden 1:

d~x(t)dt

= ~f (~x , t)

Es un sistema de ecuaciones diferenciales acopladas!

Siempre se puede escribir una ecuación diferencial ordinaria enel orden 1:

~x = ~f (~x , ~x , t)

Vamos a definir ~y = ~x :

~x = ~y

~y = ~f (~x , ~y , t)

es lo mismo que:

d~zdt

=ddt

(~x~y

)=

(~y

~f (~x , ~y , t)

)= ~g(~z, t)

Método de Euler.Ahora solo una ecuación diferencial: ~x → x .

Definición de la derivada:

dx(t)dt

= l«ım∆t→0

x(t + ∆t)− x(t)∆t

Con paso ∆t finito:

x(t + ∆t) ≈ x(t) + ∆tdx(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)dt

= l«ım∆t→0

x(t + ∆t)− x(t)∆t

Con paso ∆t finito:

x(t + ∆t) ≈ x(t) + ∆tdx(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.

Según la expansión de Taylor:

xn+1 = x(tn+1) = x(tn) + (tn+1 − tn)dx(t)

dt

∣∣∣∣t=tn

+(tn+1 − tn)2

2!

d2x(t)dt2

∣∣∣∣t=tn

+ . . .

= xn + ∆t f (xn, tn) +O[(∆t)2]

Entonces el error es del orden (∆t)2! Este error no es aceptable!

Error.

Según la expansión de Taylor:

xn+1 = x(tn+1) = x(tn) + (tn+1 − tn)dx(t)

dt

∣∣∣∣t=tn

+(tn+1 − tn)2

2!

d2x(t)dt2

∣∣∣∣t=tn

+ . . .

= xn + ∆t f (xn, tn) +O[(∆t)2]

Entonces el error es del orden (∆t)2! Este error no es aceptable!

Idéa de Euler.

ttn

x

xn

Idéa de Euler.

ttn+1tn

x

xn+1

xn

Idéa de Euler.

ttn+1tn

x

xn+1

xn

Idéa de Euler.

ttn+1tn tn+2

x

xn+1

xn

Idéa de Runge-Kutta.Tomar derivada en la mitad!

t

x

xn

tn+1tn

Idéa de Runge-Kutta.Tomar derivada en la mitad!

t

x

xn

tn+1tn

Idéa de Runge-Kutta.Tomar derivada en la mitad!

t

x

xn

tn+1tn

∆t2

∆t2

Idéa de Runge-Kutta.Tomar derivada en la mitad!

t

x

xn

tn+1tn

∆t2

∆t2

Runge-Kutta de orden 2.

t

x

xn

tn

∆t2

∆t2

tn+1

k1

1 Derivada en el comienzo:

k1 = ∆t f (xn, tn)

2 Derivada en la mitad:

k2 = ∆t f(

xn +k1

2, tn +

∆t2

)3 Runge-Kutta del orden 2:

xn+1 = xn + k2 +O[(∆t)3]

Runge-Kutta de orden 2.

t

x

xn

tn

∆t2

∆t2

tn+1

k1

1 Derivada en el comienzo:

k1 = ∆t f (xn, tn)

2 Derivada en la mitad:

k2 = ∆t f(

xn +k1

2, tn +

∆t2

)3 Runge-Kutta del orden 2:

xn+1 = xn + k2 +O[(∆t)3]

Runge-Kutta de orden 2.

t

x

xn

tn

∆t2

∆t2

tn+1

k1

1 Derivada en el comienzo:

k1 = ∆t f (xn, tn)

2 Derivada en la mitad:

k2 = ∆t f(

xn +k1

2, tn +

∆t2

)3 Runge-Kutta del orden 2:

xn+1 = xn + k2 +O[(∆t)3]

Runge-Kutta de orden 2.

t

x

xn

tn

∆t2

∆t2

tn+1

k1

1 Derivada en el comienzo:

k1 = ∆t f (xn, tn)

2 Derivada en la mitad:

k2 = ∆t f(

xn +k1

2, tn +

∆t2

)3 Runge-Kutta del orden 2:

xn+1 = xn + k2 +O[(∆t)3]

Evaluación del error.

Runge-Kutta del orden 2 dice:

xn+1 = xn + ∆t f[xn +

∆t2

f (xn, tn), tn +∆t2

]Expansión de Taylor con respecto al tiempo:

≈ xn + ∆t

f[xn +

∆t2

f (xn, tn), tn

]+

∆t2

df[xn + ∆t

2 f (xn, tn), t]

dt

∣∣∣∣∣t=tn

+O[(∆t)2]

≈ xn + ∆t

dx(t)

dt+

∆t2

d2x(t)dt2

∣∣∣∣t=tn

+O[(∆t)2]

= xn + ∆tdx(t)

dt

∣∣∣∣t=tn

+(∆t)2

2!

d2x(t)dt2

∣∣∣∣t=tn

+O[(∆t)3]

Evaluación del error.

Runge-Kutta del orden 2 dice:

xn+1 = xn + ∆t f[xn +

∆t2

f (xn, tn), tn +∆t2

]Expansión de Taylor con respecto al tiempo:

≈ xn + ∆t

f[xn +

∆t2

f (xn, tn), tn

]+

∆t2

df[xn + ∆t

2 f (xn, tn), t]

dt

∣∣∣∣∣t=tn

+O[(∆t)2]

≈ xn + ∆t

dx(t)

dt+

∆t2

d2x(t)dt2

∣∣∣∣t=tn

+O[(∆t)2]

= xn + ∆tdx(t)

dt

∣∣∣∣t=tn

+(∆t)2

2!

d2x(t)dt2

∣∣∣∣t=tn

+O[(∆t)3]

RK2.Runge-Kutta del orden 2.

RK2:Calcular coeficientes:

k1 = ∆t f (xn, tn)

k2 = ∆t f(

xn +k1

2, tn +

∆t2

)Aproximación RK2:

xn+1 = xn + k2 +O[(∆t)3]

Necesita 2 evaluaciones de la función f (x , t)!

RK4.Runge-Kutta del orden 4.

t

x

xn

tn tn+1

k1

1

RK4.Runge-Kutta del orden 4.

t

x

xn

tn tn+1

1

2k2

RK4.Runge-Kutta del orden 4.

t

x

xn

tn tn+1

1

k32

3

RK4.Runge-Kutta del orden 4.

t

x

xn

tn+1

1

2

3k4

tn

En detalle.

Secuencia de la calculación:

1 k1 = ∆t f (xn, tn)2 k2 = ∆t f (xn + k1

2 , tn + ∆t2 )

3 k3 = ∆t f (xn + k22 , tn + ∆t

2 )

4 k4 = ∆t f (xn + k3, tn + ∆t)

”Promediar” las derivadas: RK4

xn+1 = xn +16

(k1 + 2k2 + 2k3 + k4) +O[(∆t)5]

Se necesitan 4 evaluaciones de f (x , t)!

En detalle.

Secuencia de la calculación:

1 k1 = ∆t f (xn, tn)2 k2 = ∆t f (xn + k1

2 , tn + ∆t2 )

3 k3 = ∆t f (xn + k22 , tn + ∆t

2 )

4 k4 = ∆t f (xn + k3, tn + ∆t)

”Promediar” las derivadas: RK4

xn+1 = xn +16

(k1 + 2k2 + 2k3 + k4) +O[(∆t)5]

Se necesitan 4 evaluaciones de f (x , t)!

En detalle.

Secuencia de la calculación:

1 k1 = ∆t f (xn, tn)2 k2 = ∆t f (xn + k1

2 , tn + ∆t2 )

3 k3 = ∆t f (xn + k22 , tn + ∆t

2 )

4 k4 = ∆t f (xn + k3, tn + ∆t)

”Promediar” las derivadas: RK4

xn+1 = xn +16

(k1 + 2k2 + 2k3 + k4) +O[(∆t)5]

Se necesitan 4 evaluaciones de f (x , t)!

En detalle.

Secuencia de la calculación:

1 k1 = ∆t f (xn, tn)2 k2 = ∆t f (xn + k1

2 , tn + ∆t2 )

3 k3 = ∆t f (xn + k22 , tn + ∆t

2 )

4 k4 = ∆t f (xn + k3, tn + ∆t)

”Promediar” las derivadas: RK4

xn+1 = xn +16

(k1 + 2k2 + 2k3 + k4) +O[(∆t)5]

Se necesitan 4 evaluaciones de f (x , t)!

En detalle.

Secuencia de la calculación:

1 k1 = ∆t f (xn, tn)2 k2 = ∆t f (xn + k1

2 , tn + ∆t2 )

3 k3 = ∆t f (xn + k22 , tn + ∆t

2 )

4 k4 = ∆t f (xn + k3, tn + ∆t)

”Promediar” las derivadas: RK4

xn+1 = xn +16

(k1 + 2k2 + 2k3 + k4) +O[(∆t)5]

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,1k1, tn + a2∆t)

...

kM = ∆t f (xn +M−1∑m=1

bM,mkm, tn + aM∆t)

xn+1 = xn +M∑

m=1

cmkm +O[(∆t)N+1] , M∑

m=1

cm = 1

Solo para N ≤ 4 :M = N que significa N evaluaciones de lafunción f (x , t).Para N > 4: M > N y hay varios posibilidades para loscoeficientes bm,n, am, cm!Elección de los coeficientes determina el orden del error N + 1.

Runge-Kutta del orden N en general.

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

kM = ∆t f (xn +M−1∑m=1

bM,mkm, tn + aM∆t)

xn+1 = xn +M∑

m=1

cmkm +O[(∆t)N+1] , M∑

m=1

cm = 1

Solo para N ≤ 4 :M = N que significa N evaluaciones de lafunción f (x , t).Para N > 4: M > N y hay varios posibilidades para loscoeficientes bm,n, am, cm!Elección de los coeficientes determina el orden del error N + 1.

Runge-Kutta del orden N en general.

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

kM = ∆t f (xn +M−1∑m=1

bM,mkm, tn + aM∆t)

xn+1 = xn +M∑

m=1

cmkm +O[(∆t)N+1] , M∑

m=1

cm = 1

Solo para N ≤ 4 :M = N que significa N evaluaciones de lafunción f (x , t).Para N > 4: M > N y hay varios posibilidades para loscoeficientes bm,n, am, cm!Elección de los coeficientes determina el orden del error N + 1.

Runge-Kutta del orden N en general.

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

kM = ∆t f (xn +M−1∑m=1

bM,mkm, tn + aM∆t)

xn+1 = xn +M∑

m=1

cmkm +O[(∆t)N+1] , M∑

m=1

cm = 1

Solo para N ≤ 4 :M = N que significa N evaluaciones de lafunción f (x , t).Para N > 4: M > N y hay varios posibilidades para loscoeficientes bm,n, am, cm!Elección de los coeficientes determina el orden del error N + 1.

Control del error.Idéa simple.

1 Usar Runge-Kutta del orden 4 con paso ∆t :

x (1)(t + ∆t) = x(t + ∆t) +O[(∆t)5]

2 Usar en secuencia dos veces Runge-Kutta del orden 4 conpasos ∆t/2:

x (2)(t + ∆t) = x(t + ∆t) + 2×O[(∆t/2)5]

3 Comparar las soluciones:

error =∣∣∣x (1)(t + ∆t)− x (2)(t + ∆t)

∣∣∣ = O[(∆t)5]

4 “Optimizar”:

x (opt)(t + ∆t) =115

[16 x (2)(t + ∆t)− x (1)(t + ∆t)

]+O

[(∆t)6]

Control del error.Idéa simple.

1 Usar Runge-Kutta del orden 4 con paso ∆t :

x (1)(t + ∆t) = x(t + ∆t) +O[(∆t)5]

2 Usar en secuencia dos veces Runge-Kutta del orden 4 conpasos ∆t/2:

x (2)(t + ∆t) = x(t + ∆t) + 2×O[(∆t/2)5]

3 Comparar las soluciones:

error =∣∣∣x (1)(t + ∆t)− x (2)(t + ∆t)

∣∣∣ = O[(∆t)5]

4 “Optimizar”:

x (opt)(t + ∆t) =115

[16 x (2)(t + ∆t)− x (1)(t + ∆t)

]+O

[(∆t)6]

Control del error.Idéa simple.

1 Usar Runge-Kutta del orden 4 con paso ∆t :

x (1)(t + ∆t) = x(t + ∆t) +O[(∆t)5]

2 Usar en secuencia dos veces Runge-Kutta del orden 4 conpasos ∆t/2:

x (2)(t + ∆t) = x(t + ∆t) + 2×O[(∆t/2)5]

3 Comparar las soluciones:

error =∣∣∣x (1)(t + ∆t)− x (2)(t + ∆t)

∣∣∣ = O[(∆t)5]

4 “Optimizar”:

x (opt)(t + ∆t) =115

[16 x (2)(t + ∆t)− x (1)(t + ∆t)

]+O

[(∆t)6]

Control del error.Idéa simple.

1 Usar Runge-Kutta del orden 4 con paso ∆t :

x (1)(t + ∆t) = x(t + ∆t) +O[(∆t)5]

2 Usar en secuencia dos veces Runge-Kutta del orden 4 conpasos ∆t/2:

x (2)(t + ∆t) = x(t + ∆t) + 2×O[(∆t/2)5]

3 Comparar las soluciones:

error =∣∣∣x (1)(t + ∆t)− x (2)(t + ∆t)

∣∣∣ = O[(∆t)5]

4 “Optimizar”:

x (opt)(t + ∆t) =115

[16 x (2)(t + ∆t)− x (1)(t + ∆t)

]+O

[(∆t)6]

Control adaptivo de pasos.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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.

Fijar un error relativo maximal “eps” y un paso inicial ∆t .

1 Calcular paso con ∆t dado:Calcular una solución x (opt)(t + ∆t).Calcular su estimación de error “error”.

2 Decisión sobre el paso ∆t a través de la condición:

error∣∣x (opt)(t + ∆t)∣∣ ≤ eps

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?

Vamos a definir el factor:

R =error

eps×∣∣x (opt)(t + ∆t)

∣∣R ≤ 1 para un paso aceptable y R > 1 para un paso noaceptable.El paso ideal ∆tideal hubiera producido un Rideal = 1, es decirtenemos el error maximal permisible.Para un paso ∆t la estimación del error es: error ∝ (∆t)5 yentonces

RRideal

= R =

(∆t

∆tideal

)5

Resulta el paso ideal:

∆tideal = ∆t ×(

1R

) 15

Adapción de pasos.¿Cómo calcular los nuevos pasos?

Vamos a definir el factor:

R =error

eps×∣∣x (opt)(t + ∆t)

∣∣R ≤ 1 para un paso aceptable y R > 1 para un paso noaceptable.El paso ideal ∆tideal hubiera producido un Rideal = 1, es decirtenemos el error maximal permisible.Para un paso ∆t la estimación del error es: error ∝ (∆t)5 yentonces

RRideal

= R =

(∆t

∆tideal

)5

Resulta el paso ideal:

∆tideal = ∆t ×(

1R

) 15

Adapción de pasos.¿Cómo calcular los nuevos pasos?

Vamos a definir el factor:

R =error

eps×∣∣x (opt)(t + ∆t)

∣∣R ≤ 1 para un paso aceptable y R > 1 para un paso noaceptable.El paso ideal ∆tideal hubiera producido un Rideal = 1, es decirtenemos el error maximal permisible.Para un paso ∆t la estimación del error es: error ∝ (∆t)5 yentonces

RRideal

= R =

(∆t

∆tideal

)5

Resulta el paso ideal:

∆tideal = ∆t ×(

1R

) 15

Adapción de pasos.¿Cómo calcular los nuevos pasos?

Vamos a definir el factor:

R =error

eps×∣∣x (opt)(t + ∆t)

∣∣R ≤ 1 para un paso aceptable y R > 1 para un paso noaceptable.El paso ideal ∆tideal hubiera producido un Rideal = 1, es decirtenemos el error maximal permisible.Para un paso ∆t la estimación del error es: error ∝ (∆t)5 yentonces

RRideal

= R =

(∆t

∆tideal

)5

Resulta el paso ideal:

∆tideal = ∆t ×(

1R

) 15

Regla para paso adaptivo.

Paso adaptivo para RK4 + 2× RK4/2:

∆tnew = ∆told ×(

1R

) 15

R ≤ 1: Solución es aceptable, se puede continuar con:

∆tnew = ∆told ×(

1R

) 15

≥ ∆told

R > 1: Solución no es aceptable, hay que empezar de nuevocon:

∆tnew = ∆told ×(

1R

) 15

< ∆told

Regla para paso adaptivo.

Paso adaptivo para RK4 + 2× RK4/2:

∆tnew = ∆told ×(

1R

) 15

R ≤ 1: Solución es aceptable, se puede continuar con:

∆tnew = ∆told ×(

1R

) 15

≥ ∆told

R > 1: Solución no es aceptable, hay que empezar de nuevocon:

∆tnew = ∆told ×(

1R

) 15

< ∆told

Regla para paso adaptivo.

Paso adaptivo para RK4 + 2× RK4/2:

∆tnew = ∆told ×(

1R

) 15

R ≤ 1: Solución es aceptable, se puede continuar con:

∆tnew = ∆told ×(

1R

) 15

≥ ∆told

R > 1: Solución no es aceptable, hay que empezar de nuevocon:

∆tnew = ∆told ×(

1R

) 15

< ∆told

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Problema: Es lento!

De un xn al tiempo tn vamos a empezar a calcular:RK4 de tn hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).RK4 de tn hasta tn + ∆t

2 : 4 evaluaciones de f (x , t).RK4 de tn + ∆t

2 hasta tn+1 = tn + ∆t : 4 evaluaciones de f (x , t).

Son 12 evaluaciones de f (x , t).Se puede ahorar una evaluación común en el punto (xn, tn).

Problema:Se necesitan 11 evaluaciones de la función f (x , t) para un pasoadaptivo (exitoso)!

Runge-Kutta embedded.Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.

Evaluar 6 veces la función f (x , t):

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

k6 = ∆t f (xn +5∑

m=1

b6,mkm, tn + a6∆t)

Calcular dos soluciones:

x (5)n+1 = xn +

6∑m=1

cmkm +O[(∆t)6]

x (4)n+1 = xn +

6∑m=1

dmkm +O[(∆t)5]

Estimación del error: error = |x (5)n+1 − x (4)

n+1| ∝ (∆t)5

Runge-Kutta embedded.Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.

Evaluar 6 veces la función f (x , t):

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

k6 = ∆t f (xn +5∑

m=1

b6,mkm, tn + a6∆t)

Calcular dos soluciones:

x (5)n+1 = xn +

6∑m=1

cmkm +O[(∆t)6]

x (4)n+1 = xn +

6∑m=1

dmkm +O[(∆t)5]

Estimación del error: error = |x (5)n+1 − x (4)

n+1| ∝ (∆t)5

Runge-Kutta embedded.Idéa de Fehlberg: Comparar RK4 con RK5 en manera eficiente.

Evaluar 6 veces la función f (x , t):

k1 = ∆t f (xn, tn)k2 = ∆t f (xn + b2,1k1, tn + a2∆t)

...

k6 = ∆t f (xn +5∑

m=1

b6,mkm, tn + a6∆t)

Calcular dos soluciones:

x (5)n+1 = xn +

6∑m=1

cmkm +O[(∆t)6]

x (4)n+1 = xn +

6∑m=1

dmkm +O[(∆t)5]

Estimación del error: error = |x (5)n+1 − x (4)

n+1| ∝ (∆t)5

Coeficientes de Cash-Karp.

~a =

1531035178

,~~b =

15 340

940

310 − 9

1065

− 1154

52 − 70

273527

163155296

175512

57513824

44275110592

2534096

~c =

373780

2506211255940

5121771

, ~d =

282527648

018575483841352555296

27714336

14

Implementación.de_rkembedded.c

1 /*! \file de_rkembedded.c */2 #include <math.h>3 #include <float.h>4 #include <stdlib.h>5 #include <complex.h>6 /* Cash-Karp constants: */7 static const double a2 = 0.2, a3 = 0.3, a4 = 0.6,8 a5 = 1.0, a6 = 0.875;9 static const double b21 = 0.2, b31 = 3.0/40.0,

10 b32 = 9.0/40.0, b41 = 0.3, b42 = -0.9, b43 = 1.2,11 b51 = -11.0/54.0, b52=2.5, b53 = -70.0/27.0,12 b54 = 35.0/27.0, b61 = 1631.0/55296.0,13 b62 = 175.0/512.0, b63 = 575.0/13824.0,14 b64 = 44275.0/110592.0, b65 = 253.0/4096.0;15 static const double c1 = 37.0/378.0, c3 = 250.0/621.0,16 c4 = 125.0/594.0, c6 = 512.0/1771.0;17 static const double dc1 = 37.0/378.0 - 2825.0/27648.0,18 dc3 = 250.0/621.0 - 18575.0/48384.0,19 dc4 = 125.0/594.0 - 13525.0/55296.0,20 dc5 = -277.0/14336.0,21 dc6 = 512.0/1771.0 - 0.25;

Implementación.de_rkembedded.c

23 /*! Given values for sz variables x[0..sz-1] known at x,24 use the fifth-order Cash-Karp Runge-Kutta method to25 advance the solution over an interval dt and return26 the incremented variables as xout[0..sz-1]. Also return27 an estimate of the maximal relative error in xout using28 the embedded fourth-order method. The user supplies29 the routine f(dxdt, x, t), which returns derivatives30 dx/dt at t. */31 double rk_embedded(double *x, double t, size_t sz, double dt,32 double *xout,33 void (*f)(double*, double*, double))34 35 int i;36 double *k1, *k2, *k3, *k4, *k5, *k6;37 double err_max, err_tmp;38

39 k1 = malloc(sz * sizeof(double));40 k2 = malloc(sz * sizeof(double));41 k3 = malloc(sz * sizeof(double));42 k4 = malloc(sz * sizeof(double));43 k5 = malloc(sz * sizeof(double));44 k6 = malloc(sz * sizeof(double));

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

66 for (i = 0; i < sz; i++)67 xout[i] = x[i] + dt * (b61 * k1[i] + b62 * k2[i]68 + b63 * k3[i] + b64 * k4[i] + b65 * k5[i]);69 f(k6, xout, t + a6 * dt);70

71 err_max = 0.0;72 for (i = 0; i < sz; i++) 73 xout[i] = x[i] + dt * (c1 * k1[i] + c3 * k3[i]74 + c4 * k4[i] + c6 * k6[i]);75 err_tmp = fabs(dt * (dc1 * k1[i] + dc3 * k3[i]76 + dc4 * k4[i] + dc5 * k5[i] + dc6 * k6[i]))77 / (fabs(xout[i]) + DBL_MIN);78 err_max = (err_max > err_tmp) ? err_max : err_tmp;79 80

81 free(k1);82 free(k2);83 free(k3);84 free(k4);85 free(k5);86 free(k6);87 return err_max;88

Implementación.de_rkembedded.c

91 /*! Given values for sz variables x[0..sz-1] known at x,92 use the fifth-order Cash-Karp Runge-Kutta method to93 advance the solution over an interval dt and return94 the incremented variables as xout[0..sz-1]. Also return95 an estimate of the maximal relative error in xout using96 the embedded fourth-order method. The user supplies97 the routine f(dxdt, x, t), which returns derivatives98 dx/dt at t. Complex version. */99 double rk_embedded_cpx(complex double *x, double t, size_t sz,

100 double dt, complex double *xout,101 void (*f)(complex double*, complex double*, double))102 103 int i;104 complex double *k1, *k2, *k3, *k4, *k5, *k6;105 double err_max, err_tmp;106

107 k1 = malloc(sz * sizeof(complex double));108 k2 = malloc(sz * sizeof(complex double));109 k3 = malloc(sz * sizeof(complex double));110 k4 = malloc(sz * sizeof(complex double));111 k5 = malloc(sz * sizeof(complex double));112 k6 = malloc(sz * sizeof(complex double));

Implementación.de_rkembedded.c

114 f(k1, x, t);115

116 for (i = 0; i < sz; i++)117 xout[i] = x[i] + b21 * dt * k1[i];118 f(k2, xout, t + a2 * dt);119

120 for (i = 0; i < sz; i++)121 xout[i] = x[i] + dt * (b31 * k1[i] + b32 * k2[i]);122 f(k3, xout, t + a3 * dt);123

124 for (i = 0; i < sz; i++)125 xout[i] = x[i] + dt * (b41 * k1[i] + b42 * k2[i]126 + b43 * k3[i]);127 f(k4, xout, t + a4 * dt);128

129 for (i = 0; i < sz; i++)130 xout[i] = x[i] + dt * (b51 * k1[i] + b52 * k2[i]131 + b53 * k3[i] + b54 * k4[i]);132 f(k5, xout, t + a5 * dt);

Implementación.de_rkembedded.c

134 for (i = 0; i < sz; i++)135 xout[i] = x[i] + dt * (b61 * k1[i] + b62 * k2[i]136 + b63 * k3[i] + b64 * k4[i] + b65 * k5[i]);137 f(k6, xout, t + a6 * dt);138

139 err_max = 0.0;140 for (i = 0; i < sz; i++) 141 xout[i] = x[i] + dt * (c1 * k1[i] + c3 * k3[i]142 + c4 * k4[i] + c6 * k6[i]);143 err_tmp = cabs(dt * (dc1 * k1[i] + dc3 * k3[i]144 + dc4 * k4[i] + dc5 * k5[i] + dc6 * k6[i]))145 / (cabs(xout[i]) + DBL_MIN);146 err_max = (err_max > err_tmp) ? err_max : err_tmp;147 148

149 free(k1);150 free(k2);151 free(k3);152 free(k4);153 free(k5);154 free(k6);155 return err_max;156

Implementación del control adaptivo.de_solve.c

1 /*! \file de_solve.c */2

3 #include <stdlib.h>4 #include <assert.h>5 #include <math.h>6 #include <float.h>7 #include <complex.h>8

9 #define SAFETY_FACTOR 0.910

11 /*! Solves an ODE using adaptive stepsizes with the embedded RK12 method. Integrate starting values y[0..sz-1] from t1 to t213 with (relative) accuracy eps. dtmin is the minimum allowed14 stepsize (can be zero). y[..] is replaced by values at the15 end of the integration interval. "f()" is the user-supplied16 routine for calculating the right-hand side derivative. */17 int de_solve(double *y, size_t sz, double t1, double t2,18 double eps, double dtmin,19 void (*f)(double*, double*, double))20 21 double rk_embedded(double*, double, size_t, double, double*,22 void (*)(double*, double*, double));

Implementación del control adaptivo.de_solve.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

57 /*! Solves an ODE using adaptive stepsizes with the embedded RK58 method. Integrate starting values y[0..sz-1] from t1 to t259 with (relative) accuracy eps. dtmin is the minimum allowed60 stepsize (can be zero). y[..] is replaced by values at the61 end of the integration interval. "f()" is the user-supplied62 routine for calculating the right-hand side derivative.63 Complex version. */64 int de_solve_cpx(complex double *y, size_t sz, double t1,65 double t2, double eps, double dtmin,66 void (*f)(complex double*, complex double*,67 double))68 69 double rk_embedded_cpx(complex double*, double, size_t,70 double, complex double*,71 void (*)(complex double*, complex double*, double));72 size_t i;73 double t, dt, err;74 complex double *ytmp;75 int min_cnt;

2 osciladores armónicos acoplados.

m2

m1

ω2, γ2

ω1, γ1

k12

Ecuaciones de movimiento:

dp1

dt= m1

d2x1

dt2 = −k1x1 −m1γ1x1 + k12x2

dp2

dt= m2

d2x2

dt2 = −k2x2 −m2γ2x2 + k12x1

Tiempo sin unidad.

1 Las frecuencies de los osciladores (sin relajación) son

ωi =√

ki/mi = [rad/s] (i = 1,2)

2 Usamos la frecuencia ω0 ≈ ω1, ω2, γ1, γ2 como referencia paradefinir un tiempo sin dimension:

τ = ω0t = [rad]

3 Las ecuaciones de movimiento salen como (x = dx/dτ):

x1 = −ω′21 x1 − γ′1x1 + κ′1x2

x2 = −ω′22 x2 − γ′2x2 + κ′2x1

donde: ω′i = ωi/ω0, γ′i = γi/ω0 y κ′i = (Ωi/ω0)2 con Ωi =

√k12/mi .

Tiempo sin unidad.

1 Las frecuencies de los osciladores (sin relajación) son

ωi =√

ki/mi = [rad/s] (i = 1,2)

2 Usamos la frecuencia ω0 ≈ ω1, ω2, γ1, γ2 como referencia paradefinir un tiempo sin dimension:

τ = ω0t = [rad]

3 Las ecuaciones de movimiento salen como (x = dx/dτ):

x1 = −ω′21 x1 − γ′1x1 + κ′1x2

x2 = −ω′22 x2 − γ′2x2 + κ′2x1

donde: ω′i = ωi/ω0, γ′i = γi/ω0 y κ′i = (Ωi/ω0)2 con Ωi =

√k12/mi .

Tiempo sin unidad.

1 Las frecuencies de los osciladores (sin relajación) son

ωi =√

ki/mi = [rad/s] (i = 1,2)

2 Usamos la frecuencia ω0 ≈ ω1, ω2, γ1, γ2 como referencia paradefinir un tiempo sin dimension:

τ = ω0t = [rad]

3 Las ecuaciones de movimiento salen como (x = dx/dτ):

x1 = −ω′21 x1 − γ′1x1 + κ′1x2

x2 = −ω′22 x2 − γ′2x2 + κ′2x1

donde: ω′i = ωi/ω0, γ′i = γi/ω0 y κ′i = (Ωi/ω0)2 con Ωi =

√k12/mi .

Posición sin dimension.

1 Usamos una unidad de posición ∆x0:

xi = ∆x0qi (i = 1,2)

2 Salen ecuaciones de movimiento:

q1 = −ω′21 q1 − γ′1q1 + κ′1q2

q2 = −ω′22 q2 − γ′2q2 + κ′2q1

Posición sin dimension.

1 Usamos una unidad de posición ∆x0:

xi = ∆x0qi (i = 1,2)

2 Salen ecuaciones de movimiento:

q1 = −ω′21 q1 − γ′1q1 + κ′1q2

q2 = −ω′22 q2 − γ′2q2 + κ′2q1

Ecuación diferencial del orden 1.

Definimos ki = qi entonces sale sistema de ecuacionesdiferenciales:

q1

k1q2

k2

=

0 1 0 0

−ω′21 −γ′1 κ′1 00 0 0 1κ′2 0 −ω′22 −γ′2

·

q1k1q2k2

Con valores iniciales:

q1(t)k1(t)q2(t)k2(t)

t=0

=

q1(0)q2(0)q2(0)q2(0)

Ecuación diferencial del orden 1.

Definimos ki = qi entonces sale sistema de ecuacionesdiferenciales:

q1

k1q2

k2

=

0 1 0 0

−ω′21 −γ′1 κ′1 00 0 0 1κ′2 0 −ω′22 −γ′2

·

q1k1q2k2

Con valores iniciales:

q1(t)k1(t)q2(t)k2(t)

t=0

=

q1(0)q2(0)q2(0)q2(0)

Implementación.main_de_cho2.c

1 #include <stdlib.h>2 #include <stdio.h>3 #include <math.h>4

5 #define SZ 46 #define GAMMA1 0.17 #define OMEGA1 1.08 #define X_INI1 1.09 #define P_INI1 0.0

10 #define GAMMA2 0.111 #define OMEGA2 8.012 #define X_INI2 1.013 #define P_INI2 0.014 #define KAPPA1 1.015 #define KAPPA2 0.0516 #define OMEGA1SQR (OMEGA1 * OMEGA1)17 #define OMEGA2SQR (OMEGA2 * OMEGA2)

Implementación.main_de_cho2.c

19 int de_solve(double*, size_t, double, double, double, double,20 void (*)(double*, double*, double));21

22 void f(double *dxdt, double *x, double t)23 24 /* 2 coupled, damped harmonic oscillators */25 dxdt[0] = x[1];26 dxdt[1] = - OMEGA1SQR * x[0] - GAMMA1 * x[1] + KAPPA1 * x[2];27 dxdt[2] = x[3];28 dxdt[3] = KAPPA2 * x[0] - OMEGA2SQR * x[2] - GAMMA2 * x[3];29

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.2

−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 0.2 0.4 0.6 0.8 1

k 1

q1

Oscilador 1

Resultados.

−8

−6

−4

−2

0

2

4

6

8

−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1q2

k 2

Oscilador 2

Molecula en campo eléctrico.

y

ϑ

ϕ

z

x

E

Ecuaciones de movimiento.

Energía potencial en el campo eléctrico E :

V (ϑ) = −dE cosϑ− E2∆α

2cos2 ϑ

donde d = momento dipolar eléctrico permanente,∆α = α‖ − α⊥ =polarisabilidad anisotropica.Constante de movimiento (Θ = momento inercial):

Lz = Θdϕdt

sin2 ϑ

Ecuación de movimiento (conservación de energía):

Θd2ϑ

dt2 −L2

z

Θcotϑ+

∂V (ϑ)

∂ϑ= 0

Ecuaciones de movimiento.

Energía potencial en el campo eléctrico E :

V (ϑ) = −dE cosϑ− E2∆α

2cos2 ϑ

donde d = momento dipolar eléctrico permanente,∆α = α‖ − α⊥ =polarisabilidad anisotropica.Constante de movimiento (Θ = momento inercial):

Lz = Θdϕdt

sin2 ϑ

Ecuación de movimiento (conservación de energía):

Θd2ϑ

dt2 −L2

z

Θcotϑ+

∂V (ϑ)

∂ϑ= 0

Ecuaciones de movimiento.

Energía potencial en el campo eléctrico E :

V (ϑ) = −dE cosϑ− E2∆α

2cos2 ϑ

donde d = momento dipolar eléctrico permanente,∆α = α‖ − α⊥ =polarisabilidad anisotropica.Constante de movimiento (Θ = momento inercial):

Lz = Θdϕdt

sin2 ϑ

Ecuación de movimiento (conservación de energía):

Θd2ϑ

dt2 −L2

z

Θcotϑ+

∂V (ϑ)

∂ϑ= 0

Tiempo sin dimensión.

1 Usamos τ = ω0t con alguna frecuencia ω0:

Lz = Θω0dϕdτ

sin2 ϑ = Θω0ϕ sin2 ϑ

2 Definimos una constante

a =Lz

Θω0= ϕ(0) sin2 ϑ(0)

Entonces la ecuación diferencial para ϕ es:

ϕ =a

sin2 ϑ

3 La ecuación diferencial para ϑ sale como:

ϑ = a2 cotϑ− b1 sinϑ− b2 cosϑ sinϑ

donde: b1 = dE/(Θω20), b2 = ∆αE2/(Θω2

0).

Tiempo sin dimensión.

1 Usamos τ = ω0t con alguna frecuencia ω0:

Lz = Θω0dϕdτ

sin2 ϑ = Θω0ϕ sin2 ϑ

2 Definimos una constante

a =Lz

Θω0= ϕ(0) sin2 ϑ(0)

Entonces la ecuación diferencial para ϕ es:

ϕ =a

sin2 ϑ

3 La ecuación diferencial para ϑ sale como:

ϑ = a2 cotϑ− b1 sinϑ− b2 cosϑ sinϑ

donde: b1 = dE/(Θω20), b2 = ∆αE2/(Θω2

0).

Tiempo sin dimensión.

1 Usamos τ = ω0t con alguna frecuencia ω0:

Lz = Θω0dϕdτ

sin2 ϑ = Θω0ϕ sin2 ϑ

2 Definimos una constante

a =Lz

Θω0= ϕ(0) sin2 ϑ(0)

Entonces la ecuación diferencial para ϕ es:

ϕ =a

sin2 ϑ

3 La ecuación diferencial para ϑ sale como:

ϑ = a2 cotϑ− b1 sinϑ− b2 cosϑ sinϑ

donde: b1 = dE/(Θω20), b2 = ∆αE2/(Θω2

0).

Molecula homonuclear.Ejemplos: Rb2, N2, K2, etc.

No hay dípolo eléctrico permanente d = 0!Ecuaciones diferenciales:

ϕ(τ) = a sin−2[ϑ(τ)]

ϑ(τ) = κ(τ)

κ(τ) = a2 cot[ϑ(τ)]− b cos[ϑ(τ)] sin[ϑ(τ)]

donde [ω0 = Lz/(Θa)]:

b = b2 =∆αE2

Θω20

= a2 ∆αE2

L2z/Θ

= a2(

erg.potencialerg.cinetica

)Condiciones iniciales: Dado ϕ(0), ϕ(0), ϑ(0), ϑ(0) se puedeobtener

a = ϕ(0) sin2[ϑ(0)]

Queda solo un parametro libre: b = a2 × razn.

Molecula homonuclear.Ejemplos: Rb2, N2, K2, etc.

No hay dípolo eléctrico permanente d = 0!Ecuaciones diferenciales:

ϕ(τ) = a sin−2[ϑ(τ)]

ϑ(τ) = κ(τ)

κ(τ) = a2 cot[ϑ(τ)]− b cos[ϑ(τ)] sin[ϑ(τ)]

donde [ω0 = Lz/(Θa)]:

b = b2 =∆αE2

Θω20

= a2 ∆αE2

L2z/Θ

= a2(

erg.potencialerg.cinetica

)Condiciones iniciales: Dado ϕ(0), ϕ(0), ϑ(0), ϑ(0) se puedeobtener

a = ϕ(0) sin2[ϑ(0)]

Queda solo un parametro libre: b = a2 × razn.

Molecula homonuclear.Ejemplos: Rb2, N2, K2, etc.

No hay dípolo eléctrico permanente d = 0!Ecuaciones diferenciales:

ϕ(τ) = a sin−2[ϑ(τ)]

ϑ(τ) = κ(τ)

κ(τ) = a2 cot[ϑ(τ)]− b cos[ϑ(τ)] sin[ϑ(τ)]

donde [ω0 = Lz/(Θa)]:

b = b2 =∆αE2

Θω20

= a2 ∆αE2

L2z/Θ

= a2(

erg.potencialerg.cinetica

)Condiciones iniciales: Dado ϕ(0), ϕ(0), ϑ(0), ϑ(0) se puedeobtener

a = ϕ(0) sin2[ϑ(0)]

Queda solo un parametro libre: b = a2 × razn.

Visualisación.¿Qué vamos a graficar?

1 La dirección de la eje de la molecula:

~r(τ) =

cosϕ sinϑsinϕ sinϑ

cosϑ

2 El momento angular:

~l(τ) =~L(τ)

Θω0=

ϑ cosϕ− ϕ sinϑ cosϑ sinϕϑ sinϕ+ ϕ sinϑ cosϑ cosϕ

ϕ sin2 ϑ

=

ϑ cosϕ− a cotϑ sinϕϑ sinϕ+ a cotϑ cosϕ

a

Visualisación.¿Qué vamos a graficar?

1 La dirección de la eje de la molecula:

~r(τ) =

cosϕ sinϑsinϕ sinϑ

cosϑ

2 El momento angular:

~l(τ) =~L(τ)

Θω0=

ϑ cosϕ− ϕ sinϑ cosϑ sinϕϑ sinϕ+ ϕ sinϑ cosϑ cosϕ

ϕ sin2 ϑ

=

ϑ cosϕ− a cotϑ sinϕϑ sinϕ+ a cotϑ cosϕ

a

Implementación.main_de_mol.c

1 #define _XOPEN_SOURCE 5002 #define _ISOC99_SOURCE3

4 #include <stdlib.h>5 #include <stdio.h>6 #include <math.h>7

8 #define THETA_INI M_PI/1.59 #define THETADOT_INI 0.2

10 #define PHI_INI 0.011 #define PHIDOT_INI M_PI/20.012 #define A (PHIDOT_INI * sin(THETA_INI) * sin(THETA_INI))13 #define BFUNC(x) (A * A * (x))14

15 double V_T; /* potencial over L_z kinetic erg. */16 double B;17

18 int de_solve(double*, size_t, double, double, double, double,19 void (*)(double*, double*, double));

Implementación.main_de_mol.c

21 void f(double *dxdt, double *x, double t)22 23 double ss, cs;24

25 /* Polarisable homonuclear diatomic molecule with applied26 linearly polarized electric field:27 x[0] = phi, x[1] = theta, x[2] = k */28 ss = sin(x[1]);29 cs = cos(x[1]) * ss;30 ss *= ss;31 dxdt[0] = A / ss;32 dxdt[1] = x[2];33 dxdt[2] = cs * (A * dxdt[0] - B);34 35

36 void orientation(double *r, double *x)37 /* x[0] = phi, x[1] = theta, x[2] = k */38 r[2] = sin(x[1]);39 r[0] = cos(x[0]) * r[2];40 r[1] = sin(x[0]) * r[2];41 r[2] = cos(x[1]);42

Implementación.main_de_mol.c

44 void angular_momentum(double *L, double *x)45 /* x[0] = phi, x[1] = theta, x[2] = k */46 double cottheta;47 double sphi, cphi;48

49 cottheta = 1.0 / tan(x[1]);50 sphi = sin(x[0]);51 cphi = cos(x[0]);52

53 L[0] = x[2] * cphi - A * sphi * cottheta;54 L[1] = x[2] * sphi + A * cphi * cottheta;55 L[2] = A;56

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

82 for (t = 0; t < tmax; t += tstep) 83 orientation(r, x);84 angular_momentum(L, x);85 printf("%f %f %f %f %f %f %f\n", t,86 r[0], r[1], r[2],87 L[0], L[1], L[3]);88 min_cnt = de_solve(x, 3, t, t+tstep, 1.0e-7, 1.0e-10, f);89 if (min_cnt != 0)90 fprintf(stderr, "at t = %f - # of events h < hmin: %d\n",91 t, min_cnt);92 93 printf("\n\n");94

95 x[0] = PHI_INI;96 x[1] = THETA_INI;97 x[2] = THETADOT_INI;98 V_T = 0.2;99 B = BFUNC(V_T);

Implementación.main_de_mol.c

101 for (t = 0; t < tmax; t += tstep) 102 orientation(r, x);103 angular_momentum(L, x);104 printf("%f %f %f %f %f %f %f\n", t,105 r[0], r[1], r[2],106 L[0], L[1], L[3]);107 min_cnt = de_solve(x, 3, t, t+tstep, 1.0e-7, 1.0e-10, f);108 if (min_cnt != 0)109 fprintf(stderr, "at t = %f - # of events h < hmin: %d\n",110 t, min_cnt);111 112

113 return 0;114

Resultados.

−0.4 −0.2 0 0.2 0.4 0.6 0.8 1−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 0.2 0.4 0.6 0.8

1

−0.4 −0.2 0 0.2 0.4 0.6 0.8 1−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 0.2 0.4 0.6 0.8

1

−0.4 −0.2 0 0.2 0.4 0.6 0.8 1−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 0.2 0.4 0.6 0.8

1

−0.4 −0.2 0 0.2 0.4 0.6 0.8 1−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 0.2 0.4 0.6 0.8

1

−0.4 −0.2 0 0.2 0.4 0.6 0.8 1−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 0.2 0.4 0.6 0.8

1

r3

r1

r2

Resultados.

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

−0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6−0.8−0.6

−0.4−0.2

0 0.2

0.4 0.6

−1

−0.5

0

0.5

1

l3

l1

l2

Constantes predefinidas.

Estandard X/Open (Unificacion de UNIX: BSD, SVID etc):

A través de la biblioteca matemática existen constantes predefinidas:

#define _XOPEN_SOURCE 500#define _ISOC99_SOURCE

#include <math.h>

Ahora se puede usar: M_PI, M_SQRT2 etc.

Ecuación de onda en 2D.z

y

x

Ecuación de movimiento para una membrana:(∂2

x + ∂2y −

1c2 ∂

2t

)z(x , y , t) = 0

donde c2 = τ/σ, τ = es tensión, σ = densidad de masa, ∂x = ∂/∂x .Oscilación: z(x , y , t) ∝ cos(ωt + α), entonces z = −ω2z, sale laecuación de Helmholtz:(

∂2x + ∂2

y + k2) z(x , y) = 0, k = ω/c

Es ecuación diferencial del orden 2 parcial.

Ecuación de onda en 2D.z

y

x

Ecuación de movimiento para una membrana:(∂2

x + ∂2y −

1c2 ∂

2t

)z(x , y , t) = 0

donde c2 = τ/σ, τ = es tensión, σ = densidad de masa, ∂x = ∂/∂x .Oscilación: z(x , y , t) ∝ cos(ωt + α), entonces z = −ω2z, sale laecuación de Helmholtz:(

∂2x + ∂2

y + k2) z(x , y) = 0, k = ω/c

Es ecuación diferencial del orden 2 parcial.

Dos posibilidades.

Todo depende de las condiciones de borde, es decir, de la geometriadel problema:

En caso general:Algorítmos especiales para ecuaciones diferenciales parcialescon condiciones de borde.No es contenido de este curso.En caso de condiciones de borde “buenas”:Expansión en un sístema otronormal de auto-soluciones de unproblema similar y después Runge-Kutta para los coeficientes.Eso si, se puede hacer!

Dos posibilidades.

Todo depende de las condiciones de borde, es decir, de la geometriadel problema:

En caso general:Algorítmos especiales para ecuaciones diferenciales parcialescon condiciones de borde.No es contenido de este curso.En caso de condiciones de borde “buenas”:Expansión en un sístema otronormal de auto-soluciones de unproblema similar y después Runge-Kutta para los coeficientes.Eso si, se puede hacer!

Dos posibilidades.

Todo depende de las condiciones de borde, es decir, de la geometriadel problema:

En caso general:Algorítmos especiales para ecuaciones diferenciales parcialescon condiciones de borde.No es contenido de este curso.En caso de condiciones de borde “buenas”:Expansión en un sístema otronormal de auto-soluciones de unproblema similar y después Runge-Kutta para los coeficientes.Eso si, se puede hacer!

Membrana circular.z

y

x

r0

En coordenadas polares (r , ϕ) la ecuación de Helmholtz es:(1r∂r r∂r +

1r2 ∂

2ϕ + k2

)z(r , ϕ) = 0

con las condiciones de borde: z(r0, ϕ) = 0 y ∂ϕz(r0, ϕ) = 0.Se obtienen auto-valores kλ y auto-soluciones ζλ(r , ϕ), loscuales forman un conjunto de funciones ortonormales ycompletos. La solución general será:

z(r , ϕ, t) =∑λ

zλ cos(ωλt + α)ζλ(r , ϕ)

Membrana circular.z

y

x

r0

En coordenadas polares (r , ϕ) la ecuación de Helmholtz es:(1r∂r r∂r +

1r2 ∂

2ϕ + k2

)z(r , ϕ) = 0

con las condiciones de borde: z(r0, ϕ) = 0 y ∂ϕz(r0, ϕ) = 0.Se obtienen auto-valores kλ y auto-soluciones ζλ(r , ϕ), loscuales forman un conjunto de funciones ortonormales ycompletos. La solución general será:

z(r , ϕ, t) =∑λ

zλ cos(ωλt + α)ζλ(r , ϕ)

Solución analítica.Separación de variables.

Usamos el Ansatz z(r , ϕ) = R(r)Φ(ϕ) con lo cual resulta:

R′′Φ +1r

R′Φ +1r2 RΦ′′ + k2RΦ = 0

Dividir por RΦ y multiplicar por r2 produce:

−Φ′′

Φ= k2r2 + r

R′

R+ r2 R′′

R→ m2 = const

Entonces Φ′′ = −m2Φ y su solución es:

Φ(ϕ) ∝ e±imϕ, m ∈ Z (2π − periodico)

Resulta la ecuación de Bessel:

r2R′′ + rR′ + (k2r2 −m2)R = 0

cuyos soluciones son las funciones de Bessel Jm(kr) y Nm(kr).Pero: como l«ımr→0 |Nm(kr)| = ∞ solamente se usa Jm(kr):

R(r) = Jm(kr)

Solución analítica.Separación de variables.

Usamos el Ansatz z(r , ϕ) = R(r)Φ(ϕ) con lo cual resulta:

R′′Φ +1r

R′Φ +1r2 RΦ′′ + k2RΦ = 0

Dividir por RΦ y multiplicar por r2 produce:

−Φ′′

Φ= k2r2 + r

R′

R+ r2 R′′

R→ m2 = const

Entonces Φ′′ = −m2Φ y su solución es:

Φ(ϕ) ∝ e±imϕ, m ∈ Z (2π − periodico)

Resulta la ecuación de Bessel:

r2R′′ + rR′ + (k2r2 −m2)R = 0

cuyos soluciones son las funciones de Bessel Jm(kr) y Nm(kr).Pero: como l«ımr→0 |Nm(kr)| = ∞ solamente se usa Jm(kr):

R(r) = Jm(kr)

Solución analítica.Separación de variables.

Usamos el Ansatz z(r , ϕ) = R(r)Φ(ϕ) con lo cual resulta:

R′′Φ +1r

R′Φ +1r2 RΦ′′ + k2RΦ = 0

Dividir por RΦ y multiplicar por r2 produce:

−Φ′′

Φ= k2r2 + r

R′

R+ r2 R′′

R→ m2 = const

Entonces Φ′′ = −m2Φ y su solución es:

Φ(ϕ) ∝ e±imϕ, m ∈ Z (2π − periodico)

Resulta la ecuación de Bessel:

r2R′′ + rR′ + (k2r2 −m2)R = 0

cuyos soluciones son las funciones de Bessel Jm(kr) y Nm(kr).Pero: como l«ımr→0 |Nm(kr)| = ∞ solamente se usa Jm(kr):

R(r) = Jm(kr)

Condiciones de borde.

La condición de borde z(r0, ϕ, t) = 0 es equivalente a R(r0) = 0:

Jm(kr0) = 0

Como Jm(z) tiene los ceros νm,n (n = 1,2, . . . ,∞), es decirJm(νm,n) = 0, se requieren valores discretos para k :

k → km,n =νm,n

r0, ω → ωm,n = ckm,n

Membrana oscila solo con un conjunto de frecuencias discretas:

ζλ(r , ϕ) → ζm,n(r , ϕ) ∝ Jm(km,nr)e±imϕe±ickm,nt

Después una normalisación tenemos unconjunto completo de funciones ortonormales.

Condiciones de borde.

La condición de borde z(r0, ϕ, t) = 0 es equivalente a R(r0) = 0:

Jm(kr0) = 0

Como Jm(z) tiene los ceros νm,n (n = 1,2, . . . ,∞), es decirJm(νm,n) = 0, se requieren valores discretos para k :

k → km,n =νm,n

r0, ω → ωm,n = ckm,n

Membrana oscila solo con un conjunto de frecuencias discretas:

ζλ(r , ϕ) → ζm,n(r , ϕ) ∝ Jm(km,nr)e±imϕe±ickm,nt

Después una normalisación tenemos unconjunto completo de funciones ortonormales.

Condiciones de borde.

La condición de borde z(r0, ϕ, t) = 0 es equivalente a R(r0) = 0:

Jm(kr0) = 0

Como Jm(z) tiene los ceros νm,n (n = 1,2, . . . ,∞), es decirJm(νm,n) = 0, se requieren valores discretos para k :

k → km,n =νm,n

r0, ω → ωm,n = ckm,n

Membrana oscila solo con un conjunto de frecuencias discretas:

ζλ(r , ϕ) → ζm,n(r , ϕ) ∝ Jm(km,nr)e±imϕe±ickm,nt

Después una normalisación tenemos unconjunto completo de funciones ortonormales.

Conjunto completo de funciones ortonormales.

Tenemos un conjunto de funciones ζλ(x) en un espacio x ∈ S.Es un conjunto completo de funciones ortonormales si tenemos:

Ortonormalidad (ortogonalidad + normalisación):∫S

dxζ∗µ(x)ζλ(x) = δµ,λ =

1, µ = λ0, µ 6= λ

Completitud:∑λ

ζ∗λ(x)ζλ(y) = δ(x − y), x , y ∈ S

Conjunto completo de funciones ortonormales.

Tenemos un conjunto de funciones ζλ(x) en un espacio x ∈ S.Es un conjunto completo de funciones ortonormales si tenemos:

Ortonormalidad (ortogonalidad + normalisación):∫S

dxζ∗µ(x)ζλ(x) = δµ,λ =

1, µ = λ0, µ 6= λ

Completitud:∑λ

ζ∗λ(x)ζλ(y) = δ(x − y), x , y ∈ S

Conjunto completo de funciones ortonormales.

Tenemos un conjunto de funciones ζλ(x) en un espacio x ∈ S.Es un conjunto completo de funciones ortonormales si tenemos:

Ortonormalidad (ortogonalidad + normalisación):∫S

dxζ∗µ(x)ζλ(x) = δµ,λ =

1, µ = λ0, µ 6= λ

Completitud:∑λ

ζ∗λ(x)ζλ(y) = δ(x − y), x , y ∈ S

Ejemplos.

En el espacio S = R las tenemos el conjunto completo defunciones ortonormales:

ζk (x) =1√2π

eikx , k ∈ R

Ortonormalidad tenemos porque:

12π

∫ ∞

−∞dxe−iqxeikx = δ(q − k)

Completos son porque:

12π

∫dke−ikxeiky = δ(x − y)

Otros ejemplos:

Polinomiales ortogonales: L(a)n (x), Hn(x), Tn(x), P(a,b)

n (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 defunciones ortonormales:

ζk (x) =1√2π

eikx , k ∈ R

Ortonormalidad tenemos porque:

12π

∫ ∞

−∞dxe−iqxeikx = δ(q − k)

Completos son porque:

12π

∫dke−ikxeiky = δ(x − y)

Otros ejemplos:

Polinomiales ortogonales: L(a)n (x), Hn(x), Tn(x), P(a,b)

n (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):∂x [h(x , y)∂x ] + ∂y [h(x , y)∂y ]− 1

g∂2

t

z(x , y , t) = 0

donde g = constante gravitacional y h(x , y) es la altitud/nivel delliquido, c2 = gh depende del lugar.

Definir variables sin unidades:

τ = ω0t , ξ =x

∆x, η =

y∆y

, ζ =z

∆z, δ(ξ, η) =

h(ξ∆x , η∆y)

∆z

Sale la ecuación de onda:1ρ∂ξ [δ(ξ, η)∂ξ] + ρ∂η [δ(ξ, η)∂η]−

1v2 ∂

ζ(ξ, η, t) = 0

dondeρ = ∆x/∆y y v2 = g∆z/(ω20∆x∆y).

Ondas en un fluido.

Ondas superficiales de un fluido (ecuación linearisada):∂x [h(x , y)∂x ] + ∂y [h(x , y)∂y ]− 1

g∂2

t

z(x , y , t) = 0

donde g = constante gravitacional y h(x , y) es la altitud/nivel delliquido, c2 = gh depende del lugar.

Definir variables sin unidades:

τ = ω0t , ξ =x

∆x, η =

y∆y

, ζ =z

∆z, δ(ξ, η) =

h(ξ∆x , η∆y)

∆z

Sale la ecuación de onda:1ρ∂ξ [δ(ξ, η)∂ξ] + ρ∂η [δ(ξ, η)∂η]−

1v2 ∂

ζ(ξ, η, t) = 0

dondeρ = ∆x/∆y y v2 = g∆z/(ω20∆x∆y).

Ondas en un fluido.

Ondas superficiales de un fluido (ecuación linearisada):∂x [h(x , y)∂x ] + ∂y [h(x , y)∂y ]− 1

g∂2

t

z(x , y , t) = 0

donde g = constante gravitacional y h(x , y) es la altitud/nivel delliquido, c2 = gh depende del lugar.

Definir variables sin unidades:

τ = ω0t , ξ =x

∆x, η =

y∆y

, ζ =z

∆z, δ(ξ, η) =

h(ξ∆x , η∆y)

∆z

Sale la ecuación de onda:1ρ∂ξ [δ(ξ, η)∂ξ] + ρ∂η [δ(ξ, η)∂η]−

1v2 ∂

ζ(ξ, η, t) = 0

dondeρ = ∆x/∆y y v2 = g∆z/(ω20∆x∆y).

Sistema completo de funciones ortonormales.Sabemos las auto-soluciónes ζλ(ξ, η) de(

1ρ∂2ξ + ρ∂2

η + κ2λ

)ζλ(ξ, η, t) = 0, κ2

λ = (νλ/v)2

con las mismas condiciones de borde, donde νλ = ωλ/ω0.Entonces usamos una expansión en este sistema completa defunciones ortonormales:

ζ(ξ, η, τ) =∑λ

cλ(τ)ζλ(ξ, η)

donde cλ(τ) son los coeficientes de la expansión.Insertar en la ecuación de onda:∑

λ

[1ρ∂ξ (δ∂ξ) + ρ∂η (δ∂η)

]ζλ −

1v2 cλζλ

=

∑λ

δ(

1ρ∂2ξ + ρ∂2

η

)ζλ︸ ︷︷ ︸

=−κ2λζλ

+(∇δ) · (∇ζλ)

− 1v2 cλζλ

= 0

Sistema completo de funciones ortonormales.Sabemos las auto-soluciónes ζλ(ξ, η) de(

1ρ∂2ξ + ρ∂2

η + κ2λ

)ζλ(ξ, η, t) = 0, κ2

λ = (νλ/v)2

con las mismas condiciones de borde, donde νλ = ωλ/ω0.Entonces usamos una expansión en este sistema completa defunciones ortonormales:

ζ(ξ, η, τ) =∑λ

cλ(τ)ζλ(ξ, η)

donde cλ(τ) son los coeficientes de la expansión.Insertar en la ecuación de onda:∑

λ

[1ρ∂ξ (δ∂ξ) + ρ∂η (δ∂η)

]ζλ −

1v2 cλζλ

=

∑λ

δ(

1ρ∂2ξ + ρ∂2

η

)ζλ︸ ︷︷ ︸

=−κ2λζλ

+(∇δ) · (∇ζλ)

− 1v2 cλζλ

= 0

Sistema completo de funciones ortonormales.Sabemos las auto-soluciónes ζλ(ξ, η) de(

1ρ∂2ξ + ρ∂2

η + κ2λ

)ζλ(ξ, η, t) = 0, κ2

λ = (νλ/v)2

con las mismas condiciones de borde, donde νλ = ωλ/ω0.Entonces usamos una expansión en este sistema completa defunciones ortonormales:

ζ(ξ, η, τ) =∑λ

cλ(τ)ζλ(ξ, η)

donde cλ(τ) son los coeficientes de la expansión.Insertar en la ecuación de onda:∑

λ

[1ρ∂ξ (δ∂ξ) + ρ∂η (δ∂η)

]ζλ −

1v2 cλζλ

=

∑λ

δ(

1ρ∂2ξ + ρ∂2

η

)ζλ︸ ︷︷ ︸

=−κ2λζλ

+(∇δ) · (∇ζλ)

− 1v2 cλζλ

= 0

Multiplicar con ζ∗µ(ξ, η) e integrar, es decir aplicar de la izquierda:∫dξ∫

dηζ∗µ(ξ, η) . . .

Usando ortonormalidad∫

dξ∫

dηζ∗µζλ = δµ,λresulta:

∑λ

−κ2λ

∫dξ∫

dηζ∗µδζλ︸ ︷︷ ︸=Aµ,λ

+

∫dξ∫

dηζ∗µ(∇δ) · (∇ζλ)︸ ︷︷ ︸=Bµ,λ

− 1v2 cλδµ,λ

= 0

Qué sorpresa! — Tenemos una ecuación diferencial ordinaria:

d2cµ(τ)dτ2 = −v2

∑λ

(Aµ,λκ2

λ − Bµ,λ)

cλ(τ)

“Solamente” hay que obtener los coeficientes Aµ,λ y Bµ,λ!

Multiplicar con ζ∗µ(ξ, η) e integrar, es decir aplicar de la izquierda:∫dξ∫

dηζ∗µ(ξ, η) . . .

Usando ortonormalidad∫

dξ∫

dηζ∗µζλ = δµ,λresulta:

∑λ

−κ2λ

∫dξ∫

dηζ∗µδζλ︸ ︷︷ ︸=Aµ,λ

+

∫dξ∫

dηζ∗µ(∇δ) · (∇ζλ)︸ ︷︷ ︸=Bµ,λ

− 1v2 cλδµ,λ

= 0

Qué sorpresa! — Tenemos una ecuación diferencial ordinaria:

d2cµ(τ)dτ2 = −v2

∑λ

(Aµ,λκ2

λ − Bµ,λ)

cλ(τ)

“Solamente” hay que obtener los coeficientes Aµ,λ y Bµ,λ!

Multiplicar con ζ∗µ(ξ, η) e integrar, es decir aplicar de la izquierda:∫dξ∫

dηζ∗µ(ξ, η) . . .

Usando ortonormalidad∫

dξ∫

dηζ∗µζλ = δµ,λresulta:

∑λ

−κ2λ

∫dξ∫

dηζ∗µδζλ︸ ︷︷ ︸=Aµ,λ

+

∫dξ∫

dηζ∗µ(∇δ) · (∇ζλ)︸ ︷︷ ︸=Bµ,λ

− 1v2 cλδµ,λ

= 0

Qué sorpresa! — Tenemos una ecuación diferencial ordinaria:

d2cµ(τ)dτ2 = −v2

∑λ

(Aµ,λκ2

λ − Bµ,λ)

cλ(τ)

“Solamente” hay que obtener los coeficientes Aµ,λ y Bµ,λ!

Piscina rectangular.

x

z

yb

a

hm«ax

hm«ın

Usamos:

∆x = a, ∆y = b, ∆z = (hm«ax + hm«ın)/2

de lo cual resulta que ρ = a/b y v2 = g(hm«ax + hm«ın)/(2ω20ab).

La ecuación de Helmholtz simplificada es:(1ρ∂2ξ + ρ∂2

η + κ2λ

)ζλ(ξ, η) = 0

Condiciones de borde son:

∇ξλ(ξ, η) = 0, (ξ, η) ∈ borde

Funciones ortonormales.

Auto-soluciones de la ecuacion de Helmholtz son:

ζm,n(x , y) = Nm,n cos(mπξ) cos(nπη), Nm,n = 2 [(δm,0 + 1)(δn,0 + 1)]−12

donde m,n = 0,1, . . . ,∞ pero sin m = n = 0 y

ν2m,n = v2κ2

m,n = v2π2(

m2

ρ+ ρn2

)Podemos fijar v = 1, es decir

ω0 =

√g(hm«ax + hm«ın)

2ab

y asi tenemos siempre νm,n = κm,n.

Nivel del agua.

x

z

yb

a

hm«ax

hm«ın

El nivel del agua es:

h(y) = hm«ax −y∆h

bdonde ∆h = hm«ax − hm«ın, entonces tenemos

δ(η) =hm«ax − η∆h

(hm«ax + hm«ın)/2= δ0 − ηδ1

Integrales Am,n.

La definición es:

Am,n,m′,n′ = Nm,nNm′,n′

∫ 1

0dξ∫ 1

0dηζ∗m,n(ξ, η)δ(η)ζm′,n′(ξ, η)

Después haber integrado ξ:

Am,n,m′,n′ = δm,m′Nm,nNm,n′

∫ 1

0dη cos(πnη) cos(πn′η)δ(η)

= δm,,m′(δn,n′N 2

m,nδ0 −Nm,nNm,n′δ1In,n′)

La integral resulta como:

In,n′ =

∫ 1

0dηη cos(πnη) cos(πn′η) =

12 , n = n′ = 014 , n = n′ 6= 0

[(−1)n+n′−1](n2+n′2)π2(n2−n′2)2 , n 6= n′

Integrales Bm,n.

Definición:

Bm,n,m′,n′ =

∫ 1

0dξ∫ 1

0dηζ∗m,n(ξ, η)δ

′(η)∂ζm′,n′(ξ, η)

∂η

Después haber integrado ξ:

Bm,n,m′,n′ = δm,m′2πn′∆h

hm«ax + hm«ın

∫ 1

0dη cos(nπη) sin(n′πη)

= δm,m′πn′∆h

hm«ax + hm«ın

∫ 1

0dη sin[(n′ + n)πη] + sin[(n′ − n)πη]

= δm,m′πn′∆h

hm«ax + hm«ın

sin[(n′ + n)π]

(n′ + n)π+

sin[(n′ − n)π]

(n′ − n)π

= 0

Ondas en piscina: sistema de ecuaciones.

Tenemos entonces el sistema de ecuaciones:

cm,n = dm,n

dm,n = −∑n′

([N 2

m,nδ0δn,n′ −Nm,nNm,n′δ1In,n′]κ2

m,n′)

cm,n′(τ)

donde

κ2m,n = π2

(m2

ρ+ ρn2

)In,n′ = δn,n′

1 + δn,0

4+ (1− δn,n′)

[(−1)n+n′ − 1](n2 + n′2)π2(n2 − n′2)2

¿Cómo implementar el vector de datos?

Nuestro vector de datos de repente son 2 matrices, cm,n y dm,n, conm,n = 0,1, . . . ,∞ pero nuestro programa necesita un solo vector contamaño finito!

Limitar índices: m = 0, . . . ,M − 1 y n = 0,1, . . . ,N − 1.¿Qué significa eso?M, N son los números máximos de oscilaciones de ζm,n(ξ, η) enξ, η ∈ [0,1], entonces tenemos algo como una discretisación delespacio (ξ, η) en un grid de M × N elementos.Corresponde a una resolución espacial de

aM× b

N

¿Cómo implementar el vector de datos?

Nuestro vector de datos de repente son 2 matrices, cm,n y dm,n, conm,n = 0,1, . . . ,∞ pero nuestro programa necesita un solo vector contamaño finito!

Limitar índices: m = 0, . . . ,M − 1 y n = 0,1, . . . ,N − 1.¿Qué significa eso?M, N son los números máximos de oscilaciones de ζm,n(ξ, η) enξ, η ∈ [0,1], entonces tenemos algo como una discretisación delespacio (ξ, η) en un grid de M × N elementos.Corresponde a una resolución espacial de

aM× b

N

¿Cómo implementar el vector de datos?

Nuestro vector de datos de repente son 2 matrices, cm,n y dm,n, conm,n = 0,1, . . . ,∞ pero nuestro programa necesita un solo vector contamaño finito!

Limitar índices: m = 0, . . . ,M − 1 y n = 0,1, . . . ,N − 1.¿Qué significa eso?M, N son los números máximos de oscilaciones de ζm,n(ξ, η) enξ, η ∈ [0,1], entonces tenemos algo como una discretisación delespacio (ξ, η) en un grid de M × N elementos.Corresponde a una resolución espacial de

aM× b

N

Construir un vector de datos eficiente:

~x =

c0,0d0,0c0,1d0,1

...d0,N−1

c1,0...

d1,N−1......

dM−1,N−1

donde los elementos c0,0 y d0,0 no se usan.

No quiero hacer este vector por mano. Entonces un pequeñomacro para traducir (m,n) → λ:#define idx(m,n) ((m) * N + (n))

Implementar la función f .

Ahora tenemos una multiplicación con una matriz:

~x(τ) =~~M ·~x(τ)

donde

~~M =

0 00 00 1 0 0x 0 x 0 x · · ·0 0 0 1 0 · · · 0

ddt

c0,0...

...cm,ndm,n

...

...dM−1,N−1

=

0 1

x 0 x 0 x 0 x 0 x 0

·

c0,0...

...cm,ndm,n

...

...dM−1,N−1

¿Y donde esta el resultado?

Tenemos ahora la solución numérica para los coeficientes cm,n.Pero queremos la función original:

ζ(ξ, η, τ) =∑m,n

cm,n(τ)ζm,n(ξ, η)

dondeζm,n(ξ, η) = Nm,n cos(mπξ) cos(nπη)

¿Se puede calcular una suma de este tipo? — No!Es altamente inpreciso e inestable!Pero: Parte del sumante satisface una recursión:

cos(nθ) = 2 cos(θ) cos[(n − 1)θ]− cos[(n − 2)θ]

Para calcular la suma se puede usar la recursión de Clenshaw.

¿Y donde esta el resultado?

Tenemos ahora la solución numérica para los coeficientes cm,n.Pero queremos la función original:

ζ(ξ, η, τ) =∑m,n

cm,n(τ)ζm,n(ξ, η)

dondeζm,n(ξ, η) = Nm,n cos(mπξ) cos(nπη)

¿Se puede calcular una suma de este tipo? — No!Es altamente inpreciso e inestable!Pero: Parte del sumante satisface una recursión:

cos(nθ) = 2 cos(θ) cos[(n − 1)θ]− cos[(n − 2)θ]

Para calcular la suma se puede usar la recursión de Clenshaw.

¿Y donde esta el resultado?

Tenemos ahora la solución numérica para los coeficientes cm,n.Pero queremos la función original:

ζ(ξ, η, τ) =∑m,n

cm,n(τ)ζm,n(ξ, η)

dondeζm,n(ξ, η) = Nm,n cos(mπξ) cos(nπη)

¿Se puede calcular una suma de este tipo? — No!Es altamente inpreciso e inestable!Pero: Parte del sumante satisface una recursión:

cos(nθ) = 2 cos(θ) cos[(n − 1)θ]− cos[(n − 2)θ]

Para calcular la suma se puede usar la recursión de Clenshaw.

Suma con parte recursiva.

Objectivo:

Con coeficientes cn dados, calcular:

f (x) =N−1∑n=0

cngn(x)

donde gn(x) tiene la recursión:

gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

Problema:

Coeficientes cn y/o gn(x) pueden ser oscilatorios con respecto an.Suma no es convergente con errores numéricos (inevitables)!

Suma con parte recursiva.

Objectivo:

Con coeficientes cn dados, calcular:

f (x) =N−1∑n=0

cngn(x)

donde gn(x) tiene la recursión:

gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

Problema:

Coeficientes cn y/o gn(x) pueden ser oscilatorios con respecto an.Suma no es convergente con errores numéricos (inevitables)!

Construcción.Recuerde: f (x) =

Pn cngn(x).

Usando los coeficientes de la recursión:

gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

vamos a definir una función hn(x):

hn(x) = αn(x)hn+1(x) + βn+1(x)hn+2(x) + cn (n = N − 1, . . . ,0)

con valores iniciales:

hN+1(x) = hN(x) = 0

Con eso sale:

cn = hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)

Usando eso en la suma:

f (x) =N−1∑n=0

[hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x)

Construcción.Recuerde: f (x) =

Pn cngn(x).

Usando los coeficientes de la recursión:

gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

vamos a definir una función hn(x):

hn(x) = αn(x)hn+1(x) + βn+1(x)hn+2(x) + cn (n = N − 1, . . . ,0)

con valores iniciales:

hN+1(x) = hN(x) = 0

Con eso sale:

cn = hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)

Usando eso en la suma:

f (x) =N−1∑n=0

[hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x)

Construcción.Recuerde: f (x) =

Pn cngn(x).

Usando los coeficientes de la recursión:

gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

vamos a definir una función hn(x):

hn(x) = αn(x)hn+1(x) + βn+1(x)hn+2(x) + cn (n = N − 1, . . . ,0)

con valores iniciales:

hN+1(x) = hN(x) = 0

Con eso sale:

cn = hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)

Usando eso en la suma:

f (x) =N−1∑n=0

[hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x)

Reordenar la suma.Recuerde: f (x) =

PN−1n=0 [hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x).

f (x) =

h0(x)− α0(x)h1(x)︸ ︷︷ ︸=c0+β1(x)h2(x)

−β1(x)h2(x)

g0(x)

+[h1(x)− α1(x)h2(x)− β2(x)h3(x)

]g1(x)

+[h2(x)− α2(x)h3(x)− β3(x)h4(x)

]g2(x)

...+

[h6(x)− α6(x)h7(x)− β7(x)h8(x)

]g6(x)

+[h7(x)− α7(x)h8(x)− β8(x)h9(x)

]g7(x)

+[h8(x)− α8(x)h9(x)− β9(x)h10(x)

]g8(x) + . . .

Reordenar la suma.Recuerde: f (x) =

PN−1n=0 [hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x).

f (x) = . . .

...+

[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)︸ ︷︷ ︸=0

gN−2(x)

+

hN−1(x)− αN−1(x) hN(x)︸ ︷︷ ︸=0

−βN(x) hN+1(x)︸ ︷︷ ︸=0

gN−1(x)

Reordenar la suma.Recuerde: f (x) =

PN−1n=0 [hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x).

f (x) = [c0 + β1(x)h2(x)] g0(x) + h1(x)g1(x)

+ h2(x) [g2(x)− α1(x)g1(x)− β1(x)g0(x)]︸ ︷︷ ︸=0

...+ hk (x) [gk (x)− αk−1(x)gk−1(x)− βk−1(x)gk−1(x)]︸ ︷︷ ︸

=0

...+ hN−1(x) [gN−1(x)− αN−2(x)gN−2(x)− βN−2(x)gN−3(x)]︸ ︷︷ ︸

=0

= [c0 + β1(x)h2(x)] g0(x) + h1(x)g1(x)

Reordenar la suma.Recuerde: f (x) =

PN−1n=0 [hn(x)− αn(x)hn+1(x)− βn+1(x)hn+2(x)] gn(x).

Tenemos entonces:

f (x) = [c0 + β1(x)h2(x)]︸ ︷︷ ︸=h0(x)−α0(x)h1(x)

g0(x) + h1(x)g1(x)

= h0(x)g0(x) + h1(x) [g1(x)− α0(x)g0(x)]

Recursión de Clenshaw.

f (x) =N−1∑n=0

cngn(x) con : gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

Solución: Recursión de Clenshaw:

f (x) = h0(x)g0(x) + h1(x) [g1(x)− α0(x)g0(x)]

donde h0,1(x) se calcula a través de:

hn(x) = αn(x)hn+1(x) + βn+1(x)hn+2(x) + cn (n = N − 1, . . . ,0)

con valores iniciales:

hN+1(x) = hN(x) = 0

Recursión de Clenshaw.

f (x) =N−1∑n=0

cngn(x) con : gn+1(x) = αn(x)gn(x) + βn(x)gn−1(x)

Solución: Recursión de Clenshaw:

f (x) = h0(x)g0(x) + h1(x) [g1(x)− α0(x)g0(x)]

donde h0,1(x) se calcula a través de:

hn(x) = αn(x)hn+1(x) + βn+1(x)hn+2(x) + cn (n = N − 1, . . . ,0)

con valores iniciales:

hN+1(x) = hN(x) = 0

Implementar nuestro caso: Piscina.

Tenemos dos sumas:

ζ(ξ, η, τ) =∑

n

Cn(η)

=Sn(ξ)︷ ︸︸ ︷∑m

cm,nNm,n︸ ︷︷ ︸=cm,n

Cm(ξ), Cn(x) = cos(nπx)

con la recursión:

Cn+1(x) = 2 cos(πx)Cn(x)− Cn−1(x)

entonces αn = 2 cos(πx) y βn = −1.

ζ(ξ, η, τ) =∑

n

Cn(η)

=Sn(ξ)︷ ︸︸ ︷∑m

cm,nCm(ξ), cm,n = cm,nNm,n

1 Suma m con Clenshaw:

Sn(ξ) =M−1∑m=0

cm,nCm(ξ) = h(n)0 (ξ)− cos(πξ)h(n)

1 (ξ)

donde:

h(n)m (ξ) = 2 cos(πξ)h(n)

m+1(ξ)− h(n)m+2(ξ) + cm,n (m = M − 1, . . . ,0)

2 Suma n con Clenshaw:

ζ(ξ, η) =N−1∑n=0

Sn(ξ)Cn(η) = h(ξ)0 (η)− cos(πη)h(ξ)

1 (η)

donde ahora:

h(ξ)n (η) = 2 cos(πη)h(ξ)

n+1(η)− h(ξ)n+2(η) + Sn(ξ) (n = N − 1, . . . ,0)

ζ(ξ, η, τ) =∑

n

Cn(η)

=Sn(ξ)︷ ︸︸ ︷∑m

cm,nCm(ξ), cm,n = cm,nNm,n

1 Suma m con Clenshaw:

Sn(ξ) =M−1∑m=0

cm,nCm(ξ) = h(n)0 (ξ)− cos(πξ)h(n)

1 (ξ)

donde:

h(n)m (ξ) = 2 cos(πξ)h(n)

m+1(ξ)− h(n)m+2(ξ) + cm,n (m = M − 1, . . . ,0)

2 Suma n con Clenshaw:

ζ(ξ, η) =N−1∑n=0

Sn(ξ)Cn(η) = h(ξ)0 (η)− cos(πη)h(ξ)

1 (η)

donde ahora:

h(ξ)n (η) = 2 cos(πη)h(ξ)

n+1(η)− h(ξ)n+2(η) + Sn(ξ) (n = N − 1, . . . ,0)

ζ(ξ, η, τ) =∑

n

Cn(η)

=Sn(ξ)︷ ︸︸ ︷∑m

cm,nCm(ξ), cm,n = cm,nNm,n

1 Suma m con Clenshaw:

Sn(ξ) =M−1∑m=0

cm,nCm(ξ) = h(n)0 (ξ)− cos(πξ)h(n)

1 (ξ)

donde:

h(n)m (ξ) = 2 cos(πξ)h(n)

m+1(ξ)− h(n)m+2(ξ) + cm,n (m = M − 1, . . . ,0)

2 Suma n con Clenshaw:

ζ(ξ, η) =N−1∑n=0

Sn(ξ)Cn(η) = h(ξ)0 (η)− cos(πη)h(ξ)

1 (η)

donde ahora:

h(ξ)n (η) = 2 cos(πη)h(ξ)

n+1(η)− h(ξ)n+2(η) + Sn(ξ) (n = N − 1, . . . ,0)

Piscina: Condiciones iniciales.

¿Si ζ(ξ, η, 0) = ζ0(ξ, η) es la condicion inicial, como se ven loscoeficientes iniciales?

Como tenemos un sistema de funciones ortonormales ycompletos:

cm,n(τ = 0) =

∫ 1

0dξ∫ 1

0dηζ∗m,n(ξ, η)ζ0(ξ, η)

Entonces tenemos una transformación de Fourier:

cm,n(0) = Nm,n

∫ 1

0dξ cos(mπξ)

∫ 1

0dη cos(nπη)ζ0(ξ, η)

Piscina: Condiciones iniciales.

¿Si ζ(ξ, η, 0) = ζ0(ξ, η) es la condicion inicial, como se ven loscoeficientes iniciales?

Como tenemos un sistema de funciones ortonormales ycompletos:

cm,n(τ = 0) =

∫ 1

0dξ∫ 1

0dηζ∗m,n(ξ, η)ζ0(ξ, η)

Entonces tenemos una transformación de Fourier:

cm,n(0) = Nm,n

∫ 1

0dξ cos(mπξ)

∫ 1

0dη cos(nπη)ζ0(ξ, η)

Piscina: Condiciones iniciales.

¿Si ζ(ξ, η, 0) = ζ0(ξ, η) es la condicion inicial, como se ven loscoeficientes iniciales?

Como tenemos un sistema de funciones ortonormales ycompletos:

cm,n(τ = 0) =

∫ 1

0dξ∫ 1

0dηζ∗m,n(ξ, η)ζ0(ξ, η)

Entonces tenemos una transformación de Fourier:

cm,n(0) = Nm,n

∫ 1

0dξ cos(mπξ)

∫ 1

0dη cos(nπη)ζ0(ξ, η)

Caso especial: bumb en al agua.Alguien con forma esferica (guaton) se cayo en el agua, ahoratenemos un cerrito Gaussiano:

ζ0(ξ, η) = k exp

[− (ξ − ξ0)

2

2σ2ξ

− (η − η0)2

2σ2η

]

Bumb suficientemente lejos de los muros de la piscina:0 < x0 ± σ < 1∫ 1

0dx cos(nπx)e−(x−x0)

2/2σ2≈∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2

Tenemos suerte — “Fourier de Gauss = Gauss”:∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2=√

2πσ cos(nπx0)e−(πσn)2/2

Entonces los coeficientes iniciales son:

cm,n(0) = k2πσξσηNm,n cos(mπξ0) cos(nπη0) exp[−π

2

2(σ2ξm

2 + σ2ηn2)]

Caso especial: bumb en al agua.Alguien con forma esferica (guaton) se cayo en el agua, ahoratenemos un cerrito Gaussiano:

ζ0(ξ, η) = k exp

[− (ξ − ξ0)

2

2σ2ξ

− (η − η0)2

2σ2η

]

Bumb suficientemente lejos de los muros de la piscina:0 < x0 ± σ < 1∫ 1

0dx cos(nπx)e−(x−x0)

2/2σ2≈∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2

Tenemos suerte — “Fourier de Gauss = Gauss”:∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2=√

2πσ cos(nπx0)e−(πσn)2/2

Entonces los coeficientes iniciales son:

cm,n(0) = k2πσξσηNm,n cos(mπξ0) cos(nπη0) exp[−π

2

2(σ2ξm

2 + σ2ηn2)]

Caso especial: bumb en al agua.Alguien con forma esferica (guaton) se cayo en el agua, ahoratenemos un cerrito Gaussiano:

ζ0(ξ, η) = k exp

[− (ξ − ξ0)

2

2σ2ξ

− (η − η0)2

2σ2η

]

Bumb suficientemente lejos de los muros de la piscina:0 < x0 ± σ < 1∫ 1

0dx cos(nπx)e−(x−x0)

2/2σ2≈∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2

Tenemos suerte — “Fourier de Gauss = Gauss”:∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2=√

2πσ cos(nπx0)e−(πσn)2/2

Entonces los coeficientes iniciales son:

cm,n(0) = k2πσξσηNm,n cos(mπξ0) cos(nπη0) exp[−π

2

2(σ2ξm

2 + σ2ηn2)]

Caso especial: bumb en al agua.Alguien con forma esferica (guaton) se cayo en el agua, ahoratenemos un cerrito Gaussiano:

ζ0(ξ, η) = k exp

[− (ξ − ξ0)

2

2σ2ξ

− (η − η0)2

2σ2η

]

Bumb suficientemente lejos de los muros de la piscina:0 < x0 ± σ < 1∫ 1

0dx cos(nπx)e−(x−x0)

2/2σ2≈∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2

Tenemos suerte — “Fourier de Gauss = Gauss”:∫ ∞

−∞dx cos(nπx)e−(x−x0)

2/2σ2=√

2πσ cos(nπx0)e−(πσn)2/2

Entonces los coeficientes iniciales son:

cm,n(0) = k2πσξσηNm,n cos(mπξ0) cos(nπη0) exp[−π

2

2(σ2ξm

2 + σ2ηn2)]

Parte IVFunciones Especiales

Shot-noise y la distribución de Poisson.

pling!

plang!

plong!

Probabilidad Pn para observar n “clicks” en un intervalo del tiempo∆t :

Pn =(n)n

n!e−n, (distribución de Poisson)

donde n es el número promedio:

n =∞∑

n=0

Pnn

Shot-noise limit.

¿Cuál es el ancho de esta distribución? — Es la varianza ∆n (rms =root-mean-square)!

∆n =

√n2 − (n)2

Para la distribución de Poisson:

∆n =√

n, (shot-noise limit)

Un proceso estochastico es:

super-Poissonian si ∆n >√

n,sub-Poissonian si ∆n <

√n.

Ejemplo: Estadistica de fotones de un laser es distribución dePoisson.

¿Cómo calcular la distribución de Poisson?

Pn =(n)n

n!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

con los casos especiales: 0! = 1! = 1.

Implementación con recursión I.

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.

Uno no puede calcular el factorial porque siempre habráresultados más grandes que el rango de valores posibles en elcomputador.Pero los resultados de una función útil, que contiene el factorialnormalmente son valores “normales”.Ejemplo: Distribución de Poisson

Pn =(n)n

n!e−n ∈ [0,1]

mientras:

l«ımn→∞

(n)n = ∞, (n > 1), l«ımn→∞

n! = ∞

Entonces hay el problema de OVERFLOW!

Solución.

Hay que combinar las cosas en vez de separarlas:

Pn =(n)n

n!e−n

=eln[(n)n]

eln(n!)e−n

= exp

n ln(n)− n − ln(n!)︸ ︷︷ ︸∈[−∞,0]

El exponential actua como amplificador, y por lo tanto elexponente contiene números más chicos.Se cancelan en el exponente los números positivos y negativos yel exponente contiene después un número “normal”.Siempre se necesitará ln(n!) en vez de n!

La función Gamma.

Definición:Γ(z) =

∫ ∞

0dxe−xxz−1, <(z) > 0

Tiene una recursión:

Γ(z + 1) = z · Γ(z), Γ(1) = 1

Asi podemos ver que:

Γ(z + 1) = z · (z − 1) · · ·1 · Γ(1) = z!

Entonces hay que implementar una función para ln[Γ(z)].

Aproximación.Existe la aproximación de Stirling (z →∞):

Γ(z) ≈√

2πe−zzz− 12

[1 +

112z

+1

288z2 + . . .

]Pero mejor es la aproximación de Lanczos (z > 0):

Γ(z + 1) ≈√

2πe−(z+γ+ 12 )

(z + γ +

12

)z+ 12

×[c0 +

c1

z + 1+

c2

z + 2+ . . .+

cN−1

z + N − 1+ ε

]Error solamente |ε| < 2,0× 10−10 para γ = 5 y

~c =

1,00000000019001576,18009172947146−86,5053203294167724,01409824083091−1,231739572450155

0,1208650973866179× 10−2

−0,5395239384953× 10−5

, N = 7

Aproximación para ln[Γ(z)].

Aplicamos la recursión de la función Γ(z) y la aproximación deLanczos:

ln[Γ(z)] = ln[Γ(z + 1)

z

]= ln[Γ(z + 1)]− ln(z)

≈ −(

z + γ +12

)+

(z +

12

)ln(

z + γ +12

)+ ln

[√2π(

c0 + . . .+cN−1

z + N − 1

)]− ln(z)

= − (z + 5,5) + (z + 0,5) ln (z + 5,5)

+ ln[s(

c0 + . . .+cN−1

z + N − 1

)/z]

donde s =√

2π.

Implementación.sf_log_gamma.c

1 /*! \file sf_log_gamma.c */2 #define _XOPEN_SOURCE 5003 #define _ISOC99_SOURCE4

5 #include <math.h>6 #define SQRT_2PI (2.0 * M_SQRT2 / M_2_SQRTPI)7

8 /*! Calculates the natural logarithm of the Gamma9 function using the Lanczos approximation. */

10 double log_gamma(double x)11 12 double erg;13 double tmp;14 int n;15 static double s = SQRT_2PI;16 static double c[7] = 1.000000000190015,17 76.18009172947146, -86.50532032941677,18 24.01409824083091, -1.231739572450155,19 0.1208650973866179e-2, -0.5395239384953e-5;

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

La distribución de Poisson es ahora muy simple:

Pn = exp n ln(n)− n − ln[Γ(n + 1)]

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:(mn

)=

m!

n!(m − n)!= exp ln[Γ(m + 1)]− [ln[Γ(n + 1)] + ln[Γ(m − n + 1)]]

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:

B(z,w) =

∫ 1

0dx(1− x)w−1xz−1 =

Γ(z)Γ(w)

Γ(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.

Definición a través de una suma:

Hn(x) =

[ n2 ]∑

k=0

(−1)k n!

k !(n − 2k)!(2x)n−2k

Por ejemplo:

H0(x) = 1, H1(x) = 2x , . . .

y tiene la relación:

Hn(−x) = (−1)nHn(x)

entonces solamente hay que calcularlo para x > 0.Se usa en la mecánica cuántica: Son los auto-soluciones deloscilador armónico.Calcular la suma directamente no es preciso ni estable!

Polinomial orthogonal de Hermite.

Definición a través de una suma:

Hn(x) =

[ n2 ]∑

k=0

(−1)k n!

k !(n − 2k)!(2x)n−2k

Por ejemplo:

H0(x) = 1, H1(x) = 2x , . . .

y tiene la relación:

Hn(−x) = (−1)nHn(x)

entonces solamente hay que calcularlo para x > 0.Se usa en la mecánica cuántica: Son los auto-soluciones deloscilador armónico.Calcular la suma directamente no es preciso ni estable!

Polinomial orthogonal de Hermite.

Definición a través de una suma:

Hn(x) =

[ n2 ]∑

k=0

(−1)k n!

k !(n − 2k)!(2x)n−2k

Por ejemplo:

H0(x) = 1, H1(x) = 2x , . . .

y tiene la relación:

Hn(−x) = (−1)nHn(x)

entonces solamente hay que calcularlo para x > 0.Se usa en la mecánica cuántica: Son los auto-soluciones deloscilador armónico.Calcular la suma directamente no es preciso ni estable!

Recursión para polinomiales de Hermite.

Existe la recursión:

Hn+1(x) = 2xHn(x)− 2nHn−1(x)

con los valores iniciales: H0(x) = 1, H1(x) = 2x .Problema es que son polinomiales: Hn(x) ∝ xn entonces estanexplotandose! — No se puede calcular el polinomial de Hermitedirectamente!Hay que reducir la explosividad con algunos factores adicionales.

Recursión para polinomiales de Hermite.

Existe la recursión:

Hn+1(x) = 2xHn(x)− 2nHn−1(x)

con los valores iniciales: H0(x) = 1, H1(x) = 2x .Problema es que son polinomiales: Hn(x) ∝ xn entonces estanexplotandose! — No se puede calcular el polinomial de Hermitedirectamente!Hay que reducir la explosividad con algunos factores adicionales.

Recursión para polinomiales de Hermite.

Existe la recursión:

Hn+1(x) = 2xHn(x)− 2nHn−1(x)

con los valores iniciales: H0(x) = 1, H1(x) = 2x .Problema es que son polinomiales: Hn(x) ∝ xn entonces estanexplotandose! — No se puede calcular el polinomial de Hermitedirectamente!Hay que reducir la explosividad con algunos factores adicionales.

Sistema de funciones ortonormales.Se sabe que:

Son orthogonales en el espacio [−∞,+∞]:∫ ∞

−∞dxe−x2

Hm(x)Hn(x) =√π2nn!δm,n

Entonces porque no usar la version normalisada:

Hn(x) =Hn(x)e−x2/2√√

π2nn!

Ahora son ortonormal:∫ ∞

−∞dxHm(x)Hn(x) = δm,n

Se puede demonstrar que además son completos:

∞∑n=0

Hn(x)Hn(x ′) = δ(x − x ′)

Sistema de funciones ortonormales.Se sabe que:

Son orthogonales en el espacio [−∞,+∞]:∫ ∞

−∞dxe−x2

Hm(x)Hn(x) =√π2nn!δm,n

Entonces porque no usar la version normalisada:

Hn(x) =Hn(x)e−x2/2√√

π2nn!

Ahora son ortonormal:∫ ∞

−∞dxHm(x)Hn(x) = δm,n

Se puede demonstrar que además son completos:

∞∑n=0

Hn(x)Hn(x ′) = δ(x − x ′)

Recursión modificada.

La recursión para la versión normalisada es diferente del original:

Hn+1(x) =Hn+1(x)e−x2/2√√π2n+1(n + 1)!

=2xHn(x)e−x2/2√√π2n+1(n + 1)!

− 2nHn−1(x)e−x2/2√√π2n+1(n + 1)!

=2x√

2(n + 1)Hn(x)− 2n√

22(n + 1)nHn−1(x)

= x

√2

n + 1Hn(x)−

√n

n + 1Hn−1(x)

Entonces tenemos:

Hn(x) = x

√2n

Hn−1(x)−√

1− 1n

Hn−2(x)

con H0(x) = π−14 e−x2/2, y H1 =

√2xH0(x) (ver recursión).

Recursión modificada.

La recursión para la versión normalisada es diferente del original:

Hn+1(x) =Hn+1(x)e−x2/2√√π2n+1(n + 1)!

=2xHn(x)e−x2/2√√π2n+1(n + 1)!

− 2nHn−1(x)e−x2/2√√π2n+1(n + 1)!

=2x√

2(n + 1)Hn(x)− 2n√

22(n + 1)nHn−1(x)

= x

√2

n + 1Hn(x)−

√n

n + 1Hn−1(x)

Entonces tenemos:

Hn(x) = x

√2n

Hn−1(x)−√

1− 1n

Hn−2(x)

con H0(x) = π−14 e−x2/2, y H1 =

√2xH0(x) (ver recursión).

Implementación.sf_hermite1.c

7 #define LN_SQRT_PI (0.5 * log(M_PI))8

9 /*! Calculates the normalized Hermite polynomial10 using a recurrence.11 \bug Works only up to \f$n=710\f$. */12 double hermite1(int n, double x)13 14 int m;15 double g_old, g, g_new;16

17 g_old = 0.0;18 g = exp(- 0.5 * (x * x + LN_SQRT_PI));19

20 if (n > 0) 21 for (m = 1; m <= n; m++) 22 g_new = sqrt(2.0/m) * x * g - sqrt(1.0 - 1.0/m) * g_old;23 g_old = g;24 g = g_new;25 26 27 return g;28

Resultados.main_sf_hermite1.c

-0.3

-0.2

-0.1

0

0.1

0.2

0.3

0.4

0 5 10 15 20 25 30 35 40 45 50

f(x)

x

"h1main.dat" in 7

Resultados.main_sf_hermite1.c

-0.5

-0.4

-0.3

-0.2

-0.1

0

0.1

0.2

0.3

0 5 10 15 20 25 30 35 40 45 50

f(x)

x

"h1main.dat" in 8

Resultados.main_sf_hermite1.c

-0.5

-0.4

-0.3

-0.2

-0.1

0

0.1

0.2

0.3

35 36 37 38 39 40

f(x)

x

"h1main.dat" in 8

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 polynomial10 using a recurrence. Works internally with11 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.5

-0.4

-0.3

-0.2

-0.1

0

0.1

0.2

0.3

0.4

35 36 37 38 39 40 41 42

f(x)

x

"h2main.dat" in 8"h1main.dat" in 8

¿Cuándo usar cuál versión?

¿Cuándo tenemos un problema UNDERFLOW?

La función Hn(x) tiene su ultimo máximo en la posición x ∼√

2n.Para empezar con la recursión usamos:

H0(x) = π−14 e−x2/2

cuyo valor al ultimo maximo de la función Hn(x) es

H0(√

2n) ∼ exp(−n)

Este valor tiene que estar más grande que el valor minimorepresentable:

exp(−n) > DBL_MIN

es equivalente a exp(n) < DBL_MAX entonces:

n < ln(DBL_MAX)

¿Cuándo usar cuál versión?

¿Cuándo tenemos un problema UNDERFLOW?

La función Hn(x) tiene su ultimo máximo en la posición x ∼√

2n.Para empezar con la recursión usamos:

H0(x) = π−14 e−x2/2

cuyo valor al ultimo maximo de la función Hn(x) es

H0(√

2n) ∼ exp(−n)

Este valor tiene que estar más grande que el valor minimorepresentable:

exp(−n) > DBL_MIN

es equivalente a exp(n) < DBL_MAX entonces:

n < ln(DBL_MAX)

¿Cuándo usar cuál versión?

¿Cuándo tenemos un problema UNDERFLOW?

La función Hn(x) tiene su ultimo máximo en la posición x ∼√

2n.Para empezar con la recursión usamos:

H0(x) = π−14 e−x2/2

cuyo valor al ultimo maximo de la función Hn(x) es

H0(√

2n) ∼ exp(−n)

Este valor tiene que estar más grande que el valor minimorepresentable:

exp(−n) > DBL_MIN

es equivalente a exp(n) < DBL_MAX entonces:

n < ln(DBL_MAX)

¿Cuándo usar cuál versión?

¿Cuándo tenemos un problema UNDERFLOW?

La función Hn(x) tiene su ultimo máximo en la posición x ∼√

2n.Para empezar con la recursión usamos:

H0(x) = π−14 e−x2/2

cuyo valor al ultimo maximo de la función Hn(x) es

H0(√

2n) ∼ exp(−n)

Este valor tiene que estar más grande que el valor minimorepresentable:

exp(−n) > DBL_MIN

es equivalente a exp(n) < DBL_MAX entonces:

n < ln(DBL_MAX)

Versión final.sf_hermite.c

1 /*! \file sf_hermite.c */2

3 #include <math.h>4 #include <float.h>5

6 #define NMAX ((int)(floor(log(DBL_MAX))))7

8 /*! Calculates the normalized Hermite polynomial using9 either double or long double version of the

10 recurrence. The decision depends on the level n in11 relation to its maximal x value where the polynomial12 ends. There the normalization factor is probed for13 being larger or smaller than DBL_MIN. */14 double hermite(int n, double x)15 16 double hermite1(int, double);17 double hermite2(int, double);18

19 return ((n < NMAX) ? hermite1(n, x) : hermite2(n, x));20

¿Cuál es el limite?main_sf_hermite.c

-0.3

-0.2

-0.1

0

0.1

0.2

0.3

145 146 147 148 149 150 151 152

"hmain.dat" in 11

¿Cuál es el limite?main_sf_hermite.c

-0.2

-0.15

-0.1

-0.05

0

0.05

0.1

0.15

148 148.5 149 149.5 150 150.5 151 151.5 152

"hmain.dat" in 12

Economizar.sf_hermite_array.c

Si uno necesita no solo una función Hn(x) para un n, sino un setn = 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.

Tenemos una recursión dada como:

yn+1 + anyn + bnyn−1 = 0

donde an y bn son algunos coeficientes.

Lamentablemente esta recursión tiene dos soluciones!Digamos las soluciones son fn y gn.Se puede calcular la recursión en dos direcciones:

positiva de n = 0 hasta n = Nnegativa de n = N hasta n = 0

En cada dirección una de las soluciones aumentaexponencialmente!Hay que elegir la dirección correcta para obtener la solucióndeseada!

Soluciones de una recursión.

Tenemos una recursión dada como:

yn+1 + anyn + bnyn−1 = 0

donde an y bn son algunos coeficientes.

Lamentablemente esta recursión tiene dos soluciones!Digamos las soluciones son fn y gn.Se puede calcular la recursión en dos direcciones:

positiva de n = 0 hasta n = Nnegativa de n = N hasta n = 0

En cada dirección una de las soluciones aumentaexponencialmente!Hay que elegir la dirección correcta para obtener la solucióndeseada!

Soluciones de una recursión.

Tenemos una recursión dada como:

yn+1 + anyn + bnyn−1 = 0

donde an y bn son algunos coeficientes.

Lamentablemente esta recursión tiene dos soluciones!Digamos las soluciones son fn y gn.Se puede calcular la recursión en dos direcciones:

positiva de n = 0 hasta n = Nnegativa de n = N hasta n = 0

En cada dirección una de las soluciones aumentaexponencialmente!Hay que elegir la dirección correcta para obtener la solucióndeseada!

Soluciones de una recursión.

Tenemos una recursión dada como:

yn+1 + anyn + bnyn−1 = 0

donde an y bn son algunos coeficientes.

Lamentablemente esta recursión tiene dos soluciones!Digamos las soluciones son fn y gn.Se puede calcular la recursión en dos direcciones:

positiva de n = 0 hasta n = Nnegativa de n = N hasta n = 0

En cada dirección una de las soluciones aumentaexponencialmente!Hay que elegir la dirección correcta para obtener la solucióndeseada!

Ejemplo: Función de Bessel.La función de Bessel Jn(x) tiene la recursión:

yn+1 − 2anyn + yn−1 = 0, an =nx

¿Es estable?Se hace la aproximación: an → a = const:

yn+1 − 2ayn + yn−1 = 0

Idéa para una solución: yn = bn:

b2 − 2ab + 1 = 0

entonces dos soluciones:

b = a±√

a2 − 1

Recursión es estable para n = 0 → N (dirección positiva) si|b| ≤ 1, lo cual es posible solamente si |a| ≤ 1.Como an = n/x eso significa:

n ≤ x

Problemas con n largo!

Ejemplo: Función de Bessel.La función de Bessel Jn(x) tiene la recursión:

yn+1 − 2anyn + yn−1 = 0, an =nx

¿Es estable?Se hace la aproximación: an → a = const:

yn+1 − 2ayn + yn−1 = 0

Idéa para una solución: yn = bn:

b2 − 2ab + 1 = 0

entonces dos soluciones:

b = a±√

a2 − 1

Recursión es estable para n = 0 → N (dirección positiva) si|b| ≤ 1, lo cual es posible solamente si |a| ≤ 1.Como an = n/x eso significa:

n ≤ x

Problemas con n largo!

Ejemplo: Función de Bessel.La función de Bessel Jn(x) tiene la recursión:

yn+1 − 2anyn + yn−1 = 0, an =nx

¿Es estable?Se hace la aproximación: an → a = const:

yn+1 − 2ayn + yn−1 = 0

Idéa para una solución: yn = bn:

b2 − 2ab + 1 = 0

entonces dos soluciones:

b = a±√

a2 − 1

Recursión es estable para n = 0 → N (dirección positiva) si|b| ≤ 1, lo cual es posible solamente si |a| ≤ 1.Como an = n/x eso significa:

n ≤ x

Problemas con n largo!

Ejemplo: Función de Bessel.La función de Bessel Jn(x) tiene la recursión:

yn+1 − 2anyn + yn−1 = 0, an =nx

¿Es estable?Se hace la aproximación: an → a = const:

yn+1 − 2ayn + yn−1 = 0

Idéa para una solución: yn = bn:

b2 − 2ab + 1 = 0

entonces dos soluciones:

b = a±√

a2 − 1

Recursión es estable para n = 0 → N (dirección positiva) si|b| ≤ 1, lo cual es posible solamente si |a| ≤ 1.Como an = n/x eso significa:

n ≤ x

Problemas con n largo!

Estabilidad para polinomiales de Hermite.La recursión es:

yn+1 − x

√2

n + 1︸ ︷︷ ︸=an

yn +

√n

n + 1︸ ︷︷ ︸≈1

yn−1 = 0

Aproximación: an → a = const:

yn+1 − ayn + yn−1 = 0

Solución: de yn = bn sale b2 − ab + 1 = 0 y entonces tenemosdos soluciones:

b =a2±√(a

2

)2− 1

Estable para n = 0 → N solamente si |b| ≤ 1 y entonces |a| ≤ 2.Con an = x

√2/(n + 1) sale la condición:

|x | ≤√

2(n + 1)

Esta bien porque el ultimo peak es donde x ∼ ±√

2n.

Estabilidad para polinomiales de Hermite.La recursión es:

yn+1 − x

√2

n + 1︸ ︷︷ ︸=an

yn +

√n

n + 1︸ ︷︷ ︸≈1

yn−1 = 0

Aproximación: an → a = const:

yn+1 − ayn + yn−1 = 0

Solución: de yn = bn sale b2 − ab + 1 = 0 y entonces tenemosdos soluciones:

b =a2±√(a

2

)2− 1

Estable para n = 0 → N solamente si |b| ≤ 1 y entonces |a| ≤ 2.Con an = x

√2/(n + 1) sale la condición:

|x | ≤√

2(n + 1)

Esta bien porque el ultimo peak es donde x ∼ ±√

2n.

Estabilidad para polinomiales de Hermite.La recursión es:

yn+1 − x

√2

n + 1︸ ︷︷ ︸=an

yn +

√n

n + 1︸ ︷︷ ︸≈1

yn−1 = 0

Aproximación: an → a = const:

yn+1 − ayn + yn−1 = 0

Solución: de yn = bn sale b2 − ab + 1 = 0 y entonces tenemosdos soluciones:

b =a2±√(a

2

)2− 1

Estable para n = 0 → N solamente si |b| ≤ 1 y entonces |a| ≤ 2.Con an = x

√2/(n + 1) sale la condición:

|x | ≤√

2(n + 1)

Esta bien porque el ultimo peak es donde x ∼ ±√

2n.

Estabilidad para polinomiales de Hermite.La recursión es:

yn+1 − x

√2

n + 1︸ ︷︷ ︸=an

yn +

√n

n + 1︸ ︷︷ ︸≈1

yn−1 = 0

Aproximación: an → a = const:

yn+1 − ayn + yn−1 = 0

Solución: de yn = bn sale b2 − ab + 1 = 0 y entonces tenemosdos soluciones:

b =a2±√(a

2

)2− 1

Estable para n = 0 → N solamente si |b| ≤ 1 y entonces |a| ≤ 2.Con an = x

√2/(n + 1) sale la condición:

|x | ≤√

2(n + 1)

Esta bien porque el ultimo peak es donde x ∼ ±√

2n.

Ecuación de Schrödinger.

Oscilador anarmonico con fuerza externa:

i~∂

∂t|ψ(t)〉 =

p2

2m+

mω2

2(x2 + ax4)+ xF (t)

|ψ(t)〉

Anarmonicidad aFuerza externa F (t)

Problema conocido con solucion analítica:(oscilador armónico)

i~∂

∂t|ψ(t)〉 =

p2

2m+

mω2x2

2

︸ ︷︷ ︸

=H0

|ψ(t)〉

Ecuación de Schrödinger.

Oscilador anarmonico con fuerza externa:

i~∂

∂t|ψ(t)〉 =

p2

2m+

mω2

2(x2 + ax4)+ xF (t)

|ψ(t)〉

Anarmonicidad aFuerza externa F (t)

Problema conocido con solucion analítica:(oscilador armónico)

i~∂

∂t|ψ(t)〉 =

p2

2m+

mω2x2

2

︸ ︷︷ ︸

=H0

|ψ(t)〉

Expansión en auto-soluciones del oscilador armónico.Para el oscilador armónico con Hamiltoniano

H0 =p2

2m+

mω2x2

2,

la solución es:

H0|n〉 = ~ωn|n〉, ωn = ω

(n +

12

), (n = 0,1, . . . ,∞)

donde

〈x |n〉 = φn(x) =Hn

(x/∆x0√

2

)√√

2π∆x02nn!e−(x/∆x0)

2/4 =Hn

(x/∆x0√

2

)√√

2∆x0

donde la varianza de |ψ0(x)|2 es dado por el largo

∆x0 =

√~

2mωUna expansión se puede hacer asi:

|ψ(t)〉 =∞∑

n=0

|n〉 〈n|ψ(t)〉︸ ︷︷ ︸=ψn(t)

=∞∑

n=0

ψn(t)|n〉

Expansión en auto-soluciones del oscilador armónico.Para el oscilador armónico con Hamiltoniano

H0 =p2

2m+

mω2x2

2,

la solución es:

H0|n〉 = ~ωn|n〉, ωn = ω

(n +

12

), (n = 0,1, . . . ,∞)

donde

〈x |n〉 = φn(x) =Hn

(x/∆x0√

2

)√√

2π∆x02nn!e−(x/∆x0)

2/4 =Hn

(x/∆x0√

2

)√√

2∆x0

donde la varianza de |ψ0(x)|2 es dado por el largo

∆x0 =

√~

2mωUna expansión se puede hacer asi:

|ψ(t)〉 =∞∑

n=0

|n〉 〈n|ψ(t)〉︸ ︷︷ ︸=ψn(t)

=∞∑

n=0

ψn(t)|n〉

En nuestro caso.

1 Expansión:

i~∂〈n|ψ(t)〉

∂t= 〈n|

p2

2m+

mω2

2(x2 + ax4)+ xF (t)

|ψ(t)〉

= 〈n|

H0 +mω2ax4

2+ xF (t)

|ψ(t)〉

= ~ωn〈n|ψ(t)〉+∞∑

m=0

〈n|

mω2ax4

2+ xF (t)

|m〉︸ ︷︷ ︸

=~Vn,m(t)

〈m|ψ(t)〉

2 Problema para resolver con ψn(t) = 〈n|ψ(t)〉: ecuacióndiferencial ordinaria

ddtψn(t) = −iωnψn(t)− i

∞∑m=0

Vn,m(t)ψm(t)

En nuestro caso.

1 Expansión:

i~∂〈n|ψ(t)〉

∂t= 〈n|

p2

2m+

mω2

2(x2 + ax4)+ xF (t)

|ψ(t)〉

= 〈n|

H0 +mω2ax4

2+ xF (t)

|ψ(t)〉

= ~ωn〈n|ψ(t)〉+∞∑

m=0

〈n|

mω2ax4

2+ xF (t)

|m〉︸ ︷︷ ︸

=~Vn,m(t)

〈m|ψ(t)〉

2 Problema para resolver con ψn(t) = 〈n|ψ(t)〉: ecuacióndiferencial ordinaria

ddtψn(t) = −iωnψn(t)− i

∞∑m=0

Vn,m(t)ψm(t)

Tiempo sin dimensión.

1 Usamos una frecuencia caracteristica ωc para definir el tiemposin dimensión:

τ = ωc t

2 Resulta nueva ecuación diferencial (ψn = dψn/dτ ):

ψn(τ) = −iω′nψn(τ)− i∞∑

m=0

V ′n,m(τ)ψm(τ)

donde

ω′n = ω′(n +12

), ω′ =ω

ωc

V ′n,m(τ) =

1ωc

Vn,m(τ)

Tiempo sin dimensión.

1 Usamos una frecuencia caracteristica ωc para definir el tiemposin dimensión:

τ = ωc t

2 Resulta nueva ecuación diferencial (ψn = dψn/dτ ):

ψn(τ) = −iω′nψn(τ)− i∞∑

m=0

V ′n,m(τ)ψm(τ)

donde

ω′n = ω′(n +12

), ω′ =ω

ωc

V ′n,m(τ) =

1ωc

Vn,m(τ)

Calculación de la matriz.

La matriz de perturbación (con respecto al oscilador armónico)es:

V ′n,m(τ) =

1~ωc

〈n|

mω2ax4

2+ xF (τ)

|m〉

Operadores de creación y destrucción de cuantas energeticasdel oscilador:

x = ∆x0(a + a†), p = i∆p0(a− a†), ∆x0∆p0 = ~/2

Asi H0 = ~ω(a†a + 12 ) y tenemos las relaciones:

a|n〉 =√

n|n − 1〉, a†|n〉 =√

n + 1|n + 1〉, [a, a†] = 1

La matriz es ahora:

V ′n,m(τ) =

mω2a2~ωc

(∆x0)4︸ ︷︷ ︸

=a′

〈n|(a† + a

)4 |m〉+F (τ)

~ωc∆x0︸ ︷︷ ︸

=F ′(τ)

〈n|(a† + a

)|m〉

Calculación de la matriz.

La matriz de perturbación (con respecto al oscilador armónico)es:

V ′n,m(τ) =

1~ωc

〈n|

mω2ax4

2+ xF (τ)

|m〉

Operadores de creación y destrucción de cuantas energeticasdel oscilador:

x = ∆x0(a + a†), p = i∆p0(a− a†), ∆x0∆p0 = ~/2

Asi H0 = ~ω(a†a + 12 ) y tenemos las relaciones:

a|n〉 =√

n|n − 1〉, a†|n〉 =√

n + 1|n + 1〉, [a, a†] = 1

La matriz es ahora:

V ′n,m(τ) =

mω2a2~ωc

(∆x0)4︸ ︷︷ ︸

=a′

〈n|(a† + a

)4 |m〉+F (τ)

~ωc∆x0︸ ︷︷ ︸

=F ′(τ)

〈n|(a† + a

)|m〉

Calculación de la matriz.

La matriz de perturbación (con respecto al oscilador armónico)es:

V ′n,m(τ) =

1~ωc

〈n|

mω2ax4

2+ xF (τ)

|m〉

Operadores de creación y destrucción de cuantas energeticasdel oscilador:

x = ∆x0(a + a†), p = i∆p0(a− a†), ∆x0∆p0 = ~/2

Asi H0 = ~ω(a†a + 12 ) y tenemos las relaciones:

a|n〉 =√

n|n − 1〉, a†|n〉 =√

n + 1|n + 1〉, [a, a†] = 1

La matriz es ahora:

V ′n,m(τ) =

mω2a2~ωc

(∆x0)4︸ ︷︷ ︸

=a′

〈n|(a† + a

)4 |m〉+F (τ)

~ωc∆x0︸ ︷︷ ︸

=F ′(τ)

〈n|(a† + a

)|m〉

Dimensiones de los coeficientes

1 Fuerza externa: [F (τ)∆x0] = J entonces fuerza sin dimensión:

F ′(τ) =F (τ)∆x0

~ωc

2 Anarmonicidad: [a] = m−2 entonces

a′ = amω2(∆x0)

4

2~ωc=

a4

2mω~︸ ︷︷ ︸

=(∆x0)−2

(∆x0)4 ω

ωc︸︷︷︸=ω′

=[a(∆x0)

2]ω′

4

3 Resulta matriz de perturbación:

V ′n,m(τ) = a′〈n|

(a† + a

)4 |m〉+ F ′(τ)〈n|(a† + a

)|m〉

Dimensiones de los coeficientes

1 Fuerza externa: [F (τ)∆x0] = J entonces fuerza sin dimensión:

F ′(τ) =F (τ)∆x0

~ωc

2 Anarmonicidad: [a] = m−2 entonces

a′ = amω2(∆x0)

4

2~ωc=

a4

2mω~︸ ︷︷ ︸

=(∆x0)−2

(∆x0)4 ω

ωc︸︷︷︸=ω′

=[a(∆x0)

2]ω′

4

3 Resulta matriz de perturbación:

V ′n,m(τ) = a′〈n|

(a† + a

)4 |m〉+ F ′(τ)〈n|(a† + a

)|m〉

Dimensiones de los coeficientes

1 Fuerza externa: [F (τ)∆x0] = J entonces fuerza sin dimensión:

F ′(τ) =F (τ)∆x0

~ωc

2 Anarmonicidad: [a] = m−2 entonces

a′ = amω2(∆x0)

4

2~ωc=

a4

2mω~︸ ︷︷ ︸

=(∆x0)−2

(∆x0)4 ω

ωc︸︷︷︸=ω′

=[a(∆x0)

2]ω′

4

3 Resulta matriz de perturbación:

V ′n,m(τ) = a′〈n|

(a† + a

)4 |m〉+ F ′(τ)〈n|(a† + a

)|m〉

Elementos de la matriz 1.Calcular 〈n|(a† + a)k |m〉 (k = 1, 4).

1 La primera matriz es:

〈n|(a† + a)|m〉 = 〈n|√

m + 1|m + 1〉+ 〈n|√

m|m − 1〉=

√nδn,m+1 +

√mδn,m−1

Son transiciones m → m ± 1.2 La segunda es más complicada (n = a†a):

〈n|(a† + a

)4 |m〉 = 〈n|

a†a† + aa + a†a + aa†︸ ︷︷ ︸=2n+1

2

|m〉

= 〈n|[(

a†a† + aa)2

+ (2n + 1)2 +(a†a† + aa

)(2n + 1)

]|m〉

+〈n|(2n + 1)(a†a† + aa

)|m〉

= 〈n|(a†a† + aa

)2 |m〉+ (2m + 1)2δn,m

+2(m + n + 1)〈n|(a†a† + aa

)|m〉

Elementos de la matriz 1.Calcular 〈n|(a† + a)k |m〉 (k = 1, 4).

1 La primera matriz es:

〈n|(a† + a)|m〉 = 〈n|√

m + 1|m + 1〉+ 〈n|√

m|m − 1〉=

√nδn,m+1 +

√mδn,m−1

Son transiciones m → m ± 1.2 La segunda es más complicada (n = a†a):

〈n|(a† + a

)4 |m〉 = 〈n|

a†a† + aa + a†a + aa†︸ ︷︷ ︸=2n+1

2

|m〉

= 〈n|[(

a†a† + aa)2

+ (2n + 1)2 +(a†a† + aa

)(2n + 1)

]|m〉

+〈n|(2n + 1)(a†a† + aa

)|m〉

= 〈n|(a†a† + aa

)2 |m〉+ (2m + 1)2δn,m

+2(m + n + 1)〈n|(a†a† + aa

)|m〉

Elementos de la matriz 2.Calcular 〈n|(a†a† + aa)k |m〉 (k = 1, 2).

1 Con k = 1 tenemos transiciones m → m ± 2:

= 〈n|√

(m + 2)(m + 1)|m + 2〉+ 〈n|√

(m − 1)m|m − 2〉

=

√n!

(n − 2)!δn,m+2 +

√m!

(m − 2)!δn,m−2

2 Para k = 2 son transiciones m → m,m ± 4:

= 〈n|(a†a†a†a† + aaaa + a†a†aa + aaa†a†)|m〉=

√(m + 4)(m + 3)(m + 2)(m + 1)δn,m+4

+√

(m − 3)(m − 2)(m − 1)mδn,m−4

+[m(m − 1) + (m + 2)(m + 1)]δn,m

=

√n!

(n − 4)!δn,m+4 +

√m!

(m − 4)!δn,m−4

+

[m!

(m − 2)!+

(m + 2)!

m!

]δn,m

Elementos de la matriz 2.Calcular 〈n|(a†a† + aa)k |m〉 (k = 1, 2).

1 Con k = 1 tenemos transiciones m → m ± 2:

= 〈n|√

(m + 2)(m + 1)|m + 2〉+ 〈n|√

(m − 1)m|m − 2〉

=

√n!

(n − 2)!δn,m+2 +

√m!

(m − 2)!δn,m−2

2 Para k = 2 son transiciones m → m,m ± 4:

= 〈n|(a†a†a†a† + aaaa + a†a†aa + aaa†a†)|m〉=

√(m + 4)(m + 3)(m + 2)(m + 1)δn,m+4

+√

(m − 3)(m − 2)(m − 1)mδn,m−4

+[m(m − 1) + (m + 2)(m + 1)]δn,m

=

√n!

(n − 4)!δn,m+4 +

√m!

(m − 4)!δn,m−4

+

[m!

(m − 2)!+

(m + 2)!

m!

]δn,m

Matriz de perturbación completa.

V ′n,m(τ) = 3a′ [2m(m + 1) + 1] δn,m

+ F ′(τ)(√

nδn,m+1 +√

mδn,m−1)

+ 2a′[(2n − 1)

√n!

(n − 2)!δn,m+2 + (2m − 1)

√m!

(m − 2)!δn,m−2

]

+ a′[√

n!

(n − 4)!δn,m+4 +

√m!

(m − 4)!δn,m−4

]

Calcular la función de onda.Queremos saber ψ(x , τ) = 〈x |ψ(τ)〉, o la densidad de probabilidad

p(x , τ) = |ψ(x , τ)|2

Expansion en auto-estados del oscilador armonico:

ψ(x , τ) = 〈x |ψ(τ)〉 =N−1∑n=0

〈x |n〉︸ ︷︷ ︸=φn(x)

〈n|ψ(τ)〉︸ ︷︷ ︸=ψn(τ)

Queremos todo sin dimensiones: t → τ = ωc tFalta solo x → ξ = x/(∆x0

√2):

p(x , τ)dx = p(ξ, τ)dξ

entonces:

p(ξ, τ) = p(x , τ)dxdξ

= ∆x0√

2p(x , τ) =

∣∣∣∣∣∣∣∣√√

2∆x0ψ(x , τ)︸ ︷︷ ︸=ψ(ξ,τ)

∣∣∣∣∣∣∣∣2

Calcular la función de onda.Queremos saber ψ(x , τ) = 〈x |ψ(τ)〉, o la densidad de probabilidad

p(x , τ) = |ψ(x , τ)|2

Expansion en auto-estados del oscilador armonico:

ψ(x , τ) = 〈x |ψ(τ)〉 =N−1∑n=0

〈x |n〉︸ ︷︷ ︸=φn(x)

〈n|ψ(τ)〉︸ ︷︷ ︸=ψn(τ)

Queremos todo sin dimensiones: t → τ = ωc tFalta solo x → ξ = x/(∆x0

√2):

p(x , τ)dx = p(ξ, τ)dξ

entonces:

p(ξ, τ) = p(x , τ)dxdξ

= ∆x0√

2p(x , τ) =

∣∣∣∣∣∣∣∣√√

2∆x0ψ(x , τ)︸ ︷︷ ︸=ψ(ξ,τ)

∣∣∣∣∣∣∣∣2

Calcular la función de onda.Queremos saber ψ(x , τ) = 〈x |ψ(τ)〉, o la densidad de probabilidad

p(x , τ) = |ψ(x , τ)|2

Expansion en auto-estados del oscilador armonico:

ψ(x , τ) = 〈x |ψ(τ)〉 =N−1∑n=0

〈x |n〉︸ ︷︷ ︸=φn(x)

〈n|ψ(τ)〉︸ ︷︷ ︸=ψn(τ)

Queremos todo sin dimensiones: t → τ = ωc tFalta solo x → ξ = x/(∆x0

√2):

p(x , τ)dx = p(ξ, τ)dξ

entonces:

p(ξ, τ) = p(x , τ)dxdξ

= ∆x0√

2p(x , τ) =

∣∣∣∣∣∣∣∣√√

2∆x0ψ(x , τ)︸ ︷︷ ︸=ψ(ξ,τ)

∣∣∣∣∣∣∣∣2

Auto-soluciones sin dimensión.

Nueva función de onda es (x = ∆x0√

2ξ):

ψ(ξ, τ) =

√√2∆x0ψ(x , τ) =

N−1∑n=0

√√2∆x0φn(∆x0

√2ξ)︸ ︷︷ ︸

=φn(ξ)

ψn(τ)

Tenemos ahora la auto-solución:

φn(ξ) =

√√2∆x0〈∆x0

√2ξ|n〉

=

√√2∆x0

1√√2∆x0

Hn

(∆x0

√2ξ

∆x0√

2

)= Hn(ξ)

Auto-soluciones sin dimensión.

Nueva función de onda es (x = ∆x0√

2ξ):

ψ(ξ, τ) =

√√2∆x0ψ(x , τ) =

N−1∑n=0

√√2∆x0φn(∆x0

√2ξ)︸ ︷︷ ︸

=φn(ξ)

ψn(τ)

Tenemos ahora la auto-solución:

φn(ξ) =

√√2∆x0〈∆x0

√2ξ|n〉

=

√√2∆x0

1√√2∆x0

Hn

(∆x0

√2ξ

∆x0√

2

)= Hn(ξ)

Clenshaw para ψ(ξ, τ).Hay que calcular ψ(ξ, τ) =

Pn Hn(ξ)ψn(τ).

1 Tenemos una recursión para Hn(ξ):

Hn+1(ξ) = ξ

√2

n + 1︸ ︷︷ ︸=αn(ξ)

Hn(ξ)−√

nn + 1︸ ︷︷ ︸=βn

Hn−1(ξ)

2 Nueva función (n = N − 1, . . . ,0):

hn(ξ, τ) = αn(ξ)hn+1(ξ, τ) + βn+1hn+1(ξ, τ) + ψn(τ)

Corresponde a

hn(ξ, τ) = ξ

√2

n + 1hn+1(ξ, τ)−

√n + 1n + 2

hn+2(ξ, τ) + ψn(τ)

3 Solución es:

ψ(ξ, τ) = h0(ξ, τ)H0(ξ) + h1(ξ, τ)[H1(ξ)− α0(ξ)H0(ξ)

]︸ ︷︷ ︸

=0

= h0(ξ, τ)H0(ξ)

= h0(ξ, τ)π− 1

4 e−ξ2/2

Clenshaw para ψ(ξ, τ).Hay que calcular ψ(ξ, τ) =

Pn Hn(ξ)ψn(τ).

1 Tenemos una recursión para Hn(ξ):

Hn+1(ξ) = ξ

√2

n + 1︸ ︷︷ ︸=αn(ξ)

Hn(ξ)−√

nn + 1︸ ︷︷ ︸=βn

Hn−1(ξ)

2 Nueva función (n = N − 1, . . . ,0):

hn(ξ, τ) = αn(ξ)hn+1(ξ, τ) + βn+1hn+1(ξ, τ) + ψn(τ)

Corresponde a

hn(ξ, τ) = ξ

√2

n + 1hn+1(ξ, τ)−

√n + 1n + 2

hn+2(ξ, τ) + ψn(τ)

3 Solución es:

ψ(ξ, τ) = h0(ξ, τ)H0(ξ) + h1(ξ, τ)[H1(ξ)− α0(ξ)H0(ξ)

]︸ ︷︷ ︸

=0

= h0(ξ, τ)H0(ξ)

= h0(ξ, τ)π− 1

4 e−ξ2/2

Clenshaw para ψ(ξ, τ).Hay que calcular ψ(ξ, τ) =

Pn Hn(ξ)ψn(τ).

1 Tenemos una recursión para Hn(ξ):

Hn+1(ξ) = ξ

√2

n + 1︸ ︷︷ ︸=αn(ξ)

Hn(ξ)−√

nn + 1︸ ︷︷ ︸=βn

Hn−1(ξ)

2 Nueva función (n = N − 1, . . . ,0):

hn(ξ, τ) = αn(ξ)hn+1(ξ, τ) + βn+1hn+1(ξ, τ) + ψn(τ)

Corresponde a

hn(ξ, τ) = ξ

√2

n + 1hn+1(ξ, τ)−

√n + 1n + 2

hn+2(ξ, τ) + ψn(τ)

3 Solución es:

ψ(ξ, τ) = h0(ξ, τ)H0(ξ) + h1(ξ, τ)[H1(ξ)− α0(ξ)H0(ξ)

]︸ ︷︷ ︸

=0

= h0(ξ, τ)H0(ξ)

= h0(ξ, τ)π− 1

4 e−ξ2/2

Implementación.de_wavefunc.c

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) position12 ’x’ for the state being encoded by harmonic-oscillator13 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_old22 + 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 20012 #define A 0.0213 #define F 0.014 #define OMEGA_F 1.015 #define R 2.016 #define PHI (0.1 * M_PI)17

18 /* for printing */19 #define X 7.020 #define N 15021

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, double,25 void (*)(complex double*, complex double*, double));

Programa.main_de_wavefunc.c

27 /*! Calculates initial state as coherent state of28 amplitude R * exp(I*PHI). */29 void calc_ini(complex double* psi)30 31 size_t n;32 double res, tmp;33

34 res = 0.0;35 for (n = 0; n < SZ; n++) 36 psi[n] = cexp(n * PHI * I) * sqrt(poisson(n, R*R));37 tmp = cabs(psi[n]);38 res += tmp * tmp;39 40 if (fabs(res-1.0) > 1.0e-5)41 fprintf(stderr, "R too large!\n");42

Programa.main_de_wavefunc.c

44 /*! Calculates the external force of the form45 F * cos(OMEGA_F * t). */46 double force(double t)47 48 return F * cos(OMEGA_F * t);49

Programa.main_de_wavefunc.c

51 void f(complex double *dpsidt, complex double *psi, double t)52 53 size_t n;54 /* all is rotating with exp[-i (0.5 + 3.0 * A)t] */55 for (n = 0; n < SZ; n++) 56 dpsidt[n] = - I * ( (n + 6.0 * A * n * (n+1.0)) * psi[n]57 + ((n < 1) ? 0.0 : ( force(t) * sqrt(n) * psi[n-1] ))58 + ((n < 2) ? 0.0 : ( 2.0 * A * (2.0 * n - 1.0) * sqrt(n * (n-1.0)) * psi[n-2]))59 + ((n < 4) ? 0.0 : (A * sqrt(n * (n-1.0) * (n-2.0) * (n-3.0)) * psi[n-4]))60 + ((n > (SZ-5)) ? 0.0 : (A * sqrt((n+4.0) * (n+3.0) * (n+2.0) * (n+1.0)) * psi[n+4]))61 + ((n > (SZ-3)) ? 0.0 : (2.0 * A * (2.0 * n + 3.0) * sqrt((n+2.0) * (n+1.0)) * psi[n+2]))62 + ((n > (SZ-2)) ? 0.0 : ( force(t) * sqrt(n+1) * psi[n+1])) );63 64

Programa.main_de_wavefunc.c

66 /*! Checks for overflow problems in the state vector. */67 int overflow(complex double* psi, unsigned offset, double limit)68 69 size_t n;70 double tmp;71

72 for (n = SZ-offset-1; n < SZ; n++) 73 tmp = cabs(psi[n]);74 limit -= tmp * tmp;75 76 return ((limit < 0.0) ? 1 : 0);77

Programa.main_de_wavefunc.c

79 /*! Calculates the norm of the state. */80 double norm(complex double* psi)81 82 size_t n;83 double res, tmp;84

85 res = 0.0;86 for (n = 0; n < SZ; n++) 87 tmp = cabs(psi[n]);88 res += tmp * tmp;89 90 return res;91

Programa.main_de_wavefunc.c

93 /*! Prints the modulus square of the wavefunction. */94 void print_probability(complex double* psi)95 96 double x, dx, prob;97 complex double psix;98 int i;99

100 dx = 2.0 * X / N;101 x = -X;102 for (i = 0; i < N; i++) 103 psix = wavefunction(x, psi, SZ);104 prob = cabs(psix);105 prob *= prob;106 printf("%f %f\n", x, prob);107 x += dx;108 109 printf("\n\n\n");110

Programa.main_de_wavefunc.c

113 int main(void)114 115 complex double psi[SZ];116 double t, tmax, tstep, tmp;117 int min_cnt;118

119 tmax = 24.0;120 tstep = 0.05;121

122 calc_ini(psi);123 for (t = 0; t < tmax; t += tstep) 124 printf("# t = %f\n", t);125 print_probability(psi);126 min_cnt = de_solve_cpx(psi, SZ, t, t+tstep, 1.0e-7, 1.0e-10, f);127 if (min_cnt != 0)128 fprintf(stderr, "# at t = %f, (# of counts of h < hmin) = %d\n", t, min_cnt);129 if (overflow(psi, 10, 0.01))130 fprintf(stderr, "# at t = %f, population in last 10 levels too high!\n", t);131 tmp = norm(psi);132 if (fabs(tmp-1.0) > 1.0e-5)133 fprintf(stderr, "# at t = %f, norm = %f\n", t, tmp);134 135 return 0;136

Animación en GNUplot.1 #GNUPLOT ANIMATION2 cd "../dat"3 unset key4 set xlabel "x"5 set ylabel "p(x,t)"6 set yrange [0:1.0]7 #set term postscript eps color enhanced8 pause 0.2; plot "wavefuncmain.dat" in 0 with lin lw 39 pause 0.2; plot "wavefuncmain.dat" in 1 with lin lw 3

10 pause 0.2; plot "wavefuncmain.dat" in 2 with lin lw 311 pause 0.2; plot "wavefuncmain.dat" in 3 with lin lw 312 pause 0.2; plot "wavefuncmain.dat" in 4 with lin lw 313 pause 0.2; plot "wavefuncmain.dat" in 5 with lin lw 314 pause 0.2; plot "wavefuncmain.dat" in 6 with lin lw 315 pause 0.2; plot "wavefuncmain.dat" in 7 with lin lw 316 pause 0.2; plot "wavefuncmain.dat" in 8 with lin lw 317 pause 0.2; plot "wavefuncmain.dat" in 9 with lin lw 318 pause 0.2; plot "wavefuncmain.dat" in 10 with lin lw 319 pause 0.2; plot "wavefuncmain.dat" in 11 with lin lw 320 pause 0.2; plot "wavefuncmain.dat" in 12 with lin lw 321 pause 0.2; plot "wavefuncmain.dat" in 13 with lin lw 322 pause 0.2; plot "wavefuncmain.dat" in 14 with lin lw 323 pause 0.2; plot "wavefuncmain.dat" in 15 with lin lw 324 pause 0.2; plot "wavefuncmain.dat" in 16 with lin lw 3

Espacio de fase en la mecanica cuántica.

Como x y p no conmutan, no es posible especificar el estado físicodel sistema con un punto (x ,p) en el espacio de fase!Eso significa:

¿Espacio de fase no existe?¿Espacio de fase existe, pero no sabemos como esta definido?¿La distribución en en espacio de fase no es una probabilidadsino una casi-probabilidad?

Espacio de fase en la mecanica cuántica.

Como x y p no conmutan, no es posible especificar el estado físicodel sistema con un punto (x ,p) en el espacio de fase!Eso significa:

¿Espacio de fase no existe?¿Espacio de fase existe, pero no sabemos como esta definido?¿La distribución en en espacio de fase no es una probabilidadsino una casi-probabilidad?

Espacio de fase en la mecanica cuántica.

Como x y p no conmutan, no es posible especificar el estado físicodel sistema con un punto (x ,p) en el espacio de fase!Eso significa:

¿Espacio de fase no existe?¿Espacio de fase existe, pero no sabemos como esta definido?¿La distribución en en espacio de fase no es una probabilidadsino una casi-probabilidad?

Espacio de fase en la mecanica cuántica.

Como x y p no conmutan, no es posible especificar el estado físicodel sistema con un punto (x ,p) en el espacio de fase!Eso significa:

¿Espacio de fase no existe?¿Espacio de fase existe, pero no sabemos como esta definido?¿La distribución en en espacio de fase no es una probabilidadsino una casi-probabilidad?

Espacio de fase y estados coherentes.

Tenemos los operadores del oscilador armónico:

x = ∆x0(a† + a), p = i∆p0(a† − a)

Un estado coherente es algo que oscilla como un osciladorarmónico:

|γ〉 =∞∑

n=0

γn√

n!e−|γ|

2/2

Son auto-estados del operador de destrucción:

a|γ〉 = γ|γ〉

Idéa:<(γ) ∼ x , =(γ) ∼ p → espacio de fase

Falta solamente la probabilidad para estar en el estado |γ〉:

Pγ = |〈γ|ψ〉|2

Espacio de fase y estados coherentes.

Tenemos los operadores del oscilador armónico:

x = ∆x0(a† + a), p = i∆p0(a† − a)

Un estado coherente es algo que oscilla como un osciladorarmónico:

|γ〉 =∞∑

n=0

γn√

n!e−|γ|

2/2

Son auto-estados del operador de destrucción:

a|γ〉 = γ|γ〉

Idéa:<(γ) ∼ x , =(γ) ∼ p → espacio de fase

Falta solamente la probabilidad para estar en el estado |γ〉:

Pγ = |〈γ|ψ〉|2

Espacio de fase y estados coherentes.

Tenemos los operadores del oscilador armónico:

x = ∆x0(a† + a), p = i∆p0(a† − a)

Un estado coherente es algo que oscilla como un osciladorarmónico:

|γ〉 =∞∑

n=0

γn√

n!e−|γ|

2/2

Son auto-estados del operador de destrucción:

a|γ〉 = γ|γ〉

Idéa:<(γ) ∼ x , =(γ) ∼ p → espacio de fase

Falta solamente la probabilidad para estar en el estado |γ〉:

Pγ = |〈γ|ψ〉|2

Husimi Q.

Problema:

Dado: Coeficientes ψn = 〈n|ψ〉 del estado |ψ〉 en base deauto-estados |n〉 del oscilador armonico para n = 0, . . . ,N − 1.Queremos: Calcular la funcion Husimi Q

Q(γ) =1π|〈γ|ψ〉|2

Calculemos primero:

〈γ|ψ〉 = 〈γ|1|ψ〉 ≈ 〈γ|

(N−1∑n=0

|n〉〈n|

)|ψ〉 =

N−1∑n=0

φn(γ)ψn

donde φn(γ) = 〈γ|n〉 tiene una recursion.

Husimi Q.

Problema:

Dado: Coeficientes ψn = 〈n|ψ〉 del estado |ψ〉 en base deauto-estados |n〉 del oscilador armonico para n = 0, . . . ,N − 1.Queremos: Calcular la funcion Husimi Q

Q(γ) =1π|〈γ|ψ〉|2

Calculemos primero:

〈γ|ψ〉 = 〈γ|1|ψ〉 ≈ 〈γ|

(N−1∑n=0

|n〉〈n|

)|ψ〉 =

N−1∑n=0

φn(γ)ψn

donde φn(γ) = 〈γ|n〉 tiene una recursion.

Husimi Q.

Problema:

Dado: Coeficientes ψn = 〈n|ψ〉 del estado |ψ〉 en base deauto-estados |n〉 del oscilador armonico para n = 0, . . . ,N − 1.Queremos: Calcular la funcion Husimi Q

Q(γ) =1π|〈γ|ψ〉|2

Calculemos primero:

〈γ|ψ〉 = 〈γ|1|ψ〉 ≈ 〈γ|

(N−1∑n=0

|n〉〈n|

)|ψ〉 =

N−1∑n=0

φn(γ)ψn

donde φn(γ) = 〈γ|n〉 tiene una recursion.

Husimi Q.

Problema:

Dado: Coeficientes ψn = 〈n|ψ〉 del estado |ψ〉 en base deauto-estados |n〉 del oscilador armonico para n = 0, . . . ,N − 1.Queremos: Calcular la funcion Husimi Q

Q(γ) =1π|〈γ|ψ〉|2

Calculemos primero:

〈γ|ψ〉 = 〈γ|1|ψ〉 ≈ 〈γ|

(N−1∑n=0

|n〉〈n|

)|ψ〉 =

N−1∑n=0

φn(γ)ψn

donde φn(γ) = 〈γ|n〉 tiene una recursion.

Clenshaw para Husimi Q.Calcular 〈γ|ψ〉 =

PN−1n=0 φn(γ)ψn.

1 Recursion

φn+1(γ) =(γ∗)n+1√(n + 1)!

e−|γ|2/2 =

γ∗√n + 1︸ ︷︷ ︸

=αn(β)

φn(γ)

2 Clenshaw dice βn(γ) = 0, αn(γ) = γ∗/√

n + 1:

hn(γ) =γ∗√n + 1

hn+1(γ) + ψn, (n = N − 1, . . . ,0), hN(γ) = 0

3 Resultado:

〈γ|ψ〉 = h0(γ)φ0(γ) + h1(γ) [φ1(γ)− α0(γ)φ0(γ)]︸ ︷︷ ︸=0

= h0(γ)e−|γ|2/2

4 Husimi Q:

Q(γ) =1π|h0(γ)|2 e−|γ|

2

Clenshaw para Husimi Q.Calcular 〈γ|ψ〉 =

PN−1n=0 φn(γ)ψn.

1 Recursion

φn+1(γ) =(γ∗)n+1√(n + 1)!

e−|γ|2/2 =

γ∗√n + 1︸ ︷︷ ︸

=αn(β)

φn(γ)

2 Clenshaw dice βn(γ) = 0, αn(γ) = γ∗/√

n + 1:

hn(γ) =γ∗√n + 1

hn+1(γ) + ψn, (n = N − 1, . . . ,0), hN(γ) = 0

3 Resultado:

〈γ|ψ〉 = h0(γ)φ0(γ) + h1(γ) [φ1(γ)− α0(γ)φ0(γ)]︸ ︷︷ ︸=0

= h0(γ)e−|γ|2/2

4 Husimi Q:

Q(γ) =1π|h0(γ)|2 e−|γ|

2

Clenshaw para Husimi Q.Calcular 〈γ|ψ〉 =

PN−1n=0 φn(γ)ψn.

1 Recursion

φn+1(γ) =(γ∗)n+1√(n + 1)!

e−|γ|2/2 =

γ∗√n + 1︸ ︷︷ ︸

=αn(β)

φn(γ)

2 Clenshaw dice βn(γ) = 0, αn(γ) = γ∗/√

n + 1:

hn(γ) =γ∗√n + 1

hn+1(γ) + ψn, (n = N − 1, . . . ,0), hN(γ) = 0

3 Resultado:

〈γ|ψ〉 = h0(γ)φ0(γ) + h1(γ) [φ1(γ)− α0(γ)φ0(γ)]︸ ︷︷ ︸=0

= h0(γ)e−|γ|2/2

4 Husimi Q:

Q(γ) =1π|h0(γ)|2 e−|γ|

2

Clenshaw para Husimi Q.Calcular 〈γ|ψ〉 =

PN−1n=0 φn(γ)ψn.

1 Recursion

φn+1(γ) =(γ∗)n+1√(n + 1)!

e−|γ|2/2 =

γ∗√n + 1︸ ︷︷ ︸

=αn(β)

φn(γ)

2 Clenshaw dice βn(γ) = 0, αn(γ) = γ∗/√

n + 1:

hn(γ) =γ∗√n + 1

hn+1(γ) + ψn, (n = N − 1, . . . ,0), hN(γ) = 0

3 Resultado:

〈γ|ψ〉 = h0(γ)φ0(γ) + h1(γ) [φ1(γ)− α0(γ)φ0(γ)]︸ ︷︷ ︸=0

= h0(γ)e−|γ|2/2

4 Husimi Q:

Q(γ) =1π|h0(γ)|2 e−|γ|

2

Implementacion.de_husimi.c

1 /*! \file de_husimi.c */2

3 #define _XOPEN_SOURCE 5004 #define _ISOC99_SOURCE5

6 #include <math.h>7 #include <complex.h>8 #include <stdlib.h>

Implementacion.de_husimi.c

10 /*! Calculates the Husimi function Q(alpha) for the state psi11 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 2007

8 /* for printing */9 #define X 6.0

10 #define P 6.011 #define N 10012

13 double poisson(double, double);14 double husimiQ(complex double, complex double*, size_t);

Ejemplos.main_de_husimi.c

16 void print_husimiQ(complex double* psi)17 18 double x, dx, p, dp, res;19 complex double alpha;20 int i, j;21

22 dx = 2.0 * X / N;23 dp = 2.0 * P / N;24 x = -X;25 for (i = 0; i < N; i++) 26 p = -P;27 for (j = 0; j < N; j++) 28 alpha = x + I * p;29 res = husimiQ(alpha, psi, SZ);30 printf("%f %f %f\n", x, p, res);31 p += dp;32 33 printf("\n");34 x += dx;35 36 printf("\n\n\n");37

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 = 4〉 y estado coherente |α = 2,0 × e0,25×i 〉.

0 0.01 0.02 0.03 0.04 0.05 0.06 0.07

−6 −4 −2 0 2 4 6−6

−4

−2

0

2

4

6

Re(α)

Im(α

)

Resultados.Auto estado |n = 4〉 y estado coherente |α = 2,0 × e0,25×i 〉.

0 0.05 0.1 0.15 0.2 0.25 0.3 0.35

−6 −4 −2 0 2 4 6−6

−4

−2

0

2

4

6

Im(α

)

Re(α)

Función Gamma incompleta.

Definición de la función Gamma incompleta:

γ(x ,a) =

∫ a

0dttx−1e−t

Conexión con la función de Gamma:

l«ıma→∞

γ(x ,a) =

∫ ∞

0dttx−1e−t = Γ(x)

Se definen usualmente también las siguentes funciones:

P(x ,a) =γ(x ,a)

Γ(x), Q(x ,a) = 1− P(x ,a)

¿Cómo se puede calcular esta función numericamente?

Aproximaciones para la función Gamma incompleta.

Para a ≤ x + 1 existe una aproximación en forma de unaexpansión:

γ(x ,a) = e−aax∞∑

n=0

Γ(x)

Γ(x + a + 1)an

Para a ≥ x + 1 se puede usar una razón continuada:

Γ(x ,a) = Γ(x) [1− P(x ,a)] = Γ(x)Q(x ,a) = Γ(x)− γ(x ,a)

= e−aax 1

a + 1− x − 1 · (1−x)

a+3−x− 2 · (2−x)a+5−x−...

Aproximaciones para la función Gamma incompleta.

Para a ≤ x + 1 existe una aproximación en forma de unaexpansión:

γ(x ,a) = e−aax∞∑

n=0

Γ(x)

Γ(x + a + 1)an

Para a ≥ x + 1 se puede usar una razón continuada:

Γ(x ,a) = Γ(x) [1− P(x ,a)] = Γ(x)Q(x ,a) = Γ(x)− γ(x ,a)

= e−aax 1

a + 1− x − 1 · (1−x)

a+3−x− 2 · (2−x)a+5−x−...

Definición.

Definición de una razón continuada:

f (x) = b0 +a1

b1 +a2

b2 +a3

b3 + · · ·

Notación común:

f (x) = b0 +a1

b1+

a2

b2+

a3

b3+· · ·

Aproximación hasta el orden n:

fn(x) = b0 +a1

b1+

a2

b2+

a3

b3+· · · an

bn

Definición.

Definición de una razón continuada:

f (x) = b0 +a1

b1 +a2

b2 +a3

b3 + · · ·

Notación común:

f (x) = b0 +a1

b1+

a2

b2+

a3

b3+· · ·

Aproximación hasta el orden n:

fn(x) = b0 +a1

b1+

a2

b2+

a3

b3+· · · an

bn

Recursión de Wallis.Del año 1655.

Idéa de Wallis:

fn =An

Bn

con la recursión:

Am = bmAm−1 + amAm−2

Bm = bmBm−1 + amBm−2

donde los valores iniciales son:

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:

fn =An

Bn

con la recursión:

Am = bmAm−1 + amAm−2

Bm = bmBm−1 + amBm−2

donde los valores iniciales son:

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:

Cm =Am

Am−1, Dm =

Bm−1

Bm

con la recursión:

Cm = bm +am

Cm−1, C0 = b0

Dm =1

bm + amDm−1, D0 = 0

Con eso la razón continuada resulta a través de unarecursión:

fm = fm−1CmDm, f0 = b0

Recursión de Lentz.

Mejor usar razones:

Cm =Am

Am−1, Dm =

Bm−1

Bm

con la recursión:

Cm = bm +am

Cm−1, C0 = b0

Dm =1

bm + amDm−1, D0 = 0

Con eso la razón continuada resulta a través de unarecursión:

fm = fm−1CmDm, f0 = b0

gamma_incomplete.c

1 #include <math.h>2 #include <float.h>3 #include <assert.h>4

5 #define EPS DBL_EPSILON6

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.

0

0.2

0.4

0.6

0.8

1

0 2 4 6 8 10 12 14 16

P(x,a

)

a

x = 1

Resultado.

0

0.2

0.4

0.6

0.8

1

0 2 4 6 8 10 12 14 16

P(x,a

)

a

x = 1x = 2

Resultado.

0

0.2

0.4

0.6

0.8

1

0 2 4 6 8 10 12 14 16

P(x,a

)

a

x = 1x = 2x = 3

Resultado.

0

0.2

0.4

0.6

0.8

1

0 2 4 6 8 10 12 14 16

P(x,a

)

a

x = 10x = 3x = 2x = 1

Parte VInterpolación

Interpolación versus extrapolación.

Problema:

Dado: Datos xi , yi (i = 0, . . . ,N − 1) como resultados deuna calculación o de un experimento.

Pregunta: ¿Como se puede obtener valores y para x 6= xi(i = 0, . . . ,N − 1)?

x0 xN−1x1

y0

x

y

y1

Interpolación versus extrapolación.

Problema:

Dado: Datos xi , yi (i = 0, . . . ,N − 1) como resultados deuna calculación o de un experimento.

Pregunta: ¿Como se puede obtener valores y para x 6= xi(i = 0, . . . ,N − 1)?

Interpolación

x0 xN−1x1

y0

x

y

y1

Interpolación versus extrapolación.

Problema:

Dado: Datos xi , yi (i = 0, . . . ,N − 1) como resultados deuna calculación o de un experimento.

Pregunta: ¿Como se puede obtener valores y para x 6= xi(i = 0, . . . ,N − 1)?

ExtrapolaciónInterpolación

x0 xN−1x1

y0

x

y

y1

¿Para qué?

Limites en el tiempo:

Calculación de cada punto de dato necesita mucho tiempo.Podemos calcular numericamente solo un numero limitado dedatos.En el experimento solo tenemos un numero de realisacionessuficiente para un numero limitado de datos.

Objectivo de una interpolación:

Hacer plots bonitos (no tan importante).Aumentar la resolución de datos para uso en otros algoritmos(integración)!

Interpolación polinomial.Entre dos puntos de datos.

y

y0

x0 x1

x

P(x)

y1

Aproximación lineal entre N = 2 puntos:

P2(x) = y0 +y1 − y0

x1 − x0(x − x0) = y0

(x − x1)

(x0 − x1)+ y1

(x − x0)

(x1 − x0)

Es una función polinomial de orden 1.

Interpolación entre datos vecinos.

Interpolación polinomial de orden 1 entre datos vecinos:y

x

Desventajas:

P ′(x) tiene discontinuidades en cada punto de data!⇒ Solo acceptable para integración.

Interpolación entre datos vecinos.

Interpolación polinomial de orden 1 entre datos vecinos:

Discontinuidaden la derivativa!

y

x

Desventajas:

P ′(x) tiene discontinuidades en cada punto de data!⇒ Solo acceptable para integración.

Formula de Lagrange.

Para N = 2 datos tenemos una función polinomial de orden 1:

P2(x) = y0(x − x1)

(x0 − x1)+ y1

(x − x0)

(x1 − x0)

Solución de Lagrange:

Para N datos hay una función polinomial de orden N − 1:

PN(x) = y0(x − x1) · · · (x − xN−1)

(x0 − x1) · · · (x0 − xN−1)+ . . .

. . .+ yN−1(x − x0) · · · (x − xN−2)

(xN−1 − x0) · · · (xN−1 − xN−2)

Esta interpolación pasa cada punto de dato: P(xi) = yi

Formula de Lagrange.

Para N = 2 datos tenemos una función polinomial de orden 1:

P2(x) = y0(x − x1)

(x0 − x1)+ y1

(x − x0)

(x1 − x0)

Solución de Lagrange:

Para N datos hay una función polinomial de orden N − 1:

PN(x) = y0(x − x1) · · · (x − xN−1)

(x0 − x1) · · · (x0 − xN−1)+ . . .

. . .+ yN−1(x − x0) · · · (x − xN−2)

(xN−1 − x0) · · · (xN−1 − xN−2)

Esta interpolación pasa cada punto de dato: P(xi) = yi

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5x

y

data

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5

y

x

datan = 2

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5

y

x

datan = 3

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5

y

x

datan = 4

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5

y

x

datan = 5

Caracteristica de la interpolación polinomial.

0

0.5

1

1.5

2

2.5

3

0 1 2 3 4 5

y

x

datan = 6

Interpolación para N datos a, . . . ,b.

x

y

xa xa+1 xbxb−1

ya

ya+1

Interpolación polinomial (Lagrange) entre los datos a, . . . ,b:

Pa,...,b(x) = ya(x − xa+1) · · · (x − xb)

(xa − xa+1) · · · (x0 − xb)+ . . .

. . .+ yb(x − xa) · · · (x − xb−1)

(xb − xa) · · · (xb − xb−1)

Recursión de Neville.

Recursión de Neville:

Pa,...,b(x) =x − xb

xa − xbPa,...,(b−1)(x) +

xa − xxa − xb

P(a+1),...,b(x)

Para la prueba formula de Lagrange en forma mas util:

Pa,...,b(x) = ya(x − xa+1) · · · (x − xb)

(xa − xa+1) · · · (xa − xb)+ . . .

. . .+ yb(x − xa) · · · (x − xb−1)

(xb − xa) · · · (xb − xb−1)

=b∑

m=a

ym

b∏n( 6=m)=a

(x − xn

xm − xn

)

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Segun Neville:

F (x) =x − xb

xa − xbPa,...,(b−1)(x) +

xa − xxa − xb

P(a+1),...,b(x)

Usando formula de Lagrange:

F (x) =x − xb

xa − xb

b−1∑m=a

ym

b−1∏n( 6=m)=a

(x − xn

xm − xn

)

+xa − xxa − xb

b∑m=a+1

ym

b∏n( 6=m)=a+1

(x − xn

xm − xn

)

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Segun Neville:

F (x) =x − xb

xa − xbPa,...,(b−1)(x) +

xa − xxa − xb

P(a+1),...,b(x)

Usando formula de Lagrange:

F (x) =x − xb

xa − xb

b−1∑m=a

ym

b−1∏n( 6=m)=a

(x − xn

xm − xn

)

+xa − xxa − xb

b∑m=a+1

ym

b∏n( 6=m)=a+1

(x − xn

xm − xn

)

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Sacar terminos con m = a,b respectivamente:

F (x) =x − xb

xa − xb

[ya

b−1∏n=a+1

(x − xn

xa − xn

)+

+b−1∑

m=a+1

ym

b−1∏n( 6=m)=a

(x − xn

xm − xn

)+

xa − xxa − xb

[yb

b−1∏n=a+1

(x − xn

xb − xn

)

+b−1∑

m=a+1

ym

b∏n( 6=m)=a+1

(x − xn

xm − xn

)

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Recombinación:

F (x) =b−1∑

m=a+1

ym

x − xb

xa − xb

b−1∏n( 6=m)=a

(x − xn

xm − xn

)

+xa − xxa − xb

b∏n( 6=m)=a+1

(x − xn

xm − xn

)+ ya

b∏n=a+1

(x − xn

xa − xn

)+ yb

b−1∏n=a

(x − xn

xb − xn

)Donde [. . .] podemos escribir como:

b−1∏n( 6=m)=a+1

(x − xn

xm − xn

)[x − xb

xa − xb

(x − xa

xm − xa

)+

xa − xxa − xb

(x − xb

xm − xb

)]

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Recombinación:

F (x) =b−1∑

m=a+1

ym

x − xb

xa − xb

b−1∏n( 6=m)=a

(x − xn

xm − xn

)

+xa − xxa − xb

b∏n( 6=m)=a+1

(x − xn

xm − xn

)+ ya

b∏n=a+1

(x − xn

xa − xn

)+ yb

b−1∏n=a

(x − xn

xb − xn

)Donde [. . .] podemos escribir como:

b−1∏n( 6=m)=a+1

(x − xn

xm − xn

)[x − xb

xa − xb

(x − xa

xm − xa

)+

xa − xxa − xb

(x − xb

xm − xb

)]

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Evaluación de la parentesis [. . .]:

=b−1∏

n( 6=m)=a+1

(x − xn

xm − xn

)(x − xa)(x − xb)

xa − xb

(1

xm − xa− 1

xm − xb

)

=b−1∏

n( 6=m)=a+1

(x − xn

xm − xn

)(x − xa)(x − xb)

(xm − xa)(xm − xb)

=b∏

n( 6=m)=a

(x − xn

xm − xn

)

Prueba de la recursión de Neville.Es correcto que F (x) = Pa,...,b(x)?

Entonces:

F (x) =b−1∑

m=a+1

ym

b∏n( 6=m)=a

(x − xn

xm − xn

)

+ ya

b∏n=a+1

(x − xn

xa − xn

)+ yb

b−1∏n=a

(x − xn

xb − xn

)

=b∑

m=a

ym

b∏n( 6=m)=a

(x − xn

xm − xn

)= Pa,...,b(x) q.e.d.

Aplicación para la interpolación.

Hacemos una interpolación usando 4 datos:

a b

a = 0, b = 3

x1x0 x2 x3

y

x

Recursión de Neville:

Pa,...,b(x) =x − xb

xa − xbPa,...,(b−1)(x) +

xa − xxa − xb

P(a+1),...,b(x)

Donde la interpolación con solo un dato es:

P0(x) = y0, . . . , P3(x) = y3

Recursión simple.x0 x1 x3x2

P1 P2 P3P0

Recursión simple.x0 x1 x3x2

P1 P2 P3

P0,1 P1,2 P2,3

P0

Recursión simple.x0 x1 x3x2

P1 P2 P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

Recursión simple.x0 x1 x3x2

P1 P2 P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

P0,1,2,3

Complejitud computacional.Formula de Lagrange.

Lagrange:

P0,...,N−1(x) = y0(x − x1) · · · (x − xN−1)

(x0 − x1) · · · (x0 − xN−1)+ . . .

. . .+ yN−1(x − x0) · · · (x − xN−2)

(xN−1 − x0) · · · (xN−1 − xN−2)

Para calcular se necesitan:

OpsLagrange = N × [2× (N − 1)]×⊕+ [2× (N − 2) + 2]×⊗= 4N(N − 1)

∼ 4× N2

Complejitud computacional.Recursion de Neville simple.

Neville:

OpsNeville = [(N − 1) + (N − 2) + . . .+ 2 + 1]

× [5×⊕+ 4×⊗]

=92

N(N − 1)

∼ 4,5× N2

Problemas:

Lagrange y Neville ambos van como N2!Ademas falta control de errores!

Complejitud computacional.Recursion de Neville simple.

Neville:

OpsNeville = [(N − 1) + (N − 2) + . . .+ 2 + 1]

× [5×⊕+ 4×⊗]

=92

N(N − 1)

∼ 4,5× N2

Problemas:

Lagrange y Neville ambos van como N2!Ademas falta control de errores!

Otra recursión.

Mejor usar diferencias:

R(n)a (x) = Pa,...,(a+n)(x)− Pa,...,(a+n−1)(x) ∼ xn

L(n)a (x) = Pa,...,(a+n)(x)− P(a+1),...,(a+n)(x) ∼ xn

Resulta otra recursión:

R(n+1)a (x) =

xa − xxa − xa+n+1

[R(n)

a+1(x)− L(n)a (x)

]L(n+1)

a (x) =x − xa+n+1

xa − xa+n+1

[L(n)

a (x)− R(n)a+1(x)

]con valores iniciales: R(0)

a (x) = L(0)a (x) = Pa(x) = ya

Otra recursión.

Mejor usar diferencias:

R(n)a (x) = Pa,...,(a+n)(x)− Pa,...,(a+n−1)(x) ∼ xn

L(n)a (x) = Pa,...,(a+n)(x)− P(a+1),...,(a+n)(x) ∼ xn

Resulta otra recursión:

R(n+1)a (x) =

xa − xxa − xa+n+1

[R(n)

a+1(x)− L(n)a (x)

]L(n+1)

a (x) =x − xa+n+1

xa − xa+n+1

[L(n)

a (x)− R(n)a+1(x)

]con valores iniciales: R(0)

a (x) = L(0)a (x) = Pa(x) = ya

Ventaja grande?Ejemplo para N = 4 datos:

x0 x1 x3x2

P2 P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

P0,1,2,3

x

P1 = L(0)1

Ventaja grande?Ejemplo para N = 4 datos:

x0 x1 x3x2

P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

P0,1,2,3

x

R(1)1

P1 = L(0)1 P2 = R(0)

2

Ventaja grande?Ejemplo para N = 4 datos:

x0 x1 x3x2

P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

P0,1,2,3

x

R(1)1L(1)

0

L(2)0

P1 = L(0)1 P2 = R(0)

2

Ventaja grande?Ejemplo para N = 4 datos:

x0 x1 x3x2

P3

P0,1 P1,2 P2,3

P0,1,2 P1,2,3

P0

P0,1,2,3

x

L(1)0 R(1)

1

L(2)0 R(2)

1

R(3)0

P1 = L(0)1 P2 = R(0)

2

Prueba.

F (x) = L(0)1 (x) + R(1)

1 (x) + L(2)0 (x) + R(3)

0 (x)

= P1(x)

+ [P1,2(x)− P1(x)]

+ [P0,1,2(x)− P1,2(x)]

+ [P0,1,2,3(x)− P0,1,2(x)]

= P0,1,2,3(x)

Hay muchos caminos posibles hacia el resultado!

¿Cual camino es lo mejor?

Idea:El camino lo mas recto es optimal para usar la ultima iteración comoestimación de error!

Prueba.

F (x) = L(0)1 (x) + R(1)

1 (x) + L(2)0 (x) + R(3)

0 (x)

= P1(x)

+ [P1,2(x)− P1(x)]

+ [P0,1,2(x)− P1,2(x)]

+ [P0,1,2,3(x)− P0,1,2(x)]

= P0,1,2,3(x)

Hay muchos caminos posibles hacia el resultado!

¿Cual camino es lo mejor?

Idea:El camino lo mas recto es optimal para usar la ultima iteración comoestimación de error!

Prueba.

F (x) = L(0)1 (x) + R(1)

1 (x) + L(2)0 (x) + R(3)

0 (x)

= P1(x)

+ [P1,2(x)− P1(x)]

+ [P0,1,2(x)− P1,2(x)]

+ [P0,1,2,3(x)− P0,1,2(x)]

= P0,1,2,3(x)

Hay muchos caminos posibles hacia el resultado!

¿Cual camino es lo mejor?

Idea:El camino lo mas recto es optimal para usar la ultima iteración comoestimación de error!

Complejitud computacional.Recursion de Neville inteligente.

Neville+:Para una interpolación polinomial de orden N se necesita usar soloN − 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 ∝ N2!

Complejitud computacional.Recursion de Neville inteligente.

Neville+:Para una interpolación polinomial de orden N se necesita usar soloN − 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 ∝ N2!

Implementación de Neville+.ip_neville.c

1 /*! \file ip_neville.c */2

3 #include <math.h>4 #include <assert.h>5 #include <stdlib.h>6

7 /*! Polynomial interpolation using the intelligent version8 of the algorithm of Neville (Neville+).9 \todo Can it actually be done in \f$\sim N\f$?

10 */11 double ip_neville(double xi, double* x, double* y, int n)12 13 double *r, *l;14 double diff, diff_min, yi;15 double dx_lo, dx_hi;16 int i, m, i_min;17

18 assert(n > 0);19

20 r = malloc(n * sizeof(double));21 l = malloc(n * sizeof(double));

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.

x

y

x0 x1 xN−1

y0

y1

Falta solo una cosa:Para una interpolación polinomial local de orden n hay que encontrarlos datos vecinos!

Interpolación local.

x

y x

y1

y0

x0 x1 xN−1

Falta solo una cosa:Para una interpolación polinomial local de orden n hay que encontrarlos datos vecinos!

Interpolación local.

x

y x

y1

y0

x0 x1 xN−1

Falta solo una cosa:Para una interpolación polinomial local de orden n hay que encontrarlos datos vecinos!

Interpolación local.

x

y x

y1

y0

x0 x1 xN−1

Falta solo una cosa:Para una interpolación polinomial local de orden n hay que encontrarlos datos vecinos!

Interpolación local.

x

y x

y1

y0

x0 x1 xN−1

Falta solo una cosa:Para una interpolación polinomial local de orden n hay que encontrarlos datos vecinos!

Buscar en una lista ordenada.

Definición del problema:

Dado: Lista ordenada de N datos x0, . . . , xN−1 (xi ≤ xi+1,i = 0, . . . ,N − 2) y un valor x .Problema: Cuales son los indices de los dos elementos xk yxk+1, que son los vecinos de x , es decir:

xk ≤ x < xk+1

Solución:

Metodo de bi-sección puede hacerlo en ∼ log2(N) pasos!Es mas eficiente que Neville+ (∼ N2) entonces no va a afectar laeficiencia total que va a ser ∼ N2.

Buscar en una lista ordenada.

Definición del problema:

Dado: Lista ordenada de N datos x0, . . . , xN−1 (xi ≤ xi+1,i = 0, . . . ,N − 2) y un valor x .Problema: Cuales son los indices de los dos elementos xk yxk+1, que son los vecinos de x , es decir:

xk ≤ x < xk+1

Solución:

Metodo de bi-sección puede hacerlo en ∼ log2(N) pasos!Es mas eficiente que Neville+ (∼ N2) entonces no va a afectar laeficiencia total que va a ser ∼ N2.

Metodo de bi-sección.ip_searchidx.c

1 /*! \file ip_searchidx.c */2

3 #include <assert.h>4

5 /*! Search index j with \f$x[j] <= x < x[j+1]\f$ in the6 monotonically-increasing ordered list7 \f$x[i+1] >= x[i]\f$. Done by the method of8 bisection. */9 int searchidx(double xi, double* x, int n)

10

11 12 int lo, hi, mid;13

14 assert((xi >= x[0]) && (xi <= x[n-1]));

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 else23 lo = mid;24 while (hi-lo > 1);25 return lo;26

Interpolación polinomial local.ip_polylocal.c

1 /*! \file ip_polylocal.c */2

3 #include <assert.h>4

5 /*! Calculates a local polynomial interpolation using p6 neighboring data points in the vector of n data. */7 double ip_polylocal(double xi, int p, double* x, double* y,8 int n)9

10 int pos;11 int searchidx(double, double*, int);12 double ip_neville(double, double*, double*, int);13

14 assert((n > 0) && (xi >= x[0]) && (xi <= x[n-1]));15

16 pos = searchidx(xi, x, n) - p/2 + 1;17 pos = (pos < 0) ? 0 : pos; /* ensure pos >= 0 */18 pos = (pos > (n-p)) ? (n-p) : pos; /* ensure pos+p <= n */19 return ip_neville(xi, &(x[pos]), &(y[pos]), p);20

Ejemplo.main_ip_polylocal.c

1 #include <stdio.h>2

3 #define GAMMA 0.14 #define X0 0.05 #define N 206 #define XMAX 1.07 #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.

0

20

40

60

80

100

−1 −0.5 0 0.5 1

y

x

datafunción

Resultado.

0

20

40

60

80

100

−1 −0.5 0 0.5 1

y

data

polynomialfunción

x

Resultado.

0

20

40

60

80

100

−1 −0.5 0 0.5 1

datafunción

poly local (4)

x

y

Interpolación racional.

Interpolación con una función racional:

Dado: N datos (x0, y0), . . . , (xN−1, yN−1).Interpolación racional:

R(x) =Pm(x)

Qn(x)=

p0 + p1x + . . .+ pmxm

q0 + q1x + . . .qnxn

Los valores qi ,pi hay que eligir segun los datos.q0 se puede elegir arbitrariamente.(m + 1) + n ≥ N para adaptar la función a los N datos.

Interpolación racional diagonal.

Definición:

R(x) =p0 + p1x + . . .+ pmxm

q1x + . . .qnxn

La función racional de interpolación R(x) es diagonal para los Ndatos cuando:

(m + 1) + n = N

y también:

m + 1 = n si N es paresm = 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:

R(x) =p0 + p1x + . . .+ pmxm

q1x + . . .qnxn

La función racional de interpolación R(x) es diagonal para los Ndatos cuando:

(m + 1) + n = N

y también:

m + 1 = n si N es paresm = n si N es impares

Ventaja:

Se puede generar a través de una recursión de Burlisch-Stoer!

Recursión de Burlisch-Stoer.

Tenemos N = b − a + 1 datos (xa, ya), . . . , (xb, yb).La interpolación racional diagonal que contiene los puntosa, . . . ,b es Ra,...,b(x).

Recursión de Burlisch-Stoer:

Ra,...,b(x) = R(a+1),...,b(x) +R(a+1),...,b(x)− Ra,...,(b−1)(x)(

x−xax−xb

) [1− R(a+1),...,b(x)−Ra,...,(b−1)(x)

R(a+1),...,b(x)−R(a+1),...,(b−1)(x)

]Con valores iniciales: Ra(x) = ya

Con la definición: Rk,...,(k−1)(x) = 0.

Recursión de Burlisch-Stoer.

Tenemos N = b − a + 1 datos (xa, ya), . . . , (xb, yb).La interpolación racional diagonal que contiene los puntosa, . . . ,b es Ra,...,b(x).

Recursión de Burlisch-Stoer:

Ra,...,b(x) = R(a+1),...,b(x) +R(a+1),...,b(x)− Ra,...,(b−1)(x)(

x−xax−xb

) [1− R(a+1),...,b(x)−Ra,...,(b−1)(x)

R(a+1),...,b(x)−R(a+1),...,(b−1)(x)

]Con valores iniciales: Ra(x) = ya

Con la definición: Rk,...,(k−1)(x) = 0.

Recursión de Burlisch-Stoer.

Tenemos N = b − a + 1 datos (xa, ya), . . . , (xb, yb).La interpolación racional diagonal que contiene los puntosa, . . . ,b es Ra,...,b(x).

Recursión de Burlisch-Stoer:

Ra,...,b(x) = R(a+1),...,b(x) +R(a+1),...,b(x)− Ra,...,(b−1)(x)(

x−xax−xb

) [1− R(a+1),...,b(x)−Ra,...,(b−1)(x)

R(a+1),...,b(x)−R(a+1),...,(b−1)(x)

]Con valores iniciales: Ra(x) = ya

Con la definición: Rk,...,(k−1)(x) = 0.

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

data

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

datan = 2

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

datan = 3

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

datan = 4

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

datan = 5

¿Como se ve?main_ip_burlischstoer.c

−1

0

1

2

3

4

0 1 2 3 4 5

y

x

datan = 6

Recursión para diferencias.

R(n)a (x) = Ra,...,(a+n)(x)− Ra,...,(a+n−1)(x)

L(n)a (x) = Ra,...,(a+n)(x)− R(a+1),...,(a+n)(x)

Recursión para diferencias:

R(n+1)a (x) =

(x−xa

x−xa+n+1

)L(n)

a (x)[R(n)

a+1(x)− L(n)a (x)

](

x−xax−xa+n+1

)L(n)

a (x)− R(n)a+1(x)

L(n+1)a (x) =

R(n)a+1(x)

[R(n)

a+1(x)− L(n)a (x)

](

x−xax−xa+n+1

)L(n)

a (x)− R(n)a+1(x)

Valores iniciales: R(0)a (x) = L(0)

a (x) = ya

Implementación.ip_burlischstoer.c

1 /*! \file ip_burlischstoer.c */2

3 #include <math.h>4 #include <float.h>5 #include <stdlib.h>6 #include <assert.h>7

8 /*! Calculates a rational interpolation using the recursion9 of Burlisch & Stoer. */

10 double ip_burlischstoer(double xi, double* x, double* y, int n)11 12 double *r, *l;13 double diff, diff_min, yi;14 double ratio, factor;15 int i, m, i_min;16

17 assert(n > 0);18

19 r = malloc(n * sizeof(double));20 l = malloc(n * sizeof(double));

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

39 for (m = 1; m < n; m++) 40 for (i = 0; i < n-m; i++) 41 ratio = (xi-x[i])/(xi-x[i+m]) * l[i];42 factor = ratio - r[i+1];43 factor = (fabs(factor) < DBL_MIN) ? DBL_MIN : factor;44 factor = (r[i+1]-l[i])/factor;45 l[i] = r[i+1] * factor;46 r[i] = ratio * factor;47 48 yi += ( ((2*i_min) < (n-m)) ? r[i_min] : l[--i_min] );49 50 free(r);51 free(l);52 return yi;53

Resultado.main_ip_burlischstoer.c

0

20

40

60

80

100

−1 −0.5 0 0.5 1

y

x

datafunción

Resultado.main_ip_burlischstoer.c

0

20

40

60

80

100

−1 −0.5 0 0.5 1

y

x

datafunción

polinomial

Resultado.main_ip_burlischstoer.c

0

20

40

60

80

100

−1 −0.5 0 0.5 1

datafunciónracional

y

x

Interpolación racional local.ip_ratlocal.c

1 /*! \file ip_ratlocal.c */2

3 #include <assert.h>4

5 /*! Calculates a local rational interpolation using p data6 points from the vector of n data. Uses the recurrence7 by Burlisch & Stoer. */8 double ip_ratlocal(double xi, int p, double* x, double* y,9 int n)

10 11 int pos;12 int searchidx(double, double*, int);13 double ip_burlischstoer(double, double*, double*, int);14

15 assert((n > 0) && (xi >= x[0]) && (xi <= x[n-1]));16

17 pos = searchidx(xi, x, n) - p/2 + 1;18 pos = (pos < 0) ? 0 : pos; /* ensure pos >= 0 */19 pos = (pos > (n-p)) ? (n-p) : pos; /* ensure pos+p <= n */20 return ip_burlischstoer(xi, &(x[pos]), &(y[pos]), p);21

Comparación.main_ip_ratlocal.c

1 #include <stdio.h>2

3 #define GAMMA 0.14 #define X0 0.15 #define N 416 #define XMAX 0.57 #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.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunciónracional

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

rational local (4)

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

rational local (5)

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

rational local (6)

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

poly local (4)

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

poly local (5)

Resultado.

0

20

40

60

80

100

120

−0.6 −0.4 −0.2 0 0.2 0.4 0.6

y

x

datafunción

poly local (6)

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Pro y con.

Interpolación polinomial local:

Con:No puede reproducir estructuras extremas como peaks.Produce oscilaciones.

Pro: Bueno para datos suaves.

Interpolación racional local:

Con: Spikes artificialesPro:

Reproduce peaks muy bien.Bueno para datos de una función racional (espectra, Lorentz etc.).

Resumen.

Alerta:Interpolación no se puede usar sin saber la forma de la función queproduce los datos!

Parte VIIntegración

Integración como una ecuación diferencial.

Queremos calcular la integral:

I(b,a) =

∫ b

adxf (x)

Es equivalente a resolver la siguente ecuación diferencial:

dI(x ,a)

dx= f (x)

donde la condición inicial es:

I(x ,a)|x=a = 0

Aviso:Integración es un problema equivalente a resolver una ecuacióndiferencial!

Integración como una ecuación diferencial.

Queremos calcular la integral:

I(b,a) =

∫ b

adxf (x)

Es equivalente a resolver la siguente ecuación diferencial:

dI(x ,a)

dx= f (x)

donde la condición inicial es:

I(x ,a)|x=a = 0

Aviso:Integración es un problema equivalente a resolver una ecuacióndiferencial!

Regla trapezoidal.

x

y

x0 = a x1 = b

f1

f0

I(b,a) =

∫ b

adxf (x) = ∆x

(12

f0 +12

f1

)+O

(∆x3f (2)

),

∆x = b − a

Correcto para una función polinomial f (x) hasta orden 1!Es decir para una recta solo!

Regla de Simpson.

x

y

x0 = a

f0

x1 x2 = b

16

23

16

f1

f2

I(b,a) =

∫ b

adxf (x) = ∆x

(16

f0 +23

f1 +16

f2

)+O

(∆x5f (4)

)∆x = (b − a)/2

Correcto para una función polinomial f (x) hasta orden 3!Es decir para una hiperbola!

Reglas extendidas.

x

y

x0 = a xN−1 = b

∆xN

Dividir intervalo ∆x = b − a en N − 1 pequeños equidistantesintervalos con tamaño:

∆xN =∆x

N − 1=

b − aN − 1

Entonces:

I(b,a) =

∫ b

adxf (x) =

N−2∑k=0

∫ xk+1

xk

dxf (x)

Regla trapezoidal extendida.

Con la regla trapezoidal resulta:

I(b,a) =N−2∑k=0

∆xN

(12

fk +12

fk+1

)+O

(∆x3

N f (2))

= ∆xN

(12

f0 + f1 + . . .+ fN−2 +12

fN−1

)+(N − 1)×O

[(∆x

N − 1

)3

f (2)

]

= ∆xN

(12

f0 + f1 + . . .+ fN−2 +12

fN−1

)︸ ︷︷ ︸

SN

+O(

∆x3f (2)

N2

)

= SN +O(N−2)

Regla de Simpson extendida.

Con la regla de Simpson para pares de intervalos resulta:

I(b,a) =

N−12 −1∑k=0

∆xN

(16

f2k +23

f2k+1 +16

f2k+2

)+O

(∆x5

N f (4))

= ∆xN

[(16

f0 +23

f1 +16

f2

)+

(16

f2 +23

f3 +16

f4

)+ . . .

. . .+

(16

fN−3 +23

fN−2 +16

fN−1

)]+

N − 12

×O

[(∆x

N − 1

)5

f (4)

]

= ∆xN

(16

f0 +23

f1 +13

f2 +23

f3 + . . .+23

fN−2 +16

fN−1

)︸ ︷︷ ︸

SN

+O(N−4)

Iteración con regla trapezoidal extendida.

xN = 2

a b

Regla trapezoidal extendida:

I = SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]donde:

∆xN =b − aN − 1

fk = f (a + k ·∆xN), k = 0,1, . . . ,N − 1

Iteración con regla trapezoidal extendida.

x

a b

N = 3

Regla trapezoidal extendida:

I = SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]donde:

∆xN =b − aN − 1

fk = f (a + k ·∆xN), k = 0,1, . . . ,N − 1

Iteración con regla trapezoidal extendida.

x

a b

N = 5

Regla trapezoidal extendida:

I = SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]donde:

∆xN =b − aN − 1

fk = f (a + k ·∆xN), k = 0,1, . . . ,N − 1

Iteración con regla trapezoidal extendida.

x

a b

N = 9

Regla trapezoidal extendida:

I = SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]donde:

∆xN =b − aN − 1

fk = f (a + k ·∆xN), k = 0,1, . . . ,N − 1

Iteración con regla trapezoidal extendida.

x

a b

N = 9

Regla trapezoidal extendida:

I = SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]donde:

∆xN =b − aN − 1

fk = f (a + k ·∆xN), k = 0,1, . . . ,N − 1

Recursión.

Iteración #0: h(0) = b − a

S(0) = S2 = (b − a)

[12

f (a) +12

f (b)

]= h(0)

[12

f (a) +12

f(

a + h(0))]

Recursión.

Iteración #1: h(1) = h(0)/2 = (b − a)/2

S(1) = S3 =b − a

2

[12

f (a) + f(

a + b2

)+

12

f (b)

]= h(1)

[12

f (a) + f(

a + h(1))

+12

f(

a + h(0))]

=12

S(0) + h(1)f(

a + h(1))

Recursión.

Iteración #2: h(2) = h(2)/2 = (b − a)/4

S(2) = S5 =b − a

4

[12

f (a) + f(

3a + b4

)+ f(

a + b2

)+f(

a + 3b4

)+

12

f (b)

]= h(2)

[12

f (a) + f(

a + h(2))

+ f(

a + h(1))

+f(

a + h(1) + h(2))

+12

f(

a + h(0))]

=12

S(1) + h(2)[f(

a + h(2))

+ f(

a + h(1) + h(2))]

Formula de recursión.

En general la formula de recursión es:

S(i+1) =12

S(i) + h(i+1)i∑

k=0

f(

a + h(i+1) + k ·h(i))

S(0) = (b − a)

[12

f (a) +12

f (b)

]donde los pasos son:

h(i+1) = h(i)/2, h(0) = b − a

Estimación del error:

I = S(i) +O[(

N(i))−2

], N(i) = 2 +

i−1∑k=0

2k

Formula de Euler-Maclaurin.

Formula de Euler-Maclaurin:

I(b,a) =

∫ b

adxf (x) = SN + EN

donde SN es la regla trapezoidal exendida y el error es dado por:

EN = −∞∑

k=1

B2k (∆xN)2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]con numeros de Bernoulli Bn (no convergentes):

B0 = 1, B2 =16,B4 = − 1

30, B6 =

142, etc.

Orden del error en la recursión.

En la iteración i tenemos N(i) datos en la integración:

S(i) = SN(i) = I(b,a) +∞∑

k=1

B2k (∆xN(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]

= I(b,a) +∞∑

k=1

B2k(h(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]Esta suma tiene error del orden:

S(i) = I(b,a) +O[(

N(i))−2

]

Combinación inteligente.

En vez de S(i) vamos a usar la combinación:

C(i+1) =4S(i+1) − S(i)

3= I(b,a) + E (i+1)

C

Resulta que su error es mucho mejor:

C(i) = I(b,a) +O[(

N(i))−4

]

Prueba.Vamos a calcular el error:

E (i+1)C =

4E (i+1) − E (i)

3

=13

∞∑k=1

4

B2k(h(i+1)

)2k

(2k)!−

B2k(h(i))2k

(2k)!

×[f (2k−1)(b)− f (2k−1)(a)

]=

13

∞∑k=1

(44k − 1

)B2k

(h(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]

=∞∑

k=2

41−k − 13

B2k(h(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]

=∞∑

k=1

4−k − 13

B2k+2(h(i))2k+2

(2k + 2)!

[f (2k+1)(b)− f (2k+1)(a)

]

¿Que es eso?

Se puede demonstrar que:

C(i) = CN(i) =4S(i) − S(i−1)

3

= ∆xN(i)

(16

f0 +23

f1 +13

f2 +23

f3 + . . .+23

fNi−2 +16

fNi−1

)Eso es la regla de Simpson extendida. Por eso tenemos un errorO[(N(i))−4]!

Implementación.ig_simpsonext.c

1 /*! \file ig_simpsonext.c */2

3 #include <math.h>4 #include <float.h>5 #include <assert.h>6

7 /*! Calculates the integral of the function f from a to b8 with relative error eps. Uses the Simpson extended9 formula calculating a special combination of the

10 trapezoidal extended rule. */11 double ig_simpsonext(double (*f)(double), double a, double b,12 double eps)13 14 double h, s, sum, x, res, res_old;15 int n, nmax;16

17 assert((b > a) && (eps > 0.0));

Implementación.ig_simpsonext.c

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.

Sabemos para la regla trapezoidal que la integral es:

I(b,a) =

∫ b

adxf (x) = SN + EN

donde para N − 1 puntos de datos la regla trapezoidal extendidaresulta en

SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]y la formula de Euler-Maclaurin nos da el error como

EN = −∞∑

k=1

B2k (∆xN)2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]El error es una serie de potencias en el paso ∆xN !

Error es una serie de potencias.

Sabemos para la regla trapezoidal que la integral es:

I(b,a) =

∫ b

adxf (x) = SN + EN

donde para N − 1 puntos de datos la regla trapezoidal extendidaresulta en

SN = ∆xN

[f02

+ f1 + f2 + . . .+ fN−2 +fN−1

2

]y la formula de Euler-Maclaurin nos da el error como

EN = −∞∑

k=1

B2k (∆xN)2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]El error es una serie de potencias en el paso ∆xN !

Error en la recursión.La recursión para la regla trapezoidal extendida es:

S(i+1) =S(i)

2+h(i+1)

i∑k=0

f(

a + h(i+1) + k ·h(i)), S(0) =

b − a2

[f (a) + f (b)]

donde la recursión para los pasos es:

h(i+1) = h(i)/2, h(0) = b − a

El error es entonces (∆xN → ∆xNi → h(i)):

EN → ENi → E (i) = −∞∑

k=1

B2k(h(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]Definimos:

ε(i) =

(h(i)

b − a

)2

, ε(i+1) =ε(i)

4, ε(0) = 1

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:

S(i+1) =S(i)

2+h(i+1)

i∑k=0

f(

a + h(i+1) + k ·h(i)), S(0) =

b − a2

[f (a) + f (b)]

donde la recursión para los pasos es:

h(i+1) = h(i)/2, h(0) = b − a

El error es entonces (∆xN → ∆xNi → h(i)):

EN → ENi → E (i) = −∞∑

k=1

B2k(h(i))2k

(2k)!

[f (2k−1)(b)− f (2k−1)(a)

]Definimos:

ε(i) =

(h(i)

b − a

)2

, ε(i+1) =ε(i)

4, ε(0) = 1

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 (∼unpolinomial):

S(i) = I(b,a)− E(ε(i)) → S(ε(i))

1

ε

S(ε)

116

14

i = 0

i = 1i = 2

En cada paso de la recursión, hacer una extrapolación de losresultados ya calculados hacia ε→ 0.

Romberg con regla trapezoidal extendida.ig_romberg.c

1 /*! \file ig_romberg.c */2

3 #include <math.h>4 #include <float.h>5 #include <stdlib.h>6 #include <assert.h>7

8 /*! Polynomial extrapolation at the position x=0.0 using9 the Neville recurrence. It assumes that for p points

10 0 is the index of the most nearest x[i]. Gives back11 also an estimate of error dy. */12 double expol_to_zero(double* x, double* y, int p, double* dy,13 double* r, double* l)14 15 double diff, yi;16 int i, m, i_min;

Romberg con regla trapezoidal extendida.ig_romberg.c

18 for (i = 0; i < p; i++) 19 r[i] = y[i];20 l[i] = y[i];21 22 i_min = 0;23 yi = y[i_min];24

25 for (m = 1; m < p; m++) 26 for (i = 0; i < p-m; i++) 27 diff = (r[i+1]-l[i]) / (x[i]-x[i+m]);28 r[i] = x[i] * diff;29 l[i] = x[i+m] * diff;30 31 (*dy) = ( ((2*i_min) < (p-m)) ? r[i_min] : l[--i_min] );32 yi += (*dy);33 34 return yi;35

Romberg con regla trapezoidal extendida.ig_romberg.c

37 /*! Romberg integration of function f using extended38 trapezoidal formula with polynomial extrapolation39 of p data points. */40 double ig_romberg(double (*f)(double), double a, double b,41 int p, double eps)42 43 double h, sum, x, res, err;44 int i, n, nmax;45 double *s, *hv, *r, *l;46

47 assert((b > a) && (p > 1));48

49 s = malloc(p * sizeof(double));50 hv = malloc(p * sizeof(double));51 r = malloc(p * sizeof(double));52 l = malloc(p * sizeof(double));

Romberg con regla trapezoidal extendida.ig_romberg.c

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

1 /*! \file ig_romberg_simpsonext.c */2

3 #include <math.h>4 #include <float.h>5 #include <stdlib.h>6 #include <assert.h>7

8 double expol_to_zero(double*, double*, int, double*,9 double*, double*);

10

11 /*! Romberg integration of function f using extended Simpson12 formula with polynomial extrapolation of p data points. */13 double ig_romberg_simpsonext(double (*f)(double), double a,14 double b, int p, double eps)15 16 double h, sum, x, res, err;17 int i, n, nmax;18 double s, s_old;19 double *c, *hv, *r, *l;20

21 assert((b > a) && (p > 1));

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.

RS, TSRS, TS γ, κ0

Iout(ω)Iin(ω)

L ·λ0

Medio Activo (Laser)

Resonador: ω0 =Frequencia de resonancia, λ0 = 2πc/ω0

Intensidad transmitida:

Iout(ω)

Iin(ω)=

T 4S

1 + r2(ω)− 2r(ω) cos(2ωL)

r(ω) = R2s exp

− 2Lκ0γ

2

(ω − ω0)2 + γ2

Comportamiento.

0

5

10

15

20

25

0.4 0.6 0.8 1 1.2 1.4 1.6

TS = 95 %

γ/ω0 = 0,5κ0/ω0 = −0,1L = 29

I out/I

in

ω/ω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

22 double power(double omega)23 24 double f, kappa, intensity;25

26 count++;27 kappa = KAPPA_0 * GAMMA * GAMMA28 / ((omega-OMEGA_0)*(omega-OMEGA_0) + GAMMA*GAMMA);29 f = R_S * R_S * exp(-2.0 * kappa * L);30 intensity = T_S * T_S * T_S * T_S31 / (1.0 + f*f - 2.0 * f * cos(2.0*omega*L));32 return intensity;33

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

59 fprintf(stderr, "Romberg Simpson extended:\n"60 "eps\t\teff. power\tfunction calls\n");61 for (eps = 1.0e-5; eps >= 1.0e-12; eps *= 0.1) 62 count = 0;63 p = ig_romberg_simpsonext(power, 0.2, 2.0, 5, eps);64 fprintf(stderr, "%e\t%13.12f\t%d\n", eps, p, count);65 66

67 return 0;68

Resultado.

1 Simpson extended:2 eps eff. power function calls3 1.000000e-05 1.796780388508 1310734 1.000000e-06 1.796777940861 524289

Resultado.

1 Simpson extended:2 eps eff. power function calls3 1.000000e-05 1.796780388508 1310734 1.000000e-06 1.796777940861 5242895 Romber extended trapezoidal:6 eps eff. power function calls7 1.000000e-05 1.797186829173 10258 1.000000e-06 1.796748783043 20499 1.000000e-07 1.796778097073 4097

10 1.000000e-08 1.796777633013 819311 1.000000e-09 1.796777633013 819312 1.000000e-10 1.796777634905 1638513 1.000000e-11 1.796777634905 1638514 1.000000e-12 1.796777634903 32769

Resultado.

5 Romber extended trapezoidal:6 eps eff. power function calls7 1.000000e-05 1.797186829173 10258 1.000000e-06 1.796748783043 20499 1.000000e-07 1.796778097073 4097

10 1.000000e-08 1.796777633013 819311 1.000000e-09 1.796777633013 819312 1.000000e-10 1.796777634905 1638513 1.000000e-11 1.796777634905 1638514 1.000000e-12 1.796777634903 3276915 Romberg Simpson extended:16 eps eff. power function calls17 1.000000e-05 1.927207617183 1718 1.000000e-06 1.797229350106 51319 1.000000e-07 1.797187315536 102520 1.000000e-08 1.797187315536 102521 1.000000e-09 1.797187315536 102522 1.000000e-10 1.796777634751 819323 1.000000e-11 1.796777634751 819324 1.000000e-12 1.796777634751 8193

Funcion especial: Gamma incompleta.

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.024 : 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.024 : 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.

Uno de los limites es infinito:

I(∞,a) =

∫ ∞

adxf (x) = S(∞,a) + E(∞,a)

¿Cómo se puede determinar el limite maximo?

Integral es aditivo: Vamos a usar una serie de aproximacionespara el limite maximo a1,a2, . . .

S(∞,a) = S(a1,a0) + S(a2,a1) + S(a3,a2) + . . . , a0 = a

Queremos la integral con un error relativo maximo ε. Entonces

|E(∞,a)| ≤ ε|S(∞,a)|

¿Qué errores E(ak ,ak−1) podemos permitir?

Integral inpropia.

Uno de los limites es infinito:

I(∞,a) =

∫ ∞

adxf (x) = S(∞,a) + E(∞,a)

¿Cómo se puede determinar el limite maximo?

Integral es aditivo: Vamos a usar una serie de aproximacionespara el limite maximo a1,a2, . . .

S(∞,a) = S(a1,a0) + S(a2,a1) + S(a3,a2) + . . . , a0 = a

Queremos la integral con un error relativo maximo ε. Entonces

|E(∞,a)| ≤ ε|S(∞,a)|

¿Qué errores E(ak ,ak−1) podemos permitir?

Integral inpropia.

Uno de los limites es infinito:

I(∞,a) =

∫ ∞

adxf (x) = S(∞,a) + E(∞,a)

¿Cómo se puede determinar el limite maximo?

Integral es aditivo: Vamos a usar una serie de aproximacionespara el limite maximo a1,a2, . . .

S(∞,a) = S(a1,a0) + S(a2,a1) + S(a3,a2) + . . . , a0 = a

Queremos la integral con un error relativo maximo ε. Entonces

|E(∞,a)| ≤ ε|S(∞,a)|

¿Qué errores E(ak ,ak−1) podemos permitir?

Errores.

Cada parte se calcula con error relativo maximo εk :

|E(ak ,ak−1)| ≤ εk |S(ak ,ak−1)|

Error total:

|E(∞,a)| ≤∑

k

|E(ak ,ak−1)| ≤∑

k

εk |S(ak ,ak−1)|

Nuestra condicion del error relativo maximo:

|E(∞,a)| ≤ ε

∣∣∣∣∣∑k

S(ak ,ak−1)

∣∣∣∣∣ ≤ ε∑

k

|S(ak ,ak−1)|

Error maximo permitible para cada parte:

|E(∞,a)| =∑

k

εk |S(ak ,ak−1)| ≤ ε∑

k

|S(ak ,ak−1)|

entonces: εk ≤ ε.

Errores.

Cada parte se calcula con error relativo maximo εk :

|E(ak ,ak−1)| ≤ εk |S(ak ,ak−1)|

Error total:

|E(∞,a)| ≤∑

k

|E(ak ,ak−1)| ≤∑

k

εk |S(ak ,ak−1)|

Nuestra condicion del error relativo maximo:

|E(∞,a)| ≤ ε

∣∣∣∣∣∑k

S(ak ,ak−1)

∣∣∣∣∣ ≤ ε∑

k

|S(ak ,ak−1)|

Error maximo permitible para cada parte:

|E(∞,a)| =∑

k

εk |S(ak ,ak−1)| ≤ ε∑

k

|S(ak ,ak−1)|

entonces: εk ≤ ε.

Errores.

Cada parte se calcula con error relativo maximo εk :

|E(ak ,ak−1)| ≤ εk |S(ak ,ak−1)|

Error total:

|E(∞,a)| ≤∑

k

|E(ak ,ak−1)| ≤∑

k

εk |S(ak ,ak−1)|

Nuestra condicion del error relativo maximo:

|E(∞,a)| ≤ ε

∣∣∣∣∣∑k

S(ak ,ak−1)

∣∣∣∣∣ ≤ ε∑

k

|S(ak ,ak−1)|

Error maximo permitible para cada parte:

|E(∞,a)| =∑

k

εk |S(ak ,ak−1)| ≤ ε∑

k

|S(ak ,ak−1)|

entonces: εk ≤ ε.

Errores.

Cada parte se calcula con error relativo maximo εk :

|E(ak ,ak−1)| ≤ εk |S(ak ,ak−1)|

Error total:

|E(∞,a)| ≤∑

k

|E(ak ,ak−1)| ≤∑

k

εk |S(ak ,ak−1)|

Nuestra condicion del error relativo maximo:

|E(∞,a)| ≤ ε

∣∣∣∣∣∑k

S(ak ,ak−1)

∣∣∣∣∣ ≤ ε∑

k

|S(ak ,ak−1)|

Error maximo permitible para cada parte:

|E(∞,a)| =∑

k

εk |S(ak ,ak−1)| ≤ ε∑

k

|S(ak ,ak−1)|

entonces: εk ≤ ε.

Condición para terminar.La aproximacion es I(∞,a) = S(∞,a) + E(∞,a) con

S(∞,a) =∞∑

k=0

S(ak+1,ak )

Solamente usamos la suma con K terminos:

SK =K−1∑k=0

S(ak+1,ak ), EK =∞∑

k=K

S(ak+1,ak ) + E(∞,a)

Queremos que |EK | ≤ ε|SK |:

|EK | ≈

∣∣∣∣∣∞∑

k=K

S(ak+1,ak )

∣∣∣∣∣+∞∑

k=0

E(ak+1,ak )

≈ |S(aK+1,aK )|+ ε

K−1∑k=0

|S(ak+1,ak )| ≤ ε

K−1∑k=0

|S(ak+1,ak )|

entonces:

|S(aK+1,aK )| ≤ (ε− ε)K−1∑k=0

|S(ak+1,ak )|

Condición para terminar.La aproximacion es I(∞,a) = S(∞,a) + E(∞,a) con

S(∞,a) =∞∑

k=0

S(ak+1,ak )

Solamente usamos la suma con K terminos:

SK =K−1∑k=0

S(ak+1,ak ), EK =∞∑

k=K

S(ak+1,ak ) + E(∞,a)

Queremos que |EK | ≤ ε|SK |:

|EK | ≈

∣∣∣∣∣∞∑

k=K

S(ak+1,ak )

∣∣∣∣∣+∞∑

k=0

E(ak+1,ak )

≈ |S(aK+1,aK )|+ ε

K−1∑k=0

|S(ak+1,ak )| ≤ ε

K−1∑k=0

|S(ak+1,ak )|

entonces:

|S(aK+1,aK )| ≤ (ε− ε)K−1∑k=0

|S(ak+1,ak )|

Condición para terminar.La aproximacion es I(∞,a) = S(∞,a) + E(∞,a) con

S(∞,a) =∞∑

k=0

S(ak+1,ak )

Solamente usamos la suma con K terminos:

SK =K−1∑k=0

S(ak+1,ak ), EK =∞∑

k=K

S(ak+1,ak ) + E(∞,a)

Queremos que |EK | ≤ ε|SK |:

|EK | ≈

∣∣∣∣∣∞∑

k=K

S(ak+1,ak )

∣∣∣∣∣+∞∑

k=0

E(ak+1,ak )

≈ |S(aK+1,aK )|+ ε

K−1∑k=0

|S(ak+1,ak )| ≤ ε

K−1∑k=0

|S(ak+1,ak )|

entonces:

|S(aK+1,aK )| ≤ (ε− ε)K−1∑k=0

|S(ak+1,ak )|

Implementación.ig_improper.c

1 /*! \file ig_improper.c */2

3 #include <math.h>4 #include <assert.h>5

6 #define EPS_FACTOR 10.07

8 double ig_romberg(double (*)(double), double, double, int, double);9

10 double ig_improper(double (*f)(double), double a, double b,11 double dx, int p, double eps)12 13 double b_lo, b_hi;14 double res, s, err;15 double eps_internal;16

17 assert((b > a) && (p > 1));

Implementación.ig_improper.c

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

Ejemplo: Función de error.

E(x) =2√π

∫ x

0dte−t2

, l«ımx→∞

E(x) = 1

1 #define _XOPEN_SOURCE 5002 #define _ISOC99_SOURCE3 #include <math.h>4 #include <stdio.h>5

6 double ig_improper(double (*)(double), double, double, double, int,7 double);8

9 int count;10

11 double f(double x)12 13 count++;14 return M_2_SQRTPI * exp(-x * x);15

Ejemplo: Función de error.

E(x) =2√π

∫ x

0dte−t2

, l«ımx→∞

E(x) = 1

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 VIITransformación de Fourier

Signal con ancho espectral limitado.|ν| ≤ νc .

1 Simplificacion:

fc(t) =

∫ ∞

−∞dνe−2πiνt fc(ν) =

∫ νc

−νc

dνe−2πiνt fc(ν)

2 Consequencia:

fc(ν) = ∆t∞∑

n=−∞e2πiνtn fc(tn), tn = τ0 + n∆t , ∆t =

12νc

3 Resulta:

fc(t) =

∫ νc

−νc

dνe−2πiνt fc(ν) =∞∑

n=−∞fc(tn)∆t

∫ νc

−νc

dνe2πiν(tn−t)

=∞∑

n=−∞fc(tn)

sin [2πνc(tn − t)]2πνc(tn − t)

=∞∑

n=−∞fc(tn)sinc [2πνc(tn − t)]

Signal con ancho espectral limitado.|ν| ≤ νc .

1 Simplificacion:

fc(t) =

∫ ∞

−∞dνe−2πiνt fc(ν) =

∫ νc

−νc

dνe−2πiνt fc(ν)

2 Consequencia:

fc(ν) = ∆t∞∑

n=−∞e2πiνtn fc(tn), tn = τ0 + n∆t , ∆t =

12νc

3 Resulta:

fc(t) =

∫ νc

−νc

dνe−2πiνt fc(ν) =∞∑

n=−∞fc(tn)∆t

∫ νc

−νc

dνe2πiν(tn−t)

=∞∑

n=−∞fc(tn)

sin [2πνc(tn − t)]2πνc(tn − t)

=∞∑

n=−∞fc(tn)sinc [2πνc(tn − t)]

Signal con ancho espectral limitado.|ν| ≤ νc .

1 Simplificacion:

fc(t) =

∫ ∞

−∞dνe−2πiνt fc(ν) =

∫ νc

−νc

dνe−2πiνt fc(ν)

2 Consequencia:

fc(ν) = ∆t∞∑

n=−∞e2πiνtn fc(tn), tn = τ0 + n∆t , ∆t =

12νc

3 Resulta:

fc(t) =

∫ νc

−νc

dνe−2πiνt fc(ν) =∞∑

n=−∞fc(tn)∆t

∫ νc

−νc

dνe2πiν(tn−t)

=∞∑

n=−∞fc(tn)

sin [2πνc(tn − t)]2πνc(tn − t)

=∞∑

n=−∞fc(tn)sinc [2πνc(tn − t)]

Teorema de muestra (sampling).

Teorema de muestra:Dado un signal fc(t) con ancho espectral limitado, es decir fc(ν) 6= 0solo para |ν| ≤ νc , resulta que:

fc(t) =∞∑

n=−∞fc(tn)sinc [2πνc(tn − t)]

donde tn = τ0 + n∆t (τ0 arbitrario), ∆t = 1/(2νc).

Inversion del teorema de muestra.

Calculemos la transformacion de Fourier:

fc(ν) =

∫ ∞

−∞dte2πiνt

∞∑n=−∞

fc(tn)sinc [2πνc(tn − t)]

=∞∑

n=−∞fc(tn)

∫ ∞

−∞dte2πiνt

∆t∫ νc

−νc

dν′e2πiν′(tn−t)

= ∆t∞∑

n=−∞fc(tn)

∫ νc

−νc

dν′e2πiν′tn∫ ∞

−∞dte2πi(ν−ν′)t︸ ︷︷ ︸=δ(ν−ν′)

= ∆t∞∑

n=−∞fc(tn)e2πiνtn

∫ νc

−νc

dν′−dΘ(ν − ν′)

dν′

= [Θ(ν + νc)−Θ(ν − νc)]︸ ︷︷ ︸=Π(ν)

∆t∞∑

n=−∞fc(tn)e2πiνtn

Transformacion discreta.

Para signal fc(t) con ancho espectral limitado (|ν| ≤ νc):

fc(ν) = Π(ν)∆t∞∑

n=−∞fc(tn)e2πiνtn

Usamos solo N puntos discretos:

fc(ν) ≈ Π(ν)∆tN−1∑n=0

fc(tn)e2πiνtn

¿Para que frecuencias ν esta expression es correcta?

Solucion: Para los N + 1 frecuencias

νm = m∆ν, ∆ν =2νc

N=

1N∆t

, m = −N2, . . . ,

N2

Porque usamos: fc(tn+N) = fc(tn)!

Transformacion discreta.

Para signal fc(t) con ancho espectral limitado (|ν| ≤ νc):

fc(ν) = Π(ν)∆t∞∑

n=−∞fc(tn)e2πiνtn

Usamos solo N puntos discretos:

fc(ν) ≈ Π(ν)∆tN−1∑n=0

fc(tn)e2πiνtn

¿Para que frecuencias ν esta expression es correcta?

Solucion: Para los N + 1 frecuencias

νm = m∆ν, ∆ν =2νc

N=

1N∆t

, m = −N2, . . . ,

N2

Porque usamos: fc(tn+N) = fc(tn)!

Suma de Fourier.

fc(νm) = Π(νm)∆tN−1∑n=0

fc(tn)e2πiνm tn = e2πiνmτ0∆tN−1∑n=0

fc(tn)e2πi mnN

︸ ︷︷ ︸=Fm

Suma de Fourier:Para los N (es numero pares) datos fn (n = 0, . . . ,N − 1) resultan susN + 1 transformaciones discretas de Fourier como:

Fm =N−1∑n=0

fne2πi mnN (m = −N

2, . . . ,

N2

)

donde los valores extremos son iguales:

F± N2

=N−1∑n=0

fne±iπn =N−1∑n=0

fn(−1)n

Suma de Fourier.

fc(νm) = Π(νm)∆tN−1∑n=0

fc(tn)e2πiνm tn = e2πiνmτ0∆tN−1∑n=0

fc(tn)e2πi mnN

︸ ︷︷ ︸=Fm

Suma de Fourier:Para los N (es numero pares) datos fn (n = 0, . . . ,N − 1) resultan susN + 1 transformaciones discretas de Fourier como:

Fm =N−1∑n=0

fne2πi mnN (m = −N

2, . . . ,

N2

)

donde los valores extremos son iguales:

F± N2

=N−1∑n=0

fne±iπn =N−1∑n=0

fn(−1)n

Complejitud computacional.

Fm =N−1∑n=0

fne2πi mnN

que se puede escribir como:

F− N2

...F0...

F N2

=

...

· · · W mn · · ·...

·

f0...

...fN−1

, W = e2πiN

Multiplicacion de matriz (N + 1)× N:

Ops(N) ∝ O(N2)

Pares versus impares.Gauss 1805; Cooley & Tukey en los años 60.

Dado N = 2k pares, resultan N/2 datos con indices pares y N/2datos con indices impares:

Fm =N−1∑n=0

fne2πi mnN

=

N2 −1∑k=0

f2k e2πi m(2k)N +

N2 −1∑k=0

f2k+1e2πi m(2k+1)N

= F (0)m,N + e2πi m

N F (1)m,N

donde la FT de las partes pares / impares de los N datos esta dadopor:

F (0)m,N =

N2 −1∑k=0

f2k e2πi mkN/2 , F (1)

m,N =

N2 −1∑k=0

f2k+1e2πi mkN/2

Separacion en pares e impares.

Entonces tenemos:

Fm = F (0)m,N + (WN)mF (1)

m,N , WN = e2πiN

Idea:Iteracion posible hasta transformacion de Fourier de solo un dato siN = 2k !

Separacion en pares e impares.

Entonces tenemos:

Fm = F (0)m,N + (WN)mF (1)

m,N , WN = e2πiN

Idea:Iteracion posible hasta transformacion de Fourier de solo un dato siN = 2k !

Iteracion.N = 2k .

Fmk N

Iteracion.N = 2k .

F (0)m,N + (WN)mF (1)

m,N

Fmk

k − 1 N/2

N

Iteracion.N = 2k .

FmNk

N/2k − 1 F (0)m,N + (WN)mF (1)

m,N

N/4k − 2[F (00)

m, N2

+ (W N2)mF (01)

m, N2

]+ (WN)m

[F (10)

m, N2

+ (W N2)mF (11)

m, N2

]

Iteracion.N = 2k .

F (0)m,N + (WN)mF (1)

m,N

Fm

...

k

k − 1

k − 2

...

0 1

N/4

...

N/2

N

[F (00)

m, N2

+ (W N2)mF (01)

m, N2

]+ (WN)m

[F (10)

m, N2

+ (W N2)mF (11)

m, N2

]

. . . (W2)m . . . F (0010011010)

m,2 . . .

Transformaciones de un punto.

¿Que es F (p1p2...pk )m,2 ?

Es una transformacion de Fourier de un dato:

F (p1p2...pk )m,2 = e4πimfn = fn

donde n depende de la combinacion p1p2 . . .pk :

n = n(p1p2 . . .pk )

Problema:¿Cual es la dependencia entre n y los p1p2 . . .pk ?

Transformaciones de un punto.

¿Que es F (p1p2...pk )m,2 ?

Es una transformacion de Fourier de un dato:

F (p1p2...pk )m,2 = e4πimfn = fn

donde n depende de la combinacion p1p2 . . .pk :

n = n(p1p2 . . .pk )

Problema:¿Cual es la dependencia entre n y los p1p2 . . .pk ?

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15(1)

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15

3 7 11 15(11)

(1)

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15

3 7 11 15

7 15(111)

(11)

(1)

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15

3 7 11 15

7 15

7(1110)

(111)

(11)

(1)

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15

3 7 11 15

7 15

7(1110)

(111)

(11)

(1)

Resultado: n = 7 corresponde a (p1p2p3p4) = (1110)!

Pares e impares en bits.¿A que combinacion p1p2 . . . pk corresponde el indice n de N = 2k datos?

Ejemplo con n = 7 de N = 24 = 16 datos:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 3 5 7 9 11 13 15

3 7 11 15

7 15

7(1110)

(111)

(11)

(1)

Resultado: n = 7 corresponde a (p1p2p3p4) = (1110)!Pero: n = 0111 en 4-bit representacion binaria (k = 4)!

Ejemplo.N = 22 = 4.

FmN = 4k = 2

Ejemplo.N = 22 = 4.

FmN = 4k = 2

21 F (0)m,4 + (W4)

mF (1)m,4

Ejemplo.N = 22 = 4.

FmN = 4k = 2

21 F (0)m,4 + (W4)

mF (1)m,4

10[F (00)

m,2 + (W2)mF (01)

m,2

]+ (W4)

m[F (10)

m,2 + (W2)mF (11)

m,2

]

Ejemplo.N = 22 = 4.

FmN = 4k = 2

21 F (0)m,4 + (W4)

mF (1)m,4

10[F (00)

m,2 + (W2)mF (01)

m,2

]+ (W4)

m[F (10)

m,2 + (W2)mF (11)

m,2

][f(00) + (W2)

m f(01)

]+ (W4)

m[f(10) + (W2)

m f(11)

]=

Ejemplo.N = 22 = 4.

FmN = 4k = 2

21 F (0)m,4 + (W4)

mF (1)m,4

10[F (00)

m,2 + (W2)mF (01)

m,2

]+ (W4)

m[F (10)

m,2 + (W2)mF (11)

m,2

]

=

=

[f(00) + (W2)

m f(01)

]+ (W4)

m[f(10) + (W2)

m f(11)

][f(00) + (W2)

mf(10)

]+ (W4)

m[f(01) + (W2)

mf(11)

]

Estrategia simple.00 01 10 11

f0 f1 f2 f3

Estrategia simple.

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

Estrategia simple.

f0 f1 f2 f3

×(W2)m ×(W2)

m+ +

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

Estrategia simple.

f0 f1 f2 f3

×(W2)m ×(W2)

m+ +

×(W4)m

+

Fm

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

Complejitud computacional.Es muy pobre!

Complejitud computacional:

Para calcular un Fm:

Ops(N) = OpsBR(N) + (⊕+⊗)

(N2

+N4

+N8

+ . . .+ 1)

= OpsBR(N) + Nk−1∑n=0

(12

)n

= OpsBR(N) + 2N(

1− 1N

)= OpsBR(N) +O(N)

Problema:Para los N transformadas necesitamos tambien O(N2)!

Complejitud computacional.Es muy pobre!

Complejitud computacional:

Para calcular un Fm:

Ops(N) = OpsBR(N) + (⊕+⊗)

(N2

+N4

+N8

+ . . .+ 1)

= OpsBR(N) + Nk−1∑n=0

(12

)n

= OpsBR(N) + 2N(

1− 1N

)= OpsBR(N) +O(N)

Problema:Para los N transformadas necesitamos tambien O(N2)!

Idea.N = 22 = 4: m = −2, . . . ,+2.

1 En el primer paso, necesitamos para la frecuencia νm unamultiplicacion con (W2)

m:

(W2)m =

(e2πi/2

)m= (−1)m =

1, m = 0,±2

−1, m = ±1

2 En el segundo paso:

(W4)m =

(e2πi/4

)m= (i)m =

1, m = 0i , m = 1

−i , m = −1−1, m = ±2

Idea:Calcular las transformadas para todas frecuencias en paralelo!

Idea.N = 22 = 4: m = −2, . . . ,+2.

1 En el primer paso, necesitamos para la frecuencia νm unamultiplicacion con (W2)

m:

(W2)m =

(e2πi/2

)m= (−1)m =

1, m = 0,±2

−1, m = ±1

2 En el segundo paso:

(W4)m =

(e2πi/4

)m= (i)m =

1, m = 0i , m = 1

−i , m = −1−1, m = ±2

Idea:Calcular las transformadas para todas frecuencias en paralelo!

Idea.N = 22 = 4: m = −2, . . . ,+2.

1 En el primer paso, necesitamos para la frecuencia νm unamultiplicacion con (W2)

m:

(W2)m =

(e2πi/2

)m= (−1)m =

1, m = 0,±2

−1, m = ±1

2 En el segundo paso:

(W4)m =

(e2πi/4

)m= (i)m =

1, m = 0i , m = 1

−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 .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = 0,±2

×(W2)0 ×(W2)

0

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = ±1 m = 0,±2 m = ±1

×(W2)0 ×(W2)

0

×(W2)1 ×(W2)

1

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = ±1 m = 0,±2 m = ±1

m = 0

×(W4)0

×(W2)0 ×(W2)

0

×(W2)1 ×(W2)

1

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = ±1 m = 0,±2 m = ±1

m = 0 m = ±2

×(W4)0

×(W2)0 ×(W2)

0

×(W2)1 ×(W2)

1

×(W4)2

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = ±1 m = 0,±2 m = ±1

m = 0 m = 1 m = ±2

×(W4)0

×(W2)0 ×(W2)

0

×(W2)1 ×(W2)

1

×(W4)2

×(W4)1

Estrategia mas elaborada.N = 22 = 4, W2 = −1, W4 = i .

f0 f1 f2 f3

00 01 10 11

f0 f1 f2 f3Reversiónde Bits

m = 0,±2 m = ±1 m = 0,±2 m = ±1

m = 0 m = 1 m = ±2 m = −1

×(W4)0

×(W2)0 ×(W2)

0

×(W4)1

×(W4)2

×(W4)−1

×(W2)1×(W2)

1

Complejitud computacional.Ahora es mejor.

Complejitud computacional:

Para calcular todos los Fm:

Ops(N) = OpsBR(N) + log2(N)× N × (⊕+⊗)

= OpsBR(N) +O [N log2(N)]

¿Es mejor que O(N2)?

Falta:¿Complejitud computacional de la reversion de Bits?

Complejitud computacional.Ahora es mejor.

Complejitud computacional:

Para calcular todos los Fm:

Ops(N) = OpsBR(N) + log2(N)× N × (⊕+⊗)

= OpsBR(N) +O [N log2(N)]

¿Es mejor que O(N2)?

Falta:¿Complejitud computacional de la reversion de Bits?

Estrategia.

n = 00000000n = 0000 1011

Estrategia.

n+ = m;

n = 00000000n = 0000 1011

m = (n %2); (m = 1)

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n >>= 1;

n = 00000 101n <<= 1;

n = 0000 1011

(m = 1)m = (n %2);

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n+ = m;

n >>= 1;

n = 00000 101n <<= 1;

n = 0000 1011

m = (n %2);

m = (n %2);

(m = 1)

(m = 1)

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n = 000000 10 n = 00000 110

n+ = m;

n >>= 1;

n = 00000 101n <<= 1;

n >>= 1; n <<= 1;

n = 0000 1011

(m = 1)

(m = 1)

m = (n %2);

m = (n %2);

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n = 000000 10 n = 00000 110

n+ = m;

n+ = m;

n >>= 1;

n = 00000 101n <<= 1;

n >>= 1; n <<= 1;

n = 0000 1011

m = (n %2);

m = (n %2);

m = (n %2);

(m = 1)

(m = 1)

(m = 0)

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n = 000000 10 n = 00000 110

n+ = m;

n+ = m;

n = 0000000 1 n = 0000 1100

n >>= 1;

n = 00000 101n <<= 1;

n >>= 1; n <<= 1;

n >>= 1; n <<= 1;

n = 0000 1011

(m = 1)

(m = 1)

(m = 0)

m = (n %2);

m = (n %2);

m = (n %2);

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n = 000000 10 n = 00000 110

n+ = m;

n+ = m;

n = 0000000 1 n = 0000 1100

n+ = m;

n >>= 1;

n = 00000 101n <<= 1;

n >>= 1; n <<= 1;

n >>= 1; n <<= 1;

n = 0000 1011

m = (n %2);

m = (n %2);

m = (n %2);

m = (n %2);

(m = 1)

(m = 1)

(m = 0)

(m = 1)

Estrategia.

n+ = m;

n = 000000 10

n = 00000000

n = 000000 10 n = 00000 110

n+ = m;

n+ = m;

n = 0000000 1 n = 0000 1100

n+ = m;

n >>= 1;

n = 00000 101n <<= 1;

n >>= 1; n <<= 1;

n >>= 1; n <<= 1;

n = 0000 1011

n = 0000 1101

(m = 1)

(m = 1)

(m = 0)

(m = 1)

m = (n %2);

m = (n %2);

m = (n %2);

m = (n %2);

Complejitud computacional.

Complejitud computacional:

OpsBR(N) = (2× bitshift ++⊕)× log2(N) = O [log2(N)]

Transformacion rapida de Fourier (FFT):

Complejitud computacional:

Ops(N) = O [log2(N)] +O [N log2(N)]

= O [N log2(N)] O(N2)

Complejitud computacional.

Complejitud computacional:

OpsBR(N) = (2× bitshift ++⊕)× log2(N) = O [log2(N)]

Transformacion rapida de Fourier (FFT):

Complejitud computacional:

Ops(N) = O [log2(N)] +O [N log2(N)]

= O [N log2(N)] O(N2)

Implementacion.ft_bitrev.c

1 /*! \file ft_bitrev.c */2

3 #include <stdlib.h>4

5 /*! Returns ’n’ with ’bits’ numbers of bits bit-reversed. */6 size_t bit_reverse(size_t n, size_t bits)7 8 size_t m, nrev;9

10 nrev = 0;11 m = 0;12 do 13 nrev <<= 1; /* shift bits of nrev to left */14 nrev += (n % 2); /* lowest bit of n -> highest bit of nrev */15 n >>= 1; /* shift bits of n to right */16 m++; /* we did one more bit */17 while (m < bits);18

19 return nrev;20

Idea del programa.ft_fft.c

000 001 010 011 100 101 110 111

Idea del programa.ft_fft.c

000 001 010 011 100 101 110 111

blocks = N2

lines = 1points = 2

lo=0 hi=1b=0 b=1 b=2 b=3

Idea del programa.ft_fft.c

000 001 010 011 100 101 110 111

blocks = N4

blocks = N2

points = 4

lines = 1points = 2

lines = 2

lo=0

lo=0

hi=1

hi=2

b=0 b=1 b=2 b=3

b=0 b=1

Idea del programa.ft_fft.c

000 001 010 011 100 101 110 111

blocks = N4

blocks = N2

blocks = N8

points = 4

points = 8

lines = 1points = 2

lines = 2

lines = 4

lo=0

lo=0

lo=0

hi=1

hi=2

hi=4

b=0 b=1 b=2 b=3

b=0 b=1

b=0

Recursion para W mN .

Para cada numero N hay que calcular:

W mN = e2πi m

N = W m−1N exp

(2πiN

), W±N/2

N = e±iπ = −1;

Para cada N fijo una recursion con respecto a m:

Valores iniciales:

W− N2

N = −1, a = exp(

2πiN

)Recursion: w → a ·w results in: w *= (1− z) con z = 1− a, quees lo mismo que: w -= (z ∗ w).Calculacion de z:

z = 1− exp(

2πiN

)= 2 sin2

( πN

)− i sin

(2πN

)

Recursion para W mN .

Para cada numero N hay que calcular:

W mN = e2πi m

N = W m−1N exp

(2πiN

), W±N/2

N = e±iπ = −1;

Para cada N fijo una recursion con respecto a m:

Valores iniciales:

W− N2

N = −1, a = exp(

2πiN

)Recursion: w → a ·w results in: w *= (1− z) con z = 1− a, quees lo mismo que: w -= (z ∗ w).Calculacion de z:

z = 1− exp(

2πiN

)= 2 sin2

( πN

)− i sin

(2πN

)

Recursion para W mN .

Para cada numero N hay que calcular:

W mN = e2πi m

N = W m−1N exp

(2πiN

), W±N/2

N = e±iπ = −1;

Para cada N fijo una recursion con respecto a m:

Valores iniciales:

W− N2

N = −1, a = exp(

2πiN

)Recursion: w → a ·w results in: w *= (1− z) con z = 1− a, quees lo mismo que: w -= (z ∗ w).Calculacion de z:

z = 1− exp(

2πiN

)= 2 sin2

( πN

)− i sin

(2πN

)

Implementacion.ft_fft.c

1 /*! \file ft_fft.c */2

3 #define _XOPEN_SOURCE 5004 #define _ISOC99_SOURCE5

6 #include <math.h>7 #include <stdlib.h>8 #include <complex.h>9

10 size_t bit_reverse(size_t, size_t);11

12 /* Calculates the Fourier (inveres if ’isign=-1’) sum13 of 2^’bits’ ’data’ and saves result in ’data’. */14 void fft(complex double *data, size_t bits, int isign)15 16 complex double tmp, w, z;17 double wtmp, delta;18 size_t blocks, points, lines;19 size_t b, l, k;20 size_t lo, hi;

Implementacion.ft_fft.c

22 /* Bit-reversal of the data: */23 points = (1 << bits);24 for (k = 0; k < points; k++) 25 b = bit_reverse(k, bits);26 if (b > k) 27 tmp = data[k];28 data[k] = data[b];29 data[b] = tmp;30 31

Implementacion.ft_fft.c

33 blocks = (points >> 1); /* blocks=points/2 */34 points = 2;35 lines = 1;36 for (k = 0; k < bits; k++) 37 lo = 0;38

39 /* start recurrence for trigonometrics */40 delta = isign * 2.0 * M_PI / points;41 wtmp = sin(0.5 * delta);42 z = 2.0 * wtmp * wtmp - I * sin(delta);

Implementacion.ft_fft.c

44 for (b = 0; b < blocks; b++) 45 w = 1.0;46 hi = lo + lines;47 for (l = 0; l < lines; l++) 48 tmp = w * data[hi+l];49 data[hi+l] = data[lo+l] - tmp;50 data[lo+l] += tmp;51 w -= (z * w);52 53 lo += points;54 55 blocks >>= 1;56 lines <<= 1;57 points <<= 1;58 59

Resultado.main_ft_fft.c

1 #define _XOPEN_SOURCE 5002 #define _ISOC99_SOURCE3

4 #include <math.h>5 #include <stdio.h>6 #include <stdlib.h>7 #include <complex.h>8

9 /* #define PI 3.1415 */10 #define bits 811 #define N 25612 #define XMAX 2.013 #define DX XMAX/N14 #define VC 0.5/DX15

16 void fft(complex double*, size_t, int);17

18 double a, b;19

20 complex double function(double x)21 22 return exp(-a * x * x) + b * (rand()/((double)RAND_MAX)-0.5);23

Resultado.main_ft_fft.c

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

67 fft(data, bits, -1);68 for (n = 0; n < N; n++) 69 x = xvalue(n);70 printf("%f %f %f\n", x, creal(data[n])/N, cimag(data[n])/N);71 72 printf("\n\n");73

74 a = 100.0;75 b = 0.2;76 for (n = 0; n < N; n++) 77 x = xvalue(n);78 data[n] = function(x);79 printf("%f %f %f\n", x, creal(data[n]), cimag(data[n]));80 81 printf("\n\n");

Resultado.main_ft_fft.c

83 fft(data, bits, 1);84 for (n = N/2+1; n < N; n++) 85 res = data[n] * factor(n-N);86 printf("%f %f %f\n", freqvalue(n-N), creal(res), cimag(res));87 88 for (n = 0; n <= N/2; n++) 89 res = data[n] * factor(n);90 printf("%f %f %f\n", freqvalue(n), creal(res), cimag(res));91 92 printf("\n\n");93

94 fft(data, bits, -1);95 for (n = 0; n < N; n++) 96 x = xvalue(n);97 printf("%f %f %f\n", x, creal(data[n])/N, cimag(data[n])/N);98 99 return 0;

100

Ejemplo.Funcion de Gauss sin y con ruido.

0

0.2

0.4

0.6

0.8

1

−1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 0.8 1

f(t)

t

Ejemplo.Funcion de Gauss sin y con ruido.

−25

−20

−15

−10

−5

0

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ν

f(ν)

Ejemplo.Funcion de Gauss sin y con ruido.

−0.2

0

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

f(t)

t

Ejemplo.Funcion de Gauss sin y con ruido.

−25

−20

−15

−10

−5

0

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

f(ν)

ν

Parte VIIIAproximación de Chebyshev

Polinomial de Chebyshev.

Polinomial de Chebyshev:

Tn(x) = cos [n arc cos(x)] , x ∈ [−1,1]

Parece trigonometrico pero es un polinomial de orden n.Tiene recursiónSon ortogonalSon completos

¿Es un polinomial?

Como x ∈ [−1,1] podemos usar x = cos(θ):

Tn(x) = cos(nθ) = <(einθ)

Podemos escribir entonces (usando suma binomial):

Tn(x) = <[cos(θ) + i sin(θ)]n

= <

n∑k=0

(nk

)[cos(θ)]n−k [i sin(θ)]k

Parte real solo terminos con k pares y sin2(θ) = 1− x2:

Tn(x) =

[ n2 ]∑

k=0

(n

2k

)[cos(θ)]n−2k (−1)k [sin(θ)]2k

=

[ n2 ]∑

k=0

(n

2k

)(−1)k xn−2k (1− x2)k

q.e.d.

¿Es un polinomial?

Como x ∈ [−1,1] podemos usar x = cos(θ):

Tn(x) = cos(nθ) = <(einθ)

Podemos escribir entonces (usando suma binomial):

Tn(x) = <[cos(θ) + i sin(θ)]n

= <

n∑k=0

(nk

)[cos(θ)]n−k [i sin(θ)]k

Parte real solo terminos con k pares y sin2(θ) = 1− x2:

Tn(x) =

[ n2 ]∑

k=0

(n

2k

)[cos(θ)]n−2k (−1)k [sin(θ)]2k

=

[ n2 ]∑

k=0

(n

2k

)(−1)k xn−2k (1− x2)k

q.e.d.

¿Es un polinomial?

Como x ∈ [−1,1] podemos usar x = cos(θ):

Tn(x) = cos(nθ) = <(einθ)

Podemos escribir entonces (usando suma binomial):

Tn(x) = <[cos(θ) + i sin(θ)]n

= <

n∑k=0

(nk

)[cos(θ)]n−k [i sin(θ)]k

Parte real solo terminos con k pares y sin2(θ) = 1− x2:

Tn(x) =

[ n2 ]∑

k=0

(n

2k

)[cos(θ)]n−2k (−1)k [sin(θ)]2k

=

[ n2 ]∑

k=0

(n

2k

)(−1)k xn−2k (1− x2)k

q.e.d.

Ejemplos.

Primeros polinomiales de Chebyshev:

T0(x) = 1T1(x) = xT2(x) = 2x2 − 1T3(x) = 4x3 − 3xT4(x) = 8x4 − 8x2 + 1

...

Recursión.

Como cos(a± b) = cos(a) cos(b)∓ sin(a) sin(b):

Tn+1(x) = cos [(n + 1)θ]

= cos(nθ) cos(θ)− sin(nθ) sin(θ)

= 2 cos(nθ) cos(θ)− cos(nθ) cos(θ) + sin(nθ) sin(θ)= 2 cos(nθ) cos(θ)− cos [(n − 1)θ]

= 2xTn(x)− Tn−1(x)

Recursión para polinomiales de Chebyshev:

Tn+1(x) = 2xTn(x)− Tn−1(x)

Recursión.

Como cos(a± b) = cos(a) cos(b)∓ sin(a) sin(b):

Tn+1(x) = cos [(n + 1)θ]

= cos(nθ) cos(θ)− sin(nθ) sin(θ)

= 2 cos(nθ) cos(θ)− cos(nθ) cos(θ) + sin(nθ) sin(θ)= 2 cos(nθ) cos(θ)− cos [(n − 1)θ]

= 2xTn(x)− Tn−1(x)

Recursión para polinomiales de Chebyshev:

Tn+1(x) = 2xTn(x)− Tn−1(x)

Ortogonalidad.

La relación de ortogonalidad es:

∫ 1

−1dx(1− x2)− 1

2 Tm(x)Tn(x) =

0 si m 6= nπ2 si m = n 6= 0π si m = n = 0

Prueba.

∫ 1

−1dx(1− x2)− 1

2 cos [m arc cos(x)] cos [n arc cos(x)]

Substitución x = cos(θ), θ ∈ [π,0]:

=

∫ π

0dθ

sin(θ)√1− cos2(θ)

cos [mθ] cos [nθ]

=

∫ π

0dθ cos [mθ] cos [nθ]

=14

∫ π

0dθ[eimθ + e−imθ] [einθ + e−inθ]

=12

[sin[(m + n)θ]

(m + n)+

sin[(m − n)θ]

(m − n)

]π0

=12

0 si m 6= nπ si m = n 6= 0

2π si m = n = 0q.e.d.

¿Como se ve?

−1

−0.5

0

0.5

1

−1 −0.5 0 0.5 1

T n(x

)

x

n = 0

¿Como se ve?

−1

−0.5

0

0.5

1

−1 −0.5 0 0.5 1

T n(x

)

x

n = 1

¿Como se ve?

−1

−0.5

0

0.5

1

−1 −0.5 0 0.5 1

T n(x

)

x

n = 2

¿Como se ve?

−1

−0.5

0

0.5

1

−1 −0.5 0 0.5 1

T n(x

)

x

n = 3

¿Como se ve?

−1

−0.5

0

0.5

1

−1 −0.5 0 0.5 1

T n(x

)

x

n = 4

Ceros.

Buscamos los ceros x (n)k del polinomial Tn(x):

Tn(x(n)k ) = cos[n arc cos(x (n)

k )] = 0

Es equivalente a:

n arc cos(x (n)k ) = (2k + 1)

π

2

Entonces tiene n ceros en el intervalo [−1,1]:

x (n)k = cos

[π(k + 1

2

)n

](k = 0, . . . ,n − 1)

Ceros.

Buscamos los ceros x (n)k del polinomial Tn(x):

Tn(x(n)k ) = cos[n arc cos(x (n)

k )] = 0

Es equivalente a:

n arc cos(x (n)k ) = (2k + 1)

π

2

Entonces tiene n ceros en el intervalo [−1,1]:

x (n)k = cos

[π(k + 1

2

)n

](k = 0, . . . ,n − 1)

Ortogonalidad discreta.

Ortogonalidad discreta:

n−1∑k=0

Ti

(x (n)

k

)Tj

(x (n)

k

)=

0, i 6= jn2 , i = j 6= 0n, i = j = 0

=n2δi,j(1 + δi,0)

donde x (n)k son los ceros de: Tn(x

(n)k ) = 0 y i , j < n.

Consequencia.

Expansión general de una función f (x) con x ∈ [−1,1]:

f (x) =∞∑i=0

diTi(x)

Con N fijo, los valores en los ceros x (N)k son:

f(

x (N)k

)=

∞∑j=0

djTj

(x (N)

k

)Consequencia:

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)=

∞∑j=0

dj

N−1∑k=0

Ti

(x (N)

k

)Tj

(x (N)

k

)

=N−1∑j=0

djN2δi,j(1 + δi,0) = di

N2

(1 + δi,0)

Consequencia.

Expansión general de una función f (x) con x ∈ [−1,1]:

f (x) =∞∑i=0

diTi(x)

Con N fijo, los valores en los ceros x (N)k son:

f(

x (N)k

)=

∞∑j=0

djTj

(x (N)

k

)Consequencia:

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)=

∞∑j=0

dj

N−1∑k=0

Ti

(x (N)

k

)Tj

(x (N)

k

)

=N−1∑j=0

djN2δi,j(1 + δi,0) = di

N2

(1 + δi,0)

Consequencia.

Expansión general de una función f (x) con x ∈ [−1,1]:

f (x) =∞∑i=0

diTi(x)

Con N fijo, los valores en los ceros x (N)k son:

f(

x (N)k

)=

∞∑j=0

djTj

(x (N)

k

)Consequencia:

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)=

∞∑j=0

dj

N−1∑k=0

Ti

(x (N)

k

)Tj

(x (N)

k

)

=N−1∑j=0

djN2δi,j(1 + δi,0) = di

N2

(1 + δi,0)

Formula de aproximación.

Vamos a definir:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)= di(1 + δi,0)

Entonces:

f(

x (N)k

)=

N−1∑j=0

djTj

(x (N)

k

)=

N−1∑j=0

cjTj

(x (N)

k

)− c0

2

Se puede usar como aproximación también:

f (x) ≈N−1∑j=0

cjTj (x)− c0

2

Formula de aproximación.

Vamos a definir:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)= di(1 + δi,0)

Entonces:

f(

x (N)k

)=

N−1∑j=0

djTj

(x (N)

k

)=

N−1∑j=0

cjTj

(x (N)

k

)− c0

2

Se puede usar como aproximación también:

f (x) ≈N−1∑j=0

cjTj (x)− c0

2

Formula de aproximación.

Vamos a definir:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)= di(1 + δi,0)

Entonces:

f(

x (N)k

)=

N−1∑j=0

djTj

(x (N)

k

)=

N−1∑j=0

cjTj

(x (N)

k

)− c0

2

Se puede usar como aproximación también:

f (x) ≈N−1∑j=0

cjTj (x)− c0

2

Aproximación de Chebyshev.

Aproximación de Chebyshev (preliminario):

f (x) ≈N−1∑j=0

cjTj (x)− c0

2

donde:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)Es un polinomial de orden N − 1.

Es exacto para x = x (N)k .

Pregunta:

¿Es mejor que otra aproximación polinomial del mismo orden?Respuesta: No!

Aproximación de Chebyshev.

Aproximación de Chebyshev (preliminario):

f (x) ≈N−1∑j=0

cjTj (x)− c0

2

donde:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)Es un polinomial de orden N − 1.

Es exacto para x = x (N)k .

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:

ci =2N

N−1∑k=0

Ti

(x (N)

k

)f(

x (N)k

)Usar solo M N de los coeficientes:

f (x) ≈M−1∑j=0

cjTj (x)− c0

2

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 unatruncación M N es:

error ≈ cMTM(x)

TM(x) tiene M + 1 extrema y entonces el error es distribuido casihomogeneamente en [−1,1]!

Ventaja:

Con la aproximación de Chebyshev se puede obtener unaaproximación polinomial con un orden muy bajo con propiedadesoptimales.

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 unatruncación M N es:

error ≈ cMTM(x)

TM(x) tiene M + 1 extrema y entonces el error es distribuido casihomogeneamente en [−1,1]!

Ventaja:

Con la aproximación de Chebyshev se puede obtener unaaproximación polinomial con un orden muy bajo con propiedadesoptimales.

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 unatruncación M N es:

error ≈ cMTM(x)

TM(x) tiene M + 1 extrema y entonces el error es distribuido casihomogeneamente en [−1,1]!

Ventaja:

Con la aproximación de Chebyshev se puede obtener unaaproximación polinomial con un orden muy bajo con propiedadesoptimales.

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 unatruncación M N es:

error ≈ cMTM(x)

TM(x) tiene M + 1 extrema y entonces el error es distribuido casihomogeneamente en [−1,1]!

Ventaja:

Con la aproximación de Chebyshev se puede obtener unaaproximación polinomial con un orden muy bajo con propiedadesoptimales.

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 unatruncación M N es:

error ≈ cMTM(x)

TM(x) tiene M + 1 extrema y entonces el error es distribuido casihomogeneamente en [−1,1]!

Ventaja:

Con la aproximación de Chebyshev se puede obtener unaaproximación polinomial con un orden muy bajo con propiedadesoptimales.

Cambio del intervalo.

Tenemos una función f (x) con x ∈ [a,b] donde a < b arbitrarios.Hay que substituir: x → ξ donde ξ ∈ [−1,1]:

ξ =x − b+a

2b−a

2

Inversión es:x =

b + a2

+b − a

Cambio del intervalo.

Tenemos una función f (x) con x ∈ [a,b] donde a < b arbitrarios.Hay que substituir: x → ξ donde ξ ∈ [−1,1]:

ξ =x − b+a

2b−a

2

Inversión es:x =

b + a2

+b − a

Cambio del intervalo.

Tenemos una función f (x) con x ∈ [a,b] donde a < b arbitrarios.Hay que substituir: x → ξ donde ξ ∈ [−1,1]:

ξ =x − b+a

2b−a

2

Inversión es:x =

b + a2

+b − a

Implementación.ch_coef.c

1 /*! \file ch_coef.c */2

3 #define _XOPEN_SOURCE 5004 #define _ISOC99_SOURCE5

6 #include <math.h>7 #include <stdlib.h>8

9 /*! Calculates the Chebyshev coeficients ’c[0], ..., c[n-1]’10 for the funcion ’f’ being defined in the interval11 [’a’,’b’]. */12 void chebyshev_coef(double (*f)(double), double a, double b,13 double* c, int n)14 15 int k, j;16 double bma, bpa, fac, tmp, *value;

Implementación.ch_coef.c

18 value = malloc(n * sizeof(double));19 bma = 0.5 * (b - a);20 bpa = 0.5 * (b + a);21 for (k = 0; k < n; k++) 22 tmp = cos(M_PI * (k + 0.5) / n);23 value[k] = f(tmp * bma + bpa);24 25 fac = 2.0 / n;26 for (j = 0; j < n; j++) 27 tmp = 0.0;28 for (k = 0; k < n; k++)29 tmp += value[k] * cos(M_PI * j * (k + 0.5) / n);30 c[j] = fac * tmp;31 32 free(value);33

Calcular la aproximación de Chebyshev.

Problema:Usando los coeficientes ci hay que calcular ahora la aproximación deChebyshev:

f (x) ≈M−1∑j=0

cjTj [ξ(x)]− c0

2

donde ξ(x) = [2x − (b + a)]/(b − a) ∈ [−1,1]

¿Como vamos a calcular eso?

Directamente como una suma. (Uhhps...!)Como una suma pero usando recursión para Tn(x). (Uhhps...!)Usando la recursión de Clenshaw. (Excelente!)

Calcular la aproximación de Chebyshev.

Problema:Usando los coeficientes ci hay que calcular ahora la aproximación deChebyshev:

f (x) ≈M−1∑j=0

cjTj [ξ(x)]− c0

2

donde ξ(x) = [2x − (b + a)]/(b − a) ∈ [−1,1]

¿Como vamos a calcular eso?

Directamente como una suma. (Uhhps...!)Como una suma pero usando recursión para Tn(x). (Uhhps...!)Usando la recursión de Clenshaw. (Excelente!)

Calcular la aproximación de Chebyshev.

Problema:Usando los coeficientes ci hay que calcular ahora la aproximación deChebyshev:

f (x) ≈M−1∑j=0

cjTj [ξ(x)]− c0

2

donde ξ(x) = [2x − (b + a)]/(b − a) ∈ [−1,1]

¿Como vamos a calcular eso?

Directamente como una suma. (Uhhps...!)Como una suma pero usando recursión para Tn(x). (Uhhps...!)Usando la recursión de Clenshaw. (Excelente!)

Calcular la aproximación de Chebyshev.

Problema:Usando los coeficientes ci hay que calcular ahora la aproximación deChebyshev:

f (x) ≈M−1∑j=0

cjTj [ξ(x)]− c0

2

donde ξ(x) = [2x − (b + a)]/(b − a) ∈ [−1,1]

¿Como vamos a calcular eso?

Directamente como una suma. (Uhhps...!)Como una suma pero usando recursión para Tn(x). (Uhhps...!)Usando la recursión de Clenshaw. (Excelente!)

Calcular la aproximación de Chebyshev.

Problema:Usando los coeficientes ci hay que calcular ahora la aproximación deChebyshev:

f (x) ≈M−1∑j=0

cjTj [ξ(x)]− c0

2

donde ξ(x) = [2x − (b + a)]/(b − a) ∈ [−1,1]

¿Como vamos a calcular eso?

Directamente como una suma. (Uhhps...!)Como una suma pero usando recursión para Tn(x). (Uhhps...!)Usando la recursión de Clenshaw. (Excelente!)

Clenshaw para Chebyshev.Nosotros tenemos la suma:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2, Tn+1(ξ) = 2ξTn(ξ)− Tn−1(ξ)

Con Clenshaw tenemos:

Coeficientes: αn(ξ) = 2ξ, βn(ξ) = −1Recursión: hM+1(ξ) = hM(ξ) = 0

hn(ξ) = 2ξhn+1(ξ)− hn+2(ξ) + cn (n = M − 1, . . . ,0)

Resultado:

fCA [x(ξ)] = h0(ξ)T0(ξ) + h1(ξ) [T1(ξ)− α0(ξ)T0(ξ)]−c0

2

= h0(ξ)− ξh1(ξ)−c0

2

Clenshaw para Chebyshev.Nosotros tenemos la suma:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2, Tn+1(ξ) = 2ξTn(ξ)− Tn−1(ξ)

Con Clenshaw tenemos:

Coeficientes: αn(ξ) = 2ξ, βn(ξ) = −1Recursión: hM+1(ξ) = hM(ξ) = 0

hn(ξ) = 2ξhn+1(ξ)− hn+2(ξ) + cn (n = M − 1, . . . ,0)

Resultado:

fCA [x(ξ)] = h0(ξ)T0(ξ) + h1(ξ) [T1(ξ)− α0(ξ)T0(ξ)]−c0

2

= h0(ξ)− ξh1(ξ)−c0

2

Clenshaw para Chebyshev.Nosotros tenemos la suma:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2, Tn+1(ξ) = 2ξTn(ξ)− Tn−1(ξ)

Con Clenshaw tenemos:

Coeficientes: αn(ξ) = 2ξ, βn(ξ) = −1Recursión: hM+1(ξ) = hM(ξ) = 0

hn(ξ) = 2ξhn+1(ξ)− hn+2(ξ) + cn (n = M − 1, . . . ,0)

Resultado:

fCA [x(ξ)] = h0(ξ)T0(ξ) + h1(ξ) [T1(ξ)− α0(ξ)T0(ξ)]−c0

2

= h0(ξ)− ξh1(ξ)−c0

2

Clenshaw para Chebyshev.Nosotros tenemos la suma:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2, Tn+1(ξ) = 2ξTn(ξ)− Tn−1(ξ)

Con Clenshaw tenemos:

Coeficientes: αn(ξ) = 2ξ, βn(ξ) = −1Recursión: hM+1(ξ) = hM(ξ) = 0

hn(ξ) = 2ξhn+1(ξ)− hn+2(ξ) + cn (n = M − 1, . . . ,0)

Resultado:

fCA [x(ξ)] = h0(ξ)T0(ξ) + h1(ξ) [T1(ξ)− α0(ξ)T0(ξ)]−c0

2

= h0(ξ)− ξh1(ξ)−c0

2

Clenshaw para Chebyshev.Nosotros tenemos la suma:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2, Tn+1(ξ) = 2ξTn(ξ)− Tn−1(ξ)

Con Clenshaw tenemos:

Coeficientes: αn(ξ) = 2ξ, βn(ξ) = −1Recursión: hM+1(ξ) = hM(ξ) = 0

hn(ξ) = 2ξhn+1(ξ)− hn+2(ξ) + cn (n = M − 1, . . . ,0)

Resultado:

fCA [x(ξ)] = h0(ξ)T0(ξ) + h1(ξ) [T1(ξ)− α0(ξ)T0(ξ)]−c0

2

= h0(ξ)− ξh1(ξ)−c0

2

Implementación.ch_approx.c

1 /*! \file ch_approx.c */2

3 #include <assert.h>4

5 /*! Calculates the Chebyshev approximation at the value ’x’6 within the interval [’a’,’b’] using ’m’ of the Chebyshev7 coeficients ’c[]’. */8 double chebyshev_approx(double x, double a, double b,9 double* c, int m)

10 11 double alpha, h_new, h, h_old;12 int n;13

14 assert((a <= x) && (x <= b));15 alpha = 2.0 * (2.0 * x - (a + b)) / (b - a);16 h_old = 0.0; h = 0.0;17 for (n = m-1; n >= 0; n--) 18 h_new = alpha * h - h_old + c[n];19 h_old = h;20 h = h_new;21 22 return h - 0.5 *( alpha * h_old + c[0]);23

Resultado.main_ch_approx.c

1 #include <math.h>2 #include <stdio.h>3

4 #define GAMMA 0.15 #define X0 0.16 #define XMAX 0.57

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

43 chebyshev_coef(function2, -XMAX, XMAX, c, 10);44 for (x = -XMAX; x <= XMAX; x += 0.005)45 printf("%g %g\n",46 x, chebyshev_approx(x, -XMAX, XMAX, c, 10));47 printf("\n\n");48

49 chebyshev_coef(function2, -XMAX, XMAX, c, 20);50 for (x = -XMAX; x <= XMAX; x += 0.005)51 printf("%g %g\n",52 x, chebyshev_approx(x, -XMAX, XMAX, c, 20));53 printf("\n\n");54

55 chebyshev_coef(function2, -XMAX, XMAX, c, 20);56 for (x = -XMAX; x <= XMAX; x += 0.005)57 printf("%g %g\n",58 x, chebyshev_approx(x, -XMAX, XMAX, c, 10));59 printf("\n\n");60

61 chebyshev_coef(function1, -XMAX, XMAX, c, 100);62 for (x = -XMAX; x <= XMAX; x += 0.005)63 printf("%g %g\n",64 x, chebyshev_approx(x, -XMAX, XMAX, c, 100));65 printf("\n\n");

Resultado.main_ch_approx.c

67 chebyshev_coef(function1, -XMAX, XMAX, c, 200);68 for (x = -XMAX; x <= XMAX; x += 0.005)69 printf("%g %g\n",70 x, chebyshev_approx(x, -XMAX, XMAX, c, 200));71 printf("\n\n");72

73 return 0;74

Ejemplos.

0

20

40

60

80

100

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 5/5

Ejemplos.

0

20

40

60

80

100

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 10/10

Ejemplos.

0

20

40

60

80

100

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 20/20

Ejemplos.

0

20

40

60

80

100

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 10/20

Ejemplos.

0

20

40

60

80

100

120

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 100/100

Ejemplos.

0

20

40

60

80

100

120

−0.5 −0.4 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5

f(x)

x

f (x)Chebyshev 200/200

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:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2

Queremos saber la integral de esta función aproximada:

FCA(x) =

∫ x

dx ′fCA(x ′) =M−1∑j=0

cj

∫ x

dx ′Tj [ξ(x ′)]−c0

2x + const

=b − a

2

M−1∑j=1

cj

∫ ξ(x)

dξTj(ξ) +c0

2x + const

¿Cuál es la integral del polinomial de Chebyshev?

∫ ξ

dξ′Tn(ξ′) =?

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:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2

Queremos saber la integral de esta función aproximada:

FCA(x) =

∫ x

dx ′fCA(x ′) =M−1∑j=0

cj

∫ x

dx ′Tj [ξ(x ′)]−c0

2x + const

=b − a

2

M−1∑j=1

cj

∫ ξ(x)

dξTj(ξ) +c0

2x + const

¿Cuál es la integral del polinomial de Chebyshev?

∫ ξ

dξ′Tn(ξ′) =?

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:

fCA(x) =M−1∑j=0

cjTj [ξ(x)]− c0

2

Queremos saber la integral de esta función aproximada:

FCA(x) =

∫ x

dx ′fCA(x ′) =M−1∑j=0

cj

∫ x

dx ′Tj [ξ(x ′)]−c0

2x + const

=b − a

2

M−1∑j=1

cj

∫ ξ(x)

dξTj(ξ) +c0

2x + const

¿Cuál es la integral del polinomial de Chebyshev?

∫ ξ

dξ′Tn(ξ′) =?

Integral de Tn(ξ).Substitución ξ′ = cos(θ).

=

∫ ξ

dξ′ cos[n arc cos(ξ′)]

= −∫ arc cos(ξ)

dθ sin(θ) cos(nθ)

= − 14i

∫ arc cos(ξ)

dθ(

eiθ − e−iθ) (einθ + e−inθ)= − 1

4i

ei(n+1)θ

i(n + 1)− e−i(n+1)θ

−i(n + 1)− ei(n−1)θ

i(n − 1)+

e−i(n−1)

−i(n − 1)

θ=arc cos(ξ)

=14

ei(n+1)θ

n + 1+

e−i(n+1)θ

n + 1− ei(n−1)θ

n − 1− e−i(n−1)

n − 1

θ=arc cos(ξ)

=cos[(n + 1) arc cos(ξ)]

2(n + 1)− cos[(n − 1) arc cos(ξ)]

2(n − 1)

=Tn+1(ξ)

2(n + 1)− Tn−1(ξ)

2(n − 1)

Nuevos coeficientes.

Entonces la integral de la aproximación de Chebyshev es:

FCA(x) =b − a

2

M−1∑n=1

cn

∫ ξ(x)

dξ′Tn(ξ′) +

c0

2x + const

=b − a

2

M−1∑n=1

cn

[Tn+1[ξ(x)]

2(n + 1)− Tn−1[ξ(x)]

2(n − 1)

]+

c0

2x + const

=b − a

2

M∑

n=2

cn−1Tn[ξ(x)]

2n−

M−2∑n=0

cn+1Tn[ξ(x)]

2n

+b − a

2c0

2T1[ξ(x)] + const

Nuevos coeficientes.Entonces la integral de la aproximación de Chebyshev es:

=b − a

2

cM−1

2MTM [ξ(x)] +

cM−2

2(M − 1)TM−1[ξ(x)]

+M−2∑n=2

cn−1 − cn+1

2n︸ ︷︷ ︸∝Cn

Tn[ξ(x)] +c0 − c2

2︸ ︷︷ ︸∝C1

T1[ξ(x)]

+ const

≈M−1∑n=1

CnTn[ξ(x)] + const

=

M−1∑n=0

CnTn[ξ(x)]− C0

2

+ const

donde los nuevos coeficientes son:

Cn =b − a

4n(cn−1 − cn+1) (n > 0), C0 = 0

Implementación.ch_coefint.c

1 /*! \file ch_coefint.c */2

3 /*! Calculates Chebyshev coeficients ’cint[]’ for the4 integral of a function described by ’c[]’. */5 void chebyshev_coefint(double* cint, double* c, double a,6 double b, int n)7 8 int j;9 double factor, sum, sgn;

10

11 factor = 0.25 * (b-a);12 sum = 0.0;13 sgn = 1.0;14 for (j = 1; j < n-1; j++) 15 cint[j] = factor * (c[j-1] - c[j+1]) / j;16 sum += sgn * cint[j];17 sgn = -sgn;18 19 cint[n-1]= factor * c[n-2] / (n-1);20 sum += sgn * cint[n-1];21 cint[0] = 2.0 * sum; /* integral at x=a is zero */22

Derivada.

Queremos la derivada:

ddx

fCA(x) = f ′CA(x) =M−1∑n=0

cn∂

∂xTn[ξ(x)]

Pero ya sabemos la regla fCA → FCA: cn → Cn!Entonces hay que invertir eso (Cn → cn, cn → c′n) con elresultado:

f ′CA(x) =M−1∑n=0

c′nTn[ξ(x)]−c′02

donde los coeficientes se calculan a través de la recursión:

c′n−1 = c′n+1 +4n

b − acn

Derivada.

Queremos la derivada:

ddx

fCA(x) = f ′CA(x) =M−1∑n=0

cn∂

∂xTn[ξ(x)]

Pero ya sabemos la regla fCA → FCA: cn → Cn!Entonces hay que invertir eso (Cn → cn, cn → c′n) con elresultado:

f ′CA(x) =M−1∑n=0

c′nTn[ξ(x)]−c′02

donde los coeficientes se calculan a través de la recursión:

c′n−1 = c′n+1 +4n

b − acn

Derivada.

Queremos la derivada:

ddx

fCA(x) = f ′CA(x) =M−1∑n=0

cn∂

∂xTn[ξ(x)]

Pero ya sabemos la regla fCA → FCA: cn → Cn!Entonces hay que invertir eso (Cn → cn, cn → c′n) con elresultado:

f ′CA(x) =M−1∑n=0

c′nTn[ξ(x)]−c′02

donde los coeficientes se calculan a través de la recursión:

c′n−1 = c′n+1 +4n

b − acn

Implementación.ch_coefder.c

1 /*! \file ch_coefder.c */2

3 /*! Calculates the coeficients ’cder[]’ for the derivative4 of the function corresponding to ’c[]’. */5 void chder(double* cder, double* c, double a, double b, int n)6 7 int j;8 double factor;9

10 factor = 4.0 / (b - a);11 cder[n-1] = 0.0;12 cder[n-2] = factor * (n - 1.0) * c[n-1];13 for (j = n-3; j >= 0; j--)14 cder[j] = cder[j+2] + factor * (j + 1.0) * c[j+1];15

Parte IXNúmeros aleatorios

¿Para qué numeros aleatorios?

Generacion de data con ruido como simulacion de datosexperimentales para probar estabilidad de programas.Integracion multi-dimensional: Monte-Carlo algoritmos.Ecuaciones diferenciales estochasticas: Movimiento Brown,Ecuaciones de Langevin.Resolver una ecuacion maestra: Trayectorias cuanticas.Simulacion de eventos probabilisticos.

¿Para qué numeros aleatorios?

Generacion de data con ruido como simulacion de datosexperimentales para probar estabilidad de programas.Integracion multi-dimensional: Monte-Carlo algoritmos.Ecuaciones diferenciales estochasticas: Movimiento Brown,Ecuaciones de Langevin.Resolver una ecuacion maestra: Trayectorias cuanticas.Simulacion de eventos probabilisticos.

¿Para qué numeros aleatorios?

Generacion de data con ruido como simulacion de datosexperimentales para probar estabilidad de programas.Integracion multi-dimensional: Monte-Carlo algoritmos.Ecuaciones diferenciales estochasticas: Movimiento Brown,Ecuaciones de Langevin.Resolver una ecuacion maestra: Trayectorias cuanticas.Simulacion de eventos probabilisticos.

¿Para qué numeros aleatorios?

Generacion de data con ruido como simulacion de datosexperimentales para probar estabilidad de programas.Integracion multi-dimensional: Monte-Carlo algoritmos.Ecuaciones diferenciales estochasticas: Movimiento Brown,Ecuaciones de Langevin.Resolver una ecuacion maestra: Trayectorias cuanticas.Simulacion de eventos probabilisticos.

¿Para qué numeros aleatorios?

Generacion de data con ruido como simulacion de datosexperimentales para probar estabilidad de programas.Integracion multi-dimensional: Monte-Carlo algoritmos.Ecuaciones diferenciales estochasticas: Movimiento Brown,Ecuaciones de Langevin.Resolver una ecuacion maestra: Trayectorias cuanticas.Simulacion de eventos probabilisticos.

Problema.

Maquina deterministica:

Una maquina deterministica (computador) no es capaz de generarnumeros aleatorios!

Compromiso:

Computador produce sequencias s de numeros pseudo-aleatoriosN(s)

i .

1 Se repiten despues una sequencia de largo L: N(s)i+L = N(s)

i .

2 Tienen correlaciones en la sequencia: 〈N(s)i N(s)

j 〉 6= δi,j .

3 Tienen correlaciones entre sequencias: 〈N(s)i N(q)

i 〉 6= δs,q .

Problema.

Maquina deterministica:

Una maquina deterministica (computador) no es capaz de generarnumeros aleatorios!

Compromiso:

Computador produce sequencias s de numeros pseudo-aleatoriosN(s)

i .

1 Se repiten despues una sequencia de largo L: N(s)i+L = N(s)

i .

2 Tienen correlaciones en la sequencia: 〈N(s)i N(s)

j 〉 6= δi,j .

3 Tienen correlaciones entre sequencias: 〈N(s)i N(q)

i 〉 6= δs,q .

Problema.

Maquina deterministica:

Una maquina deterministica (computador) no es capaz de generarnumeros aleatorios!

Compromiso:

Computador produce sequencias s de numeros pseudo-aleatoriosN(s)

i .

1 Se repiten despues una sequencia de largo L: N(s)i+L = N(s)

i .

2 Tienen correlaciones en la sequencia: 〈N(s)i N(s)

j 〉 6= δi,j .

3 Tienen correlaciones entre sequencias: 〈N(s)i N(q)

i 〉 6= δs,q .

Problema.

Maquina deterministica:

Una maquina deterministica (computador) no es capaz de generarnumeros aleatorios!

Compromiso:

Computador produce sequencias s de numeros pseudo-aleatoriosN(s)

i .

1 Se repiten despues una sequencia de largo L: N(s)i+L = N(s)

i .

2 Tienen correlaciones en la sequencia: 〈N(s)i N(s)

j 〉 6= δi,j .

3 Tienen correlaciones entre sequencias: 〈N(s)i N(q)

i 〉 6= δs,q .

Problema.

Maquina deterministica:

Una maquina deterministica (computador) no es capaz de generarnumeros aleatorios!

Compromiso:

Computador produce sequencias s de numeros pseudo-aleatoriosN(s)

i .

1 Se repiten despues una sequencia de largo L: N(s)i+L = N(s)

i .

2 Tienen correlaciones en la sequencia: 〈N(s)i N(s)

j 〉 6= δi,j .

3 Tienen correlaciones entre sequencias: 〈N(s)i N(q)

i 〉 6= δs,q .

Numeros aleatorios en C.

En el header “stdlib.h” existen declaraciones para funciones denumeros aleatorios:

void srand(unsigned seed):Para inicialisar la sequencia de numeros “aleatorios”. Para cadavalor de seed sale una sequencia de numeros pseudo-aleatorios.#define RAND_MAX ...:Se producen numeros en el intervalo [0, RAND_MAX].int rand(void):Da un valor de la sequencia de numeros aleatorios en el intervalo[0,RAND_MAX].

Aplicacion por ejemplo como:#include <time.h>double x;srand(time(NULL);x = rand() / ((double)RAND_MAX);

Numeros aleatorios en C.

En el header “stdlib.h” existen declaraciones para funciones denumeros aleatorios:

void srand(unsigned seed):Para inicialisar la sequencia de numeros “aleatorios”. Para cadavalor de seed sale una sequencia de numeros pseudo-aleatorios.#define RAND_MAX ...:Se producen numeros en el intervalo [0, RAND_MAX].int rand(void):Da un valor de la sequencia de numeros aleatorios en el intervalo[0,RAND_MAX].

Aplicacion por ejemplo como:#include <time.h>double x;srand(time(NULL);x = rand() / ((double)RAND_MAX);

Problemas con rand().

Tipicamente RAND_MAX = 32767 que produce un intervalopequeño:x = rand() / ((double)RAND_MAX) ∈ [0,1] con unagranularidad gruesa!Algoritmo es malo (generador lineal congruencial):

1 Sequencia se repite con L =RAND_MAX+1.2 Hay correlaciones muy fuertes.

Problemas con rand().

Tipicamente RAND_MAX = 32767 que produce un intervalopequeño:x = rand() / ((double)RAND_MAX) ∈ [0,1] con unagranularidad gruesa!Algoritmo es malo (generador lineal congruencial):

1 Sequencia se repite con L =RAND_MAX+1.2 Hay correlaciones muy fuertes.

Problemas con rand().

Tipicamente RAND_MAX = 32767 que produce un intervalopequeño:x = rand() / ((double)RAND_MAX) ∈ [0,1] con unagranularidad gruesa!Algoritmo es malo (generador lineal congruencial):

1 Sequencia se repite con L =RAND_MAX+1.2 Hay correlaciones muy fuertes.

Problemas con rand().

Tipicamente RAND_MAX = 32767 que produce un intervalopequeño:x = rand() / ((double)RAND_MAX) ∈ [0,1] con unagranularidad gruesa!Algoritmo es malo (generador lineal congruencial):

1 Sequencia se repite con L =RAND_MAX+1.2 Hay correlaciones muy fuertes.

Generador lineal congruencial.Lo mas simple que se puede hacer.

Algoritmo es una recursion:

rn+1 = arn + c (mod m)

donde:a > 0 integro es el multiplicadorc > 0 integro es el incrementom > 0 integro es el moduloLos valores estan en el intervalo [0,m − 1] y se repiten despuesL = m numeros.

Generador lineal congruencial.Lo mas simple que se puede hacer.

Algoritmo es una recursion:

rn+1 = arn + c (mod m)

donde:a > 0 integro es el multiplicadorc > 0 integro es el incrementom > 0 integro es el moduloLos valores estan en el intervalo [0,m − 1] y se repiten despuesL = m numeros.

Generador lineal congruencial.Lo mas simple que se puede hacer.

Algoritmo es una recursion:

rn+1 = arn + c (mod m)

donde:a > 0 integro es el multiplicadorc > 0 integro es el incrementom > 0 integro es el moduloLos valores estan en el intervalo [0,m − 1] y se repiten despuesL = m numeros.

Generador lineal congruencial.Lo mas simple que se puede hacer.

Algoritmo es una recursion:

rn+1 = arn + c (mod m)

donde:a > 0 integro es el multiplicadorc > 0 integro es el incrementom > 0 integro es el moduloLos valores estan en el intervalo [0,m − 1] y se repiten despuesL = m numeros.

Generador lineal congruencial.Lo mas simple que se puede hacer.

Algoritmo es una recursion:

rn+1 = arn + c (mod m)

donde:a > 0 integro es el multiplicadorc > 0 integro es el incrementom > 0 integro es el moduloLos valores estan en el intervalo [0,m − 1] y se repiten despuesL = m numeros.

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Ejemplo.

Ejemplo: generador lineal congruencial con parametros: a = 65,c = 17, m = 4

Sea el valor inicial (seed) r0 = 1.r1 = 65 ∗ 1 + 19 (mod 4) = 84 %4 = 0r2 = 65 ∗ 0 + 19 (mod 4) = 19 %4 = 3r3 = 65 ∗ 3 + 19 (mod 4) = 214 %4 = 2r4 = 65 ∗ 2 + 19 (mod 4) = 149 %4 = 1Entonces tenemos la secuencia: 1,0,3,2,1,0,3,2, . . .

Correlaciones.

1 Tenemos una secuencia de L = m numeros pseudo-aleatorios.2 Vamos a construir d-dimensionales vectores como:

r0r1...

rd−1

,

rd

rd+1...

r2d−1

, . . .

3 Todos estos vectores se localisan como puntos en m1/d − 1planos, cada plano es (d − 1)-dimensional. Posiciones yorientaciones de los planos dependen de a y c.

Alerta Roja:

Estos son correlaciones muy fuertes!

Correlaciones.

1 Tenemos una secuencia de L = m numeros pseudo-aleatorios.2 Vamos a construir d-dimensionales vectores como:

r0r1...

rd−1

,

rd

rd+1...

r2d−1

, . . .

3 Todos estos vectores se localisan como puntos en m1/d − 1planos, cada plano es (d − 1)-dimensional. Posiciones yorientaciones de los planos dependen de a y c.

Alerta Roja:

Estos son correlaciones muy fuertes!

Correlaciones.

1 Tenemos una secuencia de L = m numeros pseudo-aleatorios.2 Vamos a construir d-dimensionales vectores como:

r0r1...

rd−1

,

rd

rd+1...

r2d−1

, . . .

3 Todos estos vectores se localisan como puntos en m1/d − 1planos, cada plano es (d − 1)-dimensional. Posiciones yorientaciones de los planos dependen de a y c.

Alerta Roja:

Estos son correlaciones muy fuertes!

Correlaciones.

1 Tenemos una secuencia de L = m numeros pseudo-aleatorios.2 Vamos a construir d-dimensionales vectores como:

r0r1...

rd−1

,

rd

rd+1...

r2d−1

, . . .

3 Todos estos vectores se localisan como puntos en m1/d − 1planos, cada plano es (d − 1)-dimensional. Posiciones yorientaciones de los planos dependen de a y c.

Alerta Roja:

Estos son correlaciones muy fuertes!

Pequeño programa.main_de_corr.c

1 #include <stdio.h>2

3 #define M 644

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.

0

10

20

30

40

50

60

0 10 20 30 40 50 60

¿Que necesitamos?

1 Intervalo de numeros Rn ∈ [0,Rmax] con Rmax mucho mas grandepara reducir la granularidad del numero aleatorio tipo puntoflotante:

xn = Rn/Rmax ∈ [0,1]

Eso significa reemplazar int por un tipo integro con mas bits,por ejemplo long long int (64bit).

2 Periodo de la secuencia L tiene que ser mucho mas grande ycontrolable, es decir conocido.

3 Reducir las correlaciones fuertemente.

¿Que necesitamos?

1 Intervalo de numeros Rn ∈ [0,Rmax] con Rmax mucho mas grandepara reducir la granularidad del numero aleatorio tipo puntoflotante:

xn = Rn/Rmax ∈ [0,1]

Eso significa reemplazar int por un tipo integro con mas bits,por ejemplo long long int (64bit).

2 Periodo de la secuencia L tiene que ser mucho mas grande ycontrolable, es decir conocido.

3 Reducir las correlaciones fuertemente.

¿Que necesitamos?

1 Intervalo de numeros Rn ∈ [0,Rmax] con Rmax mucho mas grandepara reducir la granularidad del numero aleatorio tipo puntoflotante:

xn = Rn/Rmax ∈ [0,1]

Eso significa reemplazar int por un tipo integro con mas bits,por ejemplo long long int (64bit).

2 Periodo de la secuencia L tiene que ser mucho mas grande ycontrolable, es decir conocido.

3 Reducir las correlaciones fuertemente.

Algoritmo multiplicativo congruencial.Otra posibilidad.

Tambien es una recursion, pero mas simple:

rn+1 = arn (mod m)

Es mas simple (mas rapido).Correlaciones no son mas fuertes.Hay que evitar r0 = 0 como valor inicial.

Algoritmo multiplicativo congruencial.Otra posibilidad.

Tambien es una recursion, pero mas simple:

rn+1 = arn (mod m)

Es mas simple (mas rapido).Correlaciones no son mas fuertes.Hay que evitar r0 = 0 como valor inicial.

Algoritmo multiplicativo congruencial.Otra posibilidad.

Tambien es una recursion, pero mas simple:

rn+1 = arn (mod m)

Es mas simple (mas rapido).Correlaciones no son mas fuertes.Hay que evitar r0 = 0 como valor inicial.

Algoritmo multiplicativo congruencial.Otra posibilidad.

Tambien es una recursion, pero mas simple:

rn+1 = arn (mod m)

Es mas simple (mas rapido).Correlaciones no son mas fuertes.Hay que evitar r0 = 0 como valor inicial.

Park & Miller.

Parametros de Park & Miller:

a = 75 = 16807m = 231 − 1 = 2,147,483,647

Resultados en un intervalo [0,2,147,483,646]. Se necesita por lomenos unsigned long int que tiene valor maximal4,294,967,295.Secuencia tiene largo L = m = 2,147,483,647.Multiplicacion a× rn resulta en valores mas grandes queunsigned long int. Entonces se necesita long long intque es 64bit (existe solo en ANSI C99).

Park & Miller.

Parametros de Park & Miller:

a = 75 = 16807m = 231 − 1 = 2,147,483,647

Resultados en un intervalo [0,2,147,483,646]. Se necesita por lomenos unsigned long int que tiene valor maximal4,294,967,295.Secuencia tiene largo L = m = 2,147,483,647.Multiplicacion a× rn resulta en valores mas grandes queunsigned long int. Entonces se necesita long long intque es 64bit (existe solo en ANSI C99).

Park & Miller.

Parametros de Park & Miller:

a = 75 = 16807m = 231 − 1 = 2,147,483,647

Resultados en un intervalo [0,2,147,483,646]. Se necesita por lomenos unsigned long int que tiene valor maximal4,294,967,295.Secuencia tiene largo L = m = 2,147,483,647.Multiplicacion a× rn resulta en valores mas grandes queunsigned long int. Entonces se necesita long long intque es 64bit (existe solo en ANSI C99).

Park & Miller.

Parametros de Park & Miller:

a = 75 = 16807m = 231 − 1 = 2,147,483,647

Resultados en un intervalo [0,2,147,483,646]. Se necesita por lomenos unsigned long int que tiene valor maximal4,294,967,295.Secuencia tiene largo L = m = 2,147,483,647.Multiplicacion a× rn resulta en valores mas grandes queunsigned long int. Entonces se necesita long long intque es 64bit (existe solo en ANSI C99).

Implementacion.rn_parkmiller.c

En C89 no habia long long int, por eso el programa (veNumerical Recipes version 2) es bien complicado — en C99 es trivial:

1 /*! \file rn_parkmiller.c */2

3 #define RND_M 2147483647LL4 #define RND_A 16807LL5 #define RND_CONVERSION (1.0/RND_M)6

7 /*! Calculates random numbers with an multiplicative8 congruential algorithm using the parameters9 following Park & Miller. ’irnd’ is a pointer

10 to the seed (inicial) value, that will be changed11 and used during the calculation. */12 double rand_parkmiller(long long int* irnd)13 14 (*irnd) = (RND_A * (*irnd)) % RND_M;15 return RND_CONVERSION * (*irnd);16

Comparacion Park & Miller con rand().main_rn_pm.c

1 #include <stdio.h>2 #include <stdlib.h>3

4 #define NBIN 505 #define N 40000000L6 #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

22 for (xpos = 0; xpos < NBIN; xpos++)23 for (ypos = 0; ypos < NBIN; ypos++)24 bin[xpos][ypos] = 0.0;25

26 irnd = 1;27 for (n = 0; n < N; n++) 28 x = rand_parkmiller(&irnd);29 y = rand_parkmiller(&irnd);30 xpos = searchidx(x, binscale, NBIN+1);31 ypos = searchidx(y, binscale, NBIN+1);32 bin[xpos][ypos] += P;33 34

35 for (xpos = 0; xpos < NBIN; xpos++) 36 for (ypos = 0; ypos < NBIN; ypos++)37 printf("%f %f %f\n", binscale[xpos], binscale[ypos],38 bin[xpos][ypos]);39 printf("\n");40 41

42 printf("\n\n\n");

Comparacion Park & Miller con rand().main_rn_pm.c

44 for (xpos = 0; xpos < NBIN; xpos++)45 for (ypos = 0; ypos < NBIN; ypos++)46 bin[xpos][ypos] = 0.0;47

48 srand(1);49 for (n = 0; n < N; n++) 50 x = rand() / ((double)RAND_MAX);51 y = rand() / ((double)RAND_MAX);52 xpos = searchidx(x, binscale, NBIN+1);53 ypos = searchidx(y, binscale, NBIN+1);54 bin[xpos][ypos] += P;55 56

57 for (xpos = 0; xpos < NBIN; xpos++) 58 for (ypos = 0; ypos < NBIN; ypos++)59 printf("%f %f %f\n", binscale[xpos], binscale[ypos],60 bin[xpos][ypos]);61 printf("\n");62 63

64 return 0;65

Correlaciones en una secuencia.Park & Miller versus rand(): 40,000,000 numeros pseudo-aleatorios en 50× 50 bins.

0.000775 0.00078 0.000785 0.00079 0.000795 0.0008 0.000805 0.00081 0.000815 0.00082 0.000825

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

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.

0.00078 0.000785 0.00079 0.000795 0.0008 0.000805 0.00081 0.000815 0.00082 0.000825

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

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

1 /*! \file rn_shuffle.c */2

3 #define RND_M 2147483647LL4 #define RND_A 16807LL5 #define RND_CONVERSION (1.0/RND_M)6 #define RND_NTAB 327 #define RND_NDIV (1+(RND_M-1)/RND_NTAB)8

9 /*! Calculates a shuffled version of10 Park-Miller random numbers. */11 double rand_shuffle(long long int* irnd)12 13 static long long int iy;14 static long long int iv[RND_NTAB];15 static int init = 1;16 int j;

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.8e−05 1.9e−05 2e−05 2.1e−05 2.2e−05 2.3e−05 2.4e−05 2.5e−05 2.6e−05 2.7e−05

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

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.8e−05 1.9e−05 2e−05 2.1e−05 2.2e−05 2.3e−05 2.4e−05 2.5e−05 2.6e−05 2.7e−05

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1

0

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1

Parte XTrayectorias cuánticas

Operador de densidad.

En la mecánica cuántica tenemos la ecuación de Schrödinger:

i~∂

∂t|Ψ(t)〉 = H|Ψ(t)〉

donde en una representación de la posición (auto-estadosx |x〉 = x |x〉) tenemos la función de onda:

Ψ(x , t) = 〈x |Ψ(t)〉

Como esta función NO es una densidad de probabilidad sino esuna “amplitud de probabilidad”, podemos construir algo máscercano a una probabilidad — el operador de densidad:

%(t) = |Ψ(t)〉〈Ψ(t)|

La densidad de probabilidad para observar el sistema en laposición x es ahora simplemente:

p(x , t) = 〈x |%(t)|x〉 = |〈x |Ψ(t)〉|2 = |Ψ(x , t)|2

Operador de densidad.

En la mecánica cuántica tenemos la ecuación de Schrödinger:

i~∂

∂t|Ψ(t)〉 = H|Ψ(t)〉

donde en una representación de la posición (auto-estadosx |x〉 = x |x〉) tenemos la función de onda:

Ψ(x , t) = 〈x |Ψ(t)〉

Como esta función NO es una densidad de probabilidad sino esuna “amplitud de probabilidad”, podemos construir algo máscercano a una probabilidad — el operador de densidad:

%(t) = |Ψ(t)〉〈Ψ(t)|

La densidad de probabilidad para observar el sistema en laposición x es ahora simplemente:

p(x , t) = 〈x |%(t)|x〉 = |〈x |Ψ(t)〉|2 = |Ψ(x , t)|2

Operador de densidad.

En la mecánica cuántica tenemos la ecuación de Schrödinger:

i~∂

∂t|Ψ(t)〉 = H|Ψ(t)〉

donde en una representación de la posición (auto-estadosx |x〉 = x |x〉) tenemos la función de onda:

Ψ(x , t) = 〈x |Ψ(t)〉

Como esta función NO es una densidad de probabilidad sino esuna “amplitud de probabilidad”, podemos construir algo máscercano a una probabilidad — el operador de densidad:

%(t) = |Ψ(t)〉〈Ψ(t)|

La densidad de probabilidad para observar el sistema en laposición x es ahora simplemente:

p(x , t) = 〈x |%(t)|x〉 = |〈x |Ψ(t)〉|2 = |Ψ(x , t)|2

Ecuación de Liouville.

La ecuación de movimiento sale de la ecuación de Schrödingercomo

i~∂

∂t%(t) =

(H%(t)− %(t)H

)= [H, %(t)]

Es la ecuación de Liouville conocido de la estadística clásica.En la estadística clásica el teorema de Liouville dice que elvolumen ocupado en el espacio de fase es incompressible.Para la densidad de probabilidad en el espacio de fase saleentonces:

ddtρ(qi ,pi, t) = 0,

En el caso de la estadística cuántica entonces:

ddt→ ∂

∂t+

1i~

[H, ]

por lo tanto siempre es la derivada parcial que sale en laecuación.

Ecuación de Liouville.

La ecuación de movimiento sale de la ecuación de Schrödingercomo

i~∂

∂t%(t) =

(H%(t)− %(t)H

)= [H, %(t)]

Es la ecuación de Liouville conocido de la estadística clásica.En la estadística clásica el teorema de Liouville dice que elvolumen ocupado en el espacio de fase es incompressible.Para la densidad de probabilidad en el espacio de fase saleentonces:

ddtρ(qi ,pi, t) = 0,

En el caso de la estadística cuántica entonces:

ddt→ ∂

∂t+

1i~

[H, ]

por lo tanto siempre es la derivada parcial que sale en laecuación.

Ecuación de Liouville.

La ecuación de movimiento sale de la ecuación de Schrödingercomo

i~∂

∂t%(t) =

(H%(t)− %(t)H

)= [H, %(t)]

Es la ecuación de Liouville conocido de la estadística clásica.En la estadística clásica el teorema de Liouville dice que elvolumen ocupado en el espacio de fase es incompressible.Para la densidad de probabilidad en el espacio de fase saleentonces:

ddtρ(qi ,pi, t) = 0,

En el caso de la estadística cuántica entonces:

ddt→ ∂

∂t+

1i~

[H, ]

por lo tanto siempre es la derivada parcial que sale en laecuación.

Ecuación maestra.

Vamos a separar el sistem total en un sistema de interés (átomo)y en su ambiente (radiación em).Después vamos a integrar (traza) sobre los variables delambiente, que actua como un reservorio (termico).Asi queda una ecuación efectiva y aproximativa (aproximaciónBorn-Markov) para la dinamica del sistema de interés:

∂t% =

1i~

[H, %] +∑λ

Sλ%S†λ −

12

S†λSλ%−12%S†λSλ

eso es la ecuación maestra en forma de Lindblad.

Ecuación maestra.

Vamos a separar el sistem total en un sistema de interés (átomo)y en su ambiente (radiación em).Después vamos a integrar (traza) sobre los variables delambiente, que actua como un reservorio (termico).Asi queda una ecuación efectiva y aproximativa (aproximaciónBorn-Markov) para la dinamica del sistema de interés:

∂t% =

1i~

[H, %] +∑λ

Sλ%S†λ −

12

S†λSλ%−12%S†λSλ

eso es la ecuación maestra en forma de Lindblad.

Ecuación maestra.

Vamos a separar el sistem total en un sistema de interés (átomo)y en su ambiente (radiación em).Después vamos a integrar (traza) sobre los variables delambiente, que actua como un reservorio (termico).Asi queda una ecuación efectiva y aproximativa (aproximaciónBorn-Markov) para la dinamica del sistema de interés:

∂t% =

1i~

[H, %] +∑λ

Sλ%S†λ −

12

S†λSλ%−12%S†λSλ

eso es la ecuación maestra en forma de Lindblad.

Ejemplo: Oscilador armónico con fricción.

La fricción es la interacción con muchos átomos de un materialen contacto con el pendulo del oscilador.El reservorio son estos átomos.La ecuación maestra sale después la aproximación Born-Markovcomo:

∂t% =

1i~

[~ω(

a†a +12

), %] + γ

a%a† − 1

2a†a%− 1

2%a†a

donde a anihila una cuánta de energía del oscilador y γ es laconstante de fricción(actualmente es una función de correlación del reservorio).

Ejemplo: Oscilador armónico con fricción.

La fricción es la interacción con muchos átomos de un materialen contacto con el pendulo del oscilador.El reservorio son estos átomos.La ecuación maestra sale después la aproximación Born-Markovcomo:

∂t% =

1i~

[~ω(

a†a +12

), %] + γ

a%a† − 1

2a†a%− 1

2%a†a

donde a anihila una cuánta de energía del oscilador y γ es laconstante de fricción(actualmente es una función de correlación del reservorio).

Ejemplo: Oscilador armónico con fricción.

La fricción es la interacción con muchos átomos de un materialen contacto con el pendulo del oscilador.El reservorio son estos átomos.La ecuación maestra sale después la aproximación Born-Markovcomo:

∂t% =

1i~

[~ω(

a†a +12

), %] + γ

a%a† − 1

2a†a%− 1

2%a†a

donde a anihila una cuánta de energía del oscilador y γ es laconstante de fricción(actualmente es una función de correlación del reservorio).

Solución formal de la ecuación maestra.Tenemos la ecuación maestra como:

∂t% =

1i~

[H, %] + S%S† − 12

S†S%− 12%S†S

=1i~

(

H − i~2

S†S)

︸ ︷︷ ︸Hef

%− %

(H − i~

2S†S

)†︸ ︷︷ ︸

H†ef

+ S%S†

donde ahora H†ef 6= Hef.

Se puede escribir formalmente con (super-) operadores:

∂t% =

(L0 + L1

)%

donde:

L0 . . . =1i~

(Hef . . .− . . . H†

ef

), L1 . . . = S . . . S†

La solución formal es entonces:

%(t) = e(L0+L1)(t−t0)%(t0)

Solución formal de la ecuación maestra.Tenemos la ecuación maestra como:

∂t% =

1i~

[H, %] + S%S† − 12

S†S%− 12%S†S

=1i~

(

H − i~2

S†S)

︸ ︷︷ ︸Hef

%− %

(H − i~

2S†S

)†︸ ︷︷ ︸

H†ef

+ S%S†

donde ahora H†ef 6= Hef.

Se puede escribir formalmente con (super-) operadores:

∂t% =

(L0 + L1

)%

donde:

L0 . . . =1i~

(Hef . . .− . . . H†

ef

), L1 . . . = S . . . S†

La solución formal es entonces:

%(t) = e(L0+L1)(t−t0)%(t0)

Solución formal de la ecuación maestra.Tenemos la ecuación maestra como:

∂t% =

1i~

[H, %] + S%S† − 12

S†S%− 12%S†S

=1i~

(

H − i~2

S†S)

︸ ︷︷ ︸Hef

%− %

(H − i~

2S†S

)†︸ ︷︷ ︸

H†ef

+ S%S†

donde ahora H†ef 6= Hef.

Se puede escribir formalmente con (super-) operadores:

∂t% =

(L0 + L1

)%

donde:

L0 . . . =1i~

(Hef . . .− . . . H†

ef

), L1 . . . = S . . . S†

La solución formal es entonces:

%(t) = e(L0+L1)(t−t0)%(t0)

Trayectorias cuánticas.

Esta solución se puede escribir en una expansión:

%(t) =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1eL0(t−tn)L1eL0(tn−tn−1)L1 . . . L1eL0(t1−t0)%(t0)

Como:

eL0(t−t′) . . . = e−iHef(t−t′)/~︸ ︷︷ ︸Uef(t,t′)

. . .eiH†ef(t−t′)/~︸ ︷︷ ︸

U†ef(t,t

′)

, L1 = S . . . S†

usando un estado inicial %(t0) = |Ψ(t0)〉〈Ψ(t0)|, la solución sepuede escribir también como:

%(t) =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1|Ψ(t ; tn, . . . , t1)〉〈Ψ(t ; tn, . . . , t1)|

donde una trayectoria cuántica es dada por:

|Ψ(t ; tn, . . . , t1)〉 = Uef(t , tn)SUef(tn, tn−1)S . . . SUef(t1, t0)|Ψ(t0)〉

Trayectorias cuánticas.

Esta solución se puede escribir en una expansión:

%(t) =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1eL0(t−tn)L1eL0(tn−tn−1)L1 . . . L1eL0(t1−t0)%(t0)

Como:

eL0(t−t′) . . . = e−iHef(t−t′)/~︸ ︷︷ ︸Uef(t,t′)

. . .eiH†ef(t−t′)/~︸ ︷︷ ︸

U†ef(t,t

′)

, L1 = S . . . S†

usando un estado inicial %(t0) = |Ψ(t0)〉〈Ψ(t0)|, la solución sepuede escribir también como:

%(t) =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1|Ψ(t ; tn, . . . , t1)〉〈Ψ(t ; tn, . . . , t1)|

donde una trayectoria cuántica es dada por:

|Ψ(t ; tn, . . . , t1)〉 = Uef(t , tn)SUef(tn, tn−1)S . . . SUef(t1, t0)|Ψ(t0)〉

Una trayectoria cuántica.

Trayectora cuantica:

|Ψ(t ; tn, . . . , t1)〉 = Uef(t , tn)SUef(tn, tn−1)S . . . SUef(t1, t0)|Ψ(t0)〉

donde tiempos tn ≥ tn−1 ≥ . . . ≥ t1 son aleatorios y

Uef(tk , tk−1) = exp

−i~

∫ tk

tk−1

dτ[H(τ)− i~

2S†S

]︸ ︷︷ ︸

=Hef(τ)

promedio estatistico:

%(t) =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1|Ψ(t ; tn, . . . , t1)〉〈Ψ(t ; tn, . . . , t1)|

Probabilidades.

Traza es siempro uno:

Tr[%(t)] =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1

×Tr [|Ψ(t ; tn, . . . , t1)〉〈Ψ(t ; tn, . . . , t1)|]

=∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1

×〈Ψ(t ; tn, . . . , t1)|Ψ(t ; tn, . . . , t1)〉= 1

Densidad de probabilidad para n eventos en tiempos tn, . . . , t1:

p(t ; tn, . . . , t1) = 〈Ψ(t ; tn, . . . , t1)|Ψ(t ; tn, . . . , t1)〉

Probabilidades.

Traza es siempro uno:

Tr[%(t)] =∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1

×Tr [|Ψ(t ; tn, . . . , t1)〉〈Ψ(t ; tn, . . . , t1)|]

=∞∑

n=0

∫ t

t0dtn . . .

∫ t2

t0dt1

×〈Ψ(t ; tn, . . . , t1)|Ψ(t ; tn, . . . , t1)〉= 1

Densidad de probabilidad para n eventos en tiempos tn, . . . , t1:

p(t ; tn, . . . , t1) = 〈Ψ(t ; tn, . . . , t1)|Ψ(t ; tn, . . . , t1)〉

Probabilidad para un evento.

Trayectoria con un evento:

|Ψ(t ; t1)〉 = Uef(t , t1)SUef(t1, t0)|Ψ(t0)〉

Justo despues del evento:

|Ψ(t1; t1)〉 = SUef(t1, t0)|Ψ(t0)〉

Probabilidad para este evento:

P(t1; t1) = dt1〈Ψ(t1; t1)|Ψ(t1; t1)〉= dt1〈Ψ(t0)|U†

ef(t1, t0)S†S Uef(t1, t0)|Ψ(t0)〉︸ ︷︷ ︸

=|Ψ(t1)〉

= dt1〈Ψ(t1)|S†S|Ψ(t1)〉

Probabilidad para un evento.

Trayectoria con un evento:

|Ψ(t ; t1)〉 = Uef(t , t1)SUef(t1, t0)|Ψ(t0)〉

Justo despues del evento:

|Ψ(t1; t1)〉 = SUef(t1, t0)|Ψ(t0)〉

Probabilidad para este evento:

P(t1; t1) = dt1〈Ψ(t1; t1)|Ψ(t1; t1)〉= dt1〈Ψ(t0)|U†

ef(t1, t0)S†S Uef(t1, t0)|Ψ(t0)〉︸ ︷︷ ︸

=|Ψ(t1)〉

= dt1〈Ψ(t1)|S†S|Ψ(t1)〉

Probabilidad para un evento.

Trayectoria con un evento:

|Ψ(t ; t1)〉 = Uef(t , t1)SUef(t1, t0)|Ψ(t0)〉

Justo despues del evento:

|Ψ(t1; t1)〉 = SUef(t1, t0)|Ψ(t0)〉

Probabilidad para este evento:

P(t1; t1) = dt1〈Ψ(t1; t1)|Ψ(t1; t1)〉= dt1〈Ψ(t0)|U†

ef(t1, t0)S†S Uef(t1, t0)|Ψ(t0)〉︸ ︷︷ ︸

=|Ψ(t1)〉

= dt1〈Ψ(t1)|S†S|Ψ(t1)〉

Probabilidad para no evento.

Vamos a definir:P0(t1) = 〈Ψ(t1)|Ψ(t1)〉

Poco calculus:

P0(t1) =d

dt1〈Ψ(t0)|U†

ef(t1, t0)Uef(t1, t0)|Ψ(t0)〉

= 〈Ψ(t0)|U†ef(t1, t0)

i~

[H†

ef(t1)− Hef(t1)]

︸ ︷︷ ︸=−S†S

Uef(t1, t0)|Ψ(t0)〉

= −〈Ψ(t1)|S†S|Ψ(t1)〉

Probabilidad para no evento.

Vamos a definir:P0(t1) = 〈Ψ(t1)|Ψ(t1)〉

Poco calculus:

P0(t1) =d

dt1〈Ψ(t0)|U†

ef(t1, t0)Uef(t1, t0)|Ψ(t0)〉

= 〈Ψ(t0)|U†ef(t1, t0)

i~

[H†

ef(t1)− Hef(t1)]

︸ ︷︷ ︸=−S†S

Uef(t1, t0)|Ψ(t0)〉

= −〈Ψ(t1)|S†S|Ψ(t1)〉

Conexion.

Conclusion:

P(t1; t1) = p(t1; t1)dt1 = −dP0(t1)dt1

dt1

Entonces:

P0(t1) = 1−∫ t1

t0dτp(τ ; τ)︸ ︷︷ ︸

=Prob. p. evento en [t0, t1]

= Prob. p. no evento en [t0, t1]

Conexion.

Conclusion:

P(t1; t1) = p(t1; t1)dt1 = −dP0(t1)dt1

dt1

Entonces:

P0(t1) = 1−∫ t1

t0dτp(τ ; τ)︸ ︷︷ ︸

=Prob. p. evento en [t0, t1]

= Prob. p. no evento en [t0, t1]

Algoritmo.

|Ψ(tk+1)〉 = Uef(tk+1, tk)|Ψ(tk)〉P0(tk+1) = 〈Ψ(tk+1)|Ψ(tk+1)〉Calcular numero aleatorio R

|Ψ(t0)〉tk = t0

1− P0(tk+1) > R ?

Evento al tiempo tk+1:

tk = tk+1

NO SI

|Ψ(tk+1)〉 = S|Ψ(tk+1)〉/| . . . |

Implementacion.qt_qtsolve.c

1 /*! \file qt_solve.c */2

3 #include <stdlib.h>4 #include <assert.h>5 #include <math.h>6 #include <float.h>7 #include <complex.h>8

9 #define SAFETY_FACTOR 0.910

11 int de_solve_cpx(complex double*, size_t, double, double,12 double, double, void (*)(complex double*, complex double*,13 double));14 double rand_shuffle(long long int*);

Implementacion.qt_qtsolve.c

16 double qt_jumpprob(complex double* y, size_t sz)17 18 double res, tmp;19 size_t n;20

21 res = 0.0;22 for (n = 0; n < sz; n++) 23 tmp = cabs(y[n]);24 res += tmp * tmp;25 26 return 1.0 - res;27

Implementacion.qt_qtsolve.c

29 /*! Calculation of a quantum trajectory. Integrate starting30 values y[0..sz-1] from t1 to t2 with (relative) accuracy31 eps. y[..] is replaced by values at the end of the32 integration interval. derivs is the user-supplied33 routine for calculating the right-hand side derivative.34 jump calculates the jump and returns the norm of the35 resulting state, irnd is the initial seed for random-36 number generation. */37 int qt_solve(complex double *y, size_t sz, double t1, double t2,38 double eps,39 void (*derivs)(complex double*, complex double*, double),40 double (*jump)(complex double*, double), long long int* irnd)41 42 size_t i;43 double t, dt, dtmin, diff_prob, norm;44 complex double *ytmp;45 int min_cnt, ok;46 static double rnd;47 static int init = 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 10008 #define POINTS 10009 #define SZ 11

10 #define GAMMA 0.0511

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

16 void calc_ini(complex double* psi)17 18 size_t n;19

20 for (n = 0; n < SZ; n++)21 psi[n] = 0.0;22 psi[SZ-1] = 1.0;23 24

25 /* Harmonic oscilator with damping: */26 void derivs(complex double *dpsidt, complex double *psi,27 double t)28 29 size_t k;30

31 for (k = 0; k < SZ; k++)32 dpsidt[k] = - (I + 0.5 * GAMMA) * k * psi[k];33

Resultados.main_qt_oscidamped.c

35 double jump(complex double* psi, double t)36 37 size_t k;38 double norm, tmp;39

40 norm = 0;41 for (k = 0; k < SZ-1; k++) 42 psi[k] = psi[k+1] * sqrt(GAMMA * (k+1.0));43 tmp = cabs(psi[k]);44 norm += tmp * tmp;45 46 psi[SZ-1] = 0.0;47 return norm;48

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

65 for (traj = 1; traj <= TRAJ_MAX; traj++) 66 calc_ini(psi);67 irnd = traj;68 t = 0.0;69 for (i = 0; i < POINTS; i++) 70 qt_solve(psi, SZ, t, t+tstep, 1.0e-7, derivs,71 jump, &irnd);72 t += tstep;73 quanta = 0.0;74 norm = 0.0;75 for (k = 0; k < SZ; k++) 76 tmp = cabs(psi[k]);77 norm += tmp * tmp;78 quanta += k * tmp * tmp;79 80 if (norm > DBL_MIN) 81 data[i] += quanta / norm;82 83 printf("%f %g\n", t, data[i] / traj);84 85 printf("\n\n");86 87 return 0;88

Promedio de trayectorias.

0

2

4

6

8

10

0 10 20 30 40 50 60 70 80 90 100

N = 1

Promedio de trayectorias.

0

2

4

6

8

10

0 10 20 30 40 50 60 70 80 90 100

N = 5

Promedio de trayectorias.

0

1

2

3

4

5

6

7

8

9

10

0 10 20 30 40 50 60 70 80 90 100

N = 50

Promedio de trayectorias.

0

1

2

3

4

5

6

7

8

9

10

0 10 20 30 40 50 60 70 80 90 100

N = 100